Hi Tom,
I was so impressed with that interface I extended the automations into Node-red and made some slight adjustments to some of the templating. Dropping back here in case someone is grappling with this in the future. There are probably better more effective ways of doing this in NR as I am still learning.
My flow for a zone is below in case it is useful to anyone else:
[{"id":"ab233bbf.7445b8","type":"trigger-state","z":"eab90dac.1ba15","name":"Zone 2 Time Trigger","server":"5d9df51f.c01a5c","entityid":"sensor.time","entityidfiltertype":"exact","debugenabled":false,"constraints":[],"constraintsmustmatch":"all","outputs":2,"customoutputs":[],"outputinitially":false,"state_type":"str","x":120,"y":900,"wires":[["bb6f30af.b8829","5621b69c.500148","3fbead61.900232"],[]]},{"id":"8548ae7.661095","type":"api-render-template","z":"eab90dac.1ba15","name":"Is Zone 2 active today","server":"5d9df51f.c01a5c","template":"{% if is_state(\"binary_sensor.zone_2_day_active\", \"on\") %}on\n{%-else %} off {% endif %}","resultsLocation":"payload","resultsLocationType":"msg","templateLocation":"","templateLocationType":"none","x":390,"y":707,"wires":[["b602c9e9.36ab78"]]},{"id":"19770f74.e86811","type":"trigger-state","z":"eab90dac.1ba15","name":"Midnight Arrives","server":"5d9df51f.c01a5c","entityid":"sensor.date","entityidfiltertype":"exact","debugenabled":false,"constraints":[],"constraintsmustmatch":"all","outputs":2,"customoutputs":[],"outputinitially":true,"state_type":"str","x":90,"y":747,"wires":[["993cc97.da44338","8548ae7.661095"],[]]},{"id":"5b03b094.e5777","type":"api-render-template","z":"eab90dac.1ba15","name":"Start Time","server":"5d9df51f.c01a5c","template":"{% if states('sensor.time') == states('input_datetime.zone_2_am_on_time').rsplit(':',1)[0] %}on\n{%-else %} off {% endif %}","resultsLocation":"payload","resultsLocationType":"msg","templateLocation":"","templateLocationType":"none","x":670,"y":920,"wires":[["1fc3136f.ed2d0d"]]},{"id":"b602c9e9.36ab78","type":"switch","z":"eab90dac.1ba15","name":"block off","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":570,"y":667,"wires":[["f4e0c833.ceaef8"]]},{"id":"f4e0c833.ceaef8","type":"change","z":"eab90dac.1ba15","name":"Enable sensor.time","rules":[{"t":"set","p":"payload","pt":"msg","to":"enable","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":740,"y":667,"wires":[["ab233bbf.7445b8"]]},{"id":"993cc97.da44338","type":"change","z":"eab90dac.1ba15","name":"Disable sensor.time","rules":[{"t":"set","p":"payload","pt":"msg","to":"disable","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":807,"wires":[["ab233bbf.7445b8"]]},{"id":"1592afd2.ae18e","type":"trigger-state","z":"eab90dac.1ba15","name":"Zone 2 Becomes Active","server":"5d9df51f.c01a5c","entityid":"binary_sensor.zone_2_day_active","entityidfiltertype":"exact","debugenabled":false,"constraints":[{"id":"kbvbtxf5trq","targetType":"this_entity","targetValue":"","propertyType":"previous_state","propertyValue":"old_state.state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"off"}],"constraintsmustmatch":"all","outputs":2,"customoutputs":[],"outputinitially":true,"state_type":"str","x":120,"y":807,"wires":[["993cc97.da44338","8548ae7.661095"],[]]},{"id":"f94411ca.91b5","type":"api-call-service","z":"eab90dac.1ba15","name":"Zone 2 Turn on","server":"5d9df51f.c01a5c","version":1,"service_domain":"switch","service":"turn_on","entityId":"switch.garden_sprinklers_zone_2","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":1400,"y":940,"wires":[[]]},{"id":"bb6f30af.b8829","type":"api-current-state","z":"eab90dac.1ba15","name":"Sprinklers Running?","server":"5d9df51f.c01a5c","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"switch.garden_sprinklers_zone_2","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":360,"y":860,"wires":[["876bb58a.f9ffe8"],[]]},{"id":"876bb58a.f9ffe8","type":"api-render-template","z":"eab90dac.1ba15","name":"Remaining Time = 0","server":"5d9df51f.c01a5c","template":"{% if states('sensor.zone_2_time_remaining')|round(0) > 0 %}on\n{%-else %} off {% endif %}","resultsLocation":"payload","resultsLocationType":"msg","templateLocation":"","templateLocationType":"none","x":600,"y":860,"wires":[["4f9468f3.42b9d8"]]},{"id":"b1b6e11b.b33d5","type":"api-call-service","z":"eab90dac.1ba15","name":"Zone 2 Turn off","server":"5d9df51f.c01a5c","version":1,"service_domain":"switch","service":"turn_off","entityId":"switch.garden_sprinklers_zone_2","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":1020,"y":860,"wires":[[]]},{"id":"4f9468f3.42b9d8","type":"switch","z":"eab90dac.1ba15","name":"block on","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"off","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":800,"y":860,"wires":[["b1b6e11b.b33d5"]]},{"id":"5b6fc169.2c4b4","type":"trigger-state","z":"eab90dac.1ba15","name":"Manual Activation","server":"5d9df51f.c01a5c","entityid":"switch.garden_sprinklers_zone_2","entityidfiltertype":"exact","debugenabled":false,"constraints":[{"id":"1f0y0109b8t","targetType":"this_entity","targetValue":"","propertyType":"previous_state","propertyValue":"old_state.state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"off"}],"constraintsmustmatch":"all","outputs":2,"customoutputs":[],"outputinitially":false,"state_type":"str","x":100,"y":707,"wires":[["409d6b9f.362fb4","993cc97.da44338"],[]]},{"id":"409d6b9f.362fb4","type":"api-render-template","z":"eab90dac.1ba15","name":"Check how activated","server":"5d9df51f.c01a5c","template":"{% if states('sensor.time') != states('input_datetime.zone_2_am_on_time').rsplit(':',1)[0] %}on\n{%-else %} off {% endif %}","resultsLocation":"payload","resultsLocationType":"msg","templateLocation":"","templateLocationType":"none","x":390,"y":647,"wires":[["b602c9e9.36ab78"]]},{"id":"5621b69c.500148","type":"api-render-template","z":"eab90dac.1ba15","name":"AM Scheduled?","server":"5d9df51f.c01a5c","template":"{% if states('input_boolean.zone_2_am_enable_schedule') == 'on' %}on\n{%-else %} off {% endif %}","resultsLocation":"payload","resultsLocationType":"msg","templateLocation":"","templateLocationType":"none","x":340,"y":920,"wires":[["37d8b24b.097a1e"]]},{"id":"17ffc403.6e24cc","type":"comment","z":"eab90dac.1ba15","name":"Zone 2","info":"","x":60,"y":667,"wires":[]},{"id":"2d46bf31.1fe21","type":"api-render-template","z":"eab90dac.1ba15","name":"Start Time","server":"5d9df51f.c01a5c","template":"{% if states('sensor.time') == states('input_datetime.zone_2_pm_on_time').rsplit(':',1)[0] %}on\n{%-else %} off {% endif %}","resultsLocation":"payload","resultsLocationType":"msg","templateLocation":"","templateLocationType":"none","x":670,"y":980,"wires":[["1fc3136f.ed2d0d"]]},{"id":"3fbead61.900232","type":"api-render-template","z":"eab90dac.1ba15","name":"PM Scheduled?","server":"5d9df51f.c01a5c","template":"{% if states('input_boolean.zone_2_pm_enable_schedule') == 'on' %}on\n{%-else %} off {% endif %}","resultsLocation":"payload","resultsLocationType":"msg","templateLocation":"","templateLocationType":"none","x":340,"y":980,"wires":[["a435c159.037ed"]]},{"id":"37d8b24b.097a1e","type":"switch","z":"eab90dac.1ba15","name":"block off","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":500,"y":920,"wires":[["5b03b094.e5777"]]},{"id":"a435c159.037ed","type":"switch","z":"eab90dac.1ba15","name":"block off","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":500,"y":980,"wires":[["2d46bf31.1fe21"]]},{"id":"dcfb829e.50752","type":"switch","z":"eab90dac.1ba15","name":"block off","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":1240,"y":940,"wires":[["f94411ca.91b5"]]},{"id":"36d2c0e3.2707e","type":"api-render-template","z":"eab90dac.1ba15","name":"Weather check","server":"5d9df51f.c01a5c","template":"{% if states('sensor.bom_brisbane_rain_today')|float < states('input_number.rain_limit')|float and\nstates('sensor.predict_rain_today')|float < states('input_number.rain_limit')|float and\nstate_attr('sensor.rain_in_last_48h' , 'max_value')|int < 30 %}on\n{%-else %} off {% endif %}","resultsLocation":"payload","resultsLocationType":"msg","templateLocation":"","templateLocationType":"none","x":1053,"y":940,"wires":[["dcfb829e.50752"]]},{"id":"1fc3136f.ed2d0d","type":"switch","z":"eab90dac.1ba15","name":"block off","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":870,"y":940,"wires":[["36d2c0e3.2707e"]]},{"id":"5d9df51f.c01a5c","type":"server","z":"","name":"Home Assistant","legacy":false,"hassio":false,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true}]
My full config is below (It contains 2 zones - The NR flow only contains Zone 2):
#################################################################
# #
# Packages/Garden Reticulation #
# #
#################################################################
#################################################################
# #
# This is a full reticulation control package using BOM #
# weather prediction to prevent watering if rain is expected, #
# or occured recently with local moisture sensor data as well #
# #
#################################################################
switch:
- platform: mqtt
name: "Garden Sprinklers Zone 1"
command_topic: "house/driveway/side-garden/cmnd/power1"
state_topic: "house/driveway/side-garden/stat/POWER1"
qos: 1
payload_on: "ON"
payload_off: "OFF"
retain: false
- platform: mqtt
name: "Garden Sprinklers Zone 2"
command_topic: "house/driveway/side-garden/cmnd/power2"
state_topic: "house/driveway/side-garden/stat/POWER2"
qos: 1
payload_on: "ON"
payload_off: "OFF"
retain: false
- platform: mqtt
name: "Side Garden Lights"
command_topic: "house/driveway/side-garden/cmnd/power3"
state_topic: "house/driveway/side-garden/stat/POWER3"
qos: 1
payload_on: "ON"
payload_off: "OFF"
retain: false
#################################################################
# #
# Zone 1 = Front Lawn Zone 2 = Side Garden #
# #
#################################################################
#################################################################
# #
# Is today a Sprinkler Day? #
# #
#################################################################
binary_sensor:
- platform: template
sensors:
zone_1_day_active:
friendly_name: Irrigation Day Active
entity_id:
- sensor.date
- input_boolestatisan.zone_1_am_enable_schedule
- input_boolean.zone_1_pm_enable_schedule
- input_boolean.zone_1_mon
- input_boolean.zone_1_tue
- input_boolean.zone_1_wed
- input_boolean.zone_1_thu
- input_boolean.zone_1_fri
- input_boolean.zone_1_sat
- input_boolean.zone_1_sun
value_template: >-
{{ (is_state('input_boolean.zone_1_am_enable_schedule', 'on')
or is_state('input_boolean.zone_1_pm_enable_schedule', 'on'))
and (( is_state('input_boolean.zone_1_mon', 'on') and now().weekday() == 0 )
or ( is_state('input_boolean.zone_1_tue', 'on') and now().weekday() == 1 )
or ( is_state('input_boolean.zone_1_wed', 'on') and now().weekday() == 2 )
or ( is_state('input_boolean.zone_1_thu', 'on') and now().weekday() == 3 )
or ( is_state('input_boolean.zone_1_fri', 'on') and now().weekday() == 4 )
or ( is_state('input_boolean.zone_1_sat', 'on') and now().weekday() == 5 )
or ( is_state('input_boolean.zone_1_sun', 'on') and now().weekday() == 6 )) }}
- platform: template
sensors:
zone_2_day_active:
friendly_name: Irrigation Day Active
entity_id:
- sensor.date
- input_boolean.zone_2_am_enable_schedule
- input_boolean.zone_2_pm_enable_schedule
- input_boolean.zone_2_mon
- input_boolean.zone_2_tue
- input_boolean.zone_2_wed
- input_sboolean.zone_2_thu
- input_boolean.zone_2_fri
- input_boolean.zone_2_sat
- input_boolean.zone_2_sun
value_template: >-
{{ (is_state('input_boolean.zone_2_am_enable_schedule', 'on')
or is_state('input_boolean.zone_2_pm_enable_schedule', 'on'))
and (( is_state('input_boolean.zone_2_mon', 'on') and now().weekday() == 0 )
or ( is_state('input_boolean.zone_2_tue', 'on') and now().weekday() == 1 )
or ( is_state('input_boolean.zone_2_wed', 'on') and now().weekday() == 2 )
or ( is_state('input_boolean.zone_2_thu', 'on') and now().weekday() == 3 )
or ( is_state('input_boolean.zone_2_fri', 'on') and now().weekday() == 4 )
or ( is_state('input_boolean.zone_2_sat', 'on') and now().weekday() == 5 )
or ( is_state('input_boolean.zone_2_sun', 'on') and now().weekday() == 6 )) }}
#################################################################
# #
# Countdown timer from when Sprinklers start #
# #
#################################################################
sensor:
# Used to pull a max_value from the statistics sensor
# Refer: https://www.home-assistant.io/integrations/statistics/
# The max_value is templated into a sensor. See 48hour_rain_figure below
- platform: statistics
name: Rain in last 48h
entity_id: sensor.bom_brisbane_rain_today
max_age:
days: 2
- platform: template
sensors:
zone_1_time_remaining:
friendly_name: 'Time Remaining'
entity_id:
- input_number.zone_1_run_time
- sensor.time
- switch.garden_sprinklers_zone_1
#Check if the zone switch is on or off before providing the number
value_template: >
{% if is_state("switch.garden_sprinklers_zone_1", "off") %} 0
{% else %}
{% set countdown_timer = [ (states('input_number.zone_1_run_time') | int - (as_timestamp(now()) - as_timestamp(states.switch.garden_sprinklers_zone_1.last_changed)) / 60) | round(0) ,0 ] | max %} {{ countdown_timer }}
{% endif %}
unit_of_measurement: "min"
zone_2_time_remaining:
friendly_name: 'Time Remaining'
entity_id:
- input_number.zone_2_run_time
- sensor.time
- switch.garden_sprinklers_zone_2
value_template: >
{% if is_state("switch.garden_sprinklers_zone_2", "off") %} 0
{% else %}
{% set countdown_timer = [ (states('input_number.zone_2_run_time') | int - (as_timestamp(now()) - as_timestamp(states.switch.garden_sprinklers_zone_2.last_changed)) / 60) | round(0) ,0 ] | max %} {{ countdown_timer }}
{% endif %}
unit_of_measurement: "min"
#################################################################
# #
# All Zones - Weather Forecasting #
# #
#################################################################
predict_rain_today:
friendly_name: 'Predicted Rain Today'
entity_id:
- sensor.bom_brisbane_forecast_chance_of_rain_0 # always a single int
- sensor.bom_brisbane_forecast_possible_rainfall_0 # two formats. Single int or "int_1 to int_2" e.g. "3 to 4"
unit_of_measurement: mm
value_template: >
{% set chance = states('sensor.bom_brisbane_forecast_chance_of_rain_0')|int /100 %}
{% if 'to' in states('sensor.bom_brisbane_forecast_possible_rainfall_0') %}
{% set amount = states('sensor.bom_brisbane_forecast_possible_rainfall_0').split(' to ') %}
{% set amount1 = amount[0] | float %}
{% set amount2 = amount[1] | float %}
{% set amount_avg = (amount1 + amount2) / 2 %}
{% else %}
{% set amount_avg = states('sensor.bom_brisbane_forecast_possible_rainfall_0') | int %}
{% endif %}
{{ (chance * amount_avg)|round(1) }}
predict_rain_tomorrow:
friendly_name: 'Predicted Rain Tomorrow'
entity_id:
- sensor.bom_brisbane_forecast_chance_of_rain_1 # always a single int
- sensor.bom_brisbane_forecast_possible_rainfall_1 # two formats. Single int or "int_1 to int_2" e.g. "3 to 4"
unit_of_measurement: mm
value_template: >
{% set chance = states('sensor.bom_brisbane_forecast_chance_of_rain_1')|int / 100 %}
{% if 'to' in states('sensor.bom_brisbane_forecast_possible_rainfall_1') %}
{% set amount = states('sensor.bom_brisbane_forecast_possible_rainfall_1').split(' to ') %}
{% set amount1 = amount[0] | float %}
{% set amount2 = amount[1] | float %}
{% set amount_avg = (amount1 + amount2) / 2 %}
{% else %}
{% set amount_avg = states('sensor.bom_brisbane_forecast_possible_rainfall_1') | int %}
{% endif %}
{{ (chance * amount_avg)|round(1) }}
48hour_rain_figure:
friendly_name: 'Rain in last 48 hours'
unit_of_measurement: mm
value_template: >
{{ state_attr('sensor.rain_in_last_48h' , 'total') }}
#################################################################
# #
# Set Start/Finish Times #
# #
#################################################################
input_datetime:
zone_1_am_on_time:
name: AM On Time
has_date: false
has_time: true
zone_1_pm_on_time:
name: PM On Time
has_date: false
has_time: true
zone_2_am_on_time:
name: AM On Time
has_date: false
has_time: true
zone_2_pm_on_time:
name: PM On Time
has_date: false
has_time: true
#################################################################
# #
# Set the days you Water here #
# #
#################################################################
input_boolean:
# Zone 1 Days
zone_1_mon:
name: Monday
icon: mdi:calendar
zone_1_tue:
name: Tuesday
icon: mdi:calendar
zone_1_wed:
name: Wednesday
icon: mdi:calendar
zone_1_thu:
name: Thursday
icon: mdi:calendar
zone_1_fri:
name: Friday
icon: mdi:calendar
zone_1_sat:
name: Saturday
icon: mdi:calendar
zone_1_sun:
name: Sunday
icon: mdi:calendar
# Zone 1 Automation Switches
zone_1_am_enable_schedule:
name: Enable AM Schedule
icon: mdi:weather-sunny
zone_1_pm_enable_schedule:
name: Enable PM Schedule
icon: mdi:weather-sunset
# Zone 2 Days
zone_2_mon:
name: Monday
icon: mdi:calendar
zone_2_tue:
name: Tuesday
icon: mdi:calendar
zone_2_wed:
name: Wednesday
icon: mdi:calendar
zone_2_thu:
name: Thursday
icon: mdi:calendar
zone_2_fri:
name: Friday
icon: mdi:calendar
zone_2_sat:
name: Saturday
icon: mdi:calendar
zone_2_sun:
name: Sunday
icon: mdi:calendar
# Zone 2 Automation Switches
zone_2_am_enable_schedule:
name: Enable AM Schedule
icon: mdi:weather-sunny
zone_2_pm_enable_schedule:
name: Enable PM Schedule
icon: mdi:weather-sunset
#################################################################
# #
# How much Rain must have fallen to stop #
# the Sprinkler cycle from running? #
# #
#################################################################
input_number:
rain_limit:
name: Rain Limit
min: 0
max: 2
step: 0.1
unit_of_measurement: mm
icon: mdi:weather-pouring
#################################################################
# #
# Set the run-time for each Zone below #
# #
#################################################################
zone_1_run_time:
name: Run Time
min: 5
max: 30
step: 5
unit_of_measurement: min
icon: mdi:clock
zone_2_run_time:
name: Run Time
min: 1
max: 10
step: 1
unit_of_measurement: min
icon: mdi:clock