Calculations in Node-RED using data from system elements

Hello
I have a Cerbo GX with Multiplus II and battery system with separate (old) wind turbine which charges the batteries in parallel to the Multi. I have a Smart-Shunt on the battery negative leg.

I am implementing a Node-RED control so that I can integrate house loads and provide a user-friendly dashboard for the home. I have enabled Node-RED on the Cerbo, and can read from the Multi and from the SmartShunt. All good so far.

Now I am trying to use the data from the readings to calculate and display other readings. For example Turbine current = battery current - inverter DC current. And, Turbine Power = Turbine Current x Battery voltage, etc. I have tried all sorts of ways to do this in Node-RED and am stuck.

I am used to LabView and other environments with a cycle time, shift registers, etc, but don’t see how to use similar in Node-RED

Can anyone help?

Images of my VRM homepage and a trial flow below!

As far as I know, in Smart Shunt settings, you can specify what it measures, and you can set it to “Wind Turbine”. Then it will naturally show it on the board as DC connected device

Hello,

So you need to do the calculation on the payload message (msg.payload) of the terms.

You will need to look a bit in the NodeRed world… Node-RED

I try to do the same on my installation and come back ASAP with some tips…

Xavier

Thanks Xavier
I have made some progress, feeding the Victron data into an array node and then sending the output to the calculation.
However, despite the array node being set to only output when it receives 2 messages, the payload seems to be mixed up so the array is sometimes [dataA,dataB] and sometimes [dataB,dataA].

So if dataA = 20 and dataB = 15 then the result of array.1 - array.2 pings back an forth between +5 and -5.

I need some way to synchronise the data and ensure it comes through in the correct order so we don’t get this reversal happening. I have tried putting a delay on the data messages, so each only get sent every 0.25s, that way you will get the same number of dataA and dataB, but that hasnt fixed the problem.

I can’t see a way of addressing the data from the SmartShunt - e.g. SmartShunt.output.Volts, or similar.

Another way would be to read data into a global variable, but that (although simple) is beyond my Node-Red knowledge

let me know if you solve it!

Yes, preventing this data mix up there is viarious way, one I use, is to create storage variable and then I read it in the correct order to compose a message …

I store the value with the flow.Variable option, then with the “compose” I can select the order of the messages… then I can process some calculation on it if needed…

Pictures : This is not linked to your case but just to draw the method…

(Yes, one of the batteries is not working OK 10.4V!! )

Xavier

Hello! Something you could do is assign topics to the messages from the Victron Nodes (With a Change node) and then Join the messages every X amount of messages. With this, you could access each data in the payload as msg.payload.topic_assigned.
I haven’t worked with the subtraction node you are using, but a simple function node could do the Job.
The following is an example that you could import in your node-red that would do the job:

[
    {
        "id": "37efb3dd9870c14b",
        "type": "inject",
        "z": "46b03a7a60f3866e",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "5",
        "payloadType": "num",
        "x": 150,
        "y": 1080,
        "wires": [
            [
                "644dc20ef6fb3743"
            ]
        ]
    },
    {
        "id": "741560b1a87b7a9c",
        "type": "inject",
        "z": "46b03a7a60f3866e",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "2",
        "payloadType": "num",
        "x": 150,
        "y": 1140,
        "wires": [
            [
                "a80a889355505c66"
            ]
        ]
    },
    {
        "id": "405cddeffd3deca1",
        "type": "join",
        "z": "46b03a7a60f3866e",
        "name": "Array",
        "mode": "custom",
        "build": "object",
        "property": "payload",
        "propertyType": "msg",
        "key": "topic",
        "joiner": "\\n",
        "joinerType": "str",
        "accumulate": true,
        "timeout": "",
        "count": "2",
        "reduceRight": false,
        "reduceExp": "",
        "reduceInit": "",
        "reduceInitType": "",
        "reduceFixup": "",
        "x": 580,
        "y": 1080,
        "wires": [
            [
                "1ecf9fe8d20fb00b",
                "a975abe4aa5d7687"
            ]
        ]
    },
    {
        "id": "644dc20ef6fb3743",
        "type": "change",
        "z": "46b03a7a60f3866e",
        "name": "Set Topic Data_A",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "Data_A",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 350,
        "y": 1080,
        "wires": [
            [
                "405cddeffd3deca1"
            ]
        ]
    },
    {
        "id": "a80a889355505c66",
        "type": "change",
        "z": "46b03a7a60f3866e",
        "name": "Set Topic Data_B",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "Data_B",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 350,
        "y": 1140,
        "wires": [
            [
                "405cddeffd3deca1"
            ]
        ]
    },
    {
        "id": "1ecf9fe8d20fb00b",
        "type": "debug",
        "z": "46b03a7a60f3866e",
        "name": "Debug",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 750,
        "y": 1080,
        "wires": []
    },
    {
        "id": "a975abe4aa5d7687",
        "type": "function",
        "z": "46b03a7a60f3866e",
        "name": "Subtraction",
        "func": "msg.payload = msg.payload.Data_A - msg.payload.Data_B;\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 590,
        "y": 1140,
        "wires": [
            [
                "3df7c0735c99d504"
            ]
        ]
    },
    {
        "id": "3df7c0735c99d504",
        "type": "debug",
        "z": "46b03a7a60f3866e",
        "name": "Debug 2",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 760,
        "y": 1140,
        "wires": []
    }
]
1 Like