The Payload Parser works the same for both Sigfox and LoRaWAN devices. At the end of this tutorial, you will end up having a connector that work in both situations.
This tutorial expects you to have read In-depth guide to Payload Parser
Each device sends data using their own specific format, usually a hexadecimal raw payload like 0x0F55028A
, this hexadecimal is great for devices, but for end users, raw payloads should be converted to actual variables like temperature
or humidity
.
In our LoRaWAN Payload parser example, we will use a four byte hexadecimal payload. The first two bytes represent the values for temperature, and the last two are the values for humidity. In this case, the temperature and humidity must be multiplied by 100 to get the correct value.
In order to create your payload parser, go to your device (Click on ‘Devices’ and select your device) and then reach the tab Payload Parser .
We have some script examples to help you to start. Just select the Parse Example for LoRaWAN or Sigfox from the Snippets list.
The current code of your payload parser will be replaced by a generic parse example.
The payload parser has access to a few Context and global variables that you can use. The most important is the " payload " global variable. The result of this variable at end of the code is what will be stored to your bucket.
/* This is a generic payload parser for LoRaWAN. It will work for any network server. ** In the code find the "payload" variable, sent by your sensor, and parse it if exists. ** The content of the payload variable is always a Hexadecimal value. ** ** Note: Additional variables can be created by the Network Server and sent directly to the bucket. Normally they aren't handled here. ** ** Testing: ** You can do manual tests to the parse by using the Device Emulator. Copy and Paste the following JSON: ** [{ "variable": "payload", "value": "0109611395" }, { "variable": "port", value: 100 }] */ // Search the payload variable in the payload global variable. Its contents is always [ { variable, value...}, {variable, value...} ...] // You can see we search for payload_raw, payload and data variables. TagoIO will normalize the hexadecimal parameter to one of those 3 variables. const payload_raw = payload.find(x => x.variable === 'payload_raw' || x.variable === 'payload' || x.variable === 'data'); if (payload_raw) { try { // Convert the data from Hex to Javascript Buffer. const buffer = Buffer.from(payload_raw.value, 'hex'); // Lets say you have a payload of 5 bytes. // 0 - Protocol Version // 1,2 - Temperature // 3,4 - Humidity // More information about buffers can be found here: https://nodejs.org/api/buffer.html const data = [ { variable: 'protocol_version', value: buffer.readInt8(0) }, { variable: 'temperature', value: buffer.readInt16BE(1) / 100, unit: '°C' }, { variable: 'humidity', value: buffer.readUInt16BE(3) / 100, unit: '%' }, ]; // If you need to add specific variables that are port dependent, you can do that with an if. const port = payload.find(x => x.variable === 'port' || x.variable === 'fport'); if (port.value === 100) { data.push({ "variable": "port_dependant", value: "value example" }); } // This will concat the content sent by your device with the content generated in this payload parser. // It also adds the field "serie" and "time" to it, copying from your sensor data. payload = payload.concat(data.map(x => ({ ...x, serie: payload_raw.serie, time: payload_raw.time }))); } catch (e) { // Print the error to the Live Inspector. console.error(e); // Return the variable parse_error for debugging. payload = [{ variable: 'parse_error', value: e.message }]; } }
Every time your device sends data to your provider and it reaches TagoIO, the payload will be parsed to temperature and humidity variables. From here, you can easily add these variables to your dashboard.
You can always edit the data object to add new variables.
This is a very common mistake where you send a variable as a string and not a number. Data type does matter when using widgets on TagoIO.
A value of a variable can be a boolean, a number or a string. You can easily fix that problem by casting your value to a number, as follows:
// toFixed(2) method will set decimal cases up to 2. const data = [ { variable: 'temperature', value: Number(buffer.readInt16BE(1).toFixed(2)), unit: '°C' }, { variable: 'humidity', value: Number(buffer.readUInt16BE(3).toFixed(2)), unit: '%' }, ];
Instead of
// toFixed(2) method will set decimal cases up to 2. const data = [ { variable: 'temperature', value: buffer.readInt16BE(1).toFixed(2), unit: '°C' }, { variable: 'humidity', value: buffer.readUInt16BE(3).toFixed(2), unit: '%' }, ];