Sum of 3 different values

I am trying to process the data of a Shelly 3EM. Es liefert je (!) Phase u.a. die aktuelle Leistung und die akkumulierte genutzte Energie. Natürlich möchte ich die Summe der Leistung über die drei Phase sowie die Summe der Energie (in Grafana) anzeigen lassen.
Gemäß folgender Seite (Node-RED: Lecture 6 – Example 6.7 Multiple inputs on a function node – Node RED Programming Guide) habe ich die Lösung so umgesetzt:

Code der function "task 1 set", um die Inputs nachher ind "function sum" unterscheiden zu können (analog der anderen beiden functions mit "task2" und "task3"):

msg.topic = "task1"
return msg;

Content of "function sum":

context.data = context.data || {};
switch (msg.topic) {
    case "task1":
        context.data.task1 = msg.payload;
        msg = null;
        break;
    case "task2":
        context.data.task2 = msg.payload;
        msg = null;
        break;
    case "task3":
        context.data.task3 = msg.payload;
        msg = null;
        break;
    default:
        msg = null;
        break;
}
if (context.data.task1 != null && context.data.task2 != null && context.data.task3 != null) {
    var sum = context.data.task1 + context.data.task2 + context.data.task3;
    context.data = null;
    return {payload:sum};
} else return msg;

My concerns:
a) Are there any errors in this solution? Is there a more elegant/shorter solution? Can I copy the function blocks 1:1, um to sum the energy of the phases? If context.data is a global variable, changing it could affect other blocks (e.g. with context.data = null;)?!

b) What's happening in the first row: context.data = context.data || {};?

Basically you have implemented a DIY version of the Join node, but you have likely forgotten some edge conditions that the Join node has ironed out over several years. You are using an obsolete method of accessing the context, you should be using context.get() and context.set().

That is the way I used to do it before the Join node existed, but now I recommend using that. See this article in the cookbook for an example.

The || is the or operator, so if the context data is undefined/null (equivalent to false) then set it to an empty object to initialise an object, so it sets {} as default value if context has not been defined yet, i.e. the first run or as in your code the context is set to null once summed.

1 Like

It isn't, it is local to the function node where you use it.
See the Storing Data section in Writing Functions : Node-RED.

1 Like

I do not really understand what benefit the join node would be. I implemented it this way. Thougts?

[
    {
        "id": "d944ef57a0872351",
        "type": "mqtt in",
        "z": "f6f2187d.f17ca8",
        "name": "Phase 0 Power",
        "topic": "shellies/shellyem3-stromkasten/emeter/0/power",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "b912bc20557e4732",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 140,
        "y": 200,
        "wires": [
            [
                "cee8fccc002717de",
                "e992565aeaea2259",
                "7c18da7111c71e67"
            ]
        ]
    },
    {
        "id": "cee8fccc002717de",
        "type": "influxdb out",
        "z": "f6f2187d.f17ca8",
        "influxdb": "af175a885afb64ae",
        "name": "Shelly 3EM",
        "measurement": "phase_0_power",
        "precision": "",
        "retentionPolicy": "",
        "database": "database",
        "precisionV18FluxV20": "ms",
        "retentionPolicyV18Flux": "",
        "org": "organisation",
        "bucket": "bucket",
        "x": 430,
        "y": 200,
        "wires": []
    },
    {
        "id": "9f6d7fa801a4188b",
        "type": "mqtt in",
        "z": "f6f2187d.f17ca8",
        "name": "Phase 1 Power",
        "topic": "shellies/shellyem3-stromkasten/emeter/1/power",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "b912bc20557e4732",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 140,
        "y": 260,
        "wires": [
            [
                "1e07e7c67607a344",
                "ea77bebac7c73a69",
                "f2eeca205243ceba"
            ]
        ]
    },
    {
        "id": "0d2678269a90a66c",
        "type": "mqtt in",
        "z": "f6f2187d.f17ca8",
        "name": "Phase 2 Power",
        "topic": "shellies/shellyem3-stromkasten/emeter/1/power",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "b912bc20557e4732",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 140,
        "y": 320,
        "wires": [
            [
                "44abd4c0cec067cf",
                "e1907a900a33b0ea",
                "7f63e59035fb3b24"
            ]
        ]
    },
    {
        "id": "1e07e7c67607a344",
        "type": "influxdb out",
        "z": "f6f2187d.f17ca8",
        "influxdb": "af175a885afb64ae",
        "name": "Shelly 3EM",
        "measurement": "phase_1_power",
        "precision": "",
        "retentionPolicy": "",
        "database": "database",
        "precisionV18FluxV20": "ms",
        "retentionPolicyV18Flux": "",
        "org": "organisation",
        "bucket": "bucket",
        "x": 430,
        "y": 260,
        "wires": []
    },
    {
        "id": "44abd4c0cec067cf",
        "type": "influxdb out",
        "z": "f6f2187d.f17ca8",
        "influxdb": "af175a885afb64ae",
        "name": "Shelly 3EM",
        "measurement": "phase_2_power",
        "precision": "",
        "retentionPolicy": "",
        "database": "database",
        "precisionV18FluxV20": "ms",
        "retentionPolicyV18Flux": "",
        "org": "organisation",
        "bucket": "bucket",
        "x": 430,
        "y": 320,
        "wires": []
    },
    {
        "id": "e992565aeaea2259",
        "type": "debug",
        "z": "f6f2187d.f17ca8",
        "name": "debug 0",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 600,
        "y": 160,
        "wires": []
    },
    {
        "id": "ea77bebac7c73a69",
        "type": "debug",
        "z": "f6f2187d.f17ca8",
        "name": "debug 1",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 600,
        "y": 220,
        "wires": []
    },
    {
        "id": "e1907a900a33b0ea",
        "type": "debug",
        "z": "f6f2187d.f17ca8",
        "name": "debug 2",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 600,
        "y": 280,
        "wires": []
    },
    {
        "id": "7c18da7111c71e67",
        "type": "change",
        "z": "f6f2187d.f17ca8",
        "name": "Set var1",
        "rules": [
            {
                "t": "set",
                "p": "var1",
                "pt": "flow",
                "to": "payload",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 440,
        "y": 380,
        "wires": [
            [
                "72f0482b4da4796b"
            ]
        ]
    },
    {
        "id": "72f0482b4da4796b",
        "type": "change",
        "z": "f6f2187d.f17ca8",
        "name": "sum",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "$flowContext('var1')+$flowContext('var2')+$flowContext('var3')",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 680,
        "y": 400,
        "wires": [
            [
                "6fae76b5a0fe8078"
            ]
        ]
    },
    {
        "id": "6fae76b5a0fe8078",
        "type": "debug",
        "z": "f6f2187d.f17ca8",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 900,
        "y": 400,
        "wires": []
    },
    {
        "id": "f2eeca205243ceba",
        "type": "change",
        "z": "f6f2187d.f17ca8",
        "name": "Set var2",
        "rules": [
            {
                "t": "set",
                "p": "var2",
                "pt": "flow",
                "to": "payload",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 440,
        "y": 420,
        "wires": [
            [
                "72f0482b4da4796b"
            ]
        ]
    },
    {
        "id": "7f63e59035fb3b24",
        "type": "change",
        "z": "f6f2187d.f17ca8",
        "name": "Set var3",
        "rules": [
            {
                "t": "set",
                "p": "var3",
                "pt": "flow",
                "to": "payload",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 440,
        "y": 460,
        "wires": [
            [
                "72f0482b4da4796b"
            ]
        ]
    },
    {
        "id": "b912bc20557e4732",
        "type": "mqtt-broker",
        "name": "Rapserry Pi Daten 1",
        "broker": "192.168.0.76",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    },
    {
        "id": "af175a885afb64ae",
        "type": "influxdb",
        "hostname": "192.168.0.76",
        "port": "8086",
        "protocol": "http",
        "database": "shellyDB",
        "name": "Shellys",
        "usetls": false,
        "tls": "",
        "influxdbVersion": "1.x",
        "url": "http://localhost:8086",
        "rejectUnauthorized": true
    }
]

For each mqtt msg that comes in you will get the sum of it and the prior two mqtt readings depending on how fast the msgs arrive.

For example lets say a msg arrives from Phase 0 Power, it will set flow.var1 then try to add it to the prior flow.var2 and flow.var3. Until all three flow variables are initilized, you won't get any output (possible bug?? I'll look into this - I'd think it would throw an error)

let's say that all three flow variables are initilized to 0 and msgs start arriving

  • msg1 arrives from Phase 0 Power, value 20 - the sum will be 20 v1=20 v2=0 v3=0
  • msg1 arrives from Phase 1 Power, value 35 - the sum will be 55 v1=20 v2=35 v3=0
  • msg2 arrives from Phase 0 Power, value 5 - the sum will be 40 v1=5 v2=35 v3=0
  • msg1 arrives from Phase 2 Power, value 40 - the sum will be 80 v1=5 v2=35 v3=40
  • msg3 arrives from Phase 0 Power, value 25 - the sum will be 100 v1=25 v2=35 v3=40
  • msg2 arrives from Phase 2 Power, value 20 - the sum will be 80 v1=25 v2=35 v3=20

If you were using a join, you could set it up so it would not pass on the data untill a msg from each mqtt-in node arrived.

Hope this doesn't confuse you.

As you can see

Understood. So I tried the following code with a join node. Which I think is worse:

[
    {
        "id": "490e81a5.72c82",
        "type": "inject",
        "z": "4af6c4897077c6ac",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "7",
        "payloadType": "num",
        "x": 350,
        "y": 180,
        "wires": [
            [
                "ce878c18.15589"
            ]
        ]
    },
    {
        "id": "e8709086.2de81",
        "type": "inject",
        "z": "4af6c4897077c6ac",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "5",
        "payloadType": "num",
        "x": 350,
        "y": 220,
        "wires": [
            [
                "ce878c18.15589"
            ]
        ]
    },
    {
        "id": "ce878c18.15589",
        "type": "join",
        "z": "4af6c4897077c6ac",
        "name": "",
        "mode": "custom",
        "build": "array",
        "property": "payload",
        "propertyType": "msg",
        "key": "topic",
        "joiner": "\\n",
        "joinerType": "str",
        "accumulate": false,
        "timeout": "",
        "count": "2",
        "reduceRight": false,
        "reduceExp": "",
        "reduceInit": "",
        "reduceInitType": "num",
        "reduceFixup": "",
        "x": 570,
        "y": 180,
        "wires": [
            [
                "bac9a9fd.bbd678"
            ]
        ]
    },
    {
        "id": "bac9a9fd.bbd678",
        "type": "change",
        "z": "4af6c4897077c6ac",
        "name": "$sum(payload)",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "$sum(payload)",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 740,
        "y": 180,
        "wires": [
            [
                "5fc858e8.750c58"
            ]
        ]
    },
    {
        "id": "5fc858e8.750c58",
        "type": "debug",
        "z": "4af6c4897077c6ac",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "x": 950,
        "y": 180,
        "wires": []
    }
]

The flaws:

  • Join is waiting for two messages before it triggers the output, but it doesn't matter whether it came from each or just twice from one
  • In the following node (change) I cannot distinguish between the inital messages. Thus I can not handle them seperately. Maybe one day I would like to deduct one from the other and not just add them up

You need to join as key value object.
e.g.

[{"id":"490e81a5.72c82","type":"inject","z":"30af2d3e.d94ea2","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"one","payload":"7","payloadType":"num","x":250,"y":2320,"wires":[["ce878c18.15589"]]},{"id":"ce878c18.15589","type":"join","z":"30af2d3e.d94ea2","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":470,"y":2320,"wires":[["bac9a9fd.bbd678"]]},{"id":"e8709086.2de81","type":"inject","z":"30af2d3e.d94ea2","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"two","payload":"5","payloadType":"num","x":250,"y":2360,"wires":[["ce878c18.15589"]]},{"id":"bac9a9fd.bbd678","type":"change","z":"30af2d3e.d94ea2","name":"$sum(payload)","rules":[{"t":"set","p":"payload","pt":"msg","to":"$sum(payload.*)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":640,"y":2320,"wires":[["5fc858e8.750c58"]]},{"id":"5fc858e8.750c58","type":"debug","z":"30af2d3e.d94ea2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","x":850,"y":2320,"wires":[]}]

Your mqtt nodes all ready have unique topics set, so all you need is a join and a change node.

1 Like

That works fine. But what could I do to substract the payload value of msg.topic=one from payload of msg.topic=two?

What does the output of the join look like in a debug node?

msg.payload:

object

two: 5

one: 7

The full message is (topic ist either "one or "two" depending which one was last:

object

_msgid: "f18c9d63cb8c732f"

payload: object

one: 7

two: 5

topic: "two"

const difference = msg.payload.one - msg.payload.two

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 to 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

1 Like

Works great.

I do not yet fully understand the node-red programming style. In the inject node I assign what I think is an element of an object (msg.topic) a value (one). And in the change node it (one) suddenly is an element of the object (msg.payload.one) and contains the payload value (7). Confusing!

Are you talking about the way the Join node uses the topics from the messages as the keys in msg.payload? That is what is meant by key/value using topic as the key, in the Join node settings.

[Edit] So you start with two messages with separate topics and values, and the Join node gives you one message with them both in msg.payload.

Just wanted to say that I need to look deeper into the node-RED principles to understand.

There is only one open point. I am using that function to sum up the Phase x Power from the inital post. These nodes do not have a field to add "msg.topic" as the inject nodes. How do I add that data? Have not found an other note who can do it.

Don't they already have a topic set? They come from MQTT so I would expect the topic to be the MQTT topic. Feed it into a debug node showing complete message to check. If you do need to set a topic you can use a Change node to Set msg.topic to (string) some_topic.
Note that if the keys in msg.payload after the join node have an mqtt topic like a/b/c then you can't use msg.payload.a/b/c in a function as the slashes would be interpreted as divide symbols. You have to use the alternative syntax msg.payload["a/b/c"]. The Copy Path button from the debug window will give it you correctly.

Setting a new topic with the change node with which I can use the "dot-notation" works fine. If I use the MQTT topic, which has slashes in it, I get the error message "Invalid JSONata expression: "The left side of the "+" operator must evaluate to a number". As recommended I am using the "bracket-notation" for this e.g. msg.payload["shellies/shellyem3-stromkasten/emeter/0/power"]


[
    {
        "id": "d944ef57a0872351",
        "type": "mqtt in",
        "z": "f6f2187d.f17ca8",
        "name": "Phase 0 Power",
        "topic": "shellies/shellyem3-stromkasten/emeter/0/power",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "b912bc20557e4732",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 140,
        "y": 220,
        "wires": [
            [
                "cee8fccc002717de",
                "e992565aeaea2259",
                "7c18da7111c71e67",
                "5aabf5a421290caa"
            ]
        ]
    },
    {
        "id": "cee8fccc002717de",
        "type": "influxdb out",
        "z": "f6f2187d.f17ca8",
        "influxdb": "af175a885afb64ae",
        "name": "Shelly 3EM",
        "measurement": "phase_0_power",
        "precision": "",
        "retentionPolicy": "",
        "database": "database",
        "precisionV18FluxV20": "ms",
        "retentionPolicyV18Flux": "",
        "org": "organisation",
        "bucket": "bucket",
        "x": 430,
        "y": 220,
        "wires": []
    },
    {
        "id": "9f6d7fa801a4188b",
        "type": "mqtt in",
        "z": "f6f2187d.f17ca8",
        "name": "Phase 1 Power",
        "topic": "shellies/shellyem3-stromkasten/emeter/1/power",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "b912bc20557e4732",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 140,
        "y": 280,
        "wires": [
            [
                "1e07e7c67607a344",
                "ea77bebac7c73a69",
                "f2eeca205243ceba",
                "5aabf5a421290caa"
            ]
        ]
    },
    {
        "id": "0d2678269a90a66c",
        "type": "mqtt in",
        "z": "f6f2187d.f17ca8",
        "name": "Phase 2 Power",
        "topic": "shellies/shellyem3-stromkasten/emeter/2/power",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "b912bc20557e4732",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 140,
        "y": 340,
        "wires": [
            [
                "44abd4c0cec067cf",
                "e1907a900a33b0ea",
                "7f63e59035fb3b24",
                "5aabf5a421290caa"
            ]
        ]
    },
    {
        "id": "1e07e7c67607a344",
        "type": "influxdb out",
        "z": "f6f2187d.f17ca8",
        "influxdb": "af175a885afb64ae",
        "name": "Shelly 3EM",
        "measurement": "phase_1_power",
        "precision": "",
        "retentionPolicy": "",
        "database": "database",
        "precisionV18FluxV20": "ms",
        "retentionPolicyV18Flux": "",
        "org": "organisation",
        "bucket": "bucket",
        "x": 430,
        "y": 280,
        "wires": []
    },
    {
        "id": "44abd4c0cec067cf",
        "type": "influxdb out",
        "z": "f6f2187d.f17ca8",
        "influxdb": "af175a885afb64ae",
        "name": "Shelly 3EM",
        "measurement": "phase_2_power",
        "precision": "",
        "retentionPolicy": "",
        "database": "database",
        "precisionV18FluxV20": "ms",
        "retentionPolicyV18Flux": "",
        "org": "organisation",
        "bucket": "bucket",
        "x": 430,
        "y": 340,
        "wires": []
    },
    {
        "id": "e992565aeaea2259",
        "type": "debug",
        "z": "f6f2187d.f17ca8",
        "name": "debug 0",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 600,
        "y": 180,
        "wires": []
    },
    {
        "id": "ea77bebac7c73a69",
        "type": "debug",
        "z": "f6f2187d.f17ca8",
        "name": "debug 1",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 600,
        "y": 240,
        "wires": []
    },
    {
        "id": "e1907a900a33b0ea",
        "type": "debug",
        "z": "f6f2187d.f17ca8",
        "name": "debug 2",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 600,
        "y": 300,
        "wires": []
    },
    {
        "id": "7c18da7111c71e67",
        "type": "change",
        "z": "f6f2187d.f17ca8",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "phase0",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 300,
        "y": 400,
        "wires": [
            [
                "4a6ce9b621c9c3de"
            ]
        ]
    },
    {
        "id": "f2eeca205243ceba",
        "type": "change",
        "z": "f6f2187d.f17ca8",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "phase1",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 300,
        "y": 440,
        "wires": [
            [
                "4a6ce9b621c9c3de"
            ]
        ]
    },
    {
        "id": "7f63e59035fb3b24",
        "type": "change",
        "z": "f6f2187d.f17ca8",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "phase2",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 300,
        "y": 480,
        "wires": [
            [
                "4a6ce9b621c9c3de"
            ]
        ]
    },
    {
        "id": "4a6ce9b621c9c3de",
        "type": "join",
        "z": "f6f2187d.f17ca8",
        "name": "",
        "mode": "custom",
        "build": "object",
        "property": "payload",
        "propertyType": "msg",
        "key": "topic",
        "joiner": "\\n",
        "joinerType": "str",
        "accumulate": false,
        "timeout": "",
        "count": "3",
        "reduceRight": false,
        "reduceExp": "",
        "reduceInit": "",
        "reduceInitType": "",
        "reduceFixup": "",
        "x": 690,
        "y": 480,
        "wires": [
            [
                "e994ccd034181f58",
                "017207fe9a6b42dc"
            ]
        ]
    },
    {
        "id": "142c1c268cf1fb31",
        "type": "debug",
        "z": "f6f2187d.f17ca8",
        "name": "debug 10",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1100,
        "y": 480,
        "wires": []
    },
    {
        "id": "e994ccd034181f58",
        "type": "change",
        "z": "f6f2187d.f17ca8",
        "name": "$sum(payload)",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "msg.payload.phase0 + msg.payload.phase1 + msg.payload.phase2",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 900,
        "y": 480,
        "wires": [
            [
                "142c1c268cf1fb31"
            ]
        ]
    },
    {
        "id": "017207fe9a6b42dc",
        "type": "debug",
        "z": "f6f2187d.f17ca8",
        "name": "debug 12",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 860,
        "y": 540,
        "wires": []
    },
    {
        "id": "5aabf5a421290caa",
        "type": "join",
        "z": "f6f2187d.f17ca8",
        "name": "",
        "mode": "custom",
        "build": "object",
        "property": "payload",
        "propertyType": "msg",
        "key": "topic",
        "joiner": "\\n",
        "joinerType": "str",
        "accumulate": false,
        "timeout": "",
        "count": "3",
        "reduceRight": false,
        "reduceExp": "",
        "reduceInit": "",
        "reduceInitType": "",
        "reduceFixup": "",
        "x": 690,
        "y": 360,
        "wires": [
            [
                "c41fb1d26fe92321",
                "0af975e5a9f5297c"
            ]
        ]
    },
    {
        "id": "8423a2b8eeade224",
        "type": "debug",
        "z": "f6f2187d.f17ca8",
        "name": "debug 13",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1100,
        "y": 360,
        "wires": []
    },
    {
        "id": "c41fb1d26fe92321",
        "type": "change",
        "z": "f6f2187d.f17ca8",
        "name": "$sum(payload)",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "msg.payload[\"shellies/shellyem3-stromkasten/emeter/0/power\"] + msg.payload[\"shellies/shellyem3-stromkasten/emeter/1/power\"] + msg.payload[\"shellies/shellyem3-stromkasten/emeter/2/power\"]",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 900,
        "y": 360,
        "wires": [
            [
                "8423a2b8eeade224"
            ]
        ]
    },
    {
        "id": "0af975e5a9f5297c",
        "type": "debug",
        "z": "f6f2187d.f17ca8",
        "name": "debug 14",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 860,
        "y": 420,
        "wires": []
    },
    {
        "id": "b912bc20557e4732",
        "type": "mqtt-broker",
        "name": "Rapserry Pi Daten 1",
        "broker": "192.168.0.76",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    },
    {
        "id": "af175a885afb64ae",
        "type": "influxdb",
        "hostname": "192.168.0.76",
        "port": "8086",
        "protocol": "http",
        "database": "shellyDB",
        "name": "Shellys",
        "usetls": false,
        "tls": "",
        "influxdbVersion": "1.x",
        "url": "http://localhost:8086",
        "rejectUnauthorized": true
    }
]

The JSONata expression would be
$$.payload.'shellies/shellyem3-stromkasten/emeter/0/power'
or better still
$sum($$.payload.*)

Personally I avoid jsonata except for very simple cases, as I find javascript easier to understand. I don't use any code (jsonata or javascript) that I don't understand as I may need to come back and modify something in a years time, and if I don't understand how it works then it could be difficult to do that.

I am wondering whether you have configured the Join in the optimum way, particularly to cope with fault conditions.
Do the three power values come in at the same time? If so do they come in at a fixed interval or what? If fixed then how often?

It looks like they are coming at the same time with an interval of circa 5 seconds

Can you switch between JSON and JavaScript Notation?