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?
- Login into our console application and navigate to the Codec Editor.
- Click on the
+
button to create a new codec. - 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.
- Click on the
decoder.js
file to open it in the editor.
Decoding Uplink Data
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
Objectbuffer
(Buffer) object with payload using Node.JS Buffer interfacefport
(number) numerical value of LoRaWAN fPortformat
(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 typeunit
(string) sensor data unitvalue
(any) actual sensor data valuename
(string, optional) some name for debugging purposetimestamp
(number, optional) used for historical data, should be provided as UTC timestamp in milliseconds
send(data)
function is mapped tosendSensors
for legacy and backward compatibility purpose with old codecs.sendDownlink(buffer, fport)
function is used to send downlink command back to the devicebuffer
(Buffer) object with payload using Node.JS Buffer interfacefport
(number) numerical value of LoRaWAN fPort
done()
function - Although it’s optional, it’s recommend to end your decoding process by callingDecoder.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).
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();