From 78efa91b133e111e735459fa7f47df432a4995ce Mon Sep 17 00:00:00 2001 From: Ilia Sotnikov Date: Tue, 10 Oct 2023 19:16:26 +0300 Subject: [PATCH] Winter mode + Added support for winter mode, that is - the switch disables any functionality of the sprinklers by putting those into standby, disabling scheduled runs, preventing tank refills and turning off peripherals power (water tank level currently) to avoid relays energized for long time * Renamed all elements previously named after `tank refill` to `peripherals power` for better clarify - corresponding relay could control more components later, besides of just water tank level device * Fixed `Flowerbed sprinklers: shutdown` button, it was referencing wrong sprinkler controller * All GPIO inputs now publish their state upon reboot or HA connect, so that corresponding code runs initially making the system follows the state of the sensors --- controllers.yaml | 61 +++++++++++++++++++--- display.yaml | 2 +- inputs.yaml | 4 ++ main.yaml | 13 ++++- outputs.yaml | 2 +- schedule.yaml | 10 ++++ script_rain_water_tank_sensors_action.yaml | 8 +++ script_refill_tank.yaml | 6 ++- status_sensors.yaml | 10 ++-- 9 files changed, 98 insertions(+), 18 deletions(-) diff --git a/controllers.yaml b/controllers.yaml index 0a2a9ac..be07a9e 100644 --- a/controllers.yaml +++ b/controllers.yaml @@ -23,7 +23,7 @@ sprinkler: file: script_refill_tank.yaml vars: sprinkler: lawn_sprinklers - relay: ${refill_tank_relay_id} + relay: ${peripherals_power_off_relay_id} condition: >- !id(disable_water_tank_refill).state && !id(water_tank_refill_after_each_valve).state @@ -48,7 +48,7 @@ sprinkler: file: script_refill_tank.yaml vars: sprinkler: lawn_sprinklers - relay: ${refill_tank_relay_id} + relay: ${peripherals_power_off_relay_id} condition: >- !id(disable_water_tank_refill).state && id(water_tank_refill_after_each_valve).state @@ -68,7 +68,7 @@ sprinkler: file: script_refill_tank.yaml vars: sprinkler: lawn_sprinklers - relay: ${refill_tank_relay_id} + relay: ${peripherals_power_off_relay_id} condition: >- !id(disable_water_tank_refill).state && id(water_tank_refill_after_each_valve).state @@ -88,7 +88,7 @@ sprinkler: file: script_refill_tank.yaml vars: sprinkler: lawn_sprinklers - relay: ${refill_tank_relay_id} + relay: ${peripherals_power_off_relay_id} condition: >- !id(disable_water_tank_refill).state && id(water_tank_refill_after_each_valve).state @@ -119,7 +119,7 @@ sprinkler: file: script_refill_tank.yaml vars: sprinkler: flowerbed_sprinklers - relay: ${refill_tank_relay_id} + relay: ${peripherals_power_off_relay_id} condition: >- !id(disable_water_tank_refill).state && !id(water_tank_refill_after_each_valve).state @@ -144,7 +144,7 @@ sprinkler: file: script_refill_tank.yaml vars: sprinkler: flowerbed_sprinklers - relay: ${refill_tank_relay_id} + relay: ${peripherals_power_off_relay_id} condition: >- !id(disable_water_tank_refill).state && id(water_tank_refill_after_each_valve).state @@ -164,7 +164,7 @@ sprinkler: file: script_refill_tank.yaml vars: sprinkler: flowerbed_sprinklers - relay: ${refill_tank_relay_id} + relay: ${peripherals_power_off_relay_id} condition: >- !id(disable_water_tank_refill).state && id(water_tank_refill_after_each_valve).state @@ -191,6 +191,51 @@ switch: optimistic: true restore_mode: RESTORE_DEFAULT_OFF entity_category: config + - platform: template + id: winter_mode + name: "Winter mode" + optimistic: true + restore_mode: RESTORE_DEFAULT_OFF + entity_category: config + turn_on_action: + - lambda: |- + // Shutdown active operations on controllers if any + id(lawn_sprinklers).shutdown(); + id(flowerbed_sprinklers).shutdown(); + // Put controllers into standby + id(lawn_sprinklers_standby_switch).turn_on(); + id(flowerbed_sprinklers_standby_switch).turn_on(); + #ifdef HAS_SCHEDULE + // Disable scheduled runs + lawn_sprinklers_disabled->turn_on(); + flowerbed_sprinklers_disabled->turn_on(); + #endif + // Turn off peripherals power (water level relay and alike) + id(${peripherals_power_off_relay_id}).turn_on(); + turn_off_action: + - lambda: |- + // Move controllers out of standby mode + id(flowerbed_sprinklers_standby_switch).turn_off(); + id(lawn_sprinklers_standby_switch).turn_off(); + #ifdef HAS_SCHEDULE + // Enabled scheduled runs + lawn_sprinklers_disabled->turn_off(); + flowerbed_sprinklers_disabled->turn_off(); + #endif + // Enable peripherals power + id(${peripherals_power_off_relay_id}).turn_off(); + // Update the state of the winter mode switch, so that any code checks + // for its state actually sees it disabled (during the trigger the + // `state` variable will still be `on` until trigger's code + // completes + id(winter_mode).publish_state(false); + + # Re-publish the state of rain and water tank empty sensors, so that + # controllers reflect their actual state + - lambda: !include + file: script_rain_water_tank_sensors_action.yaml + vars: + triggered_by: winter_mode button: - platform: template @@ -200,4 +245,4 @@ button: - platform: template name: "Flowerbed sprinklers: shutdown" on_press: - - sprinkler.shutdown: lawn_sprinklers + - sprinkler.shutdown: flowerbed_sprinklers diff --git a/display.yaml b/display.yaml index 775ca31..e8fc9d7 100644 --- a/display.yaml +++ b/display.yaml @@ -112,7 +112,7 @@ display: 42, 22, material, TextAlign::TOP_CENTER, "%s%s%s", id(${water_tank_empty_id}).state ? "\U0000f6d5": "\U0000f6d6", id(${rain_sensor_id}).state ? "\U0000f176" : "\U0000e81a", - id(${refill_tank_relay_id}).state ? "\U0000e224" : "" + id(${peripherals_power_off_relay_id}).state ? "\U0000e224" : "" ); // Run time remaining diff --git a/inputs.yaml b/inputs.yaml index b1c7766..0da8864 100644 --- a/inputs.yaml +++ b/inputs.yaml @@ -15,6 +15,7 @@ binary_sensor: filters: - delayed_on: 100ms - delayed_off: 100ms + publish_initial_state: true on_state: then: - lambda: !include @@ -35,6 +36,7 @@ binary_sensor: filters: - delayed_on: 100ms - delayed_off: 100ms + publish_initial_state: true on_state: then: - lambda: !include @@ -53,6 +55,7 @@ binary_sensor: filters: - delayed_on: 100ms - delayed_off: 100ms + publish_initial_state: true - platform: gpio internal: true pin: @@ -65,3 +68,4 @@ binary_sensor: filters: - delayed_on: 100ms - delayed_off: 100ms + publish_initial_state: true diff --git a/main.yaml b/main.yaml index 6fba458..df0320d 100644 --- a/main.yaml +++ b/main.yaml @@ -8,12 +8,12 @@ substitutions: rain_sensor_inverted: 'true' water_tank_empty_id: water_tank_empty water_tank_empty_inverted: 'true' - refill_tank_relay_id: relay_7 + peripherals_power_off_relay_id: relay_7 pump_relay_id: relay_8 valve_overlap: 1s pump_start_pump_delay: 1s pump_stop_valve_delay: 1s - refill_relay_pulse_duration: 3s + peripherals_power_refill_pulse_duration: 3s scheduled_start_wait_tank_full_duration: 60s led_id: led led_brightness: '0.5' @@ -34,3 +34,12 @@ packages: status_sensors: !include status_sensors.yaml time: !include time.yaml # Optional rtc: !include rtc.yaml # Optional + +# Both recent ESPHome version and PR below are needed to avoid crashing at +# startup when winter mode enabled +esphome: + min_version: 2023.9.3 + +external_components: + - source: github://pr#5499 + components: [sprinkler] diff --git a/outputs.yaml b/outputs.yaml index e598bf4..b4e9088 100644 --- a/outputs.yaml +++ b/outputs.yaml @@ -30,7 +30,7 @@ switch: - platform: gpio pin: GPIO15 internal: true - id: ${refill_tank_relay_id} + id: ${peripherals_power_off_relay_id} - platform: gpio pin: GPIO14 id: ${pump_relay_id} diff --git a/schedule.yaml b/schedule.yaml index 491c34b..194c69b 100644 --- a/schedule.yaml +++ b/schedule.yaml @@ -66,6 +66,11 @@ switch: optimistic: true restore_mode: RESTORE_DEFAULT_OFF entity_category: config + lambda: |- + // Prevent enabling schedule if winter mode is active + if (id(winter_mode).state) + return true; + return {}; # Schedule, flowerbed sprinklers - platform: template @@ -124,6 +129,11 @@ switch: optimistic: true restore_mode: RESTORE_DEFAULT_OFF entity_category: config + lambda: |- + // See above + if (id(winter_mode).state) + return true; + return {}; number: # Schedule, lawn sprinklers diff --git a/script_rain_water_tank_sensors_action.yaml b/script_rain_water_tank_sensors_action.yaml index 82c17e3..30255cf 100644 --- a/script_rain_water_tank_sensors_action.yaml +++ b/script_rain_water_tank_sensors_action.yaml @@ -7,6 +7,14 @@ #include "esphome/core/log.h" #define TRIGGERED_BY_${triggered_by} + // No further manipulations if winter mode is enabled + if (id(winter_mode).state) { + ESP_LOGI( + "${triggered_by}", "Winter mode active, ignoring further actions" + ); + return; + } + // Handle rain detected or water tank is empty if (id(${rain_sensor_id}).state || id(${water_tank_empty_id}).state) { ESP_LOGI( diff --git a/script_refill_tank.yaml b/script_refill_tank.yaml index 3db17a8..12d2ac7 100644 --- a/script_refill_tank.yaml +++ b/script_refill_tank.yaml @@ -12,7 +12,9 @@ if: && (id(${sprinkler}).get_component_state() & COMPONENT_STATE_LOOP) // Ignore attempt to refill the tank when it has already been reported // as empty (would be redundant) - && !id(${water_tank_empty_id}).state; + && !id(${water_tank_empty_id}).state + // Ignore attempt to refill the tank if controller is in standby + && !id(${sprinkler}).standby(); then: - logger.log: format: Triggering water tank refill @@ -23,7 +25,7 @@ if: #ifdef HAS_DISPLAY id(${display_id}).update(); #endif - - delay: ${refill_relay_pulse_duration} + - delay: ${peripherals_power_refill_pulse_duration} - switch.turn_off: ${relay} - lambda: |- #ifdef HAS_DISPLAY diff --git a/status_sensors.yaml b/status_sensors.yaml index ffbbdb5..51e00b9 100644 --- a/status_sensors.yaml +++ b/status_sensors.yaml @@ -40,12 +40,14 @@ text_sensor: return { id(${pump_relay_id}).state ? "Active" : "Idle" }; - platform: template entity_category: diagnostic - id: tank_refill_state - name: "Tank refill state" - icon: "mdi:pipe-valve" + id: peripherals_power_state + name: "Peripherals power" + icon: "mdi:flash-triangle-outline" update_interval: 5s lambda: |- - return { id(${refill_tank_relay_id}).state ? "Active" : "Idle" }; + return { + id(${peripherals_power_off_relay_id}).state ? "Off" : "On" + }; - platform: template id: lawn_sprinklers_next_schedule name: "Lawn sprinklers: next schedule"