Last active
February 16, 2022 21:45
-
-
Save vhuynen/4147d0d65edb16d525ade26eb0dfb34a to your computer and use it in GitHub Desktop.
Function to decode Helium's uplink data from RAK7204 device. Data are in LPP Cayenne format (RUI: RAK Unified Interface) and converted to Ubidots JSON format as expected. Inspired from GitHub projet : https://github.com/RAKWireless/RUI_LoRa_node_payload_decoder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Function to decode Helium's uplink data from RAK7204 device. | |
// Data are in LPP Cayenne format (RUI: RAK Unified Interface) and converted to Ubidots JSON format as expected. | |
// Decoder decodes an array of bytes and uplink_info into an object. | |
// - port contains the LoRaWAN fPort number | |
// - bytes is an array of bytes, e.g. [225, 230, 255, 0] | |
// - uplink_info contains data from the device treated by the Helium router, e.g. { app_eui: <app_eui>, fcnt: <integer>, reported_at: <timestamp> } | |
// The function must return an object, e.g. { "temperature": { "value": <float>, "timestamp": <timestamp>} } | |
function Decoder(bytes, port, uplink_info) { | |
var decoded = {}; | |
var hexString = bin2HexStr(bytes); | |
return rakSensorDataDecode(hexString, uplink_info); | |
} | |
// convert array of bytes to hex string. | |
// e.g: 026700f00768750673275a0c650053080201b9 | |
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, uplink_info) { | |
// Default timestamp | |
var timestamp = Date.now(); | |
if (uplink_info) { | |
timestamp = uplink_info.reported_at; // Timestamp reported by the Helium router | |
} | |
var str = hexStr; | |
var data = {}; | |
var context = {}; | |
context.uplink_fcnt = uplink_info.fcnt; | |
while (str.length > 4) { | |
var flag = parseInt(str.substring(0, 4), 16); | |
switch (flag) { | |
case 0x0768:// Humidity | |
var humidity = {}; | |
humidity.value = parseFloat(((parseShort(str.substring(4, 6), 16) * 0.01 / 2) * 100).toFixed(1)); // Unit: %RH | |
humidity.timestamp = timestamp; | |
humidity.context = context; | |
data.humidity = humidity; | |
str = str.substring(6); | |
break; | |
case 0x0673:// Atmospheric pressure | |
var pressure = {}; | |
pressure.value = parseFloat((parseShort(str.substring(4, 8), 16) * 0.1).toFixed(2)); // Unit: hPa | |
pressure.timestamp = timestamp; | |
pressure.context = context; | |
data.barometer = pressure; | |
str = str.substring(8); | |
break; | |
case 0x0267:// Temperature | |
var temperature = {}; | |
temperature.value = parseFloat((parseShort(str.substring(4, 8), 16) * 0.1).toFixed(2)) ; // Unit: °C | |
temperature.timestamp = timestamp; | |
temperature.context = context; | |
data.temperature = temperature; | |
str = str.substring(8); | |
break; | |
case 0x0402:// Gas Resistance | |
var gasresistance= {}; | |
gasresistance.value = parseFloat((parseShort(str.substring(4, 8), 16) * 0.01).toFixed(2)) ; // Unit: KΩ | |
gasresistance.timestamp = timestamp; | |
gasresistance.context = context; | |
data.gasResistance= gasresistance; | |
str = str.substring(8); | |
break; | |
case 0x0802:// Battery Voltage | |
var voltage = {}; | |
voltage.value = parseFloat((parseShort(str.substring(4, 8), 16) * 0.01).toFixed(2)); // Unit: Volts | |
voltage.timestamp = timestamp; | |
voltage.context = context; | |
data.battery = voltage; | |
str = str.substring(8); | |
break; | |
case 0x0c65:// Luminosity Sensor | |
var luminosity = {}; | |
luminosity .value = parseFloat((parseShort(str.substring(4, 8), 16) ).toFixed(4)); // Unit: Volts | |
luminosity .timestamp = timestamp; | |
luminosity .context = context; | |
data.lux = luminosity ; | |
str = str.substring(8); | |
break; | |
default: | |
str = str.substring(7); | |
break; | |
} | |
} | |
return data; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment