Scripts to decode RAK node(RAK5205/RAK7205/RAK7200/RAK7204) sensor data for ttn and chirpstack

Hi guys,
I have added scripts to decode RAK node sensor data on github for ttn and chirpstack respectively.
if you didn’t increase the precison of gps data or the node, please use https://github.com/RAKWireless/RUI_LoRa_node_payload_decoder/blob/master/RUISensorDataDecoder_for_TTN.js for ttn, use https://github.com/RAKWireless/RUI_LoRa_node_payload_decoder/blob/master/RUISensorDataDecoder_for_ChirpStack.js for chirpstack.

if you increased the precison of gps data, please use https://github.com/RAKWireless/RUI_LoRa_node_payload_decoder/blob/master/RUISensorDataDecoder_GPS6digitPrecison_for_TTN.js for ttn, use https://github.com/RAKWireless/RUI_LoRa_node_payload_decoder/blob/master/RUISensorDataDecoder_GPS6digitPrecison_for_ChirpStack.js for chirpstack.

2 Likes

Hi,
first i would like thanks you !
thanks to give us the possibility to use this script freely.

I use your script with chirpstack application server (AS).
All was pretty good (postgresql) until i would like to integrate into a MQTT application.

In fact as the payload codec encode a json object into a json object from the chirpstack_AS (double object in a object).When arrive the moment to read the object i get some escaped symbol (backslash)… into the json message.

At the end i use twice the json.parse() function. but not sur that is very clean.
For this case i get the hand on the “MQTT subscriber” but its not the case for all application…

Futhermore just one very little thing the units next to the value are pretty annoying for converting them to numeric data…

In all case many thanks for your share!!!

Maybe create a special key for them…

look at the message i receive:

{

	"applicationID":"3",

	"applicationName":"sondehumtemp",

	"deviceName":"node01",

	"devEUI":"YMWo//XXXX=",

	"rxInfo":

		[

			{

				"gatewayID":"3KYy/XXXXX=",

				"time":null,

				"timeSinceGPSEpoch":null,

				"rssi":-67,

				"loRaSNR":8.2,

				"channel":7,

				"rfChain":0,

				"board":0,

				"antenna":0,

				"location":

					{

						"latitude":0,

						"longitude":0,

						"altitude":0,

						"source":"UNKNOWN",

						"accuracy":0

					},

				"fineTimestampType":"NONE",

				"context":"Zp7W3A==",

				"uplinkID":"b9Prj/GYRqiPUV/XXXXX",

				"crcStatus":"CRC_OK"

			}

		],

	"txInfo":

			{

			"frequency":867900000,

			"modulation":"LORA",

			"loRaModulationInfo":

				{

				"bandwidth":125,

				"spreadingFactor":12,

				"codeRate":"4/5",

				"polarizationInversion":false

				}

			},

	"adr":true,

	"dr":0,

	"fCnt":529,

	"fPort":8,

	"data":"CAIBbgdoXQZzJXcCZwDNBAIC4g==",

	"objectJSON":"

			{

			\"DecodeDataHex\":\"0802016e07685d06732577026700cd040202e2\",

			\"DecodeDataObj\":

				{

				\"battery\":\"3.66V\",

				\"environment\":

						{

						\"barometer\":\"959.10hPa\",

						\"gasResistance\":\"7.38KΩ\",

						\"humidity\":\"46.5% RH\",

						\"temperature\":\"20.50°C\"

						}

				}

			}",		

			"tags":{}

}

I have modify the decoder script, please clone the latest script from github.
the decoded data is show as follow:
{
“acceleration_x”: “-0.001g”,
“acceleration_y”: “-0.035g”,
“acceleration_z”: “-0.978g”,
“altitude”: “563.4m”,
“barometer”: “958.1hPa”,
“battery”: “3.78V”,
“gasResistance”: “52.95KΩ”,
“humidity”: “44%RH”,
“latitude”: “34.1911°”,
“longitude”: “108.8857°”,
“temperature”: “28.5°C”
}

if you want delete the unit, please remove the unit in script:

Thanks for your help!
i try it this afternoon… no succes !

i get this message from the mqtt broker:

{"applicationID":"3","applicationName":"sondehumtemp","deviceName":"node01","devEUI":"YMWo/xxxxc=","rxInfo":[{"gatewayID":"3xxxxx2XLM=","time":null,"timeSinceGPSEpoch":null,"rssi":-59,"loRaSNR":11,"channel":7,"rfChain":0,"board":0,"antenna":0,"location":{"latitude":0,"longitude":0,"altitude":0,"source":"UNKNOWN","accuracy":0},"fineTimestampType":"NONE","context":"au6b5A==","uplinkID":"K8VV1nceSkiw/xxxx7A==","crcStatus":"CRC_OK"}],"txInfo":{"frequency":867900000,"modulation":"LORA","loRaModulationInfo":{"bandwidth":125,"spreadingFactor":12,"codeRate":"4/5","polarizationInversion":false}},"adr":true,"dr":0,"fCnt":1276,"fPort":8,"data":"CAIBbQdomwZzJYkCZwCMBAIBEg==","objectJSON":"{\"barometer\":960.9,\"battery\":3.65,\"gasResistance\":2.74,\"humidity\":77.5,\"temperature\":14}","tags":{}}

and if i do :
JSON.parse(thismessage);
I got an error. unexpected token at position
In fact it’s because i get a string caused by the double quote behind the key objectJSON
If i remove the double quote … no more problem.

To me, i would like to receive a “json” that i could parse in object with JSON.parse() function .

So maybe i’m wrong and this part have not to be in JSON format.

which mqtt client do you use? I use mqtt.fx, the result is as follow:

Outchhh…
I dont get same …
i use mosquitto … but i dont think it could come from the mqtt client
for you the lora server is chirpstack?

application/3/device/60c5abfffe783ff3/rx {"applicationID":"3","applicationName":"sondehumtemp","deviceName":"node02","devEUI":"YM123P/M=",
"rxInfo":[{"gatewayID":"3K123456LM=","time":null,"timeSinceGPSEpoch":null,"rssi":-49,"loRaSNR":8.8,"channel":0,"rfChain":1,"board":0,"antenna":0,"location":{"latitude":0,"longitude":0,"altitude":0,"source":"UNKNOWN","accuracy":0},"fineTimestampType":"NONE","context":"Eyx5nA==","uplinkID":"t6ycK5ehTt6l0ZwGH+pE6w==","crcStatus":"CRC_OK"}],
"txInfo":{"frequency":868100000,"modulation":"LORA","loRaModulationInfo":{"bandwidth":125,"spreadingFactor":12,"codeRate":"4/5","polarizationInversion":false}},"adr":true,"dr":0,"fCnt":1090,"fPort":8,"data":"CAIBbQdoZgZzJdgCZwDPBAIB8Q==",
"objectJSON":"{\"barometer\":968.8,\"battery\":3.65,\"gasResistance\":4.97,\"humidity\":51,\"temperature\":20.7}","tags":{}}

To me its on the chirpstack side that the Data “objectJson” is “stringify()” twice… i’m on discussion to know if we could do something with that.

emm, strange.
I use chirpstack as server and mosquitto as mqtt broker. What I subscribe from mqtt.fx is right.
Did you use mosquitto_sub as client? I will try to test.

This is what I test with mosquitto:

Can you paste your decoded script here? I doubt your script may be unsuitable.

Yes i use mosquitto_sub:

mosquitto_sub -t "application/3/#" -v
application/3/device/60c5456789ec7/rx {"applicationID":"3","applicationName":"sondehumtemp","deviceName":"node01","devEUI":"YMWo//54P8c=",
"rxInfo":[{"gatewayID":"3KY123456=","time":"2020-05-09T09:15:24.313107Z","timeSinceGPSEpoch":"1273050941.313s","rssi":-53,"loRaSNR":8,"channel":2,"rfChain":1,"board":0,"antenna":0,"location":{"latitude":0,"longitude":0,"altitude":0,"source":"UNKNOWN","accuracy":0},"fineTimestampType":"NONE","context":"d+GjNA==","uplinkID":"qZLyA4YOTOG6zkNcAp6kBw==","crcStatus":"CRC_OK"}],
"txInfo":{"frequency":868500000,"modulation":"LORA","loRaModulationInfo":{"bandwidth":125,"spreadingFactor":12,"codeRate":"4/5","polarizationInversion":false}},
"adr":true,
"dr":0,
"fCnt":1221,
"fPort":8,
"data":"CAIBbgdoawZzJbcCZwCvBAIDvQ==",
"objectJSON":"{\"barometer\":965.5,\"battery\":3.66,\"gasResistance\":9.57,\"humidity\":53.5,\"temperature\":17.5}","tags":{}}

Maybe i use a old Chirpstack version?

chirpstack-application-server version : 3.10.0
chirpstack-network-server version : 3.9.0
chirpstack-gateway-bridge version : 3.8.0

The script for payload decode is:

// Decode decodes an array of bytes into an object.
//  - fPort contains the LoRaWAN fPort number
//  - bytes is an array of bytes, e.g. [225, 230, 255, 0]
// The function must return an object, e.g. {"temperature": 22.5}
function Decode(fPort, bytes) {
  var decoded = {};
  var hexString=bin2HexStr(bytes);
  return rakSensorDataDecode(hexString);
}

// convert array of bytes to hex string.
// e.g: 0188053797109D5900DC140802017A0768580673256D0267011D040214AF0371FFFFFFDDFC2E
function bin2HexStr(bytesArr) {
  var str = "";
  for(var i=0; i<bytesArr.length; i++) {
    var tmp = (bytesArr[i] & 0xff).toString(16);
    if(tmp.length == 1) {
      tmp = "0" + tmp;
    }
    str += tmp;
  }
  return str;
}

// convert string to short integer
function parseShort(str, base) {
  var n = parseInt(str, base);
  return (n << 16) >> 16;
}

// convert string to triple bytes integer
function parseTriple(str, base) {
  var n = parseInt(str, base);
  return (n << 8) >> 8;
}

// decode Hex sensor string data to object
function rakSensorDataDecode(hexStr) {
  var str = hexStr;
  var myObj = {};

  while (str.length > 4) {
    var flag = parseInt(str.substring(0, 4), 16);
    switch (flag) {
      case 0x0768:// Humidity
        myObj.humidity = parseFloat(((parseShort(str.substring(4, 6), 16) * 0.01 / 2) * 100).toFixed(1));//unit:%RH
        str = str.substring(6);
        break;
      case 0x0673:// Atmospheric pressure
        myObj.barometer = parseFloat((parseShort(str.substring(4, 8), 16) * 0.1).toFixed(2)); //unit:hPa
        str = str.substring(8);
        break;
      case 0x0267:// Temperature
        myObj.temperature = parseFloat((parseShort(str.substring(4, 8), 16) * 0.1).toFixed(2));//unit: °C
        str = str.substring(8);
        break;
      case 0x0188:// GPS
        myObj.latitude = parseFloat((parseTriple(str.substring(4, 10), 16) * 0.0001).toFixed(4)) + "°";//unit:°
        myObj.longitude = parseFloat((parseTriple(str.substring(10, 16), 16) * 0.0001).toFixed(4)) + "°";//unit:°
        myObj.altitude = parseFloat((parseTriple(str.substring(16, 22), 16) * 0.01).toFixed(1)) + "m";//unit:m
        str = str.substring(22);
        break;
      case 0x0371:// Triaxial acceleration
        myObj.acceleration_x = parseFloat((parseShort(str.substring(4, 8), 16) * 0.001).toFixed(3)) + "g";//unit:g
        myObj.acceleration_y = parseFloat((parseShort(str.substring(8, 12), 16) * 0.001).toFixed(3)) + "g";//unit:g
        myObj.acceleration_z = parseFloat((parseShort(str.substring(12, 16), 16) * 0.001).toFixed(3)) + "g";//unit:g
        str = str.substring(16);
        break;
      case 0x0402:// air resistance
        myObj.gasResistance = parseFloat((parseShort(str.substring(4, 8), 16) * 0.01).toFixed(2)) ;//unit:KΩ
        str = str.substring(8);
        break;
      case 0x0802:// Battery Voltage
        myObj.battery = parseFloat((parseShort(str.substring(4, 8), 16) * 0.01).toFixed(2)) ;//unit:V
        str = str.substring(8);
        break;
      case 0x0586:// gyroscope
        myObj.gyroscope_x = parseFloat((parseShort(str.substring(4, 8), 16) * 0.01).toFixed(2)) + "°/s";//unit:°/s
        myObj.gyroscope_y = parseFloat((parseShort(str.substring(8, 12), 16) * 0.01).toFixed(2)) + "°/s";//unit:°/s
        myObj.gyroscope_z = parseFloat((parseShort(str.substring(12, 16), 16) * 0.01).toFixed(2)) + "°/s";//unit:°/s
        str = str.substring(16);
        break;
      case 0x0902:// magnetometer x
        myObj.magnetometer_x = parseFloat((parseShort(str.substring(4, 8), 16) * 0.01).toFixed(2)) + "μT";//unit:μT
        str = str.substring(8);
        break;
      case 0x0a02:// magnetometer y
        myObj.magnetometer_y = parseFloat((parseShort(str.substring(4, 8), 16) * 0.01).toFixed(2)) + "μT";//unit:μT
        str = str.substring(8);
        break;
      case 0x0b02:// magnetometer z
        myObj.magnetometer_z = parseFloat((parseShort(str.substring(4, 8), 16) * 0.01).toFixed(2)) + "μT";//unit:μT
        str = str.substring(8);
        break;
      default:
        str = str.substring(7);
        break;
    }
  }

  return myObj;
}

We use an old Chirpstack version: :sweat_smile:
chirpstack-application-server 3.5.1
chirpstack-gateway-bridge 3.4.1
chirpstack-network-server 3.4.1

I will test the new version later.

:upside_down_face: :upside_down_face:
Cool I’m waiting for your test they give me a good clew.
again thanks for your help!

chirpstack-application-server 3.10.0
chirpstack-gateway-bridge 3.8.0
chirpstack-network-server 3.9.0

the result is:

mosquitto_sub -h 172.19.174.69 -v -t “application/#”

application/2/device/3739343557376202/rx {“applicationID”:“2”,“applicationName”:“1”,“deviceName”:“3739343557376202”,“devEUI”:“3739343557376202”,“txInfo”:{“frequency”:487100000,“dr”:5},“adr”:true,“fCnt”:6,“fPort”:8,“data”:“CAIBogdoLAZzJW8CZwFHBAIR5QNxAxkAJf2n”,“object”:{“acceleration_x”:0.793,“acceleration_y”:0.037,“acceleration_z”:-0.601,“barometer”:958.3,“battery”:4.18,“gasResistance”:45.81,“humidity”:22,“temperature”:32.7}}

You can use our install scripts of chirpstack:

Ok thanks for your feedbacks,
Yes of course i could use your install and test but i want to understand .
i see too that the famous Object is call : object in your case, in my case it’s call objectJSON .
That mean Rak have adjusted it?

No, object in my case is from the decoded script. You result should also be object, but your result is objectJSON. I donnot know the reason.

maybe the marshaler into the config file ? do you use Json_v3?
i use “JSON” as it said that the Json_v3 will be deprecated soon…

https://www.chirpstack.io/application-server/install/config/

Maybe.

The application-server config file which I use is https://github.com/RAKWireless/ChirpStack_on_Ubuntu/blob/master/chirpstack-application-server.toml.

It is not the newest one. There is no marshaler item.

Ok it’s confirm you use Json_v3 because you use a kind of add-on config file.

You could get the entire config file with this command in the shell:
chirpstack-application-server configfile add |grep marshaler give to you the config.

or found it in /etc/chirpstack-application-server/chirpstack-application-server.toml

But it’s annoying because Json_v3 will be deprecated… “in the next major release” as it quoted in the config file…