32 Bit overflow in Payload Format decoder

hello everyone, the serial number field of my electricity meter actually has 32 bits. But if I add bytes 0 to 3, I get an overflow from “8F FF FF FF”. At what point in my decoder do I have to declare the 32 bit number?

Thanks in advance…

function Decoder(bytes, port) {
  var meinwert = (bytes[0]<<24) + (bytes[1]<<16) + (bytes[2]<<8) + (bytes[3]<<0);
  return {
    measurement: {
      wert: meinwert
    },
  };
}

This value exceeds the range of the signed integers used by relevant javascript operations. It would fit int a 32-bit unsgined integer but that does not exist in all implementations.

It may be best to treat this as a string of hex digits, not a number. Given that it’s a serial number it’s not like you would be performing numeric operation on it, and you can construct it by string concatenation of either the octets or of two 16 bit values.

2 Likes

Sure, of course! Thank you for the solution. I read the 4 bytes individually and add them on my server via #!/bin/bash :-). In addition to the serial number, the display of the power consumption is 4 bytes long. Why it was made so big is questionable - but that’s how it is sometimes …

root@destiny:~# echo "ibase=16; FFFFFFFF"|bc
4294967295

If you still prefer to do it in the payload format decoder:

Unsigned numbers are quite doable if you stay away from bitwise operators. To convert 4 bytes to a 32 bits unsigned integer, see uint32 in Abeeway Microtracker Decoder. Or, for a random number of bytes, but still limited to at most 6:

/**
 * Convert the array of bytes to an unsigned integer. 
 *
 * BEWARE: This is only safe up to 0x1FFFFFFFFFFFFF, so: 6 bytes.
 */
function uint(bytes) {
  return bytes.reduce(function(acc, b) {
    // Unsigned, so don't use any bitwise operators, which would always
    // yield a signed 32 bits integer instead.
    return acc * 0x100 + b;
  }, 0);
}

var i = 0;
// Convert the next 4 bytes to an unsigned integer number
var serial = uint(bytes.slice(i, i+=4));

If you want a 10 character decimal string with leading zeroes, then I’d first convert it to an unsigned number, like above, and then use ('000000000' + serial).substr(-10).

Or if you want a hexadecimal string, see hex in the same Abeeway Microtracker Decoder.

(Aside: see also How do I format my forum post? [HowTo] Thanks!)

1 Like