terrarium automation with button panel and timers

This flow is an example of my terrarium automation display, using several techniques that can be used separately. It can be used as a starting point for similar automation projects. Some of the techniques used:

  • maintaining a global state
  • building a button panel using a single dashboard template
  • using timers
  • overriding timers
  • using MQTT to handle most internal communication between nodes

prerequisites

  • This set of flows makes use of the BigTimer node for the timers.
  • It only works on the Light theme due to css settings. Should be trivial to convert to dark.

device configuration

All devices need to be configured in a single place in the top of the flow. Here I define the name, the default state, and if the default should be forced even if an existing state exists. This last part is just a precaution for certain devices I like to force to automatic mode on redeploy.

how it works

On startup the top flow is run, which reads the configured devices, and then initialises the state. State can be on,off and auto. Auto means that it's controlled by the timer. If no previous state exists, it uses the default state. For each device, an MQTT message is sent to 'terrarium/input/+' to broadcast the current state to the other flows.

The second flow handles all state changes. If any part of the system changes a state, this makes sure these changes are kept in global state variables. At the end of the flow, it broadcasts a single message with the current state of all devices.

The third flow is the dashboard/button panel. The main element is the dashboard node. It loops over all devices, and for each device generates a set of buttons. For visuals I also have a virtual LED which shows the actual output state of the device (this is fed from 'terrarium/output/+'). The state of the buttons is retrieved by listening to the full state MQTT message that the previous flow broadcasts on every state change. When you press a button, the node emits an MQTT message for that button to 'terrarium/input/+' with the desired state. It does not change the state of the button itself. This will happen automatically as the global state flow will modify the state of this button to the new state, and then send a new full state message over MQTT. The new full state is then read by the button template. This happens so fast you don't notice it.

Note, the LEDs show the actual state of the devices, not the state of the buttons.

The final flow shows the timers. The timers are set to come on/off at certain times, but they allow manual override through the input. This is controlled by listening to the 'terrarium/input/+' MQTT events. The output of the timers is then used to control physical devices by broadcasting to MQTT 'terrarium/output/+'. Any relays or other devices could be controlled by listening to these MQTT events. This is shown in the final flow with the output set to a debug node.

alt text

All these flows appear on one page. In your own project you may want to move each section to its own tab.

[{"id":"8e5f4a70.b78018","type":"inject","z":"429ff3e8.e7f3fc","name":"on start","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"x":131,"y":131,"wires":[["774e3b7f.cb5064"]]},{"id":"fcb11c37.ceec2","type":"function","z":"429ff3e8.e7f3fc","name":"init state","func":"var state   = global.get('state')   || {};\nvar devices = global.get('devices') || {};\n\n\nfor (var device in devices) {\n\n    if ( ! (device in state) ) {\n        state[device] = {}\n        state[device]['input'] = devices[device]['default'];\n    } \n    \n\n    if (devices[device]['force'] === true) {\n        state[device]['input'] = devices[device]['default'];\n    }   \n\n    payload = state[device]['input'];\n\n    node.send({\n        topic: 'terrarium/input/' + device,\n        payload: payload\n    });\n}\n\n\nglobal.set('state', state);\n","outputs":"1","noerr":0,"x":532.5,"y":131,"wires":[["67e690c6.fee5f"]]},{"id":"28b57284.b5868e","type":"comment","z":"429ff3e8.e7f3fc","name":"load state","info":"","x":123.5,"y":91,"wires":[]},{"id":"34ec8013.2ef89","type":"comment","z":"429ff3e8.e7f3fc","name":"configure devices here","info":"","x":331,"y":89,"wires":[]},{"id":"67e690c6.fee5f","type":"delay","z":"429ff3e8.e7f3fc","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":741,"y":131,"wires":[["d4755883.d12a08"]]},{"id":"774e3b7f.cb5064","type":"function","z":"429ff3e8.e7f3fc","name":"init devices","func":"/* set up all devices */\n\nvar devices = {\n    moonlight: {\n        name: 'Moon Light',\n        default: 'auto',\n        force: false,\n    },\n    light1: {\n        name: 'Light 1',\n        default: 'auto',\n        force: false\n    },\n    light2: {\n        name: 'Light 2',\n        default: 'auto',\n        force: false\n    },\n    spot1: {\n        name: 'Spot 1',\n        default: 'auto',\n        force: false\n    },\n    spot2: {\n        name: 'Spot 2',\n        default: 'auto',\n        force: false\n    },\n    mister: {\n        name: 'Mister',\n        default: 'auto',\n        force: true,\n    },\n    fans: {\n        name: 'Fans',\n        default: 'auto',\n        force: false\n    },\n    waterfall: {\n        name: 'Waterfall',\n        default: 'auto',\n        force: false\n    }\n}\n\n\nglobal.set('devices', devices);\n\nreturn msg;\n","outputs":1,"noerr":0,"x":341,"y":131,"wires":[["fcb11c37.ceec2"]]},{"id":"d4755883.d12a08","type":"mqtt out","z":"429ff3e8.e7f3fc","name":"terrarium/input/+","topic":"","qos":"","retain":"","broker":"1c2a9091.af757f","x":979,"y":130,"wires":[]},{"id":"ac37297c.48f588","type":"mqtt out","z":"429ff3e8.e7f3fc","name":"terrarium/input/+","topic":"","qos":"","retain":"","broker":"1c2a9091.af757f","x":726,"y":543,"wires":[]},{"id":"ce80979b.18fa98","type":"ui_template","z":"429ff3e8.e7f3fc","group":"bb368a59.014048","name":"buttons","order":1,"width":"9","height":"10","format":"\n<div ng-repeat=\"(key, device) in msg.payload\">\n\n    <div class=\"btn-row\" layout=\"row\" layout-sm=\"column\" layout-align=\"center center\" layout-wrap>\n        <span class=\"btn-name\" flex=\"30\">{{ device.name }}</span>\n            \n        <md-button \n            ng-click=\"send({payload: 'on', topic: 'terrarium/input/'+key});\"\n            ng-class=\"device.state.input === 'on' ? 'btn-selected' : ''\" \n            class=\"md-raised btn btn-on\" \n            flex>\n            ON\n        </md-button>\n            \n        <md-button \n            ng-click=\"send({payload: 'auto', topic: 'terrarium/input/'+key});\"\n            ng-class=\"device.state.input === 'auto' ? 'btn-selected' : ''\" \n            class=\"md-raised btn btn-auto\" \n            flex>\n            AUTO\n        </md-button>\n            \n        <md-button \n            ng-click=\"send({payload: 'off', topic: 'terrarium/input/'+key});\"\n            ng-class=\"device.state.input === 'off' ? 'btn-selected' : ''\" \n            class=\"md-raised btn btn-off\" \n            flex>\n            OFF\n        </md-button>\n        \n        <md-led \n            ng-class=\"device.state.output === 'on' ? 'md-led-on' : 'md-led-off'\"\n            class=\"md-led\"\n        </md-led>\n            \n    </div>\n</div>\n\n\n<style>\n    :focus {\n        outline: 0;\n    }\n\n    .btn-row {\n        margin-bottom: 10px;\n    }\n    \n    .nr-dashboard-theme-light .md-button.btn {\n        color: #000;\n        padding: 15px;\n        margin: 0px 10px 0px 0px;\n        background-color: #c3c3c3;\n        border: 1px solid #ababab;\n        box-shadow: 4px 4px 6px 0 #dadada;\n    }\n    \n    .nr-dashboard-theme-light .md-button.btn.btn-off.btn-selected {\n        background-color: #F4511E;\n    }\n    \n    .nr-dashboard-theme-light .md-button.btn.btn-on.btn-selected {\n        background-color: #00FF00;\n    }\n    \n    .nr-dashboard-theme-light .md-button.btn.btn-auto.btn-selected {\n        background-color: #f4c61e;\n    }\n    \n    \n    .btn-name {\n        text-align: center;\n        font-weight: bold;\n    }\n    \n\n    .md-led {\n        margin-left: 15px;\n        border-radius: 50%;\n\t    width: 20px;\n\t    height: 20px; \n\t    border: 1px solid #666666;\n    }\n    \n    .md-led.md-led-on {\n        background: #00ff00; /* Old browsers */\n        background: -moz-radial-gradient(center, ellipse cover, #00ff00 0%, #00c406 100%); /* FF3.6-15 */\n        background: -webkit-radial-gradient(center, ellipse cover, #00ff00 0%,#00c406 100%); /* Chrome10-25,Safari5.1-6 */\n        background: radial-gradient(ellipse at center, #00ff00 0%,#00c406 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */\n        filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ff00', endColorstr='#00c406',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */\n    }\n    \n    .md-led.md-led-off {\n        background: #ff0000; /* Old browsers */\n        background: -moz-radial-gradient(center, ellipse cover, #ff0000 0%, #d61800 95%, #b70300 100%); /* FF3.6-15 */\n        background: -webkit-radial-gradient(center, ellipse cover, #ff0000 0%,#d61800 95%,#b70300 100%); /* Chrome10-25,Safari5.1-6 */\n        background: radial-gradient(ellipse at center, #ff0000 0%,#d61800 95%,#b70300 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */\n        filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff0000', endColorstr='#b70300',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */\n    }\n \n</style>\n","storeOutMessages":false,"fwdInMessages":false,"x":501.5,"y":542,"wires":[["ac37297c.48f588"]]},{"id":"69349c1.c8bc064","type":"mqtt in","z":"429ff3e8.e7f3fc","name":"","topic":"terrarium/state","qos":"2","broker":"60f8fb33.312b64","x":135,"y":541,"wires":[["44feec1e.976214"]]},{"id":"44feec1e.976214","type":"json","z":"429ff3e8.e7f3fc","name":"","x":327,"y":541,"wires":[["ce80979b.18fa98"]]},{"id":"6338d14e.83224","type":"comment","z":"429ff3e8.e7f3fc","name":"Dashboard Buttons ","info":"","x":133,"y":493,"wires":[]},{"id":"af9706d9.749828","type":"mqtt in","z":"429ff3e8.e7f3fc","name":"","topic":"terrarium/input/+","qos":"2","broker":"1c2a9091.af757f","x":140,"y":302,"wires":[["787a178.b5a5fe8"]]},{"id":"d54659b3.12e518","type":"comment","z":"429ff3e8.e7f3fc","name":"handle state changes","info":"","x":123,"y":260,"wires":[]},{"id":"5bae2fa6.e0942","type":"mqtt out","z":"429ff3e8.e7f3fc","name":"","topic":"terrarium/state","qos":"2","retain":"","broker":"60f8fb33.312b64","x":909,"y":334,"wires":[]},{"id":"7bb949f4.9f81f8","type":"comment","z":"429ff3e8.e7f3fc","name":"broadcast full state","info":"","x":792,"y":279,"wires":[]},{"id":"bb2693ad.f594d","type":"mqtt in","z":"429ff3e8.e7f3fc","name":"","topic":"terrarium/output/+","qos":"2","broker":"60f8fb33.312b64","x":135,"y":364,"wires":[["b25719cf.5d0548"]]},{"id":"787a178.b5a5fe8","type":"function","z":"429ff3e8.e7f3fc","name":"store state","func":"/* get the device */\ndevice = msg.topic.split('/');\ndevice = device[2];\n\n/* store state back into state machine */\nglobal.set('state.'+device+'.input', msg.payload);\n\nreturn msg;","outputs":1,"noerr":0,"x":427.5,"y":302,"wires":[["65a98daf.da7814"]]},{"id":"65a98daf.da7814","type":"function","z":"429ff3e8.e7f3fc","name":"build state object","func":"/* build full state object */\nvar state   = global.get('state');\nvar devices = global.get('devices');\n\nfor(var device in devices) {\n    devices[device]['state'] = state[device];   \n}\n\nmsg = {\n    topic: 'terrarium/state',\n    payload: devices\n}\n\nreturn msg;\n","outputs":1,"noerr":0,"x":670,"y":334,"wires":[["5bae2fa6.e0942"]]},{"id":"b25719cf.5d0548","type":"function","z":"429ff3e8.e7f3fc","name":"store state","func":"/* get the device */\ndevice = msg.topic.split('/');\ndevice = device[2];\n\n/* store state back into state machine */\nglobal.set('state.'+device+'.output', msg.payload);\n\nreturn msg;","outputs":1,"noerr":0,"x":428.5,"y":365,"wires":[["65a98daf.da7814"]]},{"id":"739073de.ae8dfc","type":"bigtimer","z":"429ff3e8.e7f3fc","outtopic":"terrarium/output/moonlight","outpayload1":"on","outpayload2":"off","name":"Moonlight","lat":"52","lon":"4","starttime":"1320","endtime":"60","startoff":0,"endoff":0,"offs":0,"outtext1":"","outtext2":"","timeout":"1440","sun":true,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"jan":true,"feb":true,"mar":true,"apr":true,"may":true,"jun":true,"jul":true,"aug":true,"sep":true,"oct":true,"nov":true,"dec":true,"day1":0,"month1":0,"day2":0,"month2":0,"day3":0,"month3":0,"day4":0,"month4":0,"day5":0,"month5":0,"d1":0,"w1":0,"d2":0,"w2":0,"d3":0,"w3":0,"d4":0,"w4":0,"d5":0,"w5":0,"suspend":false,"random":false,"repeat":true,"atstart":true,"x":419,"y":744,"wires":[["135c087c.bbee78"],[],[]]},{"id":"135c087c.bbee78","type":"mqtt out","z":"429ff3e8.e7f3fc","name":"terrarium/output/+","topic":"","qos":"","retain":"","broker":"1c2a9091.af757f","x":860,"y":941.5,"wires":[]},{"id":"77e013ad.dfaa1c","type":"bigtimer","z":"429ff3e8.e7f3fc","outtopic":"terrarium/output/mister","outpayload1":"on","outpayload2":"off","name":"Mister","lat":"52","lon":"4","starttime":"420","endtime":"435","startoff":0,"endoff":0,"offs":0,"outtext1":"","outtext2":"","timeout":"1440","sun":true,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"jan":true,"feb":true,"mar":true,"apr":true,"may":true,"jun":true,"jul":true,"aug":true,"sep":true,"oct":true,"nov":true,"dec":true,"day1":0,"month1":0,"day2":0,"month2":0,"day3":0,"month3":0,"day4":0,"month4":0,"day5":0,"month5":0,"d1":0,"w1":0,"d2":0,"w2":0,"d3":0,"w3":0,"d4":0,"w4":0,"d5":0,"w5":0,"suspend":false,"random":false,"repeat":false,"atstart":false,"x":423.5,"y":1152.5,"wires":[["135c087c.bbee78"],[],[]]},{"id":"71b7dfa7.23842","type":"bigtimer","z":"429ff3e8.e7f3fc","outtopic":"terrarium/output/light1","outpayload1":"on","outpayload2":"off","name":"Light 1","lat":"52","lon":"4","starttime":"660","endtime":"1335","startoff":0,"endoff":0,"offs":0,"outtext1":"","outtext2":"","timeout":"1440","sun":true,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"jan":true,"feb":true,"mar":true,"apr":true,"may":true,"jun":true,"jul":true,"aug":true,"sep":true,"oct":true,"nov":true,"dec":true,"day1":0,"month1":0,"day2":0,"month2":0,"day3":0,"month3":0,"day4":0,"month4":0,"day5":0,"month5":0,"d1":0,"w1":0,"d2":0,"w2":0,"d3":0,"w3":0,"d4":0,"w4":0,"d5":0,"w5":0,"suspend":false,"random":false,"repeat":true,"atstart":true,"x":418.5,"y":812.5,"wires":[["135c087c.bbee78"],[],[]]},{"id":"6b925ce4.78fdf4","type":"bigtimer","z":"429ff3e8.e7f3fc","outtopic":"terrarium/output/light2","outpayload1":"on","outpayload2":"off","name":"Light 2","lat":"52","lon":"4","starttime":"780","endtime":"1260","startoff":0,"endoff":0,"offs":0,"outtext1":"","outtext2":"","timeout":"1440","sun":true,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"jan":true,"feb":true,"mar":true,"apr":true,"may":true,"jun":true,"jul":true,"aug":true,"sep":true,"oct":true,"nov":true,"dec":true,"day1":0,"month1":0,"day2":0,"month2":0,"day3":0,"month3":0,"day4":0,"month4":0,"day5":0,"month5":0,"d1":0,"w1":0,"d2":0,"w2":0,"d3":0,"w3":0,"d4":0,"w4":0,"d5":0,"w5":0,"suspend":false,"random":false,"repeat":true,"atstart":true,"x":415.5,"y":876.5,"wires":[["135c087c.bbee78"],[],[]]},{"id":"64003f47.8d64b","type":"bigtimer","z":"429ff3e8.e7f3fc","outtopic":"terrarium/output/spot1","outpayload1":"on","outpayload2":"off","name":"Spot1","lat":"52","lon":"4","starttime":"900","endtime":"1200","startoff":0,"endoff":0,"offs":0,"outtext1":"","outtext2":"","timeout":"1440","sun":true,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"jan":true,"feb":true,"mar":true,"apr":true,"may":true,"jun":true,"jul":true,"aug":true,"sep":true,"oct":true,"nov":true,"dec":true,"day1":0,"month1":0,"day2":0,"month2":0,"day3":0,"month3":0,"day4":0,"month4":0,"day5":0,"month5":0,"d1":0,"w1":0,"d2":0,"w2":0,"d3":0,"w3":0,"d4":0,"w4":0,"d5":0,"w5":0,"suspend":false,"random":false,"repeat":true,"atstart":true,"x":418.5,"y":941.5,"wires":[["135c087c.bbee78"],[],[]]},{"id":"3b3db576.469a7a","type":"bigtimer","z":"429ff3e8.e7f3fc","outtopic":"terrarium/output/spot2","outpayload1":"on","outpayload2":"off","name":"Spot2","lat":"52","lon":"4","starttime":"960","endtime":"1140","startoff":0,"endoff":0,"offs":0,"outtext1":"","outtext2":"","timeout":"1440","sun":true,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"jan":true,"feb":true,"mar":true,"apr":true,"may":true,"jun":true,"jul":true,"aug":true,"sep":true,"oct":true,"nov":true,"dec":true,"day1":0,"month1":0,"day2":0,"month2":0,"day3":0,"month3":0,"day4":0,"month4":0,"day5":0,"month5":0,"d1":0,"w1":0,"d2":0,"w2":0,"d3":0,"w3":0,"d4":0,"w4":0,"d5":0,"w5":0,"suspend":false,"random":false,"repeat":true,"atstart":true,"x":420.5,"y":1009.5,"wires":[["135c087c.bbee78"],[],[]]},{"id":"4a67ced9.41aa9","type":"bigtimer","z":"429ff3e8.e7f3fc","outtopic":"terrarium/output/fans","outpayload1":"on","outpayload2":"off","name":"Fans","lat":"52","lon":"4","starttime":"435","endtime":"450","startoff":0,"endoff":0,"offs":0,"outtext1":"","outtext2":"","timeout":"1440","sun":true,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"jan":true,"feb":true,"mar":true,"apr":true,"may":true,"jun":true,"jul":true,"aug":true,"sep":true,"oct":true,"nov":true,"dec":true,"day1":0,"month1":0,"day2":0,"month2":0,"day3":0,"month3":0,"day4":0,"month4":0,"day5":0,"month5":0,"d1":0,"w1":0,"d2":0,"w2":0,"d3":0,"w3":0,"d4":0,"w4":0,"d5":0,"w5":0,"suspend":false,"random":false,"repeat":true,"atstart":false,"x":422.5,"y":1227.5,"wires":[["135c087c.bbee78"],[],[]]},{"id":"dbb60563.a8c008","type":"mqtt in","z":"429ff3e8.e7f3fc","name":"","topic":"terrarium/input/moonlight","qos":"2","broker":"1c2a9091.af757f","x":153,"y":744,"wires":[["739073de.ae8dfc"]]},{"id":"b45ce04a.256d8","type":"mqtt in","z":"429ff3e8.e7f3fc","name":"","topic":"terrarium/input/mister","qos":"2","broker":"1c2a9091.af757f","x":169,"y":1153,"wires":[["77e013ad.dfaa1c"]]},{"id":"fabb91cb.bbf89","type":"mqtt in","z":"429ff3e8.e7f3fc","name":"","topic":"terrarium/input/light1","qos":"2","broker":"1c2a9091.af757f","x":167,"y":813,"wires":[["71b7dfa7.23842"]]},{"id":"f09470a3.61bb9","type":"mqtt in","z":"429ff3e8.e7f3fc","name":"","topic":"terrarium/input/light2","qos":"2","broker":"1c2a9091.af757f","x":177,"y":878,"wires":[["6b925ce4.78fdf4"]]},{"id":"28914862.5143e8","type":"mqtt in","z":"429ff3e8.e7f3fc","name":"","topic":"terrarium/input/spot1","qos":"2","broker":"1c2a9091.af757f","x":159,"y":943,"wires":[["64003f47.8d64b"]]},{"id":"e6537d1b.6ecb9","type":"mqtt in","z":"429ff3e8.e7f3fc","name":"","topic":"terrarium/input/spot2","qos":"2","broker":"1c2a9091.af757f","x":161,"y":1009,"wires":[["3b3db576.469a7a"]]},{"id":"b0d9b396.0ccc5","type":"mqtt in","z":"429ff3e8.e7f3fc","name":"","topic":"terrarium/input/fans","qos":"2","broker":"1c2a9091.af757f","x":172,"y":1227,"wires":[["4a67ced9.41aa9"]]},{"id":"94a82059.23399","type":"mqtt in","z":"429ff3e8.e7f3fc","name":"","topic":"terrarium/output/+","qos":"2","broker":"60f8fb33.312b64","x":163.5,"y":1408,"wires":[["dbbd9102.5d01a"]]},{"id":"20614843.ebbd78","type":"bigtimer","z":"429ff3e8.e7f3fc","outtopic":"terrarium/output/waterfall","outpayload1":"on","outpayload2":"off","name":"Waterfall","lat":"52","lon":"4","starttime":"960","endtime":"1140","startoff":0,"endoff":0,"offs":0,"outtext1":"","outtext2":"","timeout":"1440","sun":true,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"jan":true,"feb":true,"mar":true,"apr":true,"may":true,"jun":true,"jul":true,"aug":true,"sep":true,"oct":true,"nov":true,"dec":true,"day1":0,"month1":0,"day2":0,"month2":0,"day3":0,"month3":0,"day4":0,"month4":0,"day5":0,"month5":0,"d1":0,"w1":0,"d2":0,"w2":0,"d3":0,"w3":0,"d4":0,"w4":0,"d5":0,"w5":0,"suspend":false,"random":false,"repeat":true,"atstart":true,"x":431,"y":1082,"wires":[["135c087c.bbee78"],[],[]]},{"id":"425668a1.64d6f8","type":"mqtt in","z":"429ff3e8.e7f3fc","name":"","topic":"terrarium/input/waterfall","qos":"2","broker":"1c2a9091.af757f","x":165,"y":1076,"wires":[["20614843.ebbd78"]]},{"id":"41f36ed4.9f44b","type":"comment","z":"429ff3e8.e7f3fc","name":"use the output to switch phyisical devices","info":"","x":232.5,"y":1356,"wires":[]},{"id":"dbbd9102.5d01a","type":"debug","z":"429ff3e8.e7f3fc","name":"","active":true,"console":"false","complete":"false","x":422.5,"y":1407,"wires":[]},{"id":"39a4899c.89cda6","type":"comment","z":"429ff3e8.e7f3fc","name":"Timers","info":"","x":94.5,"y":689,"wires":[]},{"id":"1c2a9091.af757f","type":"mqtt-broker","z":"","broker":"127.0.0.1","port":"1883","clientid":"nodered","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willPayload":"","birthTopic":"","birthQos":"0","birthPayload":""},{"id":"bb368a59.014048","type":"ui_group","z":"","name":"Buttons","tab":"60be2ae4.7f2bb4","disp":true,"width":"10"},{"id":"60f8fb33.312b64","type":"mqtt-broker","z":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"15","cleansession":true,"willTopic":"","willQos":"0","willPayload":"","birthTopic":"","birthQos":"0","birthPayload":""},{"id":"60be2ae4.7f2bb4","type":"ui_tab","z":"","name":"Buttons","icon":"dashboard"}]
corbosman

Flow Info

created 2 months, 2 weeks ago

Node Types

Core
  • comment (x7)
  • debug (x1)
  • delay (x1)
  • function (x5)
  • inject (x1)
  • json (x1)
  • mqtt in (x12)
  • mqtt out (x4)
  • mqtt-broker (x2)
Other
  • bigtimer (x8)
  • ui_group (x1)
  • ui_tab (x1)
  • ui_template (x1)

Tags

  • button
  • bigtimer
  • timer
  • terrarium
  • mqtt
  • state
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option