Convert Modbus data to ACC64 (buffer-parser, Ohmpilot, SunSpec)

Hello!
I fetch 4 modbus registers which use the type "ACC64" for total powerconsumption in Wh.

So far I utterly failed to convert the buffer to a number. Could anyone please help me how to configure the buffer parser? :slight_smile:

Thank you very much! :slight_smile:

Hi, welcome to the forum.

I am unfamiliar with ACC64 but a quick search reveals it is a number format SunSpec uses - are you using SunSpec gear?

According to a Sunspec PDF, ACC64 is essentially a smaller uint64 with a range of 0 ... 9223372036854775807

9223372036854775807 is bigger than JavaScripts Number.MAX_SAFE_INTEGER so you likely need to use BigInt value (which is a true 64bit number)

Can you copy the output of the Modbus node and paste it in a reply. Also, tell us the value you expect the 4 UINT16 modbus values to be once converted.

e.g.

Modbus node debug capture:

{ payload: [0,0,16,55432], xxx: {], yyy: {}, zzz:{} }

Expected value:

203685477



How to grab data from a node

There’s a great page in the docs (Working with messages : Node-RED) that will explain how to use the debug panel to find the right path/value for any data item.

Pay particular attention to the part about the buttons that appear under your mouse pointer when you over hover a debug message property in the sidebar.

BX00Cy7yHi

How to post data values

In order to make code readable and usable it is necessary to surround your code with three backticks (also known as a left quote or backquote ```)

``` 
   code goes here 
```

You can edit and correct your post by clicking the pencil :pencil2: icon.

See this post for more details - How to share code or flow json

Hey Steve, thank you for your reply! :slight_smile:

Correct, I use a Fronius Gen24+ Inverter and Fronius Ohmpilot, they use Sunspec.

This is the output. As the Ohmpilot is brand new, I expect the Wh Lifetime Energy Consumption to be very low. But I dont know the exact value.

{"data":[0,0,0,240],"buffer":[0,0,0,0,0,0,0,240]}

Given this info, i assume my effort is correct

As i hinted to earlier, this is a 64bit value so the solution is to use BigInt. However, BigInt can be tricky to work with so I included a means of converting it to a regular number - BUT if it goes beyond Number.MAX_SAFE_INTEGER (9007199254740991) then you will start to lose precision. If you beleive this will NEVER get anywhere near that value, then thats fine. If you expect to reach that kind of number, remove the "as regular number" function and use the 64bit bigInt that buffer parser outputs.

Demo flow (use ctrl-i to import)

[{"id":"d7de344b8c78bc75","type":"buffer-parser","z":"6f432348c57a2fda","name":"","data":"payload.buffer","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"bigint64be","name":"powerconsumptionWh","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":1340,"y":420,"wires":[["7123d04b8c8db4b1","fa8a66bcfa6e7650"]]},{"id":"ab925aeaf3a588fb","type":"inject","z":"6f432348c57a2fda","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":1190,"y":360,"wires":[["07302e0635406247"]]},{"id":"07302e0635406247","type":"function","z":"6f432348c57a2fda","name":"your data","func":"\nmsg.payload = {\"data\":[0,0,0,240],\"buffer\":Buffer.from([0,0,0,0,0,0,0,240])}\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1350,"y":360,"wires":[["d7de344b8c78bc75"]]},{"id":"7123d04b8c8db4b1","type":"debug","z":"6f432348c57a2fda","name":"debug 42","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":1550,"y":420,"wires":[]},{"id":"fa8a66bcfa6e7650","type":"function","z":"6f432348c57a2fda","name":"as regular number","func":"\n// NOTE: regular numbers are much easier to work with but\n// have a MAX value of (2^53 – 1) = 9007199254740991\n\nconst max = BigInt(Number.MAX_SAFE_INTEGER)\nif (msg.payload.powerconsumptionWh > max) {\n    node.warn(\"powerconsumptionWh is bigger than MAX_SAFE_INTEGER, precision may be lost\");\n}\nmsg.payload.powerconsumptionWh = Number(msg.payload.powerconsumptionWh)\n\nreturn msg\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1380,"y":500,"wires":[["ed2a804fddbccf40"]]},{"id":"ed2a804fddbccf40","type":"debug","z":"6f432348c57a2fda","name":"debug 43","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":1560,"y":500,"wires":[]}]
1 Like

You are a true legend! :man_bowing:
Thank you so much! :slight_smile: