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"