Home > Net >  Constructing object from result of multiple If statements
Constructing object from result of multiple If statements

Time:12-15

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>
}
  • Related