Errors in MODBUS RTU communication

@UnborN Thanks for sharing this flow. I'm going to rebuild my own flow with these extra nodes and settings to make it more errorproof. I like the buffer parser.
Will take me some time...

1 Like

@grant1 make sure there are no other flows that use the same config or Serial port .. if there are, Export them, back them up and delete them temporarily so we wont have multiple Modbus / or other nodes fighting over the same device.

Strange problem .. we know that the /dev/ttySer0 path is ok .. since you get a reply with previous flows
but could you run ls /dev/*USB* from terminal to use the usb path as a test ?

@rob2 glad its working for you .. is it stable ?
sorry for hijacking your thread .. i think its all related to the same subject

I did the following:

  • exported / took notes of my working settings and then completely deleted the Flow / tab containing all the Modbus serial info
  • imported your flow from post #34 above
  • restarted Node-red (just for good measure)

Still getting errors as shown:

As Node-RED is running on some hardware that I have never used SSH before with, I will look into it and see if I can run the ls command you mentioned. Meanwhile, I noticed that this is running Nodejs v12. Could that somehow be related to the issue?

image

Can you also uncheck

image

and also "Queue Commands"

image

since we implemented our own polling queue .. the next msg (with the Inject node) should re-trigger the connection and there is no need for the Modbus config to "Reconnect on timeout"

Yes, I will do that. Right now, I am waiting for a firmware update to the hardware although nothing in this update appears to affect Node-RED.

Should have answers in about 20 minutes.

If this does not work, I will try putting a fully updated Raspberry Pi in place to see if that changes anything.

1 Like

I did the firmware upgrade (although no changes that I can see to Node-RED). I think those last two instructions...

did the trick. Here is what I see now (again, #301 and #303 are turned off at the time of this screenshot)

When I turn on #303, it correctly shows the value for that unit as "250", but will not proceed to read #305...

Any other suggestions?

Excellent !!!
it looks like the modbus nodes need some more work .. I know the developer released a couple of updates recently but still a bit buggy with their queues and reconnections.

if it works .. nope :wink:
let it run for a few days see if its stable

@UnborN Not to beat a dead horse here, but it still gets "stuck" on the #303 node and never seems to run to #305 (where the reading should be 31 to 33). Below, I moved disabled the #301 modbus node and moved the inject node. You can see that it never gets to read #305.

EDIT: But wait, there's more...It eventually threw an error and then did move to #305, but just once that I can see. Now it's back to the 250 reading for #303 every 10 seconds.

EDIT #2: After re-enabling the first modbus node (#301) and watching the flow for ~10 minutes, it does not ever report a reading for #305. Only the "250" for #303.

If I then re-order the flow to #301 --> #305 --> #303, it works! This indicates to me that the error code being thrown by #303 (250 is a sort of error code) is preventing the flow from continuing. Can we modify the function node to handle this?

image


if (msg.payload == "" || msg.hasOwnProperty('error')) {

    node.status({ fill: "red", shape: "ring", text: `Error` });

    return [null, msg]
}

else {

    return [msg, null];
}

celebrated too soon .. but there is progress

seems like it .. if you put a complete msg debug node directly after the Modbus node of 303
do you get an "empty msg" with a msg.error property ? .. if not then the error "Function" wont be able to handle this kind of fail.

i noticed that for the 301, 305 device you read

  'address': 123,

while for 303

  'address': 122, 

are the devices identical and should the registers starting address and quantity be the same ?

The two controllers are the same model, but several years apart. For reasons that are unclear, I found that I indeed need to access the slightly different addresses depending on the model. My guess is they added a parameter and updated the Modbus register list accordingly.

Here is the output of the Modbus 303 node:

For comparison, here is the complete msg output for Modbus 305 node. It looks practically the same (except for the aforementioned register changes)

we wanted the fail msg from 303 .. if there is one .. not the data msg

and please dont re-wire the flow so we'll be on the same page .. otherwise we dont know what changes
you made. Im totally confused as to how you managed to get a msg from 303 and 305 when before 303 was failing :wink:

maybe it makes a difference if the device is in Security Code mode or Control mode ? i was hoping that we didnt have to dive into a 1998 device manual

@UnborN and everyone that put up with this long back-and-forth...

It's now solved. Apparently using the 2nd output of the Flex-Getter node in combination with my Modbus data resulted in the data NOT flowing through any Modbus node where the controller was turned off.

Output 1: data Array (PDU), modbus response Buffer, input message

Output 2: modbus response Buffer, data Array (PDU), input message

This did NOT work (inject would not continue past #303, even with it reporting a valid value of 250).

image

Changing to the 1st output DID work (flow continues past #301, which is turned off, and retrieves values for #303 & #305).

And finally, having both #301 and #303 turned off, the flow retrieves the value for #305:

Thank you @UnborN for your help and also @rob2 @Steve-Mcl and @Colin for their input. Nice to have this long-standing Modbus-RTU issue with these controllers resolved.

1 Like

you are absolutely right .. it was my mistake when i shared the flow today with the new changes.
if you see post #24 it shows the wiring as you did now .. and then i wired it wrong :sleeping:
im glad you found it!
so we dont even need a second output on those "error" functions
just simply blocking the message from going to buffer-parcer when there's a failure

if (msg.payload == "" || msg.hasOwnProperty('error')) {
    node.status({ fill: "red", shape: "ring", text: `${msg.error}`});
}

else {
    node.status({ fill: "green", shape: "ring", text: ""});
    return msg;
}

I updated some the flow in the new way with modbus flex getter and error checking.
Connecting exit error flow with next input modbus node2 dit not work.

Connecting exit from modbus node1 to input modbus node2 does work:

Strange... I copied the flow from @UnborN

[{"id":"1f9af0a15c6fd77e","type":"tab","label":"Flow 2","disabled":false,"info":"","env":[]},{"id":"3fe83c3fe1ded9b6","type":"inject","z":"1f9af0a15c6fd77e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"2","topic":"","payload":"","payloadType":"date","x":120,"y":100,"wires":[["14ef1aabb5810fe4"]]},{"id":"8b3dbd30724da801","type":"function","z":"1f9af0a15c6fd77e","name":"","func":"//--KwH verbruik/levering----------------------------------------------\n\nmsg.payload = [\n    {\n        VerbruikKWH: msg.payload[0],\n    },\n    {\n        MeterId: 'K03-ID3',\n        Locatie: 'ID3',\n        Locatiegroep: 'Huis'\n    },\n    { timestamp: Date.now()}\n];\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1060,"y":160,"wires":[["f061154212ea56c0"]]},{"id":"f061154212ea56c0","type":"debug","z":"1f9af0a15c6fd77e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1270,"y":180,"wires":[]},{"id":"141167c68c491dfe","type":"modbus-response","z":"1f9af0a15c6fd77e","name":"","registerShowMax":20,"x":610,"y":100,"wires":[]},{"id":"14ef1aabb5810fe4","type":"function","z":"1f9af0a15c6fd77e","name":"function 5","func":"msg.topic = \"K03-ID3\"\n\nmsg.payload = {\n    value: msg.payload,\n    'fc': 3,\n    'unitid': 3,\n    'address': 20480,\n    'quantity': 4\n}\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":235,"y":140,"wires":[["1f4cc7a623e7b58b"]],"l":false},{"id":"1f4cc7a623e7b58b","type":"modbus-flex-getter","z":"1f9af0a15c6fd77e","name":"","showStatusActivities":false,"showErrors":true,"logIOActivities":false,"server":"bb5a04411cd75771","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":true,"keepMsgProperties":false,"x":370,"y":140,"wires":[["141167c68c491dfe","42280bb1d6e8a947","12f4fc19fc1ff8a4"],[]]},{"id":"42280bb1d6e8a947","type":"function","z":"1f9af0a15c6fd77e","name":"error","func":"\nif (msg.payload == \"\" || msg.hasOwnProperty('error')) {\n\n    node.status({ fill: \"red\", shape: \"ring\", text: `Error` });\n\n    return [null, msg]\n}\n\nelse {\n\n    return [msg, null];\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":570,"y":160,"wires":[["62c3303960d04a67"],["a9b9dbb66ee77484"]]},{"id":"775158fe14d7d7c4","type":"function","z":"1f9af0a15c6fd77e","name":"","func":"//--KwH verbruik/levering----------------------------------------------\n\nmsg.payload = [\n    {\n        VerbruikKWH: msg.payload[0],\n    },\n    {\n        MeterId: 'K04-ID4',\n        Locatie: 'ID4',\n        Locatiegroep: 'Huis'\n    },\n    { timestamp: Date.now()}\n];\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1060,"y":280,"wires":[["d64796ec1be24478"]]},{"id":"d64796ec1be24478","type":"debug","z":"1f9af0a15c6fd77e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1270,"y":300,"wires":[]},{"id":"7ad6ee8739d16983","type":"modbus-response","z":"1f9af0a15c6fd77e","name":"","registerShowMax":20,"x":610,"y":220,"wires":[]},{"id":"12f4fc19fc1ff8a4","type":"function","z":"1f9af0a15c6fd77e","name":"function 6","func":"msg.payload = {\n    value: msg.payload,\n    'fc': 3,\n    'unitid': 4,\n    'address': 20480,\n    'quantity': 4\n}\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":235,"y":260,"wires":[["10162f23fa33b20c"]],"l":false},{"id":"10162f23fa33b20c","type":"modbus-flex-getter","z":"1f9af0a15c6fd77e","name":"","showStatusActivities":false,"showErrors":false,"logIOActivities":false,"server":"bb5a04411cd75771","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":true,"keepMsgProperties":false,"x":370,"y":260,"wires":[["7ad6ee8739d16983","545e312beeaa3805"],[]]},{"id":"545e312beeaa3805","type":"function","z":"1f9af0a15c6fd77e","name":"error","func":"\nif (msg.payload == \"\" || msg.hasOwnProperty('error')) {\n\n    node.status({ fill: \"red\", shape: \"ring\", text: `Error` });\n\n    return [null, msg]\n}\n\nelse {\n\n    return [msg, null];\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":570,"y":280,"wires":[["05da5aa141d15e1a"],["0899d740618f4516"]]},{"id":"62c3303960d04a67","type":"buffer-parser","z":"1f9af0a15c6fd77e","name":"","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"uint32be","name":"VerbruikKWH","offset":4,"length":1,"offsetbit":0,"scale":"/10","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"value","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":830,"y":140,"wires":[["8b3dbd30724da801"]]},{"id":"05da5aa141d15e1a","type":"buffer-parser","z":"1f9af0a15c6fd77e","name":"","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"uint32be","name":"VerbruikKWH","offset":4,"length":1,"offsetbit":0,"scale":"/10","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"value","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":830,"y":260,"wires":[["775158fe14d7d7c4"]]},{"id":"a9b9dbb66ee77484","type":"debug","z":"1f9af0a15c6fd77e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":830,"y":180,"wires":[]},{"id":"0899d740618f4516","type":"debug","z":"1f9af0a15c6fd77e","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":830,"y":300,"wires":[]},{"id":"bb5a04411cd75771","type":"modbus-client","name":"","clienttype":"simpleser","bufferCommands":true,"stateLogEnabled":false,"queueLogEnabled":false,"failureLogEnabled":false,"tcpHost":"127.0.0.1","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttymxc2","serialType":"RTU-BUFFERD","serialBaudrate":"19200","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","serialAsciiResponseStartDelimiter":"0x3A","unit_id":"","commandDelay":"100","clientTimeout":"1000","reconnectOnTimeout":true,"reconnectTimeout":"2000","parallelUnitIdsAllowed":true}]

Any ideas what goes wrong?

The first flow will only trigger the second getter node if there is a message from output 2 of the error function node, which, looking at your code, appears to be the error output. So the second getter will only run if the first one generates an error, is that what you want to happen?

Hi Colin,
What I want is stopping wrong data or error texts going to the buffer parser, but in all cases error or not for a particular modbus meter it has to start reading the next modbusmeter.

I missed the latest message from UnborN with the corrected error message. I know almost no Javascript but it seems logical code as there is only one output node as expected.

I updated some parts of the flow to the new way with the modbus flex getter node and error checking node as suggested by UnborN but missed the last reaction. I got it working today without those corrected error check node.

Next time on location I correct the error function node and is it possible to shutdown a meter to see how the chain reacts.

For now I am very happy with the resulting flow, thank you all for your contribution. Special thanks go to @UnborN

1 Like

Hi Rob,
in my attempt to share a flow (#35) that implements the error checking Functions, i made a critical mistake with the wiring of the nodes. I was blinded by my confidence that it should work but Grant found the mistake that its the Modbus nodes that should be wired in chain instead (the error functions in your setups dont really need two outputs .. just the logic to block fail msgs to buffer-parser).

By importing your last shared Flow .. possibly like this

[{"id":"3fe83c3fe1ded9b6","type":"inject","z":"1f9af0a15c6fd77e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"2","topic":"","payload":"","payloadType":"date","x":120,"y":80,"wires":[["14ef1aabb5810fe4"]]},{"id":"8b3dbd30724da801","type":"function","z":"1f9af0a15c6fd77e","name":"","func":"//--KwH verbruik/levering----------------------------------------------\n\nmsg.payload = [\n    {\n        VerbruikKWH: msg.payload[0],\n    },\n    {\n        MeterId: 'K03-ID3',\n        Locatie: 'ID3',\n        Locatiegroep: 'Huis'\n    },\n    { timestamp: Date.now()}\n];\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":960,"y":140,"wires":[["f061154212ea56c0"]]},{"id":"f061154212ea56c0","type":"debug","z":"1f9af0a15c6fd77e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1130,"y":140,"wires":[]},{"id":"141167c68c491dfe","type":"modbus-response","z":"1f9af0a15c6fd77e","name":"","registerShowMax":20,"x":610,"y":80,"wires":[]},{"id":"14ef1aabb5810fe4","type":"function","z":"1f9af0a15c6fd77e","name":"function 5","func":"msg.topic = \"K03-ID3\"\n\nmsg.payload = {\n    value: msg.payload,\n    'fc': 3,\n    'unitid': 3,\n    'address': 20480,\n    'quantity': 4\n}\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":235,"y":140,"wires":[["1f4cc7a623e7b58b"]],"l":false},{"id":"1f4cc7a623e7b58b","type":"modbus-flex-getter","z":"1f9af0a15c6fd77e","name":"","showStatusActivities":true,"showErrors":false,"logIOActivities":false,"server":"bb5a04411cd75771","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":true,"keepMsgProperties":false,"x":370,"y":140,"wires":[["141167c68c491dfe","42280bb1d6e8a947","12f4fc19fc1ff8a4"],[]]},{"id":"42280bb1d6e8a947","type":"function","z":"1f9af0a15c6fd77e","name":"error","func":"if (msg.payload == \"\" || msg.hasOwnProperty('error')) {\n    node.status({ fill: \"red\", shape: \"ring\", text: `${msg.error}`});\n}\n\nelse {\n    node.status({ fill: \"green\", shape: \"ring\", text: \"\"});\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":570,"y":140,"wires":[["62c3303960d04a67"]]},{"id":"775158fe14d7d7c4","type":"function","z":"1f9af0a15c6fd77e","name":"","func":"//--KwH verbruik/levering----------------------------------------------\n\nmsg.payload = [\n    {\n        VerbruikKWH: msg.payload[0],\n    },\n    {\n        MeterId: 'K04-ID4',\n        Locatie: 'ID4',\n        Locatiegroep: 'Huis'\n    },\n    { timestamp: Date.now()}\n];\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":960,"y":280,"wires":[["d64796ec1be24478"]]},{"id":"d64796ec1be24478","type":"debug","z":"1f9af0a15c6fd77e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1130,"y":280,"wires":[]},{"id":"7ad6ee8739d16983","type":"modbus-response","z":"1f9af0a15c6fd77e","name":"","registerShowMax":20,"x":610,"y":220,"wires":[]},{"id":"12f4fc19fc1ff8a4","type":"function","z":"1f9af0a15c6fd77e","name":"function 6","func":"msg.payload = {\n    value: msg.payload,\n    'fc': 3,\n    'unitid': 4,\n    'address': 20480,\n    'quantity': 4\n}\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":235,"y":260,"wires":[["10162f23fa33b20c"]],"l":false},{"id":"10162f23fa33b20c","type":"modbus-flex-getter","z":"1f9af0a15c6fd77e","name":"","showStatusActivities":true,"showErrors":false,"logIOActivities":false,"server":"bb5a04411cd75771","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":true,"keepMsgProperties":false,"x":370,"y":260,"wires":[["7ad6ee8739d16983","545e312beeaa3805"],[]]},{"id":"545e312beeaa3805","type":"function","z":"1f9af0a15c6fd77e","name":"error","func":"if (msg.payload == \"\" || msg.hasOwnProperty('error')) {\n    node.status({ fill: \"red\", shape: \"ring\", text: `${msg.error}`});\n}\n\nelse {\n    node.status({ fill: \"green\", shape: \"ring\", text: \"\"});\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":570,"y":280,"wires":[["05da5aa141d15e1a"]]},{"id":"62c3303960d04a67","type":"buffer-parser","z":"1f9af0a15c6fd77e","name":"","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"uint32be","name":"VerbruikKWH","offset":4,"length":1,"offsetbit":0,"scale":"/10","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"value","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":790,"y":140,"wires":[["8b3dbd30724da801"]]},{"id":"05da5aa141d15e1a","type":"buffer-parser","z":"1f9af0a15c6fd77e","name":"","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"uint32be","name":"VerbruikKWH","offset":4,"length":1,"offsetbit":0,"scale":"/10","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"value","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":790,"y":280,"wires":[["775158fe14d7d7c4"]]},{"id":"bb5a04411cd75771","type":"modbus-client","name":"","clienttype":"simpleser","bufferCommands":true,"stateLogEnabled":false,"queueLogEnabled":false,"failureLogEnabled":false,"tcpHost":"127.0.0.1","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttymxc2","serialType":"RTU-BUFFERD","serialBaudrate":"19200","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","serialAsciiResponseStartDelimiter":"0x3A","unit_id":"","commandDelay":"100","clientTimeout":"1000","reconnectOnTimeout":false,"reconnectTimeout":"2000","parallelUnitIdsAllowed":false}]

Thank you, it is now clear to me. I updated the flows and do tests later this week. The flows from last week worked fine, none was stopped and no errors while I checked the debug screen.

I have only one concern left. I have some problems with finding out the right conversions for content of the modbus addresses to right values. I have zero experience with Javascript and raw PLC values but I like to learn :muscle: :muscle: Maybe I can ask some help? ABB info's at the bottom of this post.

I try to find out how to create the measured value represented by 4 or 2 modbus addresses.

Measured value represented by 4 modbus addresses
As 1 address in the meter is 16 bits and 4 addresses are used i think i need a 64bit variable in the bufferparser and it is an integer and unsigned, so UInt64BE. This seems not to exist, but BigUInt64(BE) is in the pulldown list.
Is this what I need? As nobody on the internet seems to use this bigint thing in modbus land...

Measured value represented by 2 modbus addresses
I think I need UInt32(BE) for reading this value.
Is this correct?

Implementation
Would this flow setup work for specs given in table?

And part 2:

This is a part of the measurements I use (summary from the manual):

Should this result in a node (actually 2 as there are more than 125 addresses between first 2) filled like this? Is this correct? (note: Active export is at modbus address 20484)

Info given by ABB

This is what I have found in the manual:

  • hardware: meters ABB models B23 112-100 and B21 112-100, link to model B23 manual (look at chapter 9 for addresses).
  • A Modbus Register is 16 bits long. All metering data is represented by one or more such registers
  • Supported function code 3 (Read holding registers)
  • It is possible to read up to 125 consecutive registers at a time.
  • Start Reg (Hex) Hexadecimal number for the first (lowest) Modbus Register for this quantity. It is expressed exactly as it is sent on the bus. That is, it should not be subtracted by 40 000 or decremented by 1
  • For quantities that are represented as more than 1 register, the most significant byte is found in the high byte of the first (lowest) register. The least significant byte is found in the low byte of the last (highest) register. BIG-endian method
  • Powers are sent out as 32 bit signed integers with 2 decimals. At least they say this, with active import I see only a resolution of 0,1kWh

Hi Rob,

Thanks for the detailed information .. yes it seems that UInt64BE are what is needed for the kwh
Based on your first buffer-parser screenshot, i believe you need offset 8 for the second value because from the node's help file :

The offset value denotes which byte to start reading data from.

and since 1 x register is 16bits which is 2 bytes, the second 4 x register 64bit BigInt value (Active Export) should have offset 8 bytes?

Some corrections i believe are needed for the second buffer node also for the uint32(be).
Offset 4 bytes for registers that are sequential. (if the registers are not sequential then further calculations are needed for the byte offset and ofcourse it all depends on the starting register number)

I dug up the raw data for the same type ABB meter (B23). Is this helpfull for choosing the right variabletype?
In the lowest part of the screenprint the raw data from the meter.