I'm struggling with constructing an object that is populated by the results of a number of If statements. The If statements should fill in the params
object where a value for a key is available and leave null for keys without a value. Unfortunately I get null no matter what even though there is certainly data available for some of the keys (e.g. humidity, temperature, etc)
function bin2HexStr(arr)
{
var str = "";
for(var i=0; i<arr.length; i )
{
var tmp = arr[i].toString(16);
if(tmp.length == 1)
{
tmp = "0" tmp;
}
tmp = "0x" tmp;
if (i != arr.length - 1) {
tmp = ",";
}
str = tmp;
}
return str;
}
//TTN Handler
function Decoder(bytes, port) {
var params = {
"battery_voltage": null,
"reed_state": null,
"light_detected": null,
"temperature": null,
"humidity": null,
"impact_magnitude": null,
"break_in": null,
"acceleration_x": null,
"acceleration_y": null,
"acceleration_z": null,
"reed_count": null,
"moisture": null,
"activity": null,
"mcu_temperature": null,
"impact_alarm": null,
"activity_count": null,
"external_input": null,
"external_input_count": null,
"decode_data_hex": bin2HexStr(bytes),
"bytes": bytes
}
for (var i = 0; i < bytes.length; i ) {
// Handle battery voltage
if(0x00 === bytes[i] && 0xFF === bytes[i 1]) {
params.battery_voltage = 0.01 * ((bytes[i 2] << 8) | bytes[i 3]);
i = i 3;
}
// Handle reed switch state
if(0x01 === bytes[i] && 0x00 === bytes[i 1]) {
if(0x00 === bytes[i 2]) {
params.reed_state = true;
} else if(0xFF === bytes[i 2]) {
params.reed_state = false;
}
i = i 2;
}
// Handle light detection
if(0x02 === bytes[i] && 0x00 === bytes[i 1]) {
if(0x00 === bytes[i 2]) {
params.light_detected = false;
} else if(0xFF === bytes[i 2]) {
params.light_detected = true;
}
i = i 2;
}
// Handle temperature
if(0x03 === bytes[i] && 0x67 === bytes[i 1]) {
// Sign-extend to 32 bits to support negative values, by shifting 24 bits
// (16 too far) to the left, followed by a sign-propagating right shift:
params.temperature = (bytes[i 2]<<24>>16 | bytes[i 3]) / 10;
i = i 3;
}
// Handle humidity
if(0x04 === bytes[i] && 0x68 === bytes[i 1]) {
params.humidity = 0.5 * bytes[i 2];
i = i 2;
}
// Handle impact magnitude
if(0x05 === bytes[i] && 0x02 === bytes[i 1]) {
// Sign-extend to 32 bits to support negative values, by shifting 24 bits
// (16 too far) to the left, followed by a sign-propagating right shift:
params.impact_magnitude = (bytes[i 2]<<24>>16 | bytes[i 3])/1000;
i = i 3;
}
// Handle break-in
if(0x06 === bytes[i] && 0x00 === bytes[i 1]) {
if(0x00 === bytes[i 2]) {
params.break_in = false;
} else if(0xFF === bytes[i 2]) {
params.break_in = true;
}
i = i 2;
}
// Handle accelerometer data
if(0x07 === bytes[i] && 0x71 === bytes[i 1]) {
// Sign-extend to 32 bits to support negative values, by shifting 24 bits
// (16 too far) to the left, followed by a sign-propagating right shift:
params.acceleration_x = (bytes[i 2]<<24>>16 | bytes[i 3])/1000;
params.acceleration_y = (bytes[i 4]<<24>>16 | bytes[i 5])/1000;
params.acceleration_z = (bytes[i 6]<<24>>16 | bytes[i 7])/1000;
i = i 7;
}
// Handle reed switch count
if(0x08 === bytes[i] && 0x04 === bytes[i 1]) {
params.reed_count = (bytes[i 2] << 8) | bytes[i 3];
i = i 3;
}
// Handle moisture
if(0x09 === bytes[i] && 0x00 === bytes[i 1]) {
i = i 1;
//check data
if (0x00 === bytes[i 1]) {
params.moisture = false;
i = i 1;
}
else if( 0xFF === bytes[i 1]) {
params.moisture = true;
i = i 1;
}
}
// Handle PIR activity
//check the channel and type
if(0x0A === bytes[i] && 0x00 === bytes[i 1]) {
i = i 1;
//check data
if (0x00 === bytes[i 1]) {
params.activity = false;
i = i 1;
}
else if( 0xFF === bytes[i 1]) {
params.activity = true;
i = i 1;
}
}
// Handle temperature
if(0x0B === bytes[i] && 0x67 === bytes[i 1]) {
// Sign-extend to 32 bits to support negative values, by shifting 24 bits
// (16 too far) to the left, followed by a sign-propagating right shift:
params.mcu_temperature = (bytes[i 2]<<24>>16 | bytes[i 3]) / 10;
i = i 3;
}
// Handle impact alarm
if(0x0C === bytes[i] && 0x00 === bytes[i 1]) {
if(0x00 === bytes[i 2]) {
params.impact_alarm = false;
} else if(0xFF === bytes[i 2]) {
params.impact_alarm = true;
}
i = i 2;
}
// Handle motion (PIR activity) event count
if(0x0D === bytes[i] && 0x04 === bytes[i 1]) {
params.activity_count = (bytes[i 2] << 8) | bytes[i 3];
i = i 3;
}
// Handle external input state
if(0x0E === bytes[i] && 0x00 === bytes[i 1]) {
if(0x00 === bytes[i 2]) {
params.external_input = true;
} else if(0xFF === bytes[i 2]) {
params.external_input = false;
}
i = i 2;
}
// Handle external input count
if(0x0F === bytes[i] && 0x04 === bytes[i 1]) {
params.external_input_count = (bytes[i 2] << 8) | bytes[i 3];
i = i 3;
}
}
return params
}
console.log(Decoder("A2cAzwRoYQD/AS0=", 10))
Yields empty params, even though there is certainly values for temperature, humidity, etc inside the if statements.
{
battery_voltage: null,
reed_state: null,
light_detected: null,
temperature: null,
humidity: null,
impact_magnitude: null,
break_in: null,
acceleration_x: null,
acceleration_y: null,
acceleration_z: null,
reed_count: null,
moisture: null,
activity: null,
mcu_temperature: null,
impact_alarm: null,
activity_count: null,
external_input: null,
external_input_count: null,
decode_data_hex: '0x0A,0x02,0x0c,0x0A,0x0z,0x0w,0x0R,0x0o,0x0Y,0x0Q,0x0D,0x0/,0x0A,0x0S,0x00,0x0=',
bytes: 'A2cAzwRoYQD/AS0='
}
CodePudding user response:
The code doesnt enter any of the ifs. Lets take for example the first if
0x00 === bytes[i] && 0xFF === bytes[i 1]
if the i provide the method a string starting with 0 you expect 0x00 === bytes[i] to be true. But it isnt, because '0' is not equal 0x00
you are comparing strings with hex values
CodePudding user response:
Thank you for your answers! You helped me realized I made a rookie mistake and neglected to pass the function bytes (not the Base64 string). I fixed it by adding:
let request = {
"PayloadData": "A2cAzwRoYQD/AS0=",
"FPort": 10
}
let buffer = Buffer.from(request.PayloadData, 'base64');
let bufferString = buffer.toString('hex');
console.log(Decoder(buffer, 10))
And now it's working. Here's the complete code:
function bin2HexStr(arr)
{
var str = "";
for(var i=0; i<arr.length; i )
{
var tmp = arr[i].toString(16);
if(tmp.length == 1)
{
tmp = "0" tmp;
}
tmp = "0x" tmp;
if (i != arr.length - 1) {
tmp = ",";
}
str = tmp;
}
return str;
}
//TTN Handler
function Decoder(bytes, port) {
var params = {
"battery_voltage": null,
"reed_state": null,
"light_detected": null,
"temperature": null,
"humidity": null,
"impact_magnitude": null,
"break_in": null,
"acceleration_x": null,
"acceleration_y": null,
"acceleration_z": null,
"reed_count": null,
"moisture": null,
"activity": null,
"mcu_temperature": null,
"impact_alarm": null,
"activity_count": null,
"external_input": null,
"external_input_count": null,
"decode_data_hex": bin2HexStr(bytes),
"bytes": bytes
}
for (var i = 0; i < bytes.length; i ) {
// Handle battery voltage
if(0x00 === bytes[i] && 0xFF === bytes[i 1]) {
params.battery_voltage = 0.01 * ((bytes[i 2] << 8) | bytes[i 3]);
i = i 3;
}
// Handle reed switch state
if(0x01 === bytes[i] && 0x00 === bytes[i 1]) {
if(0x00 === bytes[i 2]) {
params.reed_state = true;
} else if(0xFF === bytes[i 2]) {
params.reed_state = false;
}
i = i 2;
}
// Handle light detection
if(0x02 === bytes[i] && 0x00 === bytes[i 1]) {
if(0x00 === bytes[i 2]) {
params.light_detected = false;
} else if(0xFF === bytes[i 2]) {
params.light_detected = true;
}
i = i 2;
}
// Handle temperature
if(0x03 === bytes[i] && 0x67 === bytes[i 1]) {
// Sign-extend to 32 bits to support negative values, by shifting 24 bits
// (16 too far) to the left, followed by a sign-propagating right shift:
params.temperature = (bytes[i 2]<<24>>16 | bytes[i 3]) / 10;
i = i 3;
}
// Handle humidity
if(0x04 === bytes[i] && 0x68 === bytes[i 1]) {
params.humidity = 0.5 * bytes[i 2];
i = i 2;
}
// Handle impact magnitude
if(0x05 === bytes[i] && 0x02 === bytes[i 1]) {
// Sign-extend to 32 bits to support negative values, by shifting 24 bits
// (16 too far) to the left, followed by a sign-propagating right shift:
params.impact_magnitude = (bytes[i 2]<<24>>16 | bytes[i 3])/1000;
i = i 3;
}
// Handle break-in
if(0x06 === bytes[i] && 0x00 === bytes[i 1]) {
if(0x00 === bytes[i 2]) {
params.break_in = false;
} else if(0xFF === bytes[i 2]) {
params.break_in = true;
}
i = i 2;
}
// Handle accelerometer data
if(0x07 === bytes[i] && 0x71 === bytes[i 1]) {
// Sign-extend to 32 bits to support negative values, by shifting 24 bits
// (16 too far) to the left, followed by a sign-propagating right shift:
params.acceleration_x = (bytes[i 2]<<24>>16 | bytes[i 3])/1000;
params.acceleration_y = (bytes[i 4]<<24>>16 | bytes[i 5])/1000;
params.acceleration_z = (bytes[i 6]<<24>>16 | bytes[i 7])/1000;
i = i 7;
}
// Handle reed switch count
if(0x08 === bytes[i] && 0x04 === bytes[i 1]) {
params.reed_count = (bytes[i 2] << 8) | bytes[i 3];
i = i 3;
}
// Handle moisture
if(0x09 === bytes[i] && 0x00 === bytes[i 1]) {
i = i 1;
//check data
if (0x00 === bytes[i 1]) {
params.moisture = false;
i = i 1;
}
else if( 0xFF === bytes[i 1]) {
params.moisture = true;
i = i 1;
}
}
// Handle PIR activity
//check the channel and type
if(0x0A === bytes[i] && 0x00 === bytes[i 1]) {
i = i 1;
//check data
if (0x00 === bytes[i 1]) {
params.activity = false;
i = i 1;
}
else if( 0xFF === bytes[i 1]) {
params.activity = true;
i = i 1;
}
}
// Handle temperature
if(0x0B === bytes[i] && 0x67 === bytes[i 1]) {
// Sign-extend to 32 bits to support negative values, by shifting 24 bits
// (16 too far) to the left, followed by a sign-propagating right shift:
params.mcu_temperature = (bytes[i 2]<<24>>16 | bytes[i 3]) / 10;
i = i 3;
}
// Handle impact alarm
if(0x0C === bytes[i] && 0x00 === bytes[i 1]) {
if(0x00 === bytes[i 2]) {
params.impact_alarm = false;
} else if(0xFF === bytes[i 2]) {
params.impact_alarm = true;
}
i = i 2;
}
// Handle motion (PIR activity) event count
if(0x0D === bytes[i] && 0x04 === bytes[i 1]) {
params.activity_count = (bytes[i 2] << 8) | bytes[i 3];
i = i 3;
}
// Handle external input state
if(0x0E === bytes[i] && 0x00 === bytes[i 1]) {
if(0x00 === bytes[i 2]) {
params.external_input = true;
} else if(0xFF === bytes[i 2]) {
params.external_input = false;
}
i = i 2;
}
// Handle external input count
if(0x0F === bytes[i] && 0x04 === bytes[i 1]) {
params.external_input_count = (bytes[i 2] << 8) | bytes[i 3];
i = i 3;
}
}
return params
}
let request = {
"PayloadData": "A2cAzwRoYQD/AS0=",
"FPort": 10
}
let buffer = Buffer.from(request.PayloadData, 'base64');
let bufferString = buffer.toString('hex');
console.log(Decoder(buffer, 10))
Results in:
{
battery_voltage: 3.0100000000000002,
reed_state: null,
light_detected: null,
temperature: 20.7,
humidity: 48.5,
impact_magnitude: null,
break_in: null,
acceleration_x: null,
acceleration_y: null,
acceleration_z: null,
reed_count: null,
moisture: null,
activity: null,
mcu_temperature: null,
impact_alarm: null,
activity_count: null,
external_input: null,
external_input_count: null,
decode_data_hex: '0x03,0x67,0x00,0xcf,0x04,0x68,0x61,0x00,0xff,0x01,0x2d',
bytes: <Buffer 03 67 00 cf 04 68 61 00 ff 01 2d>
}