Uplink conversion from v2 to v3

Payload conversation from v2 to V3 and receiving error “TypeError: Cannot read property ‘toString’ of undefined or null at decodeUplink (:16:41(25))”. An example “frm_payload” is 5DzclmTiD88SDKU=

I have the following uplink script from v2 :

/**

  • Basic decoder for Laird RS1xx Sensors, only supporting uplink message

  • type 0x01 as defined in RS1xx LoRa Protocol v2.7.
    */
    function Decoder(bytes, f_port) {
    var messageType = bytes[0];
    // All Sensor-to-Server messages have the same options byte format.
    // The options byte is always at byte index 1.
    var options = bytes[1];
    var decoded = {
    raw: bytes,
    f_port: f_port,
    messageType: messageType,
    options: options,
    // Just for debugging: show all 8 bits, ensuring leading zeroes
    optionFlags: ‘0b’ + (‘00000000’ + options.toString(2)).slice(-8),
    sensorRequestForServerTime: (options & 1<<0) > 0,
    sensorConfigurationError: (options & 1<<1) > 0,
    sensorAlarmFlag: (options & 1<<2) > 0,
    sensorResetFlag: (options & 1<<3) > 0,
    sensorFaultFlag: (options & 1<<4) > 0
    };
    switch (messageType) {
    // 0x01 = Send Temp RH Data Notification
    case 0x01:
    decoded.humidity = bytes[3] + bytes[2]/100;

    // For temperature, both the integer and fractional parts are signed:
    // a positive value of 27.43 has a fractional portion of 43 and an
    // integer portion 27, and a negative value -15.87 uses -87 and -15.
    // Sign-extend a single byte to 32 bits to make JavaScript understand
    // negative values, by shifting 24 bits to the left, followed by a
    // sign-propagating right shift of the same number of bits:
    decoded.temperature = (bytes[5]<<24>>24) + (bytes[4]<<24>>24)/100;

    decoded.batteryIndex = bytes[6];
    decoded.batteryCapacity = {
    0: ‘0-5%’,
    1: ‘5-20%’,
    2: ‘20-40%’,
    3: ‘40-60%’,
    4: ‘60-80%’,
    5: ‘80-100%’
    }[decoded.batteryIndex] || ‘Unsupported value’;

    decoded.alarmMsgCount = bytes[7]<<8 | bytes[8];
    decoded.backlogMsgCount = bytes[9]<<8 | bytes[10];
    break;

    default:
    decoded.error = ‘Unsupported message type’;
    }

return decoded;
}

I’ve changed it to V3 but getting error “TypeError: Cannot read property ‘toString’ of undefined or null at decodeUplink (:16:41(25))”"`

function decodeUplink(input,f_port) {

var bytes = input.bytes;

var messageType = bytes[0];

// All Sensor-to-Server messages have the same options byte format.

// The options byte is always at byte index 1.

var options = bytes[1];



var decoded = {

  raw: bytes,

  f_port: f_port,

  messageType: messageType,

  options: options,

  // Just for debugging: show all 8 bits, ensuring leading zeroes

  optionFlags: '0b' + ('00000000' + options.toString(2)).slice(-8),

  sensorRequestForServerTime: (options & 1<<0) > 0,

  sensorConfigurationError: (options & 1<<1) > 0,

  sensorAlarmFlag: (options & 1<<2) > 0,

  sensorResetFlag: (options & 1<<3) > 0,

  sensorFaultFlag: (options & 1<<4) > 0

};



switch (messageType) {

  // 0x01 = Send Temp RH Data Notification

  case 0x01:

    decoded.humidity = bytes[3] + bytes[2]/100;



    // For temperature, both the integer and fractional parts are signed:

    // a positive value of 27.43 has a fractional portion of 43 and an

    // integer portion 27, and a negative value -15.87 uses -87 and -15.

    // Sign-extend a single byte to 32 bits to make JavaScript understand

    // negative values, by shifting 24 bits to the left, followed by a

    // sign-propagating right shift of the same number of bits:

    decoded.temperature = (bytes[5]<<24>>24) + (bytes[4]<<24>>24)/100;



    decoded.batteryIndex = bytes[6];

    decoded.batteryCapacity = {

      0: '0-5%',

      1: '5-20%',

      2: '20-40%',

      3: '40-60%',

      4: '60-80%',

      5: '80-100%'

    }[decoded.batteryIndex] || 'Unsupported value';



    decoded.alarmMsgCount = bytes[7]<<8 | bytes[8];

    decoded.backlogMsgCount = bytes[9]<<8 | bytes[10];

    break;

   

  default:

    decoded.error = 'Unsupported message type';

}



return decoded;

}

Check that the fport is as expected before you make assumptions about the packet contents

Thanks for the quick reply, I don’t understand how the fport would make a difference, could you clarify?

Traffic sent on each fport would have a different format, including the network management fport 0, which would carry no application data at all

It’s too bad the sensor firmware authors don’t seem to have really understood LoRaWAN though, as they seem to redundantly be putting an extra message type in the first byte of the message on whatever fport they expect, rather than using the “already paid for” fport to distinguish custom message types.

Still, your code should not even attempt to process messages which are not sent with an known and applicable fport.

If you want to see what’s actually used, you’ll need to look at the complete raw still encrypted uplink packet, as the frm_payload already has the needed information stripped off.

ok, its coming through on fport1

image

I use to be able to copy the payload and paste it in the payload format checker but it doesn’t let me in v3. The only payload I can copy is the from event details “frm_payload” and the value is “LUV9uzlgNhHb/t4=”. It looks in a different format to the MAC payload. How do you check if the code is working without waiting for the next message? Do you have any other suggestions on what to check or try to get this working?

V2 payload checker screen where i could copy and paste the payload to check if the screen works.

image