Conceptual question: single or multiple mqtt input/output

Being rather new in the field of node-red I have a conceptual question.

Lets say I have 3 lights I want to switch, for each light I define a switch. The switch has an MQTT input (for status update) and an MQTT output to instruct the hardware switch. Now I can choose to use one single MQTT input and one single MQTT output and filter the status update loop by topic:

[{"id":"2ae42f67.032e7","type":"mqtt in","z":"adc908d7.97de","name":"","topic":"#","qos":"2","datatype":"auto","broker":"e19f900c.f6ae38","x":90,"y":280,"wires":[["86c9f487.a21ad8","b4f9126c.9b34d8","222e071.bdfb7f8"]]},{"id":"77162795.3f4238","type":"mqtt out","z":"adc908d7.97de","name":"","topic":"","qos":"","retain":"","x":730,"y":280,"wires":},{"id":"86c9f487.a21ad8","type":"function","z":"adc908d7.97de","name":"pass topic1","func":"if(msg.topic == "topic1") {\n return msg;\n}","outputs":1,"noerr":0,"x":310,"y":240,"wires":[["66a86007.90ae18"]]},{"id":"b4f9126c.9b34d8","type":"function","z":"adc908d7.97de","name":"pass topic2","func":"if(msg.topic == "topic2") {\n return msg;\n}","outputs":1,"noerr":0,"x":310,"y":280,"wires":[["1322464a.2a26ea"]]},{"id":"222e071.bdfb7f8","type":"function","z":"adc908d7.97de","name":"pass topic3","func":"if(msg.topic == "topic3") {\n return msg;\n}","outputs":1,"noerr":0,"x":310,"y":320,"wires":[["9053d0b5.9937d8"]]},{"id":"66a86007.90ae18","type":"ui_switch","z":"adc908d7.97de","name":"","label":"switch1","tooltip":"","group":"58fac6f7.ee74d","order":13,"width":0,"height":0,"passthru":false,"decouple":"true","topic":"topic1","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":520,"y":240,"wires":[["77162795.3f4238"]]},{"id":"1322464a.2a26ea","type":"ui_switch","z":"adc908d7.97de","name":"","label":"switch2","tooltip":"","group":"58fac6f7.ee74d","order":13,"width":0,"height":0,"passthru":false,"decouple":"true","topic":"topic2","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":520,"y":280,"wires":[["77162795.3f4238"]]},{"id":"9053d0b5.9937d8","type":"ui_switch","z":"adc908d7.97de","name":"","label":"switch3","tooltip":"","group":"58fac6f7.ee74d","order":13,"width":0,"height":0,"passthru":false,"decouple":"true","topic":"topic3","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":520,"y":320,"wires":[["77162795.3f4238"]]},{"id":"e19f900c.f6ae38","type":"mqtt-broker","z":"","name":"Tree MQTT broker","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":"58fac6f7.ee74d","type":"ui_group","z":"","name":"Home","tab":"8b2679bd.109a8","disp":true,"width":"6","collapse":false},{"id":"8b2679bd.109a8","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

I can also define an MQTT input listening to a single topic for each switch and an MQTT output for each button:

[{"id":"604399bb.b34418","type":"mqtt in","z":"adc908d7.97de","name":"","topic":"topic1","qos":"2","datatype":"auto","broker":"e19f900c.f6ae38","x":90,"y":500,"wires":[["81b6ebc6.3c4738"]]},{"id":"81b6ebc6.3c4738","type":"ui_switch","z":"adc908d7.97de","name":"","label":"switch1","tooltip":"","group":"58fac6f7.ee74d","order":13,"width":0,"height":0,"passthru":false,"decouple":"true","topic":"topic1","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":320,"y":500,"wires":[["5ea90fe5.259eb"]]},{"id":"5ea90fe5.259eb","type":"mqtt out","z":"adc908d7.97de","name":"","topic":"","qos":"","retain":"","x":510,"y":500,"wires":},{"id":"510bbcd6.5bc80c","type":"mqtt in","z":"adc908d7.97de","name":"","topic":"topic2","qos":"2","datatype":"auto","broker":"e19f900c.f6ae38","x":90,"y":540,"wires":[["226046b5.69d6da"]]},{"id":"226046b5.69d6da","type":"ui_switch","z":"adc908d7.97de","name":"","label":"switch2","tooltip":"","group":"58fac6f7.ee74d","order":13,"width":0,"height":0,"passthru":false,"decouple":"true","topic":"topic2","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":320,"y":540,"wires":[["3d690a5e.261e16"]]},{"id":"3d690a5e.261e16","type":"mqtt out","z":"adc908d7.97de","name":"","topic":"","qos":"","retain":"","x":510,"y":540,"wires":},{"id":"3d6aebd3.5cfb3c","type":"mqtt in","z":"adc908d7.97de","name":"","topic":"topic3","qos":"2","datatype":"auto","broker":"e19f900c.f6ae38","x":90,"y":580,"wires":[["4fd716eb.d6c5e8"]]},{"id":"4fd716eb.d6c5e8","type":"ui_switch","z":"adc908d7.97de","name":"","label":"switch3","tooltip":"","group":"58fac6f7.ee74d","order":13,"width":0,"height":0,"passthru":false,"decouple":"true","topic":"topic3","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":320,"y":580,"wires":[["8085cca.9e5853"]]},{"id":"8085cca.9e5853","type":"mqtt out","z":"adc908d7.97de","name":"","topic":"","qos":"","retain":"","x":510,"y":580,"wires":},{"id":"e19f900c.f6ae38","type":"mqtt-broker","z":"","name":"Tree MQTT broker","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":"58fac6f7.ee74d","type":"ui_group","z":"","name":"Home","tab":"8b2679bd.109a8","disp":true,"width":"6","collapse":false},{"id":"8b2679bd.109a8","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

Is there a preference for one of these approaches with respect to performance (eg in case of a multitude of buttons), flexibility, clarity of design? Or is it just a matter of taste?

I think you can have various ideas and thoughts about this. I have both types of "architectures". Mainly my older designs had more of the type "one for each" creating flows with a lot of nodes but in my later designs, I try to make "smarter" solutions using less nodes. It's a matter of personal evolution I think. What I am able to do today, I was not capable of earlier due to lacking know-how. A good example excercis of "node reduction" I experienced myself is here: Video device monitoring - typically wifi ip-cameras

Another opinion is about maintenance & readability. If you create a "very smart flow" it can at a first glance be difficult to fully understand the logic if you have to dive deeper into it in the future. On the other hand maintenance might be easier than if you have many nodes scattered all over the place that you need to modify for some reason

From performance point of view, I do not think there is a significant difference unless you have many function nodes in one of the others. But if you are talking about controlling lights, you have a RFXtrx, right, the most of the wasted time is consumed in that device anyway

I generally go for the simpler solution, which is one MQTT node per switch. Easier to understand and maintain.

performance wise they should be the same - the config node maintains the one connection to the broker and when any message arrives it either would send them all to the one node - or one to each - so the same number of "hops" involved... so really it is up to you. Personally I'm with Colin on the one per thing - but "thing" can be a bit nebulous... can be an individual item (one topic) or maybe one room or group of sensors (so a wildcard subscription)... depending on what happens next. the key thing is what will you be able to understand again in 6 months time when you come back and need to recall what the flow does.

Thanks all for your thoughts. Summarizing, it is a matter of taste and readability of the flows. Only if the choice can can substantially reduce the number of hops it may make a difference in performance?

Indeed, as krambriw states, I use RFXtrx433, which may be a limiting factor, although it is still much faster than where I come from (Domitiga).

@insomniux, just as a side note; the RFXtrx is indeed much better than other similar devices. However, using any of those simpler protocols used for one-way lighting control on the 433 MHz band is a limiting factor due to risks for collision etc etc. The good thing is that the RFXtrx has a built-in communication buffer so the sw can quickly push messages to it and the commands will then be transmitted "in due time", fast enough for the purpose of turning lamps on or off

Like @krambriw said, the RFXtrx has several features to improve communication reliability:

  • Each radio transmission actually consists of a number of repeats of the basic command, so that if one is received incorrectly due to interference, there is a chance another one will get through - although this depends on the error-detecting performance of the radio protocol used by the device being controlled: naturally the RFXtrx has no control over this, and devices from different suppliers vary a lot!
  • The RFXtrx will listen for a 'clear channel' (i.e. nothing else transmitting) before it transmits a radio message, which reduces the chance of mutual interference.
  • It sends an acknowledgement response back over the USB to indicate when each command has actually been sent, or if it is being held waiting for a clear channel, or if transmission failed.
  • There is an internal command buffer so multiple messages can be queued up waiting for transmission. This buffer is limited in size, though (it varies by model)

The node-red-contrib-rfxcom node adds its own features to this. It has its own internal queue, so that it does not attempt to send more commands to the RFXtrx than the internal buffer can hold: it monitors the acknowledgement responses to determine when it is OK to send the next message, and will warn (on the debug pane) if transmission fails. This queue is 'unlimited' in size.

You can also configure the rfx-lights-out & rfx-PT2262-out nodes to retransmit (control) messages after a delay, or to repeat transmission at regular intervals. This adds another layer of redundancy you can use in difficult environments.