Skip to content

Instantly share code, notes, and snippets.

@Muntasir2001
Created June 16, 2022 10:13
Show Gist options
  • Save Muntasir2001/c9daccd7f350016d491bf2060c16bee2 to your computer and use it in GitHub Desktop.
Save Muntasir2001/c9daccd7f350016d491bf2060c16bee2 to your computer and use it in GitHub Desktop.
function Decoder(request) {
var payload = JSON.parse(request.body);
var sensor_data;
//refer page 3 for Lightricity data types and assigned numbers
var Lightricity_data = [
'Vendor ID', //0
'Sensor ID',
'Beacon Counter',
'MAC Address',
'TX Power',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'Temperature', //21 "Humidity", //22 "Pressure",
'Lux',
'Co2',
'Acceleration',
'Motion',
'Button Event',
'Battery Voltage',
];
var offset = 0;
var valid_data_len, rawData_len, sensor_data, frame_type;
for (var i = 0; i < payload.length; i++) {
var deviceData = payload[i];
if (deviceData.type === 'Gateway') continue;
var rawData = deviceData.rawData;
rawData_len = rawData.length;
for (; offset < rawData_len; ) {
valid_data_len = rawData.slice(offset, offset + 2);
valid_data_len = parseInt(valid_data_len, 16);
if (rawData.slice(offset + 2, offset + 8) == 'FF960A') {
// Found Lightricity manufacturer specific data
break;
} else {
//Discard non-Lightricity payloads offset += ((valid_data_len + 1) * 2);
}
}
if (offset == rawData_len) {
//No relevant data found
return;
}
//Lightricity data found
valid_data_len = rawData.slice(offset, offset + 2);
valid_data_len = parseInt(valid_data_len, 16);
offset = offset + 8;
frame_type = rawData.slice(offset, offset + 2);
if (frame_type == '01') {
offset = offset + 2;
//discard companyID, frame type, manufact flag valid_data_len = valid_data_len - 4;
for (; valid_data_len > 0; ) {
var dat_type = rawData.slice(offset, offset + 2);
//extract data type from bit 0-5 dat_type = parseInt(dat_type, 16); dat_type = dat_type & 0x3F;
if (dat_type == 21 || dat_type == 22) {
dat_len = 2; //Temp and humidity always 2bytes
} else if (dat_type == 26 || dat_type == 3) {
dat_len = 6; //Acceleration/MAC always 6bytes
} else {
//extract data length from bit 6 & 7 dat_len = rawData.slice(offset,offset+1); dat_len = dat_len & 0xC;
dat_len = (dat_len >> 2) + 1;
}
offset = offset + 2;
sensor_data = rawData.slice(offset, offset + dat_len * 2);
var sens_data_big_endi = '';
var len = sensor_data.length - 2;
for (; len >= 0; ) {
//convert to big endian
sens_data_big_endi += sensor_data.slice(len, len + 2);
len = len - 2;
}
sensor_data = parseInt(sens_data_big_endi, 16);
if (dat_type == 21 || dat_type == 22) {
//refer page 3 for various data types and formats
if (dat_type == 21) {
//signed data
if ((sensor_data & 0x8000) > 0) {
sensor_data = sensor_data - 0x10000;
}
}
sensor_data = sensor_data / 100;
}
offset = offset + dat_len * 2;
valid_data_len = valid_data_len - dat_len - 1;
//You have valid sensor data and data type in variables “sensor_data” and “Lightricity_data[dat_type]” respectively. Please use this as needed. “push_data_to_dashboard()” is an example API which pushes all sensor data and data type string to the dashboard. User can decide which data needs to be processed, and others can be discarded.
push_data_to_dashboard(Lightricity_data[dat_type], sensor);
}
} else if (frame_type == '02') {
/*
var vendor_ID = parseInt(rawData.slice(offset,offset+2),16); offset += 2;
//3 bytes sensor_ID
var sensor_ID = (rawData.slice(offset+4,offset+6)) + (rawData.slice(offset+2,offset+4)) + (rawData.slice(offset,offset+2)); sensor_ID = parseInt(sensor_ID, 16);
offset += 6;
var Beacon_Cnt = (rawData.slice(offset+2,offset+4)) + (rawData.slice(offset,offset+2)) Beacon_Cnt = parseInt(Beacon_Cnt, 16);
*/
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment