I have some code you could use. It runs on an ESP8266 at the moment, has been setup for 2 stations but I only used 1, and has a flow switch to confirm flow. The plan was to upgrade my code to include notifications if: 1) there was no flow when there should be, 2) there is flow when there shouldn’t be… but I never bothered to do so. It would be very easy to add that.
reticulation.yaml (package)
########################################
#
# This is a full reticulation
# control package using ESPHOMEYAML
# as the soleniod control via a NodeMCU
#
#
#
########################################
homeassistant:
customize:
switch.retic_station_1_valve:
icon: mdi:water-pump
switch.retic_station_2_valve:
icon: mdi:water-pump
input_boolean.retic_program1_enable:
icon: mdi:traffic-light
input_boolean.retic_program2_enable:
icon: mdi:traffic-light
# switch.retic_moisture_test_30s:
# assumed_state: false
sensor:
- platform: template # determine if today is selected as a watering day for program 1
sensors:
retic_program1_watering_day:
entity_id: input_boolean.retic_program1_monday, input_boolean.retic_program1_tuesday, input_boolean.retic_program1_wednesday, input_boolean.retic_program1_thursday, input_boolean.retic_program1_friday, input_boolean.retic_program1_saturday, input_boolean.retic_program1_sunday
value_template: >
{% set sensor_names = [ 'monday', 'tuesday', 'wednesday','thursday','friday','saturday','sunday'] %}
{% set today_name = sensor_names[now().weekday()] %}
{% set entity_id = 'input_boolean.retic_program1_'+today_name %}
{{ is_state(entity_id, 'on') }}
retic_program2_watering_day:
entity_id: input_boolean.retic_program2_monday, input_boolean.retic_program2_tuesday, input_boolean.retic_program2_wednesday, input_boolean.retic_program2_thursday, input_boolean.retic_program2_friday, input_boolean.retic_program2_saturday, input_boolean.retic_program2_sunday
value_template: >
{% set sensor_names = [ 'monday', 'tuesday', 'wednesday','thursday','friday','saturday','sunday'] %}
{% set today_name = sensor_names[now().weekday()] %}
{% set entity_id = 'input_boolean.retic_program2_'+today_name %}
{{ is_state(entity_id, 'on') }}
# Rain sensors from BOM forecast of today
possible_rainfall_today:
entity_id: sensor.bom_forecast_perth_weather_forecast_0
friendly_name: "Possible Rainfall Today"
value_template: >
{{ state_attr('sensor.bom_forecast_perth_weather_forecast_0', 'Possible Rainfall') | replace("mm", "") | float }}
chance_of_rain_today:
entity_id: sensor.bom_forecast_perth_weather_forecast_0
friendly_name: "Chance Of Rain Today"
value_template: >
{{ state_attr('sensor.bom_forecast_perth_weather_forecast_0', 'Chance of Rain') | replace("%", "") | float }}
input_datetime:
retic_program1_start_time: # program start time control
name: Program 1 Start Time
has_date: false
has_time: true
retic_program2_start_time:
name: Program 2 Start Time
has_date: false
has_time: true
input_number:
retic_program1_station1_run_time: # station run time control
name: Station 1 Run Time
min: 0
max: 30
step: 1
icon: mdi:camera-timer
retic_program1_station2_run_time:
name: Station 2 Run Time
min: 0
max: 30
step: 1
icon: mdi:camera-timer
retic_program2_station1_run_time:
name: Station 1 Run Time
min: 0
max: 30
step: 1
icon: mdi:camera-timer
retic_program2_station2_run_time:
name: Station 2 Run Time
min: 0
max: 30
step: 1
icon: mdi:camera-timer
allowable_rain_quantity:
name: 'Allowable Rain (mm)'
min: 0
max: 5
step: 0.1
icon: mdi:cup-water
allowable_rain_percentage:
name: 'Allowable Rain (%)'
min: 0
max: 100
step: 1
icon: mdi:water-percent
input_boolean:
retic_program1_monday: # watering day selections for program 1
name: Monday
retic_program1_tuesday:
name: Tuesday
retic_program1_wednesday:
name: Wednesday
retic_program1_thursday:
name: Thursday
retic_program1_friday:
name: Friday
retic_program1_saturday:
name: Saturday
retic_program1_sunday:
name: Sunday
retic_program2_monday: # watering day selections for program 2
name: Monday
retic_program2_tuesday:
name: Tuesday
retic_program2_wednesday:
name: Wednesday
retic_program2_thursday:
name: Thursday
retic_program2_friday:
name: Friday
retic_program2_saturday:
name: Saturday
retic_program2_sunday:
name: Sunday
retic_program1_enable: # enable program to run
name: Enable
retic_program2_enable:
name: Enable
retic_rain_parameters_met: # set to ON if rain today values are below levels set in input_numbers
name: Rain Parameters Met
icon: mdi:water
retic_rain_override: # set to ON to run retic even if rain parameters are not met
name: Rain Override
icon: mdi:water
group: # frontend interface setup
retic_manual:
control: hidden
name: 'Manual Control'
entities:
- switch.retic_station_1_valve
- switch.retic_station_2_valve
retic_program1:
control: hidden
name: 'Program 1'
entities:
- input_boolean.retic_program1_enable
- script.retic_program1_run
- input_datetime.retic_program1_start_time
- group.retic_program1_watering_days
- group.retic_program1_run_times
retic_program2:
control: hidden
name: 'Program 2'
entities:
- input_boolean.retic_program2_enable
- script.retic_program2_run
- input_datetime.retic_program2_start_time
- group.retic_program2_watering_days
- group.retic_program2_run_times
retic_program1_watering_days:
control: hidden
name: 'Watering days'
icon: mdi:calendar-multiple-check
entities:
- input_boolean.retic_program1_monday
- input_boolean.retic_program1_tuesday
- input_boolean.retic_program1_wednesday
- input_boolean.retic_program1_thursday
- input_boolean.retic_program1_friday
- input_boolean.retic_program1_saturday
- input_boolean.retic_program1_sunday
retic_program2_watering_days:
control: hidden
name: 'Watering days'
icon: mdi:calendar-multiple-check
entities:
- input_boolean.retic_program2_monday
- input_boolean.retic_program2_tuesday
- input_boolean.retic_program2_wednesday
- input_boolean.retic_program2_thursday
- input_boolean.retic_program2_friday
- input_boolean.retic_program2_saturday
- input_boolean.retic_program2_sunday
retic_program1_run_times:
control: hidden
name: 'Run times'
icon: mdi:camera-timer
entities:
- input_number.retic_program1_station1_run_time
- input_number.retic_program1_station2_run_time
retic_program2_run_times:
control: hidden
name: 'Run times'
icon: mdi:camera-timer
entities:
- input_number.retic_program2_station1_run_time
- input_number.retic_program2_station2_run_time
retic_status:
control: hidden
name: 'Status'
icon: mdi:water
entities:
- binary_sensor.retic_station_1_flow
- switch.retic_moisture_sensor_control
- sensor.retic_moisture_sensor_reading
#switch: # Solenoid control (will be signals to NodeMCU) NOT USED HERE BECAUSE CONTROL IS NOW VIA ESPHOMEYAML ADDON
# - platform: mqtt
# name: "Retic Station 1 Valve"
# state_topic: "retic/station1/state"
# command_topic: "retic/station1/cmd"
# payload_on: "1"
# payload_off: "0"
# optimistic: false
# qos: 0
# retain: true
# - platform: mqtt
# name: "Retic Station 2 Valve"
# state_topic: "retic/station2/state"
# command_topic: "retic/station2/cmd"
# payload_on: "1"
# payload_off: "0"
# optimistic: false
# qos: 0
# retain: true
automation:
- alias: Check rain parameters # check that todays rain doesnt need to disable the retic from running
initial_state: 'on'
trigger:
- platform: template
value_template: "{{ states('sensor.time') == ((states.input_datetime.retic_program1_start_time.attributes.timestamp - 600) | int | timestamp_custom('%H:%M', False)) }}"
- platform: state
entity_id: input_number.allowable_rain_quantity
- platform: state
entity_id: input_number.allowable_rain_percentage
## condition:
## conditions:
## - condition: template
## value_template: "{{ states('sensor.bom_current_weather_rain_today') <= states('input_number.allowable_rain_quantity') }}"
## - condition: template
## value_template: "{{ states('sensor.possible_rainfall_today') <= states('input_number.allowable_rain_percentage') }}"
action:
# - service_template: >
# {% if states('sensor.bom_perth_rain_today') <= states('input_number.allowable_rain_quantity') and states('sensor.possible_rainfall_today') <= states('input_number.allowable_rain_percentage') %}
# input_boolean.turn_on
# {% else %}
# input_boolean.turn_off
# {% endif %}
# entity_id: input_boolean.retic_rain_parameters_met
- service_template: >
input_boolean.turn_{{'on' if states('sensor.bom_perth_rain_today') <= states('input_number.allowable_rain_quantity') and
states('sensor.possible_rainfall_today') <= states('input_number.allowable_rain_percentage') else 'off'}}
entity_id: input_boolean.retic_rain_parameters_met
- alias: Reticulation Run Program 1 # start program 1 at designated time if it is enabled and today is selected as a watering day
initial_state: 'on'
trigger:
platform: template
value_template: "{{ states('sensor.time') == (states.input_datetime.retic_program1_start_time.attributes.timestamp | int | timestamp_custom('%H:%M', False)) }}"
condition:
condition: and
conditions:
- condition: state
entity_id: input_boolean.retic_program1_enable
state: 'on'
- condition: state
entity_id: sensor.retic_program1_watering_day
state: 'True'
- condition: or
conditions:
- condition: state
entity_id: input_boolean.retic_rain_parameters_met
state: 'on'
- condition: state
entity_id: input_boolean.retic_rain_override
state: 'on'
action:
- service: script.turn_on
entity_id: script.retic_program1_run
- alias: Reticulation Run Program 2 # start program 2 at designated time if it is enabled and today is selected as a watering day
initial_state: 'on'
trigger:
platform: template
value_template: "{{ states('sensor.time') == (states.input_datetime.retic_program2_start_time.attributes.timestamp | int | timestamp_custom('%H:%M', False)) }}"
condition:
condition: and
conditions:
- condition: state
entity_id: input_boolean.retic_program2_enable
state: 'on'
- condition: state
entity_id: sensor.retic_program2_watering_day
state: 'True'
- condition: or
conditions:
- condition: state
entity_id: input_boolean.retic_rain_parameters_met
state: 'on'
- condition: state
entity_id: input_boolean.retic_rain_override
state: 'on'
action:
- service: script.turn_on
entity_id: script.retic_program2_run
script:
retic_program1_run: #run retic program 1 through each station for selected time
alias: Program 1 Run
sequence:
- service: switch.turn_on
data:
entity_id: switch.retic_station_1_valve
- delay: "00:{{ states('input_number.retic_program1_station1_run_time')|int }}:00"
- service: switch.turn_off
data:
entity_id: switch.retic_station_1_valve
- service: switch.turn_on
data:
entity_id: switch.retic_station_2_valve
- delay: "00:{{ states('input_number.retic_program1_station2_run_time')|int }}:00"
- service: switch.turn_off
data:
entity_id: switch.retic_station_2_valve
retic_program2_run: #run retic program 2 through each station for selected time
alias: Program 2 Run
sequence:
- service: switch.turn_on
data:
entity_id: switch.retic_station_1_valve
- delay: "00:{{ states('input_number.retic_program2_station1_run_time')|int }}:00"
- service: switch.turn_off
data:
entity_id: switch.retic_station_1_valve
- service: switch.turn_on
data:
entity_id: switch.retic_station_2_valve
- delay: "00:{{ states('input_number.retic_program2_station2_run_time')|int }}:00"
- service: switch.turn_off
data:
entity_id: switch.retic_station_2_valve
ESPhome code (on the ESP8266)
esphomeyaml:
name: ha_retic_controller_1
platform: ESP8266
board: nodemcuv2
wifi:
ssid: 'xxxx'
password: 'xxxx'
manual_ip:
static_ip: 192.168.0.61
gateway: 192.168.0.1
subnet: 255.255.255.0
api:
# Enable logging
logger:
ota:
password: 'xxxx'
switch:
- platform: gpio
name: "Retic Station 1 Valve"
# id: s1
icon: mdi:water-pump
pin:
number: D1
inverted: true
- platform: gpio
name: "Retic Station 2 Valve"
# id: s2
icon: mdi:water-pump
pin:
number: D2
inverted: true
- platform: gpio
name: "Retic Moisture Sensor Control"
id: s3
icon: mdi:water-percent
pin:
number: D3
inverted: false
- platform: template
name: "Retic Moisture Test 30s"
id: s4
icon: mdi:water-percent
optimistic: yes
turn_on_action:
- switch.turn_on: s3
- delay: 30s
- switch.turn_off: s3
- switch.turn_off: s4
binary_sensor:
- platform: gpio
name: "Retic Station 1 Flow"
pin:
number: D4
inverted: true
mode: INPUT_PULLUP
# - platform: gpio
# name: "Retic Station 1 Manual Button"
# pin:
# number: D5
# inverted: true
# mode: INPUT_PULLUP
# filters:
# - delayed_on: 10ms
# on_press:
# then:
# - switch.toggle: s1
sensor:
- platform: adc
pin: A0
name: "Retic Moisture Sensor Reading"
icon: mdi:water-percent
unit_of_measurement: "%"
accuracy_decimals: 1
filters:
- lambda: return ((1- x) / 1) * 140; # multiplying by 140 to scale value since reading is only 70% in water
# - filter_out: > 100
Lovelace screen
The moisture sensor reports over 100% when its turned off. I only run it for a short period because extended time on will corrode the sensor. I will actually be getting rid of it this week as I now have Mi Flora sensors instead which are much better.