Dynamically Populate Dashboard with Buttons to Tasmota-Sonoff Devices

This flow listens for messages from devices running the Tasmota-Sonoff firmware (but can work for other devices that publish data on MQTT) and adds or removes buttons from the Node Red dashboard when devices come online or disappear.

It basically works by listening for outputs from the devices on MQTT. The msg are manipulated to extract the device name which is fed into a collector node. Whenever a new device is added, the collector node sends a msg to a dashboard template node which has the following code:

<md-list>
    <md-list-item ng-repeat="device in msg.payload">
        <md-button class="md-ink-ripple" 
                 ng-href="http://{{device.Hostname}}" 
            target="_blank">{{device.Name}}</md-button>
    </md-list-item>
</md-list>

which iterates over the array of device names and creates a button for each which opens the device's configuration web page.

A trigger node, set to fire at start-up, does a group poll so that all of the devices respond to populate the initial dashboard. There is also a MQTT node listening for LWT messages from devices which it uses to trigger deleting the device name from the collector node and hence from the dashboard.

[{"id":"ae01eb30.2a687","type":"inject","z":"1c429fc1.6372a","name":"Send probe","topic":"cmnd/sonoffs/STATUS","payload":"5","payloadType":"str","repeat":"","crontab":"","once":true,"x":116.42855834960938,"y":34.285667419433594,"wires":[["3a6b7f67.431c98"]]},{"id":"de6bf955.a53eb8","type":"mqtt in","z":"1c429fc1.6372a","name":"","topic":"tele/+/LWT","qos":"2","broker":"c689a17e.a806a8","x":106.07144165039062,"y":103.28568267822266,"wires":[["41b7585d.2273b8"]]},{"id":"6cdaaf73.e2a6c","type":"mqtt in","z":"1c429fc1.6372a","name":"","topic":"tele/+/INFO2","qos":"2","broker":"c689a17e.a806a8","x":108.5,"y":300,"wires":[["5b058b8a.e3c2bc"]]},{"id":"c5a9bf9f.41ee88","type":"mqtt in","z":"1c429fc1.6372a","name":"","topic":"stat/+/STATUS5","qos":"2","broker":"c689a17e.a806a8","x":119.28573608398438,"y":362.85711669921875,"wires":[["bff46a48.07ae9"]]},{"id":"bff46a48.07ae9","type":"json","z":"1c429fc1.6372a","name":"","pretty":false,"x":335.0000305175781,"y":362.8570251464844,"wires":[["62649a3b.6f89fc"]]},{"id":"5b058b8a.e3c2bc","type":"json","z":"1c429fc1.6372a","name":"","pretty":false,"x":335.7856750488281,"y":299.8571472167969,"wires":[["caaf7b55.f4eaf"]]},{"id":"41b7585d.2273b8","type":"change","z":"1c429fc1.6372a","name":"","rules":[{"t":"change","p":"topic","pt":"msg","from":"tele/(.+)/LWT","fromt":"re","to":"$1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":372.1429138183594,"y":102.71427154541016,"wires":[["9dc4592e.8b8b68"]]},{"id":"9dc4592e.8b8b68","type":"match","z":"1c429fc1.6372a","name":"","rules":[{"property":"payload","propertyType":"msg","type":"eq","value":"Online","valueType":"str"}],"x":597.8570556640625,"y":102.85713958740234,"wires":[["bded06c.02ccc78"],["4973e61c.2759e"]],"outputLabels":["Online","Offline"]},{"id":"caaf7b55.f4eaf","type":"change","z":"1c429fc1.6372a","name":"","rules":[{"t":"change","p":"topic","pt":"msg","from":"tele/(.+)/INFO2","fromt":"re","to":"$1","tot":"str"},{"t":"set","p":"payload.Name","pt":"msg","to":"topic","tot":"msg"},{"t":"delete","p":"payload.WebserverMode","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":551.4286499023438,"y":300,"wires":[["fdd620b4.d28188"]]},{"id":"62649a3b.6f89fc","type":"change","z":"1c429fc1.6372a","name":"","rules":[{"t":"change","p":"topic","pt":"msg","from":"stat/(.+)/STATUS5","fromt":"re","to":"$1","tot":"str"},{"t":"set","p":"payload.Hostname","pt":"msg","to":"payload.StatusNET.Hostname","tot":"msg"},{"t":"set","p":"payload.Name","pt":"msg","to":"topic","tot":"msg"},{"t":"delete","p":"payload.StatusNET","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":547.142822265625,"y":362.8570861816406,"wires":[["fdd620b4.d28188"]]},{"id":"fdd620b4.d28188","type":"collector","z":"1c429fc1.6372a","name":"","onlyIfChanged":true,"x":1143.5000610351562,"y":292,"wires":[["61486286.f925bc"]]},{"id":"61486286.f925bc","type":"ui_template","z":"1c429fc1.6372a","group":"cd6a6011.f60598","name":"","order":1,"width":0,"height":0,"format":"<md-list>\n    <md-list-item ng-repeat=\"device in msg.payload\">\n        <md-button class=\"md-ink-ripple\" ng-href=\"http://{{device.Hostname}}\" target=\"_blank\">{{device.Name}}</md-button>\n    </md-list-item>\n    \n</md-list>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":1365,"y":294.2855529785156,"wires":[[]]},{"id":"3a6b7f67.431c98","type":"mqtt out","z":"1c429fc1.6372a","name":"","topic":"","qos":"2","retain":"false","broker":"c689a17e.a806a8","x":1397.8572998046875,"y":28.571365356445312,"wires":[]},{"id":"5d345790.b90158","type":"delay","z":"1c429fc1.6372a","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1117.8570861816406,"y":61.42853546142578,"wires":[["3a6b7f67.431c98"]]},{"id":"bded06c.02ccc78","type":"change","z":"1c429fc1.6372a","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"5","tot":"str"},{"t":"change","p":"topic","pt":"msg","from":"(.+)","fromt":"re","to":"cmnd/$1/STATUS","tot":"str"},{"t":"delete","p":"qos","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":857.8571428571428,"y":71.42857142857142,"wires":[["5d345790.b90158"]]},{"id":"4973e61c.2759e","type":"change","z":"1c429fc1.6372a","name":"","rules":[{"t":"delete","p":"payload","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":854.6429138183594,"y":124.99999237060547,"wires":[["57933581.0a986c","fdd620b4.d28188"]]},{"id":"c689a17e.a806a8","type":"mqtt-broker","z":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"verifyservercert":true,"compatmode":true,"keepalive":"15","cleansession":true,"willTopic":"","willQos":"0","willRetain":null,"willPayload":"","birthTopic":"","birthQos":"0","birthRetain":null,"birthPayload":""},{"id":"cd6a6011.f60598","type":"ui_group","z":"","name":"Devices","tab":"cce679d3.9909c","order":2,"disp":true,"width":"18"},{"id":"cce679d3.9909c","type":"ui_tab","z":"","name":"Sonoff","icon":"dashboard"}]
DeanCording

Flow Info

created 1 month ago

Node Types

Core
  • change (x5)
  • delay (x1)
  • inject (x1)
  • json (x2)
  • mqtt in (x3)
  • mqtt out (x1)
  • mqtt-broker (x1)
Other
  • collector (x1)
  • match (x1)
  • ui_group (x1)
  • ui_tab (x1)
  • ui_template (x1)

Tags

  • tasmota-sonoff
  • tasmota
  • sonoff
  • dynamic
  • dashboard
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option