Edited to update the flow. It’s simpler and debugged. Still only supports one 4ch.
In case anyone gets here, I’ll add my solution. It’s a HA front-end with Node-RED doing the work. When a zone is selected from the drop down it queries the sonoff for its stored settings and updates the HA UI. As settings are changed their states are tracked and when the save toggle is clicked it gathers them all together and sends the MQTT commands to the sonoff.
There’s a lot going on. HA has to have all the inputs setup, but Node-RED does the actual talking to the sonoff. There is a noticeable delay when reading the settings out of the sonoff, but I’ll live with it.
[{“id”:“72f1bcae.a467f4”,“type”:“tab”,“label”:“Irrigation”,“disabled”:false,“info”:“”},{“id”:“776aecc8.bb5974”,“type”:“function”,“z”:“72f1bcae.a467f4”,“name”:“Build Strings”,“func”:“// build the MQTT string to send to the Tasmota device\n// there should always be on on and off timer\n//\n// set your MQTT path!\n//\n// example to turn on timer1 at 2:23 on Tues, Wed, Sat\n// Timer1 {"Arm":1,"Time":"02:23",Days":"–TW–S","Repeat":1,"Output":1,"Action":1}\n\n// build the payload with flow variables\nvar msg1 = { payload: "{\"Arm\":\"" + flow.get(‘armed’) + "\",\"Time\":\"" + flow.get(‘start’) + "\",\"Days\":\"" + flow.get(‘days’) +"\", \"Repeat\":\"1\",\"Output\":" + flow.get(‘zone’) +",\"Action\":\"1\"}" };\nvar msg2 = { payload: "{\"Arm\":\"" + flow.get(‘armed’) + "\",\"Time\":\"" + flow.get(‘end’) + "\",\"Days\":\"" + flow.get(‘days’) +"\", \"Repeat\":\"1\",\"Output\":" + flow.get(‘zone’) +",\"Action\":\"0\"}" };\nvar zone = flow.get(‘zone’);\n// build the topic (MQTT topic too) based on selected zone\nswitch (zone){\ncase 0:\n msg1.topic = ‘’;\n msg2.topic = ‘’;\n break;\ncase 1:\n msg1.topic = ‘cmnd/sonoff_garden_1/Timer1’;\n msg2.topic = ‘cmnd/sonoff_garden_1/Timer2’;\n break;\ncase 2:\n msg1.topic = ‘cmnd/sonoff_garden_1/Timer3’;\n msg2.topic = ‘cmnd/sonoff_garden_1/Timer4’;\n break;\ncase 3:\n msg1.topic = ‘cmnd/sonoff_garden_1/Timer5’;\n msg2.topic = ‘cmnd/sonoff_garden_1/Timer6’;\n break;\ncase 4:\n msg1.topic = ‘cmnd/sonoff_garden_1/Timer7’;\n msg2.topic = ‘cmnd/sonoff_garden_1/Timer8’;\n break;\n}\n\n// the third output is to trigger resetting the \n// zone selection, which will trigger reading \n// back from the Tasmota the settings\nmsg.payload = ‘on’;\nnode.status({text:‘zone:’+flow.get(‘zone’)});\nif (zone !== 0) return [msg1,msg2, msg];”,“outputs”:3,“noerr”:0,“x”:430,“y”:390,“wires”:[[“3e30b4aa.8c73ec”],[“3e30b4aa.8c73ec”],[“ce931c43.4359a”]]},{“id”:“15fa380f.215fc8”,“type”:“server-state-changed”,“z”:“72f1bcae.a467f4”,“name”:“Save Button”,“server”:“157fbb29.ba9835”,“entityidfilter”:“input_boolean.save_timer”,“entityidfiltertype”:“substring”,“haltifstate”:“off”,“x”:100,“y”:390,“wires”:[[“ab8fdfb.88d9c2”]]},{“id”:“5968c4f7.fa495c”,“type”:“function”,“z”:“72f1bcae.a467f4”,“name”:“days encoder”,“func”:“// encode seperate booleans into a string for \n// days to activate\n\n// get the flow variable and split it out\nvar week = flow.get(‘days’);\nvar sun=week.substr(0,1);\nvar mon=week.substr(1,1);\nvar tue=week.substr(2,1);\nvar wed=week.substr(3,1);\nvar thu=week.substr(4,1);\nvar fri=week.substr(5,1);\nvar sat=week.substr(6,1);\n\n// make updates based on user input\nif (msg.topic == ‘input_boolean.sunday’) {\n //sunday\n if (msg.payload == ‘on’) {sun=‘1’} else {sun=‘0’}\n} else if (msg.topic == ‘input_boolean.monday’) {\n //monday\n if (msg.payload == ‘on’) {mon=‘1’} else {mon=‘0’}\n} else if (msg.topic == ‘input_boolean.tuesday’) {\n //tuesday\n if (msg.payload == ‘on’) {tue=‘1’} else {tue=‘0’}\n} else if (msg.topic == ‘input_boolean.wednesday’) {\n //wednesday\n if (msg.payload == ‘on’) {wed=‘1’} else {wed=‘0’}\n} else if (msg.topic == ‘input_boolean.thursday’) {\n //thursday\n if (msg.payload == ‘on’) {thu=‘1’} else {thu=‘0’}\n} else if (msg.topic == ‘input_boolean.friday’) {\n //friday\n if (msg.payload == ‘on’) {fri=‘1’} else {fri=‘0’}\n} else if (msg.topic == ‘input_boolean.saturday’) {\n //saturday\n if (msg.payload == ‘on’) {sat=‘1’} else {sat=‘0’}\n}\n\n// recombine the string\nweek = sun+mon+tue+wed+thu+fri+sat;\nflow.set(‘days’,week);\n\nnode.status({text:flow.get(‘days’)});\nreturn msg;”,“outputs”:1,“noerr”:0,“x”:710,“y”:165,“wires”:[]},{“id”:“ab8fdfb.88d9c2”,“type”:“api-call-service”,“z”:“72f1bcae.a467f4”,“name”:“Clear Button”,“server”:“157fbb29.ba9835”,“service_domain”:“input_boolean”,“service”:“turn_off”,“data”:“{ "entity_id": "input_boolean.save_timer" }”,“mergecontext”:“”,“x”:265,“y”:390,“wires”:[[“776aecc8.bb5974”]]},{“id”:“3e30b4aa.8c73ec”,“type”:“mqtt out”,“z”:“72f1bcae.a467f4”,“name”:“Publish to MQTT”,“topic”:“”,“qos”:“2”,“retain”:“false”,“broker”:“940130c6.3f4e2”,“x”:735,“y”:435,“wires”:},{“id”:“f4614267.37f68”,“type”:“function”,“z”:“72f1bcae.a467f4”,“name”:“Select Timers”,“func”:“// send the MQTT command to read timer settings\n// from the Tasmota device\n//\n// set your MQTT path!\n//\nif (msg.payload == "Select") {\n flow.set(‘zone’, 0);\n} else {\n var msg1 = { payload: null };\n var msg2 = { payload: null};\n var zone = parseInt(msg.payload);\n\n flow.set(‘zone’, zone);\n\n switch (zone){\n case 1:\n msg1.topic = ‘cmnd/sonoff_garden_1/Timer1’;\n msg2.topic = ‘cmnd/sonoff_garden_1/Timer2’;\n break;\n case 2:\n msg1.topic = ‘cmnd/sonoff_garden_1/Timer3’;\n msg2.topic = ‘cmnd/sonoff_garden_1/Timer4’;\n break;\n case 3:\n msg1.topic = ‘cmnd/sonoff_garden_1/Timer5’;\n msg2.topic = ‘cmnd/sonoff_garden_1/Timer6’;\n break;\n case 4:\n msg1.topic = ‘cmnd/sonoff_garden_1/Timer7’;\n msg2.topic = ‘cmnd/sonoff_garden_1/Timer8’;\n break;\n }\n return [msg1, msg2];\n}\nnode.status({text:‘zone:’+msg.payload});\n”,“outputs”:2,“noerr”:0,“x”:485,“y”:465,“wires”:[[“3e30b4aa.8c73ec”],[“3e30b4aa.8c73ec”]]},{“id”:“d338acd7.85452”,“type”:“mqtt in”,“z”:“72f1bcae.a467f4”,“name”:“”,“topic”:“stat/sonoff_garden_1/+”,“qos”:“0”,“broker”:“940130c6.3f4e2”,“x”:130,“y”:45,“wires”:[[“3e1013a0.2fdedc”]]},{“id”:“82735e74.6983”,“type”:“server-state-changed”,“z”:“72f1bcae.a467f4”,“name”:“Zone”,“server”:“157fbb29.ba9835”,“entityidfilter”:“input_select.irrigation_zone”,“entityidfiltertype”:“substring”,“haltifstate”:“”,“x”:80,“y”:450,“wires”:[[“b0db5a30.2e9a88”]],“outputLabels”:[“?”]},{“id”:“aa69a80d.ffacd8”,“type”:“function”,“z”:“72f1bcae.a467f4”,“name”:“decoder”,“func”:“// extract the timer data and rebuild the UI\nvar timer1 = Object.values(msg.payload)[0];\nvar timer2 = Object.values(msg.payload)[1];\n\n// no zone selected\nif (flow.get(‘zone’) == ‘0’) {\n //set all msgs to off/0 and exit\n\t// clear all the boolean switches\n\tnode.send({payload: {data:{entity_id:"input_boolean.armed"},"domain":"input_boolean", service: "turn_off"}});\n\tnode.send({payload: {data:{entity_id:"input_boolean.sunday"},"domain":"input_boolean", service: "turn_off"}});\n\tnode.send({payload: {data:{entity_id:"input_boolean.monday"},"domain":"input_boolean", service: "turn_off"}});\n\tnode.send({payload: {data:{entity_id:"input_boolean.tuesday"},"domain":"input_boolean", service: "turn_off"}});\n\tnode.send({payload: {data:{entity_id:"input_boolean.wednesday"},"domain":"input_boolean", service: "turn_off"}});\n\tnode.send({payload: {data:{entity_id:"input_boolean.thursday"},"domain":"input_boolean", service: "turn_off"}});\n\tnode.send({payload: {data:{entity_id:"input_boolean.friday"},"domain":"input_boolean", service: "turn_off"}});\n\tnode.send({payload: {data:{entity_id:"input_boolean.saturday"},"domain":"input_boolean", service: "turn_off"}});\n\tnode.send({payload: {data:{entity_id:"input_boolean.saturday"},"domain":"input_boolean", service: "turn_off"}});\n\n\t// clear the sliders\n\tnode.send({payload: {data:{ "entity_id": "input_number.start_time_hour", "value":0 },domain:"input_number", service: "set_value"}});\n\tnode.send({payload: {data:{ "entity_id": "input_number.start_time_minute", "value":0 },domain:"input_number", service: "set_value"}});\n\tnode.send({payload: {data:{ "entity_id": "input_number.run_duration", "value":0 },domain:"input_number", service: "set_value"}});\n} else {\n// zones 1-4 selected\n // armed\n if (timer1.Arm == "1") {\n node.send({payload: {data:{entity_id:"input_boolean.armed"},"domain":"input_boolean", service: "turn_on"}});\n flow.set(‘armed’,1);\n } else {\n node.send({payload: {data:{entity_id:"input_boolean.armed"},"domain":"input_boolean", service: "turn_off"}});\n flow.set(‘armed’,0);\n }\n \n // set the flow variable for days to run\n flow.set(‘days’,timer1.Days); // store the entire week\n // Sunday\n if (timer1.Days.substr(0,1) != "0") {\n node.send({payload: {data:{entity_id:"input_boolean.sunday"},"domain":"input_boolean", service: "turn_on"}});\n } else {\n node.send({payload: {data:{entity_id:"input_boolean.sunday"},"domain":"input_boolean", service: "turn_off"}});\n }\n\n // Monday\n if (timer1.Days.substr(1,1) != "0") {\n node.send({payload: {data:{entity_id:"input_boolean.monday"},"domain":"input_boolean", service: "turn_on"}});\n } else {\n node.send({payload: {data:{entity_id:"input_boolean.monday"},"domain":"input_boolean", service: "turn_off"}});\n }\n\n // Tuesday\n if (timer1.Days.substr(2,1) != "0") {\n node.send({payload: {data:{entity_id:"input_boolean.tuesday"},"domain":"input_boolean", service: "turn_on"}});\n } else {\n node.send({payload: {data:{entity_id:"input_boolean.tuesday"},"domain":"input_boolean", service: "turn_off"}});\n }\n\n // Wednesday\n if (timer1.Days.substr(3,1) != "0") {\n node.send({payload: {data:{entity_id:"input_boolean.wednesday"},"domain":"input_boolean", service: "turn_on"}});\n } else {\n node.send({payload: {data:{entity_id:"input_boolean.wednesday"},"domain":"input_boolean", service: "turn_off"}});\n }\n\n // Thrusday\n if (timer1.Days.substr(4,1) != "0") {\n node.send({payload: {data:{entity_id:"input_boolean.thursday"},"domain":"input_boolean", service: "turn_on"}});\n } else {\n node.send({payload: {data:{entity_id:"input_boolean.thursday"},"domain":"input_boolean", service: "turn_off"}});\n }\n\n // Friday\n if (timer1.Days.substr(5,1) != "0") {\n node.send({payload: {data:{entity_id:"input_boolean.friday"},"domain":"input_boolean", service: "turn_on"}});\n } else {\n node.send({payload: {data:{entity_id:"input_boolean.friday"},"domain":"input_boolean", service: "turn_off"}});\n }\n\n // Saturday\n if (timer1.Days.substr(6,1) != "0") {\n node.send({payload: {data:{entity_id:"input_boolean.saturday"},"domain":"input_boolean", service: "turn_on"}});\n } else {\n node.send({payload: {data:{entity_id:"input_boolean.saturday"},"domain":"input_boolean", service: "turn_off"}});\n }\n\n // get the start time\n var start_hour = parseInt(timer1.Time.substr(0,2));\n var start_min = parseInt(timer1.Time.substr(3,2));\n //node.warn(‘start1=’+start_hour+‘:’+start_min); \n \n // format payload for start hour and minute\n node.send({payload: {data:{"entity_id":"input_number.start_time_hour", "value": start_hour},"domain":"input_number", service: "set_value"}});\n node.send({payload: {data:{"entity_id":"input_number.start_time_minute", "value": start_min},"domain":"input_number", service: "set_value"}});\n \n // set the flow variables, add leading 0 padding \n if (start_hour < 10) { start_hour=‘0’+start_hour; }\n if (start_min < 10) { start_min=‘0’+start_min; }\n flow.set(‘hour’,start_hour); // store the hour\n flow.set(‘minute’,start_min); // store the minute\n flow.set(‘start’, start_hour+‘:’+start_min);\n\n // get the end time\n var end_hour = timer2.Time.substr(0,2);\n var end_min = timer2.Time.substr(3,2);\n flow.set(‘end’,end_hour+‘:’+end_min);\n //node.warn(‘end=’+end_hour+‘:’+end_min); \n \n // calculate the duration. Works for any number of minutes, doesn’t work across days\n var dur_hour = parseInt(end_hour) - parseInt(start_hour);\n var dur_min = parseInt(end_min) - parseInt(start_min) + (60 * dur_hour);\n flow.set(‘duration’,dur_min);\n \n node.send({payload: {data:{"entity_id":"input_number.run_duration", "value": dur_min},"domain":"input_number", service: "set_value"}});\n}\n\nnode.status({text:‘zone:’+flow.get(‘zone’)+’ armed:‘+flow.get(‘armed’)+’ days:‘+flow.get(‘days’)+ ’ start:’+flow.get(‘start’)+’ end:'+flow.get(‘end’)});\n//return [msg0,msg1,msg2,msg3,msg4,msg5,msg6,msg7,msg8,msg9,msg10];”,“outputs”:1,“noerr”:0,“x”:120,“y”:225,“wires”:[[“3bab667f.cc680a”]]},{“id”:“4fb87809.bbb2d8”,“type”:“json”,“z”:“72f1bcae.a467f4”,“name”:“Make Obj”,“property”:“payload”,“action”:“obj”,“pretty”:false,“x”:120,“y”:135,“wires”:[[“e1b2979d.1a2688”]]},{“id”:“e1b2979d.1a2688”,“type”:“join”,“z”:“72f1bcae.a467f4”,“name”:“combine”,“mode”:“custom”,“build”:“merged”,“property”:“payload”,“propertyType”:“msg”,“key”:“topic”,“joiner”:“\n”,“joinerType”:“str”,“accumulate”:false,“timeout”:“”,“count”:“2”,“reduceRight”:false,“reduceExp”:“”,“reduceInit”:“”,“reduceInitType”:“”,“reduceFixup”:“”,“x”:120,“y”:180,“wires”:[[“aa69a80d.ffacd8”]]},{“id”:“3e1013a0.2fdedc”,“type”:“function”,“z”:“72f1bcae.a467f4”,“name”:“Filter”,“func”:“// only pass along messages that have ‘Timer’ in the\n// payload. This is to filter only the relevant \n// timer data\nif (msg.payload.search(‘Timer’) != -1) {return msg}\nelse {return null}\n”,“outputs”:1,“noerr”:0,“x”:125,“y”:90,“wires”:[[“4fb87809.bbb2d8”]]},{“id”:“207b42d7.1a9b3e”,“type”:“api-call-service”,“z”:“72f1bcae.a467f4”,“name”:“Clear Inputs”,“server”:“157fbb29.ba9835”,“service_domain”:“”,“service”:“”,“data”:“”,“mergecontext”:“”,“x”:835,“y”:390,“wires”:[]},{“id”:“3bab667f.cc680a”,“type”:“api-call-service”,“z”:“72f1bcae.a467f4”,“name”:“Set values”,“server”:“157fbb29.ba9835”,“service_domain”:“”,“service”:“”,“data”:“”,“mergecontext”:“”,“x”:130,“y”:285,“wires”:[]},{“id”:“b69e90c6.22d75”,“type”:“function”,“z”:“72f1bcae.a467f4”,“name”:“Store ‘arm’”,“func”:“// setup the ‘armed’ boolean\nif (msg.payload == ‘on’) {\n flow.set(‘armed’,1);\n} else {\n flow.set(‘armed’,0);\n}\nnode.status({text:flow.get(‘armed’)});\nreturn msg;”,“outputs”:1,“noerr”:0,“x”:865,“y”:75,“wires”:[]},{“id”:“63e8e488.23aa2c”,“type”:“server-state-changed”,“z”:“72f1bcae.a467f4”,“name”:“Armed”,“server”:“157fbb29.ba9835”,“entityidfilter”:“input_boolean.armed”,“entityidfiltertype”:“substring”,“haltifstate”:“null”,“x”:680,“y”:75,“wires”:[[“b69e90c6.22d75”]],“outputLabels”:[“?”]},{“id”:“70386c41.b85394”,“type”:“server-state-changed”,“z”:“72f1bcae.a467f4”,“name”:“Sun”,“server”:“157fbb29.ba9835”,“entityidfilter”:“input_boolean.sunday”,“entityidfiltertype”:“substring”,“haltifstate”:“null”,“x”:500,“y”:45,“wires”:[[“5968c4f7.fa495c”]],“outputLabels”:[“?”]},{“id”:“b8a9cf1e.f3b6f”,“type”:“server-state-changed”,“z”:“72f1bcae.a467f4”,“name”:“Tues”,“server”:“157fbb29.ba9835”,“entityidfilter”:“input_boolean.tuesday”,“entityidfiltertype”:“substring”,“haltifstate”:“null”,“x”:500,“y”:135,“wires”:[[“5968c4f7.fa495c”]],“outputLabels”:[“?”]},{“id”:“fb6477b4.0fdbf8”,“type”:“server-state-changed”,“z”:“72f1bcae.a467f4”,“name”:“Wed”,“server”:“157fbb29.ba9835”,“entityidfilter”:“input_boolean.wednesday”,“entityidfiltertype”:“substring”,“haltifstate”:“null”,“x”:500,“y”:180,“wires”:[[“5968c4f7.fa495c”]],“outputLabels”:[“?”]},{“id”:“e7ff1abf.727948”,“type”:“server-state-changed”,“z”:“72f1bcae.a467f4”,“name”:“Thu”,“server”:“157fbb29.ba9835”,“entityidfilter”:“input_boolean.thursday”,“entityidfiltertype”:“substring”,“haltifstate”:“null”,“x”:500,“y”:225,“wires”:[[“5968c4f7.fa495c”]],“outputLabels”:[“?”]},{“id”:“2eb1d94d.ede0f6”,“type”:“server-state-changed”,“z”:“72f1bcae.a467f4”,“name”:“Fri”,“server”:“157fbb29.ba9835”,“entityidfilter”:“input_boolean.friday”,“entityidfiltertype”:“substring”,“haltifstate”:“null”,“x”:500,“y”:270,“wires”:[[“5968c4f7.fa495c”]],“outputLabels”:[“?”]},{“id”:“a478a6bc.d2bfe8”,“type”:“server-state-changed”,“z”:“72f1bcae.a467f4”,“name”:“Sat”,“server”:“157fbb29.ba9835”,“entityidfilter”:“input_boolean.saturday”,“entityidfiltertype”:“substring”,“haltifstate”:“null”,“x”:500,“y”:315,“wires”:[[“5968c4f7.fa495c”]],“outputLabels”:[“?”]},{“id”:“c5a7417d.1a0be”,“type”:“server-state-changed”,“z”:“72f1bcae.a467f4”,“name”:“Mon”,“server”:“157fbb29.ba9835”,“entityidfilter”:“input_boolean.monday”,“entityidfiltertype”:“substring”,“haltifstate”:“null”,“x”:500,“y”:90,“wires”:[[“5968c4f7.fa495c”]],“outputLabels”:[“?”]},{“id”:“f168803d.26072”,“type”:“function”,“z”:“72f1bcae.a467f4”,“name”:“time encoder”,“func”:“// read in the flow variables\nvar start = flow.get(‘start’);\nvar hour = flow.get(‘hour’);\nvar minute = flow.get(‘minute’);\nvar end = flow.get(‘end’);\nvar duration = flow.get(‘duration’);\n\n// extract the value to be updated\nif (msg.topic == ‘input_number.start_time_hour’) {\n hour = parseInt(msg.payload);\n if (hour < 10) {hour = ‘0’+hour}\n} \nif (msg.topic == ‘input_number.start_time_minute’) {\n minute = parseInt(msg.payload);\n if (minute < 10){minute = ‘0’+minute}\n}\nif (msg.topic == ‘input_number.run_duration’) {\n duration = parseInt(msg.payload);\n}\n\n// setup the new flow variables\nflow.set(‘hour’, hour);\nflow.set(‘minute’, minute);\nflow.set(‘start’,hour+‘:’+minute);\nflow.set(‘duration’,duration);\n\n// calculate the end time based on the duration\nvar endMin = parseInt(flow.get(‘minute’)) + parseInt(duration);\nvar endHr = parseInt(flow.get(‘hour’));\nendHr = parseInt(endHr + parseInt(endMin/60));\nendMin = parseInt(endMin - 60parseInt(endMin/60));\n//node.warn(‘endMin=’+endMin);\n//node.warn(‘endHr=’+endHr);\n\n// add padding\nif (endMin < 10){ endMin = "0" + endMin}\nif (endHr < 10){ endHr = "0" + endHr}\nflow.set(‘end’,endHr + ":" + endMin);\n\nnode.status({text:‘{start:’+flow.get(‘start’)+‘} {end:’+flow.get(‘end’)+‘}’});\nreturn msg;“,“outputs”:1,“noerr”:0,“x”:895,“y”:285,“wires”:[[]]},{“id”:“37ef85fa.984f4a”,“type”:“server-state-changed”,“z”:“72f1bcae.a467f4”,“name”:“Duration”,“server”:“157fbb29.ba9835”,“entityidfilter”:“input_number.run_duration”,“entityidfiltertype”:“substring”,“haltifstate”:“null”,“x”:690,“y”:330,“wires”:[[“f168803d.26072”]],“outputLabels”:[”?“]},{“id”:“9197e9b.4390218”,“type”:“server-state-changed”,“z”:“72f1bcae.a467f4”,“name”:“Start Minute”,“server”:“157fbb29.ba9835”,“entityidfilter”:“input_number.start_time_minute”,“entityidfiltertype”:“substring”,“haltifstate”:“null”,“x”:700,“y”:285,“wires”:[[“f168803d.26072”]],“outputLabels”:[”?“]},{“id”:“494ab671.5611c8”,“type”:“server-state-changed”,“z”:“72f1bcae.a467f4”,“name”:“Start Hour”,“server”:“157fbb29.ba9835”,“entityidfilter”:“input_number.start_time_hour”,“entityidfiltertype”:“substring”,“haltifstate”:“null”,“x”:690,“y”:240,“wires”:[[“f168803d.26072”]],“outputLabels”:[”?“]},{“id”:“ce931c43.4359a”,“type”:“function”,“z”:“72f1bcae.a467f4”,“name”:“clear”,“func”:”// clear all the boolean switches\nnode.send({payload: {data:{entity_id:"input_boolean.armed"},"domain":"input_boolean", service: "turn_off"}});\nnode.send({payload: {data:{entity_id:"input_boolean.sunday"},"domain":"input_boolean", service: "turn_off"}});\nnode.send({payload: {data:{entity_id:"input_boolean.monday"},"domain":"input_boolean", service: "turn_off"}});\nnode.send({payload: {data:{entity_id:"input_boolean.tuesday"},"domain":"input_boolean", service: "turn_off"}});\nnode.send({payload: {data:{entity_id:"input_boolean.wednesday"},"domain":"input_boolean", service: "turn_off"}});\nnode.send({payload: {data:{entity_id:"input_boolean.thursday"},"domain":"input_boolean", service: "turn_off"}});\nnode.send({payload: {data:{entity_id:"input_boolean.friday"},"domain":"input_boolean", service: "turn_off"}});\nnode.send({payload: {data:{entity_id:"input_boolean.saturday"},"domain":"input_boolean", service: "turn_off"}});\nnode.send({payload: {data:{entity_id:"input_boolean.saturday"},"domain":"input_boolean", service: "turn_off"}});\n\n// clear the input selection\nnode.send({payload: {data:{ "entity_id": "input_select.irrigation_zone", "option":"Select" },domain:"input_select", service: "select_option"}});\n\n// clear the sliders\nnode.send({payload: {data:{ "entity_id": "input_number.start_time_hour", "value":0 },domain:"input_number", service: "set_value"}});\nnode.send({payload: {data:{ "entity_id": "input_number.start_time_minute", "value":0 },domain:"input_number", service: "set_value"}});\nnode.send({payload: {data:{ "entity_id": "input_number.run_duration", "value":0 },domain:"input_number", service: "set_value"}});\n\n",“outputs”:1,“noerr”:0,“x”:695,“y”:390,“wires”:[[“207b42d7.1a9b3e”]]},{“id”:“80b83e2.5b612c”,“type”:“comment”,“z”:“72f1bcae.a467f4”,“name”:“Setup instructions”,“info”:"Setup your HA I/O in:\n the HA input nodes\n* the HA output nodes\n\nSetup your MQTT server in:\n* the MQTT input node\n* the Publish to MQTT output node\n\nSet your MQTT path in :\n* the MQTT input node\n* the Build Strings function node\n* the Select Timers function node\n”,“x”:345,“y”:90,“wires”:},{“id”:“63b8f367.34910c”,“type”:“comment”,“z”:“72f1bcae.a467f4”,“name”:“HA groups config”,“info”:“garden:\n view: no\n control: hidden\n name: "Garden Irrigation"\n icon: ‘mdi:flower’\n entities:\n - switch.garden1_zone_1\n - switch.garden1_zone_2\n - switch.garden1_zone_3\n - switch.garden1_zone_4\n - group.timer_settings\n\n\ntimer_settings:\n view: no\n control: hidden\n name: "Zone Settings"\n icon: mdi:settings\n entities:\n - input_select.irrigation_zone\n - input_boolean.armed\n - input_boolean.sunday\n - input_boolean.monday\n - input_boolean.tuesday\n - input_boolean.wednesday\n - input_boolean.thursday\n - input_boolean.friday\n - input_boolean.saturday\n - input_number.start_time_hour\n - input_number.start_time_minute\n - input_number.run_duration\n - input_boolean.save_timer”,“x”:335,“y”:135,“wires”:},{“id”:“2e7e3696.fdc50a”,“type”:“comment”,“z”:“72f1bcae.a467f4”,“name”:“HA inputs”,“info”:“# input_select.yaml\nirrigation_zone:\n name: "Select Zone:"\n icon: mdi:arrange-bring-to-front\n options:\n - Select\n - 1\n - 2\n - 3\n - 4\n initial: Select\n\n#input_boolean.yaml \n armed:\n name: Armed\n icon: mdi:alarm-light\n initial: off\n sunday:\n name: Sunday\n icon: mdi:calendar\n initial: off\n monday:\n name: Monday\n icon: mdi:calendar\n initial: off\n tuesday:\n name: Tuesday\n icon: mdi:calendar\n initial: off\n wednesday:\n name: Wednesday\n icon: mdi:calendar\n initial: off\n thursday:\n name: Thursday\n icon: mdi:calendar\n initial: off\n friday:\n name: Friday\n icon: mdi:calendar\n initial: off\n saturday:\n name: Saturday\n icon: mdi:calendar\n initial: off\n save_timer:\n name: Save Settings\n initial: off\n icon: mdi:lock-reset\n\n\n\n#input_number.yaml \nstart_time_hour:\n name: "Hour"\n initial: 0\n min: 0\n max: 23\n step: 1\n icon: mdi:timer\nstart_time_minute:\n name: "Minute"\n initial: 0\n min: 0\n max: 55\n step: 5\n icon: mdi:timer\nrun_duration:\n name: "Duration"\n initial: 30\n min: 0\n max: 120\n step: 2\n icon: mdi:timer”,“x”:315,“y”:180,“wires”:},{“id”:“b0db5a30.2e9a88”,“type”:“switch”,“z”:“72f1bcae.a467f4”,“name”:“Select”,“property”:“payload”,“propertyType”:“msg”,“rules”:[{“t”:“eq”,“v”:“Select”,“vt”:“str”},{“t”:“else”}],“checkall”:“true”,“repair”:false,“outputs”:2,“x”:290,“y”:450,“wires”:[[“ce931c43.4359a”],[“f4614267.37f68”]]},{“id”:“157fbb29.ba9835”,“type”:“server”,“z”:“”,“name”:“Home Assistant”,“url”:“http://hassio/homeassistant",“pass”:“”},{“id”:“940130c6.3f4e2”,“type”:“mqtt-broker”,“z”:“”,“name”:“Mesquito”,“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”:"”}]