mirror of
https://github.com/brianhanifin/esphome-config.git
synced 2026-07-27 19:55:41 +00:00
455 lines
13 KiB
YAML
455 lines
13 KiB
YAML
---
|
|
# Forked from: https://github.com/bruxy70/Irrigation-with-display
|
|
# MIT License: https://github.com/brianhanifin/Irrigation-with-display/blob/master/LICENSE
|
|
#
|
|
# Credit: @bruxy70 thank you for the significant head start!
|
|
# Personal project goals: https://github.com/brianhanifin/Home-Assistant-Config/issues/37
|
|
#
|
|
substitutions:
|
|
friendly_name: Irrigation
|
|
id: irrigation
|
|
hostname: irrigation
|
|
ip: 10.0.20.18
|
|
|
|
zone1_name: Front yard drip
|
|
zone1_times_entity: input_text.front_yard_drip_times
|
|
|
|
zone2_name: Pool filler
|
|
zone2_times_entity: input_text.pool_filler_times
|
|
|
|
<<: !include common/substitutions/gpio/sonoff4chpror2.yaml
|
|
|
|
esphome:
|
|
friendly_name: $friendly_name
|
|
name: $hostname
|
|
includes:
|
|
- irrigation.h
|
|
|
|
<<: !include common/esphome/leds/status_with_api.yaml
|
|
|
|
esp8266:
|
|
board: esp01_1m
|
|
framework:
|
|
version: recommended
|
|
|
|
wifi:
|
|
ssid: !secret wifi_ssid
|
|
password: !secret wifi_password
|
|
|
|
# Disable rebooting due to losing connection with Home Assistant. This will allow
|
|
# the watering schedule to continue if Home Assistant goes down. Should it become
|
|
# unresponsive, we can have Home Assistant power cycle a smart plug to reboot it.
|
|
reboot_timeout: 0s
|
|
|
|
# Using these as a precaution to ensure solid WiFi connectivity.
|
|
#power_save_mode: none
|
|
manual_ip:
|
|
static_ip: $ip
|
|
gateway: 10.0.20.1
|
|
subnet: 255.255.255.0
|
|
|
|
# Fallback Hotspot (requires "captive_portal:").
|
|
ap:
|
|
ssid: $id
|
|
password: !secret failover_password
|
|
|
|
captive_portal:
|
|
|
|
<<: !include common/ota.yaml
|
|
<<: !include common/logger.yaml
|
|
<<: !include common/api.yaml
|
|
|
|
globals:
|
|
# ============================================================================= #
|
|
# Irrigation time remaining
|
|
- id: remaining_time1
|
|
type: int
|
|
restore_value: no
|
|
initial_value: "300"
|
|
- id: remaining_time2
|
|
type: int
|
|
restore_value: no
|
|
initial_value: "300"
|
|
|
|
# ============================================================================= #
|
|
# Store previous values to verify change.
|
|
- id: remaining_time1_previous
|
|
type: int
|
|
restore_value: no
|
|
initial_value: "0"
|
|
- id: remaining_time2_previous
|
|
type: int
|
|
restore_value: no
|
|
initial_value: "0"
|
|
|
|
# Common housekeeping components.
|
|
output:
|
|
<<: !include common/outputs/status_led.yaml
|
|
|
|
light:
|
|
<<: !include common/lights/status_led.yaml
|
|
|
|
|
|
binary_sensor:
|
|
- !include common/binary_sensors/status.yaml
|
|
|
|
# ============================================================================= #
|
|
# Buttons along the left side of the unit (R1, R2, R3, R4).
|
|
- platform: gpio
|
|
id: key1
|
|
pin:
|
|
number: $button1_gpio
|
|
mode: INPUT_PULLUP
|
|
inverted: True
|
|
filters:
|
|
- delayed_on: 100ms
|
|
- delayed_off: 100ms
|
|
on_click:
|
|
min_length: 50ms
|
|
max_length: 350ms
|
|
then:
|
|
- switch.toggle: irrigation_zone1
|
|
|
|
- platform: gpio
|
|
id: key2
|
|
pin:
|
|
number: $button2_gpio
|
|
mode: INPUT_PULLUP
|
|
inverted: True
|
|
filters:
|
|
- delayed_on: 100ms
|
|
- delayed_off: 100ms
|
|
on_click:
|
|
min_length: 50ms
|
|
max_length: 350ms
|
|
then:
|
|
- switch.toggle: irrigation_zone2
|
|
|
|
button:
|
|
- !include common/switches/restart.yaml
|
|
|
|
number:
|
|
- platform: template
|
|
name: $zone1_name duration
|
|
id: irrigation_zone1_duration
|
|
icon: mdi:timer-sand
|
|
#mode: slider #auto, box, slider
|
|
#unit_of_measurement: minutes
|
|
optimistic: true
|
|
initial_value: 0
|
|
restore_value: true
|
|
min_value: 0
|
|
max_value: 60
|
|
step: 1
|
|
# set_action:
|
|
# then:
|
|
# - globals.set:
|
|
# id: irrigation_zone1_duration
|
|
# value: !lambda return id(ui_zone1_duration).state;
|
|
|
|
- platform: template
|
|
name: $zone2_name duration
|
|
id: irrigation_zone2_duration
|
|
#id: ui_zone2_duration
|
|
icon: mdi:timer-sand
|
|
#mode: slider #auto, box, slider
|
|
#unit_of_measurement: minutes
|
|
optimistic: true
|
|
initial_value: 0
|
|
restore_value: true
|
|
min_value: 0
|
|
max_value: 60
|
|
step: 1
|
|
# set_action:
|
|
# then:
|
|
# - globals.set:
|
|
# id: irrigation_zone2_duration
|
|
# value: !lambda return id(ui_zone2_duration).state;
|
|
|
|
|
|
sensor:
|
|
- !include common/sensors/uptime.yaml
|
|
- !include common/sensors/wifi_signal.yaml
|
|
|
|
# ============================================================================= #
|
|
# Countdown sensors.
|
|
- platform: template
|
|
name: $zone1_name remaining
|
|
id: irrigation_zone1_remaining
|
|
lambda: "return 0;"
|
|
accuracy_decimals: 0
|
|
unit_of_measurement: minutes
|
|
icon: mdi:timer-outline
|
|
on_value:
|
|
then:
|
|
- if:
|
|
condition:
|
|
lambda: return id(remaining_time1) == 0;
|
|
then:
|
|
- switch.turn_off: relay1
|
|
|
|
- platform: template
|
|
name: $zone2_name remaining
|
|
id: irrigation_zone2_remaining
|
|
lambda: "return 0;"
|
|
accuracy_decimals: 0
|
|
unit_of_measurement: minutes
|
|
icon: mdi:timer-outline
|
|
on_value:
|
|
then:
|
|
- if:
|
|
condition:
|
|
lambda: return id(remaining_time2) == 0;
|
|
then:
|
|
- switch.turn_off: relay2
|
|
|
|
# ============================================================================= #
|
|
# Retrieve durations settings from the Home Assistant UI.
|
|
# - platform: homeassistant
|
|
# id: ui_zone1_duration
|
|
# entity_id: input_number.irrigation_zone1_duration
|
|
# on_value:
|
|
# then:
|
|
# - sensor.template.publish:
|
|
# id: irrigation_zone1_duration
|
|
# state: !lambda return id(ui_zone1_duration).state;
|
|
|
|
# - platform: homeassistant
|
|
# id: ui_zone2_duration
|
|
# entity_id: input_number.irrigation_zone2_duration
|
|
# on_value:
|
|
# then:
|
|
# - sensor.template.publish:
|
|
# id: irrigation_zone2_duration
|
|
# state: !lambda return id(ui_zone2_duration).state;
|
|
|
|
# ============================================================================= #
|
|
# Store durations.
|
|
# - platform: template
|
|
# name: $zone1_name duration
|
|
# id: irrigation_zone1_duration
|
|
# - platform: template
|
|
# name: $zone2_name duration
|
|
# id: irrigation_zone2_duration
|
|
|
|
|
|
switch:
|
|
#- !include common/switches/restart.yaml
|
|
|
|
# ============================================================================= #
|
|
# Virtual zone Switches which toggle the relay, and store the current state.
|
|
- platform: template
|
|
name: $zone1_name
|
|
id: irrigation_zone1
|
|
lambda: return id(relay1).state;
|
|
optimistic: true
|
|
turn_on_action:
|
|
# Turn on if not disabled.
|
|
if:
|
|
condition:
|
|
lambda: return id(irrigation_zone1_duration) > 0;
|
|
then:
|
|
- switch.turn_on: relay1
|
|
turn_off_action:
|
|
- switch.turn_off: relay1
|
|
|
|
- platform: template
|
|
name: $zone2_name
|
|
id: irrigation_zone2
|
|
lambda: return id(relay2).state;
|
|
optimistic: true
|
|
turn_on_action:
|
|
# Turn on if not disabled.
|
|
if:
|
|
condition:
|
|
lambda: return id(irrigation_zone2_duration) > 0;
|
|
then:
|
|
- switch.turn_on: relay2
|
|
turn_off_action:
|
|
- switch.turn_off: relay2
|
|
|
|
# ============================================================================= #
|
|
# Relays which trigger solenoids
|
|
- platform: gpio
|
|
id: relay1
|
|
pin: $relay1_gpio
|
|
on_turn_on:
|
|
then:
|
|
# Start the countdown timer.
|
|
- globals.set:
|
|
id: remaining_time1
|
|
value: !lambda return id(irrigation_zone1_duration).state * 60;
|
|
# Show the remaining time.
|
|
- sensor.template.publish:
|
|
id: irrigation_zone1_remaining
|
|
state: !lambda return id(irrigation_zone1_duration).state;
|
|
# Show the "Next Time" as "now".
|
|
- text_sensor.template.publish:
|
|
id: irrigation_zone1_next
|
|
state: "now"
|
|
on_turn_off:
|
|
then:
|
|
- sensor.template.publish:
|
|
id: irrigation_zone1_remaining
|
|
state: "0"
|
|
# Update the next scheduled run time.
|
|
- text_sensor.template.publish:
|
|
id: irrigation_zone1_next
|
|
state: !lambda |-
|
|
return update_next_runtime(id(irrigation_zone1_times).state);
|
|
|
|
- platform: gpio
|
|
id: relay2
|
|
pin: $relay2_gpio
|
|
on_turn_on:
|
|
then:
|
|
# Start the countdown timer.
|
|
- globals.set:
|
|
id: remaining_time2
|
|
value: !lambda return id(irrigation_zone2_duration).state * 60;
|
|
# Show the remaining time.
|
|
- sensor.template.publish:
|
|
id: irrigation_zone2_remaining
|
|
state: !lambda return id(irrigation_zone2_duration).state;
|
|
# Show the "Next Time" as "now".
|
|
- text_sensor.template.publish:
|
|
id: irrigation_zone2_next
|
|
state: "now"
|
|
on_turn_off:
|
|
then:
|
|
- sensor.template.publish:
|
|
id: irrigation_zone2_remaining
|
|
state: "0"
|
|
# Update the next scheduled run time.
|
|
- text_sensor.template.publish:
|
|
id: irrigation_zone2_next
|
|
state: !lambda |-
|
|
return update_next_runtime(id(irrigation_zone2_times).state);
|
|
|
|
|
|
text_sensor:
|
|
# ============================================================================= #
|
|
# Retrieve list of times from the Home Assistant UI.
|
|
- platform: homeassistant
|
|
id: ui_zone1_times
|
|
entity_id: $zone1_times_entity
|
|
on_value:
|
|
then:
|
|
#- delay: 10sec
|
|
- text_sensor.template.publish:
|
|
id: irrigation_zone1_times
|
|
state: !lambda return id(ui_zone1_times).state;
|
|
|
|
- platform: homeassistant
|
|
id: ui_zone2_times
|
|
entity_id: $zone2_times_entity
|
|
on_value:
|
|
then:
|
|
#- delay: 10sec
|
|
- text_sensor.template.publish:
|
|
id: irrigation_zone2_times
|
|
state: !lambda return id(ui_zone2_times).state;
|
|
|
|
# ============================================================================= #
|
|
# Store time lists.
|
|
- platform: template
|
|
name: $zone1_name times
|
|
id: irrigation_zone1_times
|
|
on_value:
|
|
then:
|
|
# Update the next scheduled run time.
|
|
- text_sensor.template.publish:
|
|
id: irrigation_zone1_next
|
|
state: !lambda |-
|
|
return update_next_runtime(id(irrigation_zone1_times).state);
|
|
|
|
- platform: template
|
|
name: $zone2_name times
|
|
id: irrigation_zone2_times
|
|
on_value:
|
|
then:
|
|
# Update the next scheduled run time.
|
|
- text_sensor.template.publish:
|
|
id: irrigation_zone2_next
|
|
state: !lambda |-
|
|
return update_next_runtime(id(irrigation_zone2_times).state);
|
|
|
|
# ============================================================================= #
|
|
# Set the next scheduled time.
|
|
- platform: template
|
|
name: $zone1_name next
|
|
id: irrigation_zone1_next
|
|
- platform: template
|
|
name: $zone2_name next
|
|
id: irrigation_zone2_next
|
|
|
|
|
|
# Update the countdown timers every 5 seconds.
|
|
interval:
|
|
- interval: 5s
|
|
then:
|
|
- lambda: |-
|
|
if (id(remaining_time1) > 0) {
|
|
// Store the previous time.
|
|
id(remaining_time1_previous) = id(remaining_time1);
|
|
|
|
// When the relay is on.
|
|
if (id(relay1).state) {
|
|
// Decrement the timer.
|
|
id(remaining_time1) -= 5;
|
|
|
|
// Turn off the relay when the time reaches zero... or the remaining time fails a sanity check!
|
|
//if (id(remaining_time1) <= 0 || id(irrigation_zone1_remaining).state > id(irrigation_zone1_duration).state){
|
|
if (id(remaining_time1) <= 0) {
|
|
id(relay1).turn_off();
|
|
id(remaining_time1) = 0;
|
|
}
|
|
}
|
|
|
|
// Update the remaining time display.
|
|
if (id(remaining_time1_previous) != id(remaining_time1)) {
|
|
id(irrigation_zone1_remaining).publish_state( (id(remaining_time1)/60) + 1 );
|
|
}
|
|
}
|
|
|
|
if (id(remaining_time2) > 0) {
|
|
// Store the previous time.
|
|
id(remaining_time2_previous) = id(remaining_time2);
|
|
|
|
// When the relay is on.
|
|
if (id(relay2).state) {
|
|
// Decrement the timer.
|
|
id(remaining_time2) -= 5;
|
|
|
|
// Turn off the relay when the time reaches zero... or the remaining time fails a sanity check!
|
|
//if (id(remaining_time2) <= 0 || id(irrigation_zone2_remaining).state > id(irrigation_zone2_duration).state){
|
|
if (id(remaining_time2) <= 0) {
|
|
id(relay2).turn_off();
|
|
id(remaining_time2) = 0;
|
|
}
|
|
}
|
|
|
|
// Update the remaining time display.
|
|
if (id(remaining_time2_previous) != id(remaining_time2)) {
|
|
id(irrigation_zone2_remaining).publish_state( (id(remaining_time2)/60) + 1 );
|
|
}
|
|
}
|
|
|
|
|
|
# Time based automations.
|
|
time:
|
|
- platform: homeassistant
|
|
id: homeassistant_time
|
|
timezone: America/Los_Angeles
|
|
on_time:
|
|
- seconds: 0
|
|
minutes: /1
|
|
then:
|
|
- lambda: |-
|
|
if (scheduled_runtime(id(irrigation_zone1_next).state.c_str())) {
|
|
id(irrigation_zone1).turn_on();
|
|
}
|
|
if (scheduled_runtime(id(irrigation_zone2_next).state.c_str())) {
|
|
id(irrigation_zone2).turn_on();
|
|
}
|