Custom Devices - implemented externally or in p44script
What are "Custom Devices"?
"Custom devices" are devices that behave in the system (Digital Strom with P44-DSB-xx, or via matter integration) exactly like other devices, but can be implemented by the user in a simple way. In this way, special hardware can also be easily integrated into the Smart Home, for example via an http API or (e.g. on P44-DSB-X) via direct hardware extensions (RaspberryPi shields, chips connected to GPIO, etc.).
How are "Custom Devices" created?
"Custom Devices" can be implemented in two different ways:
-
Starting with firmware version 2.6.0 directly in the P44-xx device as p44script. This kind of external devices can be created completely from the web interface of P44-xx devices, and are also saved in the configuration backups as part of the device configuration. p44script provides a lot of convenient functions to control different kinds of devices: from functions for accessing HTTP APIs (geturl, posturl, puturl), direct access to digital (digitalio) and analog (analogio) inputs and outputs, to motors with limit switches and current monitoring (dcmotor), to the graphics subsystem lrgraphics for SmartLED chains, a lot is possible. Here are easy to implement/extend examples to find.
-
Already since firmware 1.5.0.8 there is the external device API. With this API an external script or application can connect to a P44-xx device via a TCP socket and easily integrate devices into the smarthome system. This way is useful e.g. to establish connections between different systems, or to integrate devices with very complex implementation that would go beyond the scope of p44Script performance. Here are several examples to find how the external device API can be used.
These two possible implementation types work almost identically in concept, the only difference is where the implementation runs (inside the P44-xx device as p44script, or outside and connected via TCP socket). In both cases, however, the communication "language" of the device implementation with the system is the same, namely the external device API. For p44script implementations, the message() function is used to receive and send external device API messages. For fully external devices, messages are exchanged over TCP/IP.
Similarities between p44script and external implementations
- The device is described to the system by the so-called init message, which takes the form of a JSON object.
- In the init-message you can choose between a very simple text variant and a more detailed JSON variant for further communication. By default JSON is used, which is very easy to read and write in p44Script.
- The implementation only has to take care of passing output values given by the system to the hardware and reporting input values to the system. All the complexity of scenes, room assignments, click detection, dimming behavior, sensor value filters, etc. is handled by the p44-xx device.
Differences between p44script and external implementations
- For p44script implementations, the init message is entered once when the device is created in the web interface. For external devices, the init message must be submitted at the beginning of communication (each time the TCP connection is re-established).
- For p44script implementations, the init message may be written on multiple lines and may even contain C-style comments
/* ... */
. For external implementations, the whole init-message must be sent on a single line and as pure JSON without comments (because the end of line is taken as a message separator). - In external implementations, it is possible to run multiple devices over a single TCP connection; the messages are then assigned to different devices via so-called tags. In p44script implementations there is no such multiple device mechanism, and therefore no tags. The references to tag parameters in the following description of the external device API are therefore irrelevant for p44script implementations.
- In p44script implementations the messages initvdc, log and bye are not available.
Using the external device API from p44script implementations
Creating p44script based devices
To create a p44script based device, use the "+ Scripted" button in the P44-xx web interface. You can then enter a init message (specification below), which is then immediately used to create a device.
Operation of p44script implemented devices
The device must be implemented in a script that basically does the following
-
initialize the device (set-up hardware, initialize parameters etc.)
-
If the device has outputs, make sure to have a handler processing incoming messages, like:
on (message()) as m {
// check the message and act upon channel changes etc.
if (m.message="channel") {
// ...update the channel in the hardware
}
}
- If the device has buttons, inputs or sensors, make sure to use message(msg_to_send) to report to the system when inputs change. This can be done from a permanently running main loop (but do not forget to include enough delay() to avoid using excessive CPU time and slow down the entire device!), or
on() {...}
handlers based on input events or regular timing (e.g. using the every() function), for example
on (every(0:05)) {
// every 5 minutes, poll a sensor
var s = getmysensorvalue()
var m = { 'message': 'sensor', 'index':0 }
m.value = s;
message(m)
}
- either keep running (e.g. in a loop) or return true. Note that returning true (or keep running) is essential because all other ways a script ends is treated as a possibly temporary problem, which means the script is re-started. Only if the implementation scripts returns true, this is treated as an OK signal meaning that the device can operate without a script running permanently (i.e. only via
on(...) {}
handlers that trigger some code when needed)
For more information, see the examples.
Using the external device API via TCP-IP
To host external devices, vdcd must be started with the --externaldevices option, providing a port number or absolute unix socket path for device implementation to connect to. For security reasons, it is recommended to run the scripts and programs implementing devices on the same device as vdcd itself. However for development purposes the --externalnonlocal command line option can be specified to allow device API connections from non-local clients.
The plan44.ch Digital Strom products P44-DSB-xx and P44-DSB-xx support the external device API from version 1.5.0.8 onwards. Multiple devices sharing a single connection is supported from version 1.5.2.0 onwards. Single device support is supported from 1.6.0.2 onwards. However, the external device API is active by default only for P44-DSB devices enabled for "testing"/beta (available upon request), or for devices with userlevel set to 1 or higher (default for production devices is 0, can be set to 1 via remote support upon request). In the free "P44-DSB-X" plan44.ch image for RaspberryPi, the external device API is always enabled. By default, vdcd uses port 8999 for the external device API
Operation of TCP-IP connected external devices
Each external device implementation needs to
- open a connection to the TCP port or unix socket specified with the --externaldevices vdcd command line option (default is port 8999).
- optionally, send a initvdc message to adjust vdc-level data (like vdc model name and icon)
- send a init message declaring the properties of the device (specifying outputs, inputs, names, default group membership etc.). The init message uses JSON syntax. However, no JSON support is actually needed in a device implementation, because the init message can specify to use a extremely simple text protocol for any communication beyond the init message itself. And the init message is usually a constant string that can be sent easily using any programming language. (Note that for single devices, which have complex actions and events, and for some advanced features like output transition times, only the JSON syntax is supported).
- enter a loop, waiting for messages from the vdcd indicating output channel changes, or sending messages to the vdcd indicating input changes.
- When connection closes (due to error or when vdcd explicitly closes it), the device implementation should restart, see first bullet point. This can be achieved within the device implementation itself, or by having the device implementation run as a daemon under control of a daemon supervisor like runit or procd or systemd, which re-start daemons when they terminate.
- from version 1.5.2.0 onwards, multiple devices can be created on the same TCP connection. To distinguish them, each one must be assigned a tag in the init message, which must/will then be used in all further messages to/from that device.
Message Format over TCP/IP
Messages consist of strings, delimited by a single LF (0x0A) character. The init message must always be in JSON format. Further messages are either JSON or simple text messages, depending on the protocol option in the init message (see below).
Initvdc Message (only for external devices over TCP/IP)
The optional initvdc message can be sent by an external device implementation to set some vdc-global parameters:
Field | Type | Description |
---|---|---|
message | string | identifies the message type, must be initvdc for the initvdc message |
modelname | optional string | a string describing the vdc model. This will be displayed by the dSS as "HW Info". By default, the vdc has a model name like "P44-DSB-X external" |
modelVersion | optional string | a string providing version information about the hardware device governing the access to a device bus/network such as a KNX bridge. |
iconname | optional string | a string that is used to construct a file name of the icon to be displayed for the vdc.Default for iconname is "vdc_ext". |
configurl | optional string | a URL that will be shown in the context menu of the vdc in the dSS configurator (i.e. the contents of the "configURL" vdc property in the vDC API).If not specified, this will default to the vdchost's default URL (if any). |
alwaysVisible | optional boolean | if set to true, the vdc will announce itself to the vDC API client even if it does not (yet) contain any devices. |
name | optional string | the default name the external vDC will have in the Digital Strom system. Note that this can be changed by the user via dSS Web interface. |
Sending the Init Message over TCP/IP
The init message is sent by a external device implementation as the first message after opening the socket connection. It needs to be formatted as a single line JSON object.
To initialize multiple devices sharing the same connection, multiple init messages can be put into a JSON array. This is required in particular to create multiple devices that are meant to communicate via the simple text API - because after the first message, the protocol will be switched to simple text and would not allow further JSON init messages.
A simple init message for a light dimmer might look like (on a single line):
{'message': 'init','protocol':'simple','output':'light','name':'ext dimmer','uniqueid':'myUniqueID1234'}
A init message for two light dimmers on the same connection might look like (on a single line):
[{'message': 'init', 'tag':'A', 'protocol':'simple', 'output':'light', 'name':'ext dimmer A', 'uniqueid':'myUniqueID1234_A'}, {'message': 'init', 'tag':'B', 'protocol':'simple', 'output':'light', 'name':'ext dimmer B', 'uniqueid':'myUniqueID1234_B'}]
For more information, see the examples.
External device API specification
The rest of this document specifies the external device API protocol and applies to both p44script implemnented devices (where messages are exchanged via the message() function) and externally running implenmentations communicating via TCP/IP.
Init message structure
The following tables describes all possible fields of the init message JSON object:
Field | Type | Description |
---|---|---|
message | string | identifies the message type, must be init for the init message |
protocol | optional string | Can be set to simple to use the simple text protocol for all further communication beyond the init message. This allows implementing devices without need for any JSON parsing.If set to json (default), further API communication are JSON messages. Note: protocol can be specified only in the first init message. It is ignored if present in any subsequent init messages. Note that single devices (those that use actions, events, properties or states) must use the JSON protocol. |
tag | optional string | When multiple devices are created on the same connection, each device needs to have a tag assigned. The tag must not contain '=' or ':'. The tag is used to identify the device in further communication. |
uniqueid | string (optional for p44script devices, required for external API devices) | This string is optional for p44script implemented devices, but required for external API devices. If specified, it must uniquely define the device at least among all other external devices connected to the same vdcd, or even globally.To identify the device globally, use a UUID string (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX) or a valid 34 hex digit Digital Strom dSUID. To identify the device uniquely among all other devices in the same vdcd, use any other string. From firmware 2.7 onwards: If the uniqueid has the form of an URN like schema:hardwareID , then the dSS will display the hardwareID part, which must then be globally unique within the schema (as an example, your device might have a mac-address, then an unique id of the form macaddress:xx:xx:xx:xx:xx would be useful. Similarily, if your device has its proprietary id scheme, use something like typeofid:xxxx ). |
subdeviceindex | optional integer | This can be used to create multiple devices with the same base dSUID (i.e. same uniqueid passed in the init message), which is recommended for composite devices like fan coil units, which have a heater/cooler subdevice and a fan subdevice, or for multiple buttons that can be combined to form 2-way buttons. |
colorclass | optional integer | defines the device's color class (if not specified, a default color is derived from group and/or output)
|
group | optional integer | defines the group of the device's output (if not specified, the output type determines a default group)
|
output | optional string | Defines the type of output:
|
kind | optional string for shadow and ventilation output type | Defines the kind of device. For shadow:
|
dimmable | optional boolean | This can be used to set the output operation mode of a device between continuously dimmable (true) or on/off (false). Note that this does not make sense for all output types. All output types have a default operation mode. This option makes most sense for the generic basic output type |
positional | optional boolean | This can be used to set the output operation mode of a device to positional (similar to dimmable, but not controlling an intensity, but a physical position, e.g. of a blind, window motor etc.). Note that this does not make sense for all output types. All output types have a default operation mode. This option makes most sense for the generic basic output type |
endcontacts | optional boolean for shadow output type | If set to true, device implementation must report reaching top and bottom positions by updating channel value to 100 or 0, resp. (using the "channel" message). Otherwise, the shadow behaviour uses move time settings to derive actual positions from timing alone. |
move | optional boolean | If set to true, the device must support the "move" or "MV" message (see below), which is issued by the device to start or stop a movement (increase, decrease) of the output value. The relative move semantic might be more useful for blind type devices than absolute channel output values. Default is false (no move semantics) |
sync | optional boolean | if set to true, the device must support the "sync" message and must respond to "sync" with the "synced" message. "sync" is issued by the vdcd when it needs to know current output values (e.g. for a saveScene operation). "synced" is sent by the device when updated output channel values have been sent to the vdcd.Default is false (no output value sync requests) |
controlvalues | optional boolean | If set to true, control values (such as room temperature set points and actual values) are forwarded to the external device using the "control"/CTRL message. |
scenecommands | optional boolean | If set to true, the vDC will send the "scenecommand"/SCMD message to devices for some special scene commands that may have additional semantics beyond changing channel values. |
groups | optional array of integers | can be used to explicitly indicate membership of one or more output groups. This overrides all other group affiliations derived from colorclass, group and output. The group numbers are the same as for group, see above. |
hardwarename | optional string | a string describing the type of output hardware, such as "dimmer" or "relay" etc.Default is the string specified in output. |
modelname | optional string | a string describing the device model. This will be displayed by the dSS as "HW Info". |
modelversion | optional string | a string describing the device's firmware version. This will be displayed by the dSS as "Firmware Version". When this string is empty, the software version of the vdc host is used instead (representing the device's vdc-side implementation version). |
vendorname | optional string | the vendor name |
oemmodelguid | optional string | the GUID that is used to identify devices (in particular: single devices) in the Digital Strom server side database to provide extended information. Usually this is a GS1 formatted GTIN like:'gs1:(01)76543210123' |
iconname | optional string | a string that is used as a base to construct a file name of the icon to be displayed for the device. vdcd will first try to load a icon named "iconname_groupcolor" (with groupcolor being the color of the device). If such a file does not exist, vdcd tries to load "iconname_other". The default value for iconname is "ext" for external devices and "scpt" for scripted devices. |
configurl | optional string | a URL that will be shown in the context menu of the device in the dSS configurator (i.e. the contents of the "configURL" device property in the vDC API).If not specified, this will default to the vdchost's default URL (if any). |
typeidentifier | optional string | an identifier specifying the (hardware implementation) type of this device. By default, it is just "external". This identifier is not used in Digital Strom, but it is exposed as "x-p44-deviceType" for local Web-UI, and it is used to load type-specific scene tables/properties from .csv files. |
deviceclass | optional string | a device class intended to group functionally equivalent single devices (washing machines, kettles, ovens, etc.). This must match a Digital Strom-defined device class, and the device must provide the actions/states/events/properties as specified for that class. |
deviceclassversion | optional integer | a version number for the device class. |
name | optional string | the default name the device will have in the Digital Strom system. Note that this can be changed by the user via dSS Web interface. |
buttons | optional array of objects | Defines the buttons of the device. See table below for fields in the button objects |
inputs | optional array of objects | Defines the binary inputs of the device. See table below for fields in the input objects |
sensors | optional array of objects | Defines the sensors of the device. See table below for fields in the sensor objects |
configurations | optional object containing named configurations | Defines the device configurations (such as two-way button vs. two separate one-way buttons) possible for this device. Note that devices must use the JSON protocol to use configurations.The configurations object can contain 1..n configuration objects, see table below |
currentConfigId | string | For devices with multiple configurations (see above), this field must contain the current configuration's id. |
actions | optional object containing named actions | Defines the device actions of the device (for 'single' devices). Note that single devices must use the JSON protocol.The actions object can contain 1..n action objects, see table below |
dynamicactions | optional object containing dynamic actions by their id | Defines ainitial set of dynamic actions of the device (for 'single' devices). Note that single devices must use the JSON protocol.The dynamicactions object can contain 1..n dynamicaction objects, see table below. If no dynamic actions are known at the time of device instantiation, dynamicactions can be omitted.Note that dynamic actions (unlike normal actions) can als be added, changed and deleted during device operation using the dynamicAction message, see below. |
standardactions | optional object containing standard actions by their id | Defines the standard actions of the device (for 'single' devices). Note that single devices must use the JSON protocol.The standardactions object can contain 1..n standardaction objects, see table below. |
autoaddstandardactions | optional boolean | If set to true, a standard action is created automatically for each defined action using the action's name prefixed by "std." |
noconfirmaction | optional boolean | Can be set to true when the device implementation does not want to confirm action completion |
states | optional object containing states by their id | Defines the states of the device (for 'single' devices). Note that single devices must use the JSON protocol.The states object can contain 1..n state objects, see table below |
events | optional object containing events by their id | Defines the events of the device (for 'single' devices). Note that single devices must use the JSON protocol.The events object can contain 1..n event objects, see table below |
properties | optional object containing properties by their id | Defines the device properties of the device (for 'single' devices). Note that single devices must use the JSON protocol.The properties object can contain 1..n property objects, see table below |
Button object in the buttons field of the init message
Field | Type | Description |
---|---|---|
id | optional string | string id, unique within the device to reference the button via vDC API. |
buttonid | optional integer | Note: this field can also be set as "id" for backward compatibility with earlier versions of this API. Identifies the hardware button this button input belongs to. Two-way or multi-way buttons will have multiple button definitions with the same id. Defaults to 0 |
buttontype | optional integer | Defines the type of button:
|
element | optional integer | Defines which element of a multi-element button is represented by this button input:
|
group | optional integer | defines the primary color (group) of the button:
|
combinables | optional integer | if set to a multiple of 2, this indicates that there are other devices with same uniqueid but different subdeviceindex, which can be combined to form two-way buttons. In this case, each of the combinable devices must have a single button only, and the subdeviceindex must be in the range n..n+combinable-1, with n=subdeviceindex MOD combinable |
localbutton | optional boolean | If set to true, this button acts as a local button for the device (directly switches and dims the output) |
hardwarename | optional string | a string describing the button element, such as "up" or "down" etc. Default is "button_idX_elY" where X is the buttonid and Y is the element |
Input object in the inputs field of the init message
Field | Type | Description |
---|---|---|
id | optional string | string id, unique within the device to reference the binary input via vDC API. |
inputtype | optional integer | Defines the type of input:
|
usage | optional integer | Defines usage:
|
group | optional integer | defines the primary color (group) of the input:
|
updateinterval | optional double | defines the expected update interval of this input, i.e. how often the actual state is reported by the device. Defaults to 0, which means no fixed interval |
alivesigninterval | optional double | defines after what time with no input state update the input should be considered offline/invalid, in seconds. Defaults to 0 (meaning: no guaranteed alive reports) |
hardwarename | optional string | a string describing the input, e.g. "door contact" or "glass break" etc. Default is "input_tyX" where X is the numeric inputtype |
Sensor object in the sensors field of the init message
Field | Type | Description |
---|---|---|
id | optional string | string id, unique within the device to reference the sensor via vDC API. |
sensortype | optional integer | Defines the type of sensor:
|
usage | optional integer | Defines usage:
|
group | optional integer | defines the primary color (group) of the sensor:
|
updateinterval | optional double | defines the time precision of the sensor, i.e. how quickly it reports relevant changes. For sensors with a regular polling mechanism, this actually is the expected update interval. For sensors that update only when change is detected, this denotes the timing accuray of the update.Defaults to 5 seconds |
alivesigninterval | optional double | defines after what time with no sensor update the sensor should be considered offline/invalid, in seconds.Defaults to 0 (meaning: no guaranteed alive reports) |
changesonlyinterval | optional double | defines the minimum time interval between reporting the same sensor value again, in seconds.Defaults to 5 minutes (300 seconds)Note that this value is only a default used for new devices. The vDC API allows to change this value later. |
hardwarename | optional string | a string describing the sensor, e.g. "indoor temperature" or "water level" etc. Default is "sensor_tyX" where X is the numeric sensor type |
min | optional double | minimal value, defaults to 0 |
max | optional double | maximal value, defaults to 100 |
resolution | optional double | sensor resolution, defaults to 1 |
Action object in actions field of the init message
Field | Type | Description |
---|---|---|
description | optional string | description text (for logs and debugging) of the action |
params | optional object | defines the parameters of the device action |
Standardaction object in standardactions field of the init message
Field | Type | Description |
---|---|---|
action | string | name of the action this standardaction is based on |
title | optional string | title text for the standard action |
params | optional object | defines the parameters to be used when calling action |
Configuration object in configurations field of the init message
Field | Type | Description |
---|---|---|
id | string | configuration id |
description | string | description text for the configuration |
Dynamicaction object in dynamicactions field of the init message and in the dynamicAction message
Field | Type | Description |
---|---|---|
title | string | The title (device-side user-assigned string in user language) for the dynamic action |
description | optional string | description text (for logs and debugging) of the action |
params | optional object | defines the parameters of the device action |
State object in states field of the init message
Field | Type | Description |
---|---|---|
description | optional string | description text (for logs and debugging) of the state |
type, siunit, min, max... | fields | definition of the state, see value description fields below |
Event object in events field of the init message
Field | Type | Description |
---|---|---|
description | optional string | description text (for logs and debugging) of the state |
type, siunit, min, max... | fields | definition of the state, see value description fields below |
Property object in properties field of the init message
Field | Type | Description |
---|---|---|
readonly | optional boolean | can be set to make the property read-only (from the vDC API side - the device implementation can use updateProperty to update/push the value) |
type, siunit, min, max... | fields | definition of the property, see value description fields below |
value description fields (for action parameters, states, properties)
Field | Type | Description |
---|---|---|
type | string | must be one of "numeric", "integer", "boolean", "enumeration" or "string" |
siunit | optional string | defines the SI-unit of numeric type |
default | optional numeric | default value according to type (not for enumerations) |
min | optional double | minimal value for numeric and integer types |
max | optional double | minimal value for numeric and integer types |
resolution | optional double | resolution for numeric types |
values | array of strings | possible values for enumeration type, default value prefixed with an exclamation mark (!). |
Messages from vdcd to device(s)
vdcd sends (depending on the features selected in the init message) the messages shown in the table below.
If devices were created with a tag (which is required when creating multiple devices on a single connection), all JSON protocol messages will include the tag field, and all simple text protocol messages will be prefixed by tag plus a colon.
JSON protocol | Simple protocol | Description |
---|---|---|
{ 'message': 'status', 'status': s, 'errorcode': e, 'errormessage': m, 'errordomain':d, 'tag': t } | OK or `ERROR= m |
Status for init message.If ok, s is the string "ok" in the JSON protocol. m is a textual error message e is the vdcd internal error code d is the vdcd internal error domain t is the tag (only present if device was created with a tag in the init message) |
{ 'message': 'channel','index': i , 'id':id , 'type':ty,'value': v, 'transition': ttime, 'dimming': dim, 'tag':t} | C i = v or with tag: t:C i = v |
Output channel index i has changed its value to v.v is a double value. The device implementation should forward the new channel value to the device's output. The JSON variant of this message additionally reports the transition time as ttime (in Seconds), a boolean dim flag indicating if the output change is due to dimming, the channel's name/idstring as id and the channel type as ty :
|
{ 'message': 'move', 'index': i, 'direction': d, 'tag': t } | MV i = d or with tag: t:MV i = d |
When the init message has specified move=true, the vdcd can request starting or stopping movement of channel i as follows:
|
{ 'message': 'control', 'name': n, 'value': v, 'tag': t } | CTRL. n = v or with tag: t:CTRL. n = v |
When the init message has specified controlvalues=true, the vdcd will forward control values received for the device. n is the name of the control value (such as "heatingLevel", "TemperatureZone", "TemperatureSetPoint" etc.) v is a double value t is the tag (only present if device was created with a tag in the init message) |
{ 'message': 'sync', 'tag': t } | SYNC or with tag: t:SYNC |
When the init message has specified sync=true, the vdcd can request updating output channel values by sending sync. The device is expected to update channel values (using the "channel"/"C" message, see below) and then sending the synced message. Note that the device can also announce a batch of channel updates by itself by sending sync, see below. t is the tag (only present if device was created with a tag in the init message) |
{ 'message': 'scenecommand', 'cmd': c, 'tag': t } | SCMD=c or with tag: t :SCMD= c |
When the init message has specified scenecommands=true, the vdcd will send this message for some "special" scene calls, because not all scene call's semantics are fully represented by channel value changes alone.Currently, c can be one of the following values:
|
Operations related to multiple device configurations are only available in the JSON protocol as follows:
JSON protocol | Description |
---|---|
{ 'message': 'setConfiguration', 'id': configid , 'tag':t } | The device is requested to the configuration identified by id configid.The device implementation MUST disconnect all devices affected by the configuration change (using the bye message), and then re-connect the device(s) with new init messages describing the new configuration (number of buttons, sensors, etc.) and containing configid in the currentConfigId field. |
Operations related to 'single' devices are only available in the JSON protocol as follows:
JSON protocol | Description |
---|---|
{ 'message': 'invokeAction', 'action': a, 'params':p, 'tag': t } | The action a has been invoked with parameters p.The device implementation must perform the action and then must return a confirmAction message (unless confirming actions is disabled by including the noconfirmaction field in the init message) t is the tag (only present if device was created with a tag in the init message) |
{ 'message': 'setProperty', 'property': p, 'value': v, 'tag': t } | The property p has been changed to value v.The device implementation should update its internal value for this property. |
Messages from device(s) to vdcd
the device(s) can send (depending on the features selected in the init message) the messages shown in the table below.
If devices were created with a tag (which is required when creating multiple devices on a single connection), all JSON protocol messages must include the tag field, and all simple text protocol messages must be prefixed by tag plus a colon to identify the device.
JSON protocol | Simple protocol | Description |
---|---|---|
{ 'message': 'bye', 'tag': t } | BYE or with tag: t :BYE |
(external devices via TCP/IP only) The device can send this message to disconnect from the vdcd, for example when it detects its hardware is no longer accessible. Just closing the socket connection has the same effect as sending bye (in case of multiple tagged devices, closing socket is like sending bye to each device) t is the tag (only needed when device was created with a tag in the init message) |
{ 'message': 'log', 'level': n , 'text':logmessage, 'tag': t } | L n = logmessage or with tag: t :L n = logmessage |
(external devices via TCP/IP only) The device can send a logmessage to the vdcd log. n is the log level (by default, levels above 5 are not shown in the log - 7=debug, 6=info, 5=notice, 4=warning, 3=error, 2=critical, 1=alert, 0=emergency) t is the tag (only needed when device was created with a tag in the init message) |
{ 'message': 'channel', 'index': i, 'type': ty ,'id':id, 'value': v , 'tag':t} | C i = v or with tag: t :C i = v |
The device should send this message when its output channel with index i (or named id or typed ty , see below) has changed its value to v for another reason than having received a channel message (e.g. after initialisation, or for devices than can be controlled directly).Devices that cannot immediately detect output changes can specifiy sync=true in the init message, so the vdcd will request updating output channel values by sending sync only when these values are actually needed. The JSON variant of this message additionally allows selecting the channel by name/idstring id or type ty (instead of index i ). t is the tag (only needed when device was created with a tag in the init message) |
{ 'message': 'channel_progress', 'index': i, 'type': ty ,'id':id, 'value': v , 'tag':t} | P i = v or with tag: t :P i = v |
The device can optionally send this message to report progress of a hardware transition (such as a moving blind) for its output channel with index i (or named id or typed ty , see below). The JSON variant of this message additionally allows selecting the channel by name/idstring id or type ty (instead of index i ). t is the tag (only needed when device was created with a tag in the init message) |
{ 'message': 'button', 'index': i, 'id':id, 'value': v, 'tag':t} | B i = v or with tag: t :B i = v |
The device should send this message when the state of its button at index i (or named id , see below) has changed. If the button was pressed, v must be set to 1, if the button was released, v must be set to 0. To simulate a button press+release with a single message, set v to the press duration in milliseconds. To directly simulate a single, double, triple, or quadruple click, -1, -2, -3, or -4 can be passed for v, as well as -11 for start of holding down the button and -10 for releasing the button. Note that mixing direct clicks (negative values) and button state reporting (positive values) should not be mixed in use for the same button! t is the tag (only needed when device was created with a tag in the init message)The JSON variant of this message allows selecting the button by name/idstring id (instead of index i ). |
{ 'message': 'input', 'index': i, 'id': id, 'value': v , 'tag': t } | I i = v or with tag: t :I i = v |
The device should send this message when the state of its input at index i (or named id , see below) has changed. If the input has changed to active v must be set to 1, if the input has changed to inactive, v must be set to 0. To explicitly signal that the value is unknown/not available at this time, set v to the string undefined (simple) or to the NULL value (JSON). t is the tag (only needed when device was created with a tag in the init message). The JSON variant of this message allows selecting the input by name/idstring id (instead of index i ). |
{ 'message': 'sensor', 'index': i, 'id':id, 'value': v ,'tag':t } | S i = v or with tag: t:S i = v |
The device should send this message when the value of its sensor at index i (or named id , see below) has changed. v is the new value (double) and should be within the range specified with min and max in the init message. To explicitly signal that the value is unknown/not available at this time, set v to the string undefined (simple) or to the NULL value (JSON). t is the tag (only needed when device was created with a tag in the init message). The JSON variant of this message allows selecting the sensor by name/idstring id (instead of index i ). |
{ 'message': 'sync', 'tag': t } | SYNC or with tag: t:SYNC |
The device can send this message to announce that it will update multiple output channel values, and will complete the update by sending synced. t is the tag (only needed when device was created with a tag in the init message) |
{ 'message': 'synced', 'tag': t } | SYNCED or with tag: t:SYNCED |
The device must send this message after receiving sync and having updated output channel values. t is the tag (only needed when device was created with a tag in the init message) |
Some more specialised operations, e.g. those relating to 'Single Devices', are only available in the JSON protocol as follows:
JSON protocol | Description |
---|---|
{ 'message': 'opstate', 'level': lvl , 'text':txt } | Sets the operation state of the device. lvl is the "health" level, from -1 (unknown) to 0 (bad) to 100 (perfect). txt is a short keyword for the operating status, e.g. "Low Bat". Only one of the two pieces of information can be specified. t is the tag (only present if the device was created with a tag in the init message) |
{ 'message': 'channel_config', 'index': i, 'type': ty ,'id':id, 'min': min, 'max': max , 'tag':t} | The device can optionally send this message to dynamically configure min/max values for the output channel with index i, or named id or typed ty. Note that the output must be of type basic and be dimmable or positional to allow configuration. t is the tag (only needed when device was created with a tag in the init message) |
{ 'message': 'confirmAction', 'action': a , 'errorcode': ec, 'errortext': et , 'tag':t } | Unless confirming actions is disabled by including the noconfirmaction field in the init message, the device must send this message to confirm the execution (or failure) of action a that has been invoked before.It can return a status code in ec , which must be 0 for successful execution or another value indicating an error. et can be used to supply an error text. t is the tag (only present when device was created with a tag in the init message) |
{ 'message': 'updateProperty', 'property': p, 'value':v, 'push':push, 'tag': t } | The device can send this message to update the value v of the property p , as seen from the vdc API.If the optional push boolean value is set, the property change will also be pushed upstream.Note it is possible to just push the current property value without changing its value by omitting value, only specifying push. t is the tag (only present when device was created with a tag in the init message) |
{ 'message': 'pushNotification', 'statechange':{ s:v }, 'events': [e1,e2,...], 'tag': t } | The device can use this message to push state changes and events.The statechange field is an optional object assinging a new value v to a state s , the events field is an optional array of event ids ( e1,e2,... ) to be pushed along the state change (or by themselves if the statechange field is missing). t is the tag (only present when device was created with a tag in the init message) |
{ 'message': 'dynamicAction', 'changes': { id:actiondesc, ... }, 'tag': t } | The device can use this message to add, change or remove dynamic actions while the device is already operating.The changes field is a JSON object, containing one or multiple actions identified by their id s and described by an actiondesc (same format as dynamicAction in the init message, see above). If a dynamic action is to be removed, pass null for actiondesc. t is the tag (only present when device was created with a tag in the init message) |