Skip to main content

Downlink Commands

Similar to template capabilities / decoder.js relation, there is a relation with the template downlink commands and encoder.js file.

First step is to add a downlink_commands attribute as part of the template, for example:

[
{
"order": 0,
"label": null,
"variables": [
{
"order": 0,
"label": "Reading Interval",
"type": "string",
"key": "command.interval",
"form": "select",
"min": null,
"max": null,
"required": true,
"hide_on_setup": true,
"help_texts": [
{
"value": "Device must be online before changing interval setting",
"order": 0
}
],
"default_value": "600",
"values": [
{
"label": "10 minutes",
"value": "600"
},
{
"label": "20 minutes",
"value": "1200"
}
]
},
{
"order": 1,
"label": "Another Setting",
"type": "number",
"key": "command.anothersetting",
"form": "input",
"min": 60,
"max": 3600,
"required": true,
"hide_on_setup": true,
"help_texts": [
{
"value": "Device must be online before changing interval setting",
"order": 0
}
],
"default_value": 600
}
]
}
]

The example above defines two downlink commands:

  • interval, which uses a dropdown select field
  • anothersetting, which uses an input field

The key attribute must be prefixed with command. then the part after the dot can be any string and will be used as a channel in the encoder.

Options for the form attribute can be either "select" or "input".

Options for the type attribute can be either "string" or "number".

Second step is to implement the downlink command in the encoder.js codec file, for example:

const channel = Encoder.data.channel; // retrieve channel (eg. "interval" or "anothersetting")
const value = Encoder.data.value; // retrieve user configured value

switch (channel) {
case "interval":
if (value > 0) {
// See https://nodejs.org/docs/latest-v18.x/api/buffer.html for available write functions
const payload = Buffer.alloc(2); // allocate a 2 bytes buffer
payload.writeUInt16LE(value, 0); // write the value
Encoder.sendDownlink(payload, 85); // send payload on frame port 85
}
break;

case "anothersetting":
if (value > 0) {
const payload = Buffer.alloc(2);
payload.writeUInt16LE(value, 0);
Encoder.sendDownlink(payload, 86);
}
break;

default:
break;
}
Encoder.done();

With this workflow in place, any time a value is changed in device setting page and saved, it will trigger the matching downlink command.

In case you need to send multiple settings in a single downlinks, you can use object definition feature.

From the form_settings attributes, add suffixes to variables key, eg. command.{channel}.{setting}. For instance

  • command.config.interval
  • command.config.offset

In such a case, the encoder will be triggered with channel set to 'config' and value an object:

{
"interval": 100,
"offset": 10
}

You can then use this value object to compose your downlink.

const channel = Encoder.data.channel;
const object = Encoder.data.value;

switch (channel) {
case "config":
const payload = Buffer.alloc(2);
if (object.interval > 0) { // setting defined with command.config.interval
payload.writeUInt16LE(object.interval, 0);
}
if (object.offset > 0) { // setting defined with command.config.offset
payload.writeUInt8(object.offset, 1);
}
Encoder.sendDownlink(payload, 85);
break;

default:
break;
}
Encoder.done();