Filter results by

Proxy Hub

Using the Proxy Hub, you can connect devices that cannot directly communicate to ARTIK cloud services. The Proxy Hub is ideal for any of the following scenarios:

  • The device only has local network connection (e.g. Bluetooth, ZigBee) and cannot access the internet directly.
  • The device does not offer an external cloud or necessary APIs for building a Cloud Connector.
  • Your device benefits from real-time device status updates and increased rate limits. For example, the Proxy Hub is the ideal way to control and monitor Philips Hue on ARTIK cloud services.

The Proxy Hub discovers and maps local devices to virtual devices on ARTIK cloud services via proxy plugins. Supported device types are updated on our Works With page.

This article describes how to build new proxy plugins for your devices.

What is a proxy plugin?

The Proxy Hub can host multiple proxy plugins. A proxy plugin does the following for local device types:

  • Maps local physical devices to existing virtual devices on ARTIK cloud services or new virtual devices that it creates on ARTIK cloud services.
  • Sends local device data to ARTIK cloud services.
  • Relays Actions from ARTIK cloud services to local devices.

A plugin communicates with local devices via a device-specific hub (e.g. Philips Hue hub), intermediate software, manufacturer SDK, connectivity protocols (e.g. Zigbee, Z-Wave), or external APIs.

Use the hub

Prerequisites

  • node (Version >= 4.5.0)

Installation and setup

The Proxy Hub must be installed on a computer that can access devices (on your local network).

Download the Proxy Hub application. cd to the folder where the program was unzipped.

In order to add a supported device after Proxy Hub setup, also download and add its corresponding plugin to the /proxies folder, if it is not already there.

At the root directory, run this command to install the hub:

1
npm install

On a machine with a fixed IP address, run this command to start the server:

1
npm start

On the terminal, you will see the following line. Load the URL in a browser.

1
GO TO THIS WEBPAGE TO ACCESS THE UI: <url>

You will be prompted to login to ARTIK cloud services. After logging in, the UI will guide you through hub setup. Afterward, you will have created an application in the Developer Dashboard and used the application information to configure the hub.

Proxy Hub Setup Process

Add a device

To add a currently supported device type to the Proxy Hub, click "Add Another Device", then select the device type to add.

Device types can be added to the Proxy Hub only if their plugins have been downloaded and added to /proxies. See Installation and setup.

Add Devices

A device is either discovered by the hub or added manually. A physical device (e.g. Philips Hue) should be discoverable. A device which is a piece of software running on a local machine (e.g. Shell Proxy and TTS Player) is added manually. We refer to these two types of local devices as discoverable and on-demand.

After adding the device type to the hub, you will see that a corresponding virtual device is added to your account. You can then log off from the hub in your browser. You must keep the server running. The devices will continue to communicate with ARTIK cloud services via their proxy plugins on the hub.

Develop a new proxy plugin

You can extend the Proxy Hub by adding a new proxy plugin.

The proxy plugin must correspond to at least one device type in ARTIK cloud services. If the device type does not exist, first create one and define its Manifest. Note the device type's ID by viewing its details in the Dashboard.

Please be aware that one proxy plugin can handle devices of multiple device types (e.g. Belkin WeMo).

  • Duplicate the _template folder included with the proxy plugins in the repo
  • Rename the folder (folders beginning with a "_" will not be loaded)
  • Update template.js:
    • Rename the JavaScript file
    • Rename the Template class
    • Implement logics relevant to your proxy
  • Update package.json:
    • Fill in "name" with a meaningful name
    • Import any API libraries you wish to use in the above JavaScript into this file.
  • Update config.json

The below discussion is limited to the files in the renamed _template folder, implementing logistics in the renamed template.js file, and setting up the config.json file, unless otherwise specified.

Add or discover a device

The Proxy Hub recognizes two types of local devices: discoverable and on-demand. You implement init() for a discoverable device (e.g. Philips Hue) and addNewDevice() for an on-demand device (e.g. TTS Player).

Discover a device

Implement init() function and remove addNewDevice() in the JavaScript file. In init(), discover local devices, and then declare each of them by emitting a newDevice event. To discover a device, you normally need the libraries provided by the manufacturer of the device.

The following code snippet uses a fictional third-party device library called sdk_bluetoothlock. For working examples, see the philips-hue and wemo directories on GitHub.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
bleLocker.prototype.init = function () {
  /* Use the appropriate libraries to discover local devices, and then 
   * emit "newDevice" for each device found. This will display the device 
   * in the hub UI.
   *
   * device_info: device data from the discovered device
   */
  device_info = sdk_bluetoothlock.onDiscover( function(device_info){
    this.emit('newDevice', {
      'proxyDeviceInternalId': device_info.id,
      'proxyDeviceName': device_info.name,
      'proxyDeviceTypeName': 'ProxyDT',
      'akcDtid': 'dt1234',
      'proxyDeviceData': device_info.data
    })
    
    // The following emit function will send a message to ARTIK Cloud. 
    // Payload format should be consistent the corresponding device Manifest.
    // Here it is assumed that payload is {'state', string}
    this.emit('newMessage', device_info.id, { 'state': device_info.data.status })
  })
  
  // If needed, send status massege to ARTIK Cloud upon state of the device changes
  sdk_bluetoothlock.onNewEvent( function(device_info){
    this.emit('newMessage', device_info.id, { 'state': device_info.data.status })
  })

  sdk_bluetoothlock.startDiscovery()
}

proxyDeviceInternalId: Manage this as you like.
proxyDeviceName: Choose a relevant device name.
proxyDeviceTypeName: The device type name to be shown in the hub.
akcDtid: The device type ID used by ARTIK cloud services.
proxyDeviceData: Custom data that you manage.

Consider putting the values of some fields into config.json and reading the values from that file.

addNewDevice() is not needed for a discoverable device.

Add an on-demand device

Implement addNewDevice() function and remove init().

The following code snippet illustrates the implementation of addNewDevice(). For working examples, see the shell and mediaplayer directories on GitHub.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Shell.prototype.addNewDevice = function () {
var name = this._config.public.defaultName
var id = 'shell.'+Date.now()

this.emit('newDevice', {
'proxyDeviceInternalId': id,
'proxyDeviceName': name,
'proxyDeviceTypeName': 'New Shell Proxy',
'akcDtid': this._akcDtid,
'proxyDeviceData': name
})

// device is off by default
// Payload format should be consistent with the corresponding device Manifest. 
// Here it is assumed that payload is {'state', string}
this.emit('newMessage', id, { 'state': 'off' })
....
}

Send data to ARTIK cloud services

The proxy plugin should periodically send a device status to ARTIK cloud services. You can do this in the init() function for a discoverable device (e.g. with a callback named onNewEvent in the code snippet).

To send status, call emit() with type newMessage. Pass the JSON message that describes the device status. The message format should be consistent with the corresponding device Manifest in ARTIK cloud services.

1
this.emit('newMessage', 'proxyDeviceInternalId', {'state':'on' })

Receive Actions from ARTIK cloud services

For each Action defined in the device Manifest, create a function suffixed by "Action". For example, if the Manifest defines Action setOn, you should implement function setOnAction here.

1
2
3
4
Template.prototype.setOnAction = function (proxyDeviceInfo) {
  // actionParams map can be omitted for action with no parameters
}

If an Action has parameters, you can get them from actionParams as a JSON map:

1
2
3
4
Template.prototype.setStateAction = function (proxyDeviceInfo, actionParams) {
  // Act on Action to set the state of the device managed by the hub
  // Use received parameters to perform that operation.
}

Schedule update

The hub can perform updates at regular intervals. For example, you can get the status of the devices and send them to ARTIK cloud services. To do so, specify scheduleUpdate to true in config.json and implement scheduledUpdate() function in the JavaScript file as follows:

1
2
3
// in config file
"scheduleUpdate": true,
"scheduleUpdatePeriodMs": 30000,
1
2
3
4
5
// in proxy JavaScript file
Template.prototype.scheduledUpdate = function () { 
  // Do device refreshing and status update with ARTIK Cloud
  // Use the value of 'scheduleUpdatePeriodMs' from config.json
}

Get the proxy plugin status

On the getStatus() function, you can reflect the status of the proxy plugin. Optionally warn the user to perform an Action. In the status, level can be OK, WARNING, or ERROR, with the corresponding codes 200, 401, or 403. Below is an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
PhilipsHue.prototype.getStatus = function () {
  if (this.hueBridgeLinkButtonHasNotBeenPressed) {
    return {
      'level': 'ERROR',
      'message': 'Please press your Hue Bridge Link Button to discover your lights',
      'code': 403
    }
  }
  else {
    return {
      'level': 'OK',
      'message': '',
      'code': 200
    }
  }
}

Add user parameters for proxy plugin

Define parameters

You can optionally add user parameters for a proxy plugin. For example, use the parameters to store user credentials for the external platform. Define them in the userParameters array in the config.json file. The following shows userParameters of config.json for the Nest proxy plugin:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public: {
  ...
  "userParameters": [
    {
      "name": "username",
      "value": "",
      "type": "string",
      "description": "NEST account login e-mail"
    },
    {
      "name": "password",
      "value": "",
      "type": "password",
      "description": "NEST account password"
    }
  ],
  ...
}

Access parameters

You can access user parameters within the JavaScript code as follows:

1
2
3
var userParams = config.public.userParameters
username = userParams[0].value
password = userParams[1].value

Update parameters

In the JavaScript code, you can update userParameters of config.json. You need to do this if the user modifies the parameters via UI. The following example shows how to change the user name. In the JavaScript code, update the configuration object with the one provided by the user, serialize it as a JSON object, and then write it to the config.json:

1
2
3
this._config.username = user
var configPath = path.resolve(__dirname, 'config.json')
Fs.writeFileSync(configPath, JSON.stringify(this._config, null, 2))

Validate parameters

You can implement validateUserParameters() in the JavaScript code. It checks the parameters provided by the user and throws any JavaScript exception to warn the user when applicable:

1
2
3
4
Template.prototype.validateUserParameters = function (userParams) {
  logger.debug(userParams)
  //Check if userParams are valid.....
}

Add user parameters for device

You can set up default user parameters for individual devices. Fill in the userParametersPerDevice group in config.json as follows:

1
2
3
4
5
6
7
8
9
{
  "userParametersPerDevice": {
    "mediaplayer": {
      "displayName": "Media player command",
      "value": "mplayer",
      "description": "Shell command used to play media."
    },
  },
}

userParametersPerDevice can have multiple objects. For each object (e.g. mediaplayer), the displayName, value, and description are displayed on the web UIs of the Proxy Hub. The following UI example matches the values in the above JSON example:

Proxy Hub user device parameter

The JavaScript code can access device's user parameters via the proxyDeviceInfo.userParametersPerDevice object, as shown below:

1
 var player = proxyDeviceInfo.userParametersPerDevice.mediaplayer.value

Logging

To log, include the logging module and create a logger object in the JavaScript code:

1
2
var ProxyHubLogger = require('../../lib/proxy-hub-logger.js')
logger = ProxyHubLogger(<name display in log>, <config file of the proxy>)

In the root level config.json (not the config.json for each proxy plugin), you can specify the logging level (debug, warn, or error) and a log filename. If you do not specify filename, the logs are displayed on your terminal.

1
2
3
4
"log": {
  "level": "debug",
  "filename": "log/proxyhub.log"
}

Below is a usage example:

1
2
logger.log('debug', 'Create MediaPlayer proxy')
logger.debug("userParams = " + JSON.stringify(userParams))

Mandatory fields in config.json

Your config.json must specify the value of akcDtNames. It is an array of the display names of the device types on ARTIK cloud services used by your proxy plugin. Below is an example:

1
2
3
4
"akcDtNames": [
  "Belkin WeMo Switch Proxy",
  "Belkin WeMo Insight Switch Proxy"
]