Skip to content

Instantly share code, notes, and snippets.

@DeanCording
Last active March 12, 2021 17:03
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DeanCording/1541bcbba48bb088ec1503dba109f63c to your computer and use it in GitHub Desktop.
Save DeanCording/1541bcbba48bb088ec1503dba109f63c to your computer and use it in GitHub Desktop.
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"}]
@rlust
Copy link

rlust commented Oct 15, 2018

Well done, this is great! Is it possible to have the host name appended with .local or use or display the ip address?

@riker65
Copy link

riker65 commented Mar 12, 2021

Hi
looks great but havong an issue importing

The workspace contains some unknown node types:

httpInMultipart
fs-ops-move
md5
fs-ops-access
config

  • 3 more

which nodes packages need to be installed?

Thanks T

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment