I am using node-red-contrib-buffer-parser to parse a long buffer that I recieve via Modbus. It is a mix of (u)int16 und (u)int32 values. As the documentation for this device does not say anything about endianess I used big endian for the (u)int16 values which worked fine. But the (u)int32 values are wrong. I would need to swap bytes which would give me correct values for the (u)int32 values but would mess up all the other values. Is there a way to swap bytes on a per-value-basis? A type uint32sw would be great. Of course I could make a workaround and do two (u)int16 values and calculate the correct value afterwards in a function node, but my goal was to get all values from the buffer parser node.
Are you certain you are correctly aligned on the byte marks?
A work around would be to feed the data through 2 parsers. You can either do it in parallel (then use a join node after) or in series by adding an entry in the first that outputs the full buffer (use -1 for the length) then apply swaps in the 2nd parser.
have to read what kind of data is sent by your device over Modbus. Personally, I do not buffer parser. I will type my own custom JavaScript to convert data, which is faster than Buffer.
This is an example script for you:
// 4. Decoding Helper Functions
function decodeFloat(lowWord, highWord) {
const buf = new ArrayBuffer(4);
const view = new DataView(buf);
view.setUint16(0, highWord, false);
view.setUint16(2, lowWord, false);
return Math.round(view.getFloat32(0, false) * 1000) / 1000;
}
function decodeInt32(lowWord, highWord) {
let u = ((highWord & 0xFFFF) << 16) | (lowWord & 0xFFFF);
return u >> 0;
}
function decodeUint32(lowWord, highWord) {
return ((highWord & 0xFFFF) * 65536) + (lowWord & 0xFFFF);
}
function decodeBCD(w) {
return ((w >> 12) & 0xF) * 1000 + ((w >> 8) & 0xF) * 100 + ((w >> 4) & 0xF) * 10 + (w & 0xF);
}
function decodeBool(w, bit) {
return ((w >> bit) & 1) === 1;
}