Skip to main content

Codecs

A codec is our term for a device's decoder and encoder. It's a JavaScript function that takes the raw payload data from a device and converts it into a format that can be displayed in the myDevices dashboard.

How to Create a Codec?

  1. Login into our console application and navigate to the Codec Editor.
  2. Click on the + button to create a new codec.
  3. Notice that the editor is pre-populated with a sample codec files:
    • decoder.js is the main file for decoding the payload.
    • encoder.js is the main file for encoding the payload (sending a downlink command to a device).
    • common.js is a file that can be used to store common functions that are used in both the encoder and decoder.
    • README.md is a file that can be used to document the codec.
  4. Click on the decoder.js file to open it in the editor.

Codec Editor

Here is a minimal source code for the decoder.js file, with comments explaining each part/section.

// Example Payload Decoder
// Test with 00F000C8
// Temp = 24°C
// Lum = 200lux

const multiplier = 0.1;

// Could use console.log to help debugging Codec
console.log("multiplier = %d", multiplier);

// Decoder.data.buffer contains a Node.JS Buffer object with the payload data
// See https://nodejs.org/docs/latest-v18.x/api/buffer.html for more information
console.log("Decoder.data.buffer = %s", Decoder.data.buffer.toString("hex"));
const buffer = Decoder.data.buffer;

// Decoder.data.fport contains LoRaWAN fPort
// Could be used to filter uplink or adapt data decoding accordingly
console.log("Decoder.data.fport = %d", Decoder.data.fport);

// Decoder must send a Sensor Object or Sensor Object Array
Decoder.sendSensors({
channel: 0, // Data Channel, must matches with Template Capability
type: DataTypes.TYPE.TEMPERATURE, // Data Type
unit: DataTypes.UNIT.CELSIUS, // Data Unit
value: buffer.readInt16BE(0) * multiplier // Data Value
});

Decoder.sendSensors({
channel: 2,
type: DataTypes.TYPE.LUMINOSITY,
unit: DataTypes.UNIT.LUX,
value: buffer.readUInt16BE(2)
});

// Complete Decoding process (optional, allows for faster response and prevent Codec timeout)
Decoder.done();

Since it’s a JavaScript file, it allows us define a special context with dedicated data and functions. In opposite to LoRaWAN type-of Codec, myDevices Engine doesn’t expect any specific function (although it could use a LoRaWAN type-of Codec), but provides tools to write Codec like any Node.JS script instead.

Our Engine main global object is Decoder one, which hold:

  • data Object
    • buffer (Buffer) object with payload using Node.JS Buffer interface
    • fport (number) numerical value of LoRaWAN fPort
    • format (string) set to "buffer" with LoRaWAN payload
  • sendSensors(sensors) function is used to send sensor data, either atomically, or grouped in an array. Each sensor is an object with a few attributes:
    • channel (number) sensor data channel (eg. unique identifier)
    • type (string) sensor data type
    • unit (string) sensor data unit
    • value (any) actual sensor data value
    • name (string, optional) some name for debugging purpose
    • timestamp (number, optional) used for historical data, should be provided as UTC timestamp in milliseconds
  • send(data) function is mapped to sendSensors for legacy and backward compatibility purpose with old codecs.
  • sendDownlink(buffer, fport) function is used to send downlink command back to the device
  • done() function - Although it’s optional, it’s recommend to end your decoding process by calling Decoder.done(). This allows to complete Decoding process before context timeout, speeding up processing. By default codecs are granted a maximum execution time of 100ms, which should be enough for most of use cases. It could be increased by opening a ticket in our support portal.

The second important global object is DataTypes, which have definition for all TYPE and UNIT available. You can use editor completion to find out existing types and unit available (shortcut CTRL-SPACE). Codec Editor

Since it’s running in a sandbox, you can also use usual console.log and console.error JavaScript function, and see the result directly in the editor. However those functions will be ignored when decoding real data (from real device) in order to speed up execution time.

Using LoRaWAN Codec API

In order to use LoRaWAN type-of Codec, you just have to include the function in your myDevices codec, call it with proper arguments, and then map and send the result into sensor objects (with channel/type/unit/value).

// Past your decodeUplink function
function decodeUplink(input) {
// ... do something with input
return output;
}

// Call it
const result = decodeUplink({
bytes: Decoder.data.buffer,
fPort: Decoder.data.fport,
recvTime: new Date(Decoder.data.timestamp)
});

// Map and send sensor data
Decoder.sendSensors({
channel: 1,
type: DataTypes.TYPE.TEMPERATURE,
unit: DataTypes.UNIT.CELSIUS,
value: result.temperature
});

Decoder.done();

Examples