Three way light switch emulation

Is there an easier way to accomplish this? I am trying to create a pseudo three way light switch with two Tasmota switches. LobbyA has the load and LobbyB only sends on/off to LobbyA and back to Dashboard node.

This is similar to SmartHome Insteon "Linking." I am hoping for a better way so that 4,5,n-way switching can be implemented.

[{"id":"26f841ca.725036","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"6478eae2.ad6d94","type":"ui_switch","z":"26f841ca.725036","name":"Lobby Chandelier","label":"Lobby Chandelier","tooltip":"","group":"4bbcf441.3900e4","order":4,"width":"4","height":"1","passthru":false,"decouple":"false","topic":"House/LightLobbyA/cmnd/POWER","style":"","onvalue":"ON","onvalueType":"str","onicon":"","oncolor":"","offvalue":"OFF","offvalueType":"str","officon":"","offcolor":"","x":790,"y":600,"wires":[["a0834568.7e447"]],"inputLabels":["House/LightLobbyA/stat/POWER"]},{"id":"7ff3a66a.bd9c08","type":"mqtt in","z":"26f841ca.725036","name":"","topic":"House/LightLobbyA/stat/POWER","qos":"2","broker":"12dd1610.da9e4a","x":150,"y":600,"wires":[["78851a6c.3ba7fc","6478eae2.ad6d94","bb484857.94bc"]]},{"id":"93a76ea4.106b1","type":"debug","z":"26f841ca.725036","name":"Debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":990,"y":760,"wires":[],"inputLabels":["House/#"]},{"id":"52e0bc3b.617904","type":"mqtt in","z":"26f841ca.725036","name":"","topic":"House/LightLobbyB/stat/POWER","qos":"2","broker":"12dd1610.da9e4a","x":150,"y":700,"wires":[["d32d9cf3.23946"]]},{"id":"de649eb2.e3574","type":"ui_text","z":"26f841ca.725036","group":"4bbcf441.3900e4","order":6,"width":"2","height":"1","name":"","label":"","format":"<font color={{msg.color}} ><i class=\"fa fa-circle\" style=\"font-size:24px;\"></i></font>","layout":"row-spread","x":830,"y":640,"wires":[]},{"id":"78851a6c.3ba7fc","type":"function","z":"26f841ca.725036","name":"ColorSet","func":"msg.color = (msg.payload === \"ON\")?\"green\":\"grey\";\nreturn msg;","outputs":1,"noerr":0,"x":620,"y":640,"wires":[["de649eb2.e3574"]]},{"id":"d32d9cf3.23946","type":"function","z":"26f841ca.725036","name":"3wayBtoA","func":"var newMsg = { topic: \"House/LightLobbyA/cmnd/POWER\"}; \n\nvar LobbyA=flow.get('LobbyA') || 0;\n\n//if (msg.topic===\"House/LightLobbyA/stat/POWER\") {\n    if (LobbyA===0) {\n        if (msg.payload === \"ON\") {\n            newMsg.payload = \"ON\";\n            LobbyA=1\n            flow.set('LobbyA',LobbyA);\n            return newMsg;  \n        }\n    }\n    else {\n        if (msg.payload === \"OFF\") {\n            newMsg.payload = \"OFF\";\n            LobbyA=0;\n            flow.set('LobbyA',LobbyA);\n            return newMsg; \n        }\n    }\n//}","outputs":1,"noerr":0,"x":500,"y":700,"wires":[["93a76ea4.106b1","acbfa624.3650d8"]],"inputLabels":["House/LightLobbyB/stat/POWER"]},{"id":"acbfa624.3650d8","type":"mqtt out","z":"26f841ca.725036","name":"","topic":"","qos":"","retain":"","broker":"12dd1610.da9e4a","x":990,"y":700,"wires":[]},{"id":"3cc1c6be.263a22","type":"inject","z":"26f841ca.725036","name":"","topic":"","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":290,"y":760,"wires":[["d32d9cf3.23946"]],"outputLabels":["House/LightLobbyB/stat/POWER"]},{"id":"a270d733.96bef8","type":"inject","z":"26f841ca.725036","name":"","topic":"","payload":"OFF","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":290,"y":800,"wires":[["d32d9cf3.23946"]],"outputLabels":["House/LightLobbyB/stat/POWER"]},{"id":"bb484857.94bc","type":"function","z":"26f841ca.725036","name":"3wayAtoB","func":"var newMsg = { topic: \"House/LightLobbyB/cmnd/POWER\"}; \nvar LobbyB=flow.get('LobbyB') || 0;\n\n//if (msg.topic===\"House/LightLobbyA/stat/POWER\") {\n    if (LobbyB===0) {\n        if (msg.payload === \"ON\") {\n            newMsg.payload = \"ON\";\n            LobbyB=1\n            flow.set('LobbyB',LobbyB);\n            return newMsg;  \n        }\n    }\n    else {\n        if (msg.payload === \"OFF\") {\n            newMsg.payload = \"OFF\";\n            LobbyB=0;\n            flow.set('LobbyB',LobbyB);\n            return newMsg; \n        }\n    }\n//}\n","outputs":1,"noerr":0,"x":500,"y":560,"wires":[["c7962c05.28c8e8","a0834568.7e447"]],"inputLabels":["House/LightLobbyA/stat/POWER"]},{"id":"a0834568.7e447","type":"mqtt out","z":"26f841ca.725036","name":"","topic":"","qos":"","retain":"","broker":"12dd1610.da9e4a","x":990,"y":600,"wires":[]},{"id":"c7962c05.28c8e8","type":"debug","z":"26f841ca.725036","name":"Debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":990,"y":540,"wires":[],"inputLabels":["House/#"]},{"id":"406daced.472844","type":"inject","z":"26f841ca.725036","name":"","topic":"","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":290,"y":500,"wires":[["bb484857.94bc"]],"outputLabels":["House/LightLobbyA/stat/POWER"]},{"id":"a33d117e.961728","type":"inject","z":"26f841ca.725036","name":"","topic":"","payload":"OFF","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":290,"y":540,"wires":[["bb484857.94bc"]],"outputLabels":["House/LightLobbyA/stat/POWER"]},{"id":"4bbcf441.3900e4","type":"ui_group","z":"","name":"Home","tab":"3f9beed4.78316a","order":1,"disp":true,"width":"6","collapse":false},{"id":"12dd1610.da9e4a","type":"mqtt-broker","z":"","name":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"3f9beed4.78316a","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

Please edit your post above, and format your flow as described here.
The way that you have posted it makes it unusable.

This seems overly complex but maybe I've misinterpreted your meaning.

With my system, I can have any number of switches controlling a light. The switch is controlled by an MQTT topic. I use generic topics such as COMMAND/SWITCH01 since I don't want to have to change code just because I had to swap out a SONOFF or other device.

So anything can send a command to that address - there is a very simple flow that listens to COMMAND/? and translates the commands to the appropriate hardware addresses.

I use a different flow to monitor for controllers which can be anything that can send a signal to Node-RED. I have a mix of controllers using LightwaveRF, Home Easy and WiFi.

Now I can map the controller id's to commands. I can also map a controller ID to multiple commands so that, for example, a HomeEasy switch could turn on/off any number of lights.

Of course, other flows can also issue command messages. For example, I have a Telegram "bot" that is able to turn lights on and off remotely.

Hope that makes sense - it is easier to do than to write!

  • switch - a device that turns power on/off (or dims, changes colour, etc)
  • controller - a device that sends information to Node-RED
  • command - indirect message to a switch.

A controller sends a message to Node-RED. Flow 1 maps that message to one or more commands and sends it to MQTT. Flow 2 listens for commands via MQTT and maps to a switch.

Of course, in reality many flows can map incoming messages to commands.

Thank you for the response. Does your method update the status lights on all of the remote switches?

Well, depends how they work. For Tasmota, the device lights simply connect to whether things are on or off so that all works as expected. That's how most things work so its fine.

I also have a dashboard that shows status - that also works fine since the MQTT topics act as an intermediate store. Again, all works well with devices that actually send back status updates. With things like LightwaveRF, they don't send back status so things can get out of step. You handle that slightly differently - mainly be making Node-RED/MQTT the master.

Sometimes - like with system restarts - you will send out your expected state to make sure the devices match that.

Bearing in mind that many devices can also be changed locally - so a LightwaveRF switch can be locally changed but because it doesn't send out updates, Node-RED/MQTT will now be out of step. Not much you can do about that. With SONOFF devices, that is different since they send out an update when they change status so it is easy to keep everything in step.

If the switches are a toggle on or off type (rather than momentary) a method would be to change the switches output (in NR) to true when either is selected (so acting like a momentary switch when switched to either on or off) and then feed all the switches to a toggle sub-flow to change condition.

https://www.iotwithus.com/node-red-toggle-function-subflow/