How to do a simple sum of 2 msgs

Hello,
Im working in my final paper and I find myself in a situation I cant solve a simple sum of two mqtt messages.

Could someone help-me?

Each msg going into the function will be acted upon seperately. Take a look at the join node.

  1. You can use join node
  2. In Fuction node define two msg.payloads as flows and add the two flows data and take output as single or multiple outputs.
    i hope you gone through documentation of fuction node

Could you helpme with the code?
I`ve tried different ones, but none worked.

Show us what you tried

Hi Eder,
first of all: you don't need a function node for that. Avoid using function nodes for such a simple task. I use node-red very often and it is really really rare the situations where I need to use a function. Usually all situations are solved by using "switch", "change", "split" and "join".

In your case you can do something like this:

[{"id":"490e81a5.72c82","type":"inject","z":"2901a55a.0bd27a","name":"","topic":"","payload":"2","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":120,"wires":[["31c9f087.3438f"]]},{"id":"e8709086.2de81","type":"inject","z":"2901a55a.0bd27a","name":"","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":160,"wires":[["7b8e0037.f117a"]]},{"id":"ce878c18.15589","type":"join","z":"2901a55a.0bd27a","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":510,"y":120,"wires":[["bac9a9fd.bbd678"]]},{"id":"31c9f087.3438f","type":"change","z":"2901a55a.0bd27a","name":"","rules":[{"t":"set","p":"parts","pt":"msg","to":"1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":120,"wires":[["ce878c18.15589"]]},{"id":"7b8e0037.f117a","type":"change","z":"2901a55a.0bd27a","name":"","rules":[{"t":"set","p":"parts","pt":"msg","to":"2","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":160,"wires":[["ce878c18.15589"]]},{"id":"bac9a9fd.bbd678","type":"change","z":"2901a55a.0bd27a","name":"$sum(payload)","rules":[{"t":"set","p":"payload","pt":"msg","to":"$sum(payload)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":680,"y":120,"wires":[["5fc858e8.750c58"]]},{"id":"5fc858e8.750c58","type":"debug","z":"2901a55a.0bd27a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","x":890,"y":120,"wires":[]}]

or even something like this:

[{"id":"490e81a5.72c82","type":"inject","z":"2901a55a.0bd27a","name":"","topic":"","payload":"2","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":120,"wires":[["31c9f087.3438f"]]},{"id":"e8709086.2de81","type":"inject","z":"2901a55a.0bd27a","name":"","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":160,"wires":[["60ed0472.c5a9dc"]]},{"id":"31c9f087.3438f","type":"change","z":"2901a55a.0bd27a","name":"","rules":[{"t":"set","p":"var1","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":120,"wires":[["bac9a9fd.bbd678"]]},{"id":"bac9a9fd.bbd678","type":"change","z":"2901a55a.0bd27a","name":"sum","rules":[{"t":"set","p":"payload","pt":"msg","to":"$flowContext('var1')+$flowContext('var2')","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":530,"y":140,"wires":[["5fc858e8.750c58"]]},{"id":"5fc858e8.750c58","type":"debug","z":"2901a55a.0bd27a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","x":750,"y":140,"wires":[]},{"id":"60ed0472.c5a9dc","type":"change","z":"2901a55a.0bd27a","name":"","rules":[{"t":"set","p":"var2","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":160,"wires":[["bac9a9fd.bbd678"]]}]
1 Like

I tried the two options. None worked.
This is what a tried.
[{"id":"2a7ab69f.a264ca","type":"mqtt in","z":"53c582.5dd31a8","name":"","topic":"V1","qos":"1","broker":"89cee77f.d83e78","x":150,"y":220,"wires":[["df44497c.180d78"]]},{"id":"e3422c01.7e31d","type":"mqtt in","z":"53c582.5dd31a8","name":"","topic":"V2","qos":"1","broker":"89cee77f.d83e78","x":150,"y":300,"wires":[["5c352832.8cd458"]]},{"id":"e59efe2e.e5ad5","type":"join","z":"53c582.5dd31a8","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":490,"y":240,"wires":[["f5c0b9ab.c10208"]]},{"id":"f5c0b9ab.c10208","type":"change","z":"53c582.5dd31a8","name":"$sum(payload)","rules":[{"t":"set","p":"payload","pt":"msg","to":"$sum(payload)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":660,"y":240,"wires":[["dc3533b7.3c382"]]},{"id":"dc3533b7.3c382","type":"debug","z":"53c582.5dd31a8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":850,"y":240,"wires":[]},{"id":"c39651c9.b6f5f","type":"mqtt in","z":"53c582.5dd31a8","name":"","topic":"V2","qos":"1","broker":"89cee77f.d83e78","x":150,"y":480,"wires":[["5f832ae8.939834"]]},{"id":"4ddbf2da.38324c","type":"mqtt in","z":"53c582.5dd31a8","name":"","topic":"V1","qos":"1","broker":"89cee77f.d83e78","x":150,"y":400,"wires":[["333e8100.3ef77"]]},{"id":"333e8100.3ef77","type":"change","z":"53c582.5dd31a8","name":"","rules":[{"t":"set","p":"var1","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":420,"wires":[["50af2dc8.ca4c44"]]},{"id":"5f832ae8.939834","type":"change","z":"53c582.5dd31a8","name":"","rules":[{"t":"set","p":"var2","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":460,"wires":[["50af2dc8.ca4c44"]]},{"id":"50af2dc8.ca4c44","type":"change","z":"53c582.5dd31a8","name":"sum","rules":[{"t":"set","p":"payload","pt":"msg","to":"$flowContext('var1')+$flowContext('var2')","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":510,"y":440,"wires":[["9f4f2e16.8278d"]]},{"id":"df44497c.180d78","type":"change","z":"53c582.5dd31a8","name":"","rules":[{"t":"set","p":"parts","pt":"msg","to":"1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":240,"wires":[["e59efe2e.e5ad5"]]},{"id":"5c352832.8cd458","type":"change","z":"53c582.5dd31a8","name":"","rules":[{"t":"set","p":"parts","pt":"msg","to":"2","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":280,"wires":[["e59efe2e.e5ad5"]]},{"id":"9f4f2e16.8278d","type":"debug","z":"53c582.5dd31a8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":690,"y":440,"wires":[]},{"id":"89cee77f.d83e78","type":"mqtt-broker","z":"","name":"","broker":"m11.cloudmqtt.com","port":"10808","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

Hi Eder,
I pasted your flow on my system and both options are working fine.
Are you sure you are receiving the MQTT messages? Could you please add Debug nodes right after the MQTT nodes, configure it for "complete message", wait until the messages arrive and paste the debug result (screenshot) here?

The MQTT node is working.

It`s showing this message.
Invalid JSONata expression: The left side of the "+" operator must evaluate to a number

[{"id":"c39651c9.b6f5f","type":"mqtt in","z":"53c582.5dd31a8","name":"","topic":"V2","qos":"1","broker":"89cee77f.d83e78","x":150,"y":240,"wires":[["5f832ae8.939834"]]},{"id":"4ddbf2da.38324c","type":"mqtt in","z":"53c582.5dd31a8","name":"","topic":"V1","qos":"1","broker":"89cee77f.d83e78","x":150,"y":160,"wires":[["333e8100.3ef77"]]},{"id":"333e8100.3ef77","type":"change","z":"53c582.5dd31a8","name":"","rules":[{"t":"set","p":"V1","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":180,"wires":[["50af2dc8.ca4c44"]]},{"id":"5f832ae8.939834","type":"change","z":"53c582.5dd31a8","name":"","rules":[{"t":"set","p":"V2","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":220,"wires":[["50af2dc8.ca4c44"]]},{"id":"50af2dc8.ca4c44","type":"change","z":"53c582.5dd31a8","name":"sum","rules":[{"t":"set","p":"payload","pt":"msg","to":"$flowContext('V1') + $flowContext('V2')","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":510,"y":200,"wires":[["dc3533b7.3c382"]]},{"id":"dc3533b7.3c382","type":"debug","z":"53c582.5dd31a8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":690,"y":200,"wires":},{"id":"89cee77f.d83e78","type":"mqtt-broker","z":"","name":"","broker":"m11.cloudmqtt.com","port":"10808","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

What version of Node-RED you have installed in your system ?

I`m using the v0.19.2

I haven't followed the full discussion, but I can see from the Debug output your V1/V2 payloads are Strings not Numbers. This is why JSONata complains when you try to add them together. You can fix the Change node expression to convert the strings to numbers before adding them:

$number($flowContext('V1')) + $number($flowContext('V2'))
2 Likes

I am doing something similar perhaps simpler.

I have 2 mqtt messages each contents "1" or "0", I am trying to create a function which only passes through the "1" when both input are equal to "1", pretty much an AND GATE function.

again a function is not needed. You can simply use a "change" node for that:

Here is an example:

[{"id":"490e81a5.72c82","type":"inject","z":"2901a55a.0bd27a","name":"","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":120,"wires":[["31c9f087.3438f"]]},{"id":"e8709086.2de81","type":"inject","z":"2901a55a.0bd27a","name":"","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":160,"wires":[["60ed0472.c5a9dc"]]},{"id":"31c9f087.3438f","type":"change","z":"2901a55a.0bd27a","name":"","rules":[{"t":"set","p":"var1","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":120,"wires":[["bac9a9fd.bbd678"]]},{"id":"bac9a9fd.bbd678","type":"change","z":"2901a55a.0bd27a","name":"sum","rules":[{"t":"set","p":"payload","pt":"msg","to":"$flowContext('var1') and $flowContext('var2')","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":530,"y":140,"wires":[["5fc858e8.750c58"]]},{"id":"5fc858e8.750c58","type":"debug","z":"2901a55a.0bd27a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","x":750,"y":140,"wires":[]},{"id":"60ed0472.c5a9dc","type":"change","z":"2901a55a.0bd27a","name":"","rules":[{"t":"set","p":"var2","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":160,"wires":[["bac9a9fd.bbd678"]]}]

Thank yo so much! This is a "Hello world" to JSONata for me.

Thank you. It works well for me

Hey! can you explain it clearly like why exactly did you use change and join.

The very first important thing here is to understand that node-red is based on events.
If you want to sum 2 events you have 2 options:

  1. Join those 2 events with a Join node: try to play a bit with the join node and you will understand how it works
  2. Store the values on a Flow variable and sum them every time a new event is triggered

Regarding why I used the "change" node before the join node, it is simply because the Join node requires the msg.parts attribute as stated in the manual of the node:

1 Like

Actually, I was testing this flow and there's a bug on it. If you click twice on the first button it will sum only the values of the first button. I'm afraid it is not possible to implement it with a Join node (sorry community :cold_face: for the wrong answer).
I strongly recommend the second alternative (save variables to the flow context and then sum later)

1 Like