MQTT Connections - Three paylods

Hey guys, I want to do the following task in Node Red.
I have 3 different mqtt topics namely Owl/Away/HotWater, Owl/Away/HeatingUpstairs and Owl/Away/HeatingDownstairs. If all three topics have payload "off" then a payload "On" need to be sent a payload to topic /Owl/Away. Otherwise, a payload "Off" need to be sent to topic /Owl/Away.

I have created the 3 mqtt but I do not know how to do the logic with the 3 topics.
Anyone can help?

You need to use a Join node to combine the three messages into one, then you can use a function node to send On or Off depending on the values.

I like to use JSONata in the change node in combination with a filter node to limit repeated messages to do this sort of thing.
e.g.

[{"id":"8b48b1d7ea63411d","type":"inject","z":"da8a6ef0b3c9a5c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"Owl/Away/HotWateR","payload":"on","payloadType":"str","x":130,"y":4600,"wires":[["f41e062cab9769c2"]]},{"id":"f41e062cab9769c2","type":"join","z":"da8a6ef0b3c9a5c8","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"3","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":410,"y":4680,"wires":[["cf0b16afe5f152c9"]]},{"id":"bbdd42f7060df635","type":"inject","z":"da8a6ef0b3c9a5c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"Owl/Away/HotWateR","payload":"off","payloadType":"str","x":130,"y":4640,"wires":[["f41e062cab9769c2"]]},{"id":"d4e2ea6db1225b06","type":"inject","z":"da8a6ef0b3c9a5c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"Owl/Away/HeatingUpstairs","payload":"on","payloadType":"str","x":160,"y":4680,"wires":[["f41e062cab9769c2"]]},{"id":"3d511336015abe66","type":"inject","z":"da8a6ef0b3c9a5c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"Owl/Away/HeatingUpstairs","payload":"off","payloadType":"str","x":160,"y":4720,"wires":[["f41e062cab9769c2"]]},{"id":"72d7a9c505afb22a","type":"inject","z":"da8a6ef0b3c9a5c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"Owl/Away/HeatingDownstairs","payload":"on","payloadType":"str","x":150,"y":4760,"wires":[["f41e062cab9769c2"]]},{"id":"5ceea35d519d6136","type":"inject","z":"da8a6ef0b3c9a5c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"Owl/Away/HeatingDownstairs","payload":"off","payloadType":"str","x":150,"y":4800,"wires":[["f41e062cab9769c2"]]},{"id":"cf0b16afe5f152c9","type":"change","z":"da8a6ef0b3c9a5c8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"\"on\" in $$.payload.* ? \"off\" : \"on\"","tot":"jsonata"},{"t":"set","p":"topic","pt":"msg","to":"Owl/Away","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":4680,"wires":[["7841e6ea5ad985fd"]]},{"id":"7841e6ea5ad985fd","type":"rbe","z":"da8a6ef0b3c9a5c8","name":"","func":"rbe","gap":"","start":"","inout":"out","septopics":true,"property":"payload","topi":"topic","x":710,"y":4680,"wires":[["9b498d9f9b9b0b73"]]},{"id":"9b498d9f9b9b0b73","type":"debug","z":"da8a6ef0b3c9a5c8","name":"debug 231","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":510,"y":4540,"wires":[]}]

JSONata expression after join

"on" in $$.payload.* ? "off" : "on"
1 Like

It seems that it work after the change "on" in $$.payload.* ? "on" : "off"
Before it was working the other way round.

Thanks for your help

You asked for

That's what i showed in the example.

But you really wanted 3 off's to send payload "off"

You are right @E1cid .
My bad.

Hello @E1cid
Just another quick question.
I am trying to understand when the off will be send as per the last part of this process.
Does it keeps count only the last 3 packets that should be on in order to send the on?

How does this work?
What if 10 packets are coming in a short time?
How is this handled?

The join node creates an object

{
  "Owl/Away/HotWateR":"on", 
  "Owl/Away/HeatingUpstairs":"off",
  "Owl/Away/HeatingDownstairs":"on"
}

when ever a new message arrives this object is updated with on or off according to topic.
Each time the change node converts the object to an array with $$.payload.*
e.g. ["on","off","on"]
Then it checks to see if there are any on's in the array. If there are it outputs on, if not it outputs off.
The filter node only allows the msg to pass if the payload is different from last payload.

If 10 msg in quick succession arrive in quick succession it will only output if the change node output changes.

last output on - [on, off,on]
[on,on,on] - no output as output in still on
[on,on,off] no output as output is still on
[on,off,off] no output as output is still on
[off,off,off] output off as the output has changed
etc.

Thanks for the explanation.

How can I convert this in order to send an on only and onlly if in the array all the 3 are on?

What about off's. Please be specific as your question leaves a little ambiguity.

"off" in $$.payload.* ? "off" : "on"

This will send on if 3 on's, anything else will send off.

Thanks @E1cid

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.