From 84b5d9b21c90f8e38e360762b4368bbf8b29e511 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Mon, 22 Dec 2025 14:00:12 -0500 Subject: [PATCH 1/3] [core] Remove deprecated config options from before 2025 (#12622) Co-authored-by: Claude --- esphome/components/bedjet/climate/__init__.py | 25 ++----------------- esphome/components/bh1750/sensor.py | 10 -------- esphome/components/ethernet/__init__.py | 4 --- esphome/components/i2c/__init__.py | 4 --- esphome/components/remote_base/__init__.py | 15 +---------- esphome/components/sensor/__init__.py | 3 --- esphome/components/tca9548a/__init__.py | 3 +-- .../components/template/switch/__init__.py | 4 --- esphome/components/tuya/light/__init__.py | 6 ----- esphome/components/uart/__init__.py | 4 --- esphome/components/wifi/__init__.py | 4 --- 11 files changed, 4 insertions(+), 78 deletions(-) diff --git a/esphome/components/bedjet/climate/__init__.py b/esphome/components/bedjet/climate/__init__.py index 0da2107d43..4de9dcca0b 100644 --- a/esphome/components/bedjet/climate/__init__.py +++ b/esphome/components/bedjet/climate/__init__.py @@ -1,12 +1,7 @@ import esphome.codegen as cg -from esphome.components import ble_client, climate +from esphome.components import climate import esphome.config_validation as cv -from esphome.const import ( - CONF_HEAT_MODE, - CONF_RECEIVE_TIMEOUT, - CONF_TEMPERATURE_SOURCE, - CONF_TIME_ID, -) +from esphome.const import CONF_HEAT_MODE, CONF_TEMPERATURE_SOURCE from .. import BEDJET_CLIENT_SCHEMA, bedjet_ns, register_bedjet_child @@ -38,22 +33,6 @@ CONFIG_SCHEMA = ( } ) .extend(cv.polling_component_schema("60s")) - .extend( - # TODO: remove compat layer. - { - cv.Optional(ble_client.CONF_BLE_CLIENT_ID): cv.invalid( - "The 'ble_client_id' option has been removed. Please migrate " - "to the new `bedjet_id` option in the `bedjet` component.\n" - "See https://esphome.io/components/climate/bedjet/" - ), - cv.Optional(CONF_TIME_ID): cv.invalid( - "The 'time_id' option has been moved to the `bedjet` component." - ), - cv.Optional(CONF_RECEIVE_TIMEOUT): cv.invalid( - "The 'receive_timeout' option has been moved to the `bedjet` component." - ), - } - ) .extend(BEDJET_CLIENT_SCHEMA) ) diff --git a/esphome/components/bh1750/sensor.py b/esphome/components/bh1750/sensor.py index 7c7eecb88c..36af5aeef9 100644 --- a/esphome/components/bh1750/sensor.py +++ b/esphome/components/bh1750/sensor.py @@ -20,16 +20,6 @@ CONFIG_SCHEMA = ( device_class=DEVICE_CLASS_ILLUMINANCE, state_class=STATE_CLASS_MEASUREMENT, ) - .extend( - { - cv.Optional("resolution"): cv.invalid( - "The 'resolution' option has been removed. The optimal value is now dynamically calculated." - ), - cv.Optional("measurement_duration"): cv.invalid( - "The 'measurement_duration' option has been removed. The optimal value is now dynamically calculated." - ), - } - ) .extend(cv.polling_component_schema("60s")) .extend(i2c.i2c_device_schema(0x23)) ) diff --git a/esphome/components/ethernet/__init__.py b/esphome/components/ethernet/__init__.py index e1ed327fb9..f140f395e4 100644 --- a/esphome/components/ethernet/__init__.py +++ b/esphome/components/ethernet/__init__.py @@ -220,10 +220,6 @@ BASE_SCHEMA = cv.Schema( cv.Optional(CONF_MANUAL_IP): MANUAL_IP_SCHEMA, cv.Optional(CONF_DOMAIN, default=".local"): cv.domain_name, cv.Optional(CONF_USE_ADDRESS): cv.string_strict, - cv.Optional("enable_mdns"): cv.invalid( - "This option has been removed. Please use the [disabled] option under the " - "new mdns component instead." - ), cv.Optional(CONF_MAC_ADDRESS): cv.mac_address, } ).extend(cv.COMPONENT_SCHEMA) diff --git a/esphome/components/i2c/__init__.py b/esphome/components/i2c/__init__.py index 7706484e97..b7436ccc39 100644 --- a/esphome/components/i2c/__init__.py +++ b/esphome/components/i2c/__init__.py @@ -237,10 +237,6 @@ def i2c_device_schema(default_address): """ schema = { cv.GenerateID(CONF_I2C_ID): cv.use_id(I2CBus), - cv.Optional("multiplexer"): cv.invalid( - "This option has been removed, please see " - "the tca9584a docs for the updated way to use multiplexers" - ), } if default_address is None: schema[cv.Required(CONF_ADDRESS)] = cv.i2c_address diff --git a/esphome/components/remote_base/__init__.py b/esphome/components/remote_base/__init__.py index d24d24b000..9d3e655c57 100644 --- a/esphome/components/remote_base/__init__.py +++ b/esphome/components/remote_base/__init__.py @@ -108,9 +108,6 @@ def register_trigger(name, type, data_type): validator = automation.validate_automation( { cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(type), - cv.Optional(CONF_RECEIVER_ID): cv.invalid( - "This has been removed in ESPHome 2022.3.0 and the trigger attaches directly to the parent receiver." - ), } ) registerer = TRIGGER_REGISTRY.register(f"on_{name}", validator) @@ -207,13 +204,7 @@ validate_binary_sensor = cv.validate_registry_entry( "remote receiver", BINARY_SENSOR_REGISTRY ) TRIGGER_REGISTRY = SimpleRegistry() -DUMPER_REGISTRY = Registry( - { - cv.Optional(CONF_RECEIVER_ID): cv.invalid( - "This has been removed in ESPHome 1.20.0 and the dumper attaches directly to the parent receiver." - ), - } -) +DUMPER_REGISTRY = Registry() def validate_dumpers(value): @@ -480,10 +471,6 @@ COOLIX_BASE_SCHEMA = cv.Schema( { cv.Required(CONF_FIRST): cv.hex_int_range(0, 16777215), cv.Optional(CONF_SECOND, default=0): cv.hex_int_range(0, 16777215), - cv.Optional(CONF_DATA): cv.invalid( - "'data' option has been removed in ESPHome 2023.8. " - "Use the 'first' and 'second' options instead." - ), } ) diff --git a/esphome/components/sensor/__init__.py b/esphome/components/sensor/__init__.py index 027d9a69b8..83b2656661 100644 --- a/esphome/components/sensor/__init__.py +++ b/esphome/components/sensor/__init__.py @@ -304,9 +304,6 @@ _SENSOR_SCHEMA = ( cv.Optional(CONF_DEVICE_CLASS): validate_device_class, cv.Optional(CONF_STATE_CLASS): validate_state_class, cv.Optional(CONF_ENTITY_CATEGORY): sensor_entity_category, - cv.Optional("last_reset_type"): cv.invalid( - "last_reset_type has been removed since 2021.9.0. state_class: total_increasing should be used for total values." - ), cv.Optional(CONF_FORCE_UPDATE, default=False): cv.boolean, cv.Optional(CONF_EXPIRE_AFTER): cv.All( cv.requires_component("mqtt"), diff --git a/esphome/components/tca9548a/__init__.py b/esphome/components/tca9548a/__init__.py index cef779de2e..72973a54ad 100644 --- a/esphome/components/tca9548a/__init__.py +++ b/esphome/components/tca9548a/__init__.py @@ -1,7 +1,7 @@ import esphome.codegen as cg from esphome.components import i2c import esphome.config_validation as cv -from esphome.const import CONF_CHANNEL, CONF_CHANNELS, CONF_ID, CONF_SCAN +from esphome.const import CONF_CHANNEL, CONF_CHANNELS, CONF_ID CODEOWNERS = ["@andreashergert1984"] @@ -18,7 +18,6 @@ CONFIG_SCHEMA = ( cv.Schema( { cv.GenerateID(): cv.declare_id(TCA9548AComponent), - cv.Optional(CONF_SCAN): cv.invalid("This option has been removed"), cv.Optional(CONF_CHANNELS, default=[]): cv.ensure_list( { cv.Required(CONF_BUS_ID): cv.declare_id(TCA9548AChannel), diff --git a/esphome/components/template/switch/__init__.py b/esphome/components/template/switch/__init__.py index e86657510f..8ae5a07dc3 100644 --- a/esphome/components/template/switch/__init__.py +++ b/esphome/components/template/switch/__init__.py @@ -7,7 +7,6 @@ from esphome.const import ( CONF_ID, CONF_LAMBDA, CONF_OPTIMISTIC, - CONF_RESTORE_STATE, CONF_STATE, CONF_TURN_OFF_ACTION, CONF_TURN_ON_ACTION, @@ -44,9 +43,6 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_TURN_ON_ACTION): automation.validate_automation( single=True ), - cv.Optional(CONF_RESTORE_STATE): cv.invalid( - "The restore_state option has been removed in 2023.7.0. Use the restore_mode option instead" - ), } ) .extend(cv.COMPONENT_SCHEMA), diff --git a/esphome/components/tuya/light/__init__.py b/esphome/components/tuya/light/__init__.py index 1d2286e3c7..4d2ccba8b1 100644 --- a/esphome/components/tuya/light/__init__.py +++ b/esphome/components/tuya/light/__init__.py @@ -37,10 +37,6 @@ COLOR_TYPES = { TuyaLight = tuya_ns.class_("TuyaLight", light.LightOutput, cg.Component) -COLOR_CONFIG_ERROR = ( - "This option has been removed, use color_datapoint and color_type instead." -) - CONFIG_SCHEMA = cv.All( light.BRIGHTNESS_ONLY_LIGHT_SCHEMA.extend( { @@ -49,8 +45,6 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_DIMMER_DATAPOINT): cv.uint8_t, cv.Optional(CONF_MIN_VALUE_DATAPOINT): cv.uint8_t, cv.Optional(CONF_SWITCH_DATAPOINT): cv.uint8_t, - cv.Optional(CONF_RGB_DATAPOINT): cv.invalid(COLOR_CONFIG_ERROR), - cv.Optional(CONF_HSV_DATAPOINT): cv.invalid(COLOR_CONFIG_ERROR), cv.Inclusive(CONF_COLOR_DATAPOINT, "color"): cv.uint8_t, cv.Inclusive(CONF_COLOR_TYPE, "color"): cv.enum(COLOR_TYPES, upper=True), cv.Optional(CONF_COLOR_INTERLOCK, default=False): cv.boolean, diff --git a/esphome/components/uart/__init__.py b/esphome/components/uart/__init__.py index 6494aaa286..9baa6ebd81 100644 --- a/esphome/components/uart/__init__.py +++ b/esphome/components/uart/__init__.py @@ -19,7 +19,6 @@ from esphome.const import ( CONF_DUMMY_RECEIVER_ID, CONF_FLOW_CONTROL_PIN, CONF_ID, - CONF_INVERT, CONF_LAMBDA, CONF_NUMBER, CONF_PORT, @@ -304,9 +303,6 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_PARITY, default="NONE"): cv.enum( UART_PARITY_OPTIONS, upper=True ), - cv.Optional(CONF_INVERT): cv.invalid( - "This option has been removed. Please instead use invert in the tx/rx pin schemas." - ), cv.Optional(CONF_DEBUG): maybe_empty_debug, } ).extend(cv.COMPONENT_SCHEMA), diff --git a/esphome/components/wifi/__init__.py b/esphome/components/wifi/__init__.py index 2c10506011..fb23837e78 100644 --- a/esphome/components/wifi/__init__.py +++ b/esphome/components/wifi/__init__.py @@ -348,10 +348,6 @@ CONFIG_SCHEMA = cv.All( cv.boolean, cv.only_on_esp32 ), cv.Optional(CONF_PASSIVE_SCAN, default=False): cv.boolean, - cv.Optional("enable_mdns"): cv.invalid( - "This option has been removed. Please use the [disabled] option under the " - "new mdns component instead." - ), cv.Optional(CONF_ENABLE_ON_BOOT, default=True): cv.boolean, cv.Optional(CONF_ON_CONNECT): automation.validate_automation(single=True), cv.Optional(CONF_ON_DISCONNECT): automation.validate_automation( From cd45fe0c3a72eeeb474e8c748c3dc7368288f38c Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Mon, 22 Dec 2025 13:13:03 -0600 Subject: [PATCH 2/3] [thermostat] Optimizations to reduce binary size (#12621) --- .../thermostat/thermostat_climate.cpp | 54 +++++++++++++++---- .../thermostat/thermostat_climate.h | 29 +++------- 2 files changed, 52 insertions(+), 31 deletions(-) diff --git a/esphome/components/thermostat/thermostat_climate.cpp b/esphome/components/thermostat/thermostat_climate.cpp index e588407c4a..d5fb259dad 100644 --- a/esphome/components/thermostat/thermostat_climate.cpp +++ b/esphome/components/thermostat/thermostat_climate.cpp @@ -3,8 +3,7 @@ #include "esphome/core/helpers.h" #include "esphome/core/log.h" -namespace esphome { -namespace thermostat { +namespace esphome::thermostat { static const char *const TAG = "thermostat.climate"; @@ -66,10 +65,12 @@ void ThermostatClimate::setup() { } void ThermostatClimate::loop() { - for (auto &timer : this->timer_) { - if (timer.active && (timer.started + timer.time < App.get_loop_component_start_time())) { + uint32_t now = App.get_loop_component_start_time(); + for (uint8_t i = 0; i < THERMOSTAT_TIMER_COUNT; i++) { + auto &timer = this->timer_[i]; + if (timer.active && (now - timer.started >= timer.time)) { timer.active = false; - timer.func(); + this->call_timer_callback_(static_cast(i)); } } } @@ -916,8 +917,42 @@ uint32_t ThermostatClimate::timer_duration_(ThermostatClimateTimerIndex timer_in return this->timer_[timer_index].time; } -std::function ThermostatClimate::timer_cbf_(ThermostatClimateTimerIndex timer_index) { - return this->timer_[timer_index].func; +void ThermostatClimate::call_timer_callback_(ThermostatClimateTimerIndex timer_index) { + switch (timer_index) { + case THERMOSTAT_TIMER_COOLING_MAX_RUN_TIME: + this->cooling_max_run_time_timer_callback_(); + break; + case THERMOSTAT_TIMER_COOLING_OFF: + this->cooling_off_timer_callback_(); + break; + case THERMOSTAT_TIMER_COOLING_ON: + this->cooling_on_timer_callback_(); + break; + case THERMOSTAT_TIMER_FAN_MODE: + this->fan_mode_timer_callback_(); + break; + case THERMOSTAT_TIMER_FANNING_OFF: + this->fanning_off_timer_callback_(); + break; + case THERMOSTAT_TIMER_FANNING_ON: + this->fanning_on_timer_callback_(); + break; + case THERMOSTAT_TIMER_HEATING_MAX_RUN_TIME: + this->heating_max_run_time_timer_callback_(); + break; + case THERMOSTAT_TIMER_HEATING_OFF: + this->heating_off_timer_callback_(); + break; + case THERMOSTAT_TIMER_HEATING_ON: + this->heating_on_timer_callback_(); + break; + case THERMOSTAT_TIMER_IDLE_ON: + this->idle_on_timer_callback_(); + break; + case THERMOSTAT_TIMER_COUNT: + default: + break; + } } void ThermostatClimate::cooling_max_run_time_timer_callback_() { @@ -1344,7 +1379,7 @@ void ThermostatClimate::set_timer_duration_in_sec_(ThermostatClimateTimerIndex t ESP_LOGVV(TAG, "timer %d completing immediately (elapsed %d >= new %d)", timer_index, elapsed, new_duration_ms); this->timer_[timer_index].active = false; // Trigger the timer callback immediately - this->timer_[timer_index].func(); + this->call_timer_callback_(timer_index); return; } else { // Adjust timer to run for remaining time - keep original start time @@ -1672,5 +1707,4 @@ ThermostatClimateTargetTempConfig::ThermostatClimateTargetTempConfig(float defau float default_temperature_high) : default_temperature_low(default_temperature_low), default_temperature_high(default_temperature_high) {} -} // namespace thermostat -} // namespace esphome +} // namespace esphome::thermostat diff --git a/esphome/components/thermostat/thermostat_climate.h b/esphome/components/thermostat/thermostat_climate.h index 2443af58d6..564b6127b3 100644 --- a/esphome/components/thermostat/thermostat_climate.h +++ b/esphome/components/thermostat/thermostat_climate.h @@ -10,8 +10,7 @@ #include #include -namespace esphome { -namespace thermostat { +namespace esphome::thermostat { enum HumidificationAction : uint8_t { THERMOSTAT_HUMIDITY_CONTROL_ACTION_OFF = 0, @@ -41,13 +40,11 @@ enum OnBootRestoreFrom : uint8_t { struct ThermostatClimateTimer { ThermostatClimateTimer() = default; - ThermostatClimateTimer(bool active, uint32_t time, uint32_t started, std::function func) - : active(active), time(time), started(started), func(std::move(func)) {} + ThermostatClimateTimer(bool active, uint32_t time, uint32_t started) : active(active), time(time), started(started) {} bool active; uint32_t time; uint32_t started; - std::function func; }; struct ThermostatClimateTargetTempConfig { @@ -266,7 +263,8 @@ class ThermostatClimate : public climate::Climate, public Component { bool cancel_timer_(ThermostatClimateTimerIndex timer_index); bool timer_active_(ThermostatClimateTimerIndex timer_index); uint32_t timer_duration_(ThermostatClimateTimerIndex timer_index); - std::function timer_cbf_(ThermostatClimateTimerIndex timer_index); + /// Call the appropriate timer callback based on timer index + void call_timer_callback_(ThermostatClimateTimerIndex timer_index); /// Enhanced timer duration setter with running timer adjustment void set_timer_duration_in_sec_(ThermostatClimateTimerIndex timer_index, uint32_t time); @@ -534,27 +532,16 @@ class ThermostatClimate : public climate::Climate, public Component { Trigger<> *prev_humidity_control_trigger_{nullptr}; /// Climate action timers - std::array timer_{ - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::cooling_max_run_time_timer_callback_, this)), - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::cooling_off_timer_callback_, this)), - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::cooling_on_timer_callback_, this)), - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::fan_mode_timer_callback_, this)), - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::fanning_off_timer_callback_, this)), - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::fanning_on_timer_callback_, this)), - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::heating_max_run_time_timer_callback_, this)), - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::heating_off_timer_callback_, this)), - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::heating_on_timer_callback_, this)), - ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::idle_on_timer_callback_, this)), - }; + std::array timer_{}; /// The set of standard preset configurations this thermostat supports (Eg. AWAY, ECO, etc) FixedVector preset_config_{}; /// The set of custom preset configurations this thermostat supports (eg. "My Custom Preset") FixedVector custom_preset_config_{}; - /// Default custom preset to use on start up (pointer to entry in custom_preset_config_) + private: + /// Default custom preset to use on start up (pointer to entry in custom_preset_config_) const char *default_custom_preset_{nullptr}; }; -} // namespace thermostat -} // namespace esphome +} // namespace esphome::thermostat From 08c0f65f30e711e48b4af20d1ce77d2d7ca30b28 Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Mon, 22 Dec 2025 13:13:18 -0600 Subject: [PATCH 3/3] [sprinkler] Remove internal latching valve support (#12603) --- esphome/components/sprinkler/__init__.py | 109 ++++-------- esphome/components/sprinkler/sprinkler.cpp | 195 +++++---------------- esphome/components/sprinkler/sprinkler.h | 51 +----- 3 files changed, 84 insertions(+), 271 deletions(-) diff --git a/esphome/components/sprinkler/__init__.py b/esphome/components/sprinkler/__init__.py index 2dccb6896a..50c69f9496 100644 --- a/esphome/components/sprinkler/__init__.py +++ b/esphome/components/sprinkler/__init__.py @@ -19,6 +19,7 @@ from esphome.const import ( UNIT_MINUTE, UNIT_SECOND, ) +from esphome.helpers import docs_url AUTO_LOAD = ["number", "switch"] CODEOWNERS = ["@kbx81"] @@ -162,55 +163,9 @@ def validate_sprinkler(config): raise cv.Invalid( f"{CONF_RUN_DURATION} must be greater than {CONF_VALVE_OPEN_DELAY}" ) - if ( - CONF_PUMP_OFF_SWITCH_ID in valve and CONF_PUMP_ON_SWITCH_ID not in valve - ) or ( - CONF_PUMP_ON_SWITCH_ID in valve and CONF_PUMP_OFF_SWITCH_ID not in valve - ): + if CONF_VALVE_SWITCH_ID not in valve: raise cv.Invalid( - f"Both {CONF_PUMP_OFF_SWITCH_ID} and {CONF_PUMP_ON_SWITCH_ID} must be specified for latching pump configuration" - ) - if CONF_PUMP_SWITCH_ID in valve and ( - CONF_PUMP_OFF_SWITCH_ID in valve or CONF_PUMP_ON_SWITCH_ID in valve - ): - raise cv.Invalid( - f"Do not specify {CONF_PUMP_OFF_SWITCH_ID} or {CONF_PUMP_ON_SWITCH_ID} when using {CONF_PUMP_SWITCH_ID}" - ) - if CONF_PUMP_PULSE_DURATION not in sprinkler_controller and ( - CONF_PUMP_OFF_SWITCH_ID in valve or CONF_PUMP_ON_SWITCH_ID in valve - ): - raise cv.Invalid( - f"{CONF_PUMP_PULSE_DURATION} must be specified when using {CONF_PUMP_OFF_SWITCH_ID} and {CONF_PUMP_ON_SWITCH_ID}" - ) - if ( - CONF_VALVE_OFF_SWITCH_ID in valve - and CONF_VALVE_ON_SWITCH_ID not in valve - ) or ( - CONF_VALVE_ON_SWITCH_ID in valve - and CONF_VALVE_OFF_SWITCH_ID not in valve - ): - raise cv.Invalid( - f"Both {CONF_VALVE_OFF_SWITCH_ID} and {CONF_VALVE_ON_SWITCH_ID} must be specified for latching valve configuration" - ) - if CONF_VALVE_SWITCH_ID in valve and ( - CONF_VALVE_OFF_SWITCH_ID in valve or CONF_VALVE_ON_SWITCH_ID in valve - ): - raise cv.Invalid( - f"Do not specify {CONF_VALVE_OFF_SWITCH_ID} or {CONF_VALVE_ON_SWITCH_ID} when using {CONF_VALVE_SWITCH_ID}" - ) - if CONF_VALVE_PULSE_DURATION not in sprinkler_controller and ( - CONF_VALVE_OFF_SWITCH_ID in valve or CONF_VALVE_ON_SWITCH_ID in valve - ): - raise cv.Invalid( - f"{CONF_VALVE_PULSE_DURATION} must be specified when using {CONF_VALVE_OFF_SWITCH_ID} and {CONF_VALVE_ON_SWITCH_ID}" - ) - if ( - CONF_VALVE_SWITCH_ID not in valve - and CONF_VALVE_OFF_SWITCH_ID not in valve - and CONF_VALVE_ON_SWITCH_ID not in valve - ): - raise cv.Invalid( - f"Either {CONF_VALVE_SWITCH_ID} or {CONF_VALVE_OFF_SWITCH_ID} and {CONF_VALVE_ON_SWITCH_ID} must be specified in valve configuration" + f"{CONF_VALVE_SWITCH_ID} must be specified in valve configuration" ) if CONF_RUN_DURATION not in valve and CONF_RUN_DURATION_NUMBER not in valve: raise cv.Invalid( @@ -290,8 +245,15 @@ SPRINKLER_VALVE_SCHEMA = cv.Schema( ), key=CONF_NAME, ), - cv.Optional(CONF_PUMP_OFF_SWITCH_ID): cv.use_id(switch.Switch), - cv.Optional(CONF_PUMP_ON_SWITCH_ID): cv.use_id(switch.Switch), + # Removed latching pump keys - accepted for validation error reporting + cv.Optional(CONF_PUMP_OFF_SWITCH_ID): cv.invalid( + f"This option was removed in 2026.1.0; for latching pumps, use {CONF_PUMP_SWITCH_ID} with an H-Bridge switch. " + f"See {docs_url('components/switch/h_bridge')} for more information" + ), + cv.Optional(CONF_PUMP_ON_SWITCH_ID): cv.invalid( + f"This option was removed in 2026.1.0; for latching pumps, use {CONF_PUMP_SWITCH_ID} with an H-Bridge switch. " + f"See {docs_url('components/switch/h_bridge')} for more information" + ), cv.Optional(CONF_PUMP_SWITCH_ID): cv.use_id(switch.Switch), cv.Optional(CONF_RUN_DURATION): cv.positive_time_period_seconds, cv.Optional(CONF_RUN_DURATION_NUMBER): cv.maybe_simple_value( @@ -321,8 +283,15 @@ SPRINKLER_VALVE_SCHEMA = cv.Schema( switch.switch_schema(SprinklerControllerSwitch), key=CONF_NAME, ), - cv.Optional(CONF_VALVE_OFF_SWITCH_ID): cv.use_id(switch.Switch), - cv.Optional(CONF_VALVE_ON_SWITCH_ID): cv.use_id(switch.Switch), + # Removed latching valve keys - accepted for validation error reporting + cv.Optional(CONF_VALVE_OFF_SWITCH_ID): cv.invalid( + f"This option was removed in 2026.1.0; for latching valves, use {CONF_VALVE_SWITCH_ID} with an H-Bridge switch. " + f"See {docs_url('components/switch/h_bridge')} for more information" + ), + cv.Optional(CONF_VALVE_ON_SWITCH_ID): cv.invalid( + f"This option was removed in 2026.1.0; for latching valves, use {CONF_VALVE_SWITCH_ID} with an H-Bridge switch. " + f"See {docs_url('components/switch/h_bridge')} for more information" + ), cv.Optional(CONF_VALVE_SWITCH_ID): cv.use_id(switch.Switch), } ) @@ -410,8 +379,15 @@ SPRINKLER_CONTROLLER_SCHEMA = cv.Schema( validate_min_max, key=CONF_NAME, ), - cv.Optional(CONF_PUMP_PULSE_DURATION): cv.positive_time_period_milliseconds, - cv.Optional(CONF_VALVE_PULSE_DURATION): cv.positive_time_period_milliseconds, + # Removed latching valve keys - accepted for validation error reporting + cv.Optional(CONF_PUMP_PULSE_DURATION): cv.invalid( + f"This option was removed in 2026.1.0; for latching pumps, use {CONF_PUMP_SWITCH_ID} with an H-Bridge switch. " + f"See {docs_url('components/switch/h_bridge')} for more information" + ), + cv.Optional(CONF_VALVE_PULSE_DURATION): cv.invalid( + f"This option was removed in 2026.1.0; for latching valves, use {CONF_VALVE_SWITCH_ID} with an H-Bridge switch. " + f"See {docs_url('components/switch/h_bridge')} for more information" + ), cv.Exclusive( CONF_PUMP_START_PUMP_DELAY, "pump_start_xxxx_delay" ): cv.positive_time_period_seconds, @@ -765,35 +741,10 @@ async def to_code(config): valve_index, valve_switch, valve[CONF_RUN_DURATION] ) ) - elif CONF_VALVE_OFF_SWITCH_ID in valve and CONF_VALVE_ON_SWITCH_ID in valve: - valve_switch_off = await cg.get_variable( - valve[CONF_VALVE_OFF_SWITCH_ID] - ) - valve_switch_on = await cg.get_variable(valve[CONF_VALVE_ON_SWITCH_ID]) - cg.add( - var.configure_valve_switch_pulsed( - valve_index, - valve_switch_off, - valve_switch_on, - sprinkler_controller[CONF_VALVE_PULSE_DURATION], - valve[CONF_RUN_DURATION], - ) - ) if CONF_PUMP_SWITCH_ID in valve: pump = await cg.get_variable(valve[CONF_PUMP_SWITCH_ID]) cg.add(var.configure_valve_pump_switch(valve_index, pump)) - elif CONF_PUMP_OFF_SWITCH_ID in valve and CONF_PUMP_ON_SWITCH_ID in valve: - pump_off = await cg.get_variable(valve[CONF_PUMP_OFF_SWITCH_ID]) - pump_on = await cg.get_variable(valve[CONF_PUMP_ON_SWITCH_ID]) - cg.add( - var.configure_valve_pump_switch_pulsed( - valve_index, - pump_off, - pump_on, - sprinkler_controller[CONF_PUMP_PULSE_DURATION], - ) - ) if CONF_RUN_DURATION_NUMBER in valve: num_rd_var = await number.new_number( diff --git a/esphome/components/sprinkler/sprinkler.cpp b/esphome/components/sprinkler/sprinkler.cpp index 69452f2e9e..ca9f85abd8 100644 --- a/esphome/components/sprinkler/sprinkler.cpp +++ b/esphome/components/sprinkler/sprinkler.cpp @@ -11,70 +11,6 @@ namespace esphome::sprinkler { static const char *const TAG = "sprinkler"; -SprinklerSwitch::SprinklerSwitch() {} -SprinklerSwitch::SprinklerSwitch(switch_::Switch *sprinkler_switch) : on_switch_(sprinkler_switch) {} -SprinklerSwitch::SprinklerSwitch(switch_::Switch *off_switch, switch_::Switch *on_switch, uint32_t pulse_duration) - : pulse_duration_(pulse_duration), off_switch_(off_switch), on_switch_(on_switch) {} - -bool SprinklerSwitch::is_latching_valve() { return (this->off_switch_ != nullptr) && (this->on_switch_ != nullptr); } - -void SprinklerSwitch::loop() { - if ((this->pinned_millis_) && (App.get_loop_component_start_time() > this->pinned_millis_ + this->pulse_duration_)) { - this->pinned_millis_ = 0; // reset tracker - if (this->off_switch_->state) { - this->off_switch_->turn_off(); - } - if (this->on_switch_->state) { - this->on_switch_->turn_off(); - } - } -} - -void SprinklerSwitch::turn_off() { - if (!this->state()) { // do nothing if we're already in the requested state - return; - } - if (this->off_switch_ != nullptr) { // latching valve, start a pulse - if (!this->off_switch_->state) { - this->off_switch_->turn_on(); - } - this->pinned_millis_ = millis(); - } else if (this->on_switch_ != nullptr) { // non-latching valve - this->on_switch_->turn_off(); - } - this->state_ = false; -} - -void SprinklerSwitch::turn_on() { - if (this->state()) { // do nothing if we're already in the requested state - return; - } - if (this->off_switch_ != nullptr) { // latching valve, start a pulse - if (!this->on_switch_->state) { - this->on_switch_->turn_on(); - } - this->pinned_millis_ = millis(); - } else if (this->on_switch_ != nullptr) { // non-latching valve - this->on_switch_->turn_on(); - } - this->state_ = true; -} - -bool SprinklerSwitch::state() { - if ((this->off_switch_ == nullptr) && (this->on_switch_ != nullptr)) { // latching valve is not configured... - return this->on_switch_->state; // ...so just return the pump switch state - } - return this->state_; -} - -void SprinklerSwitch::sync_valve_state(bool latch_state) { - if (this->is_latching_valve()) { - this->state_ = latch_state; - } else if (this->on_switch_ != nullptr) { - this->state_ = this->on_switch_->state; - } -} - void SprinklerControllerNumber::setup() { float value; if (!this->restore_value_) { @@ -219,8 +155,8 @@ void SprinklerValveOperator::start() { this->state_ = STARTING; // STARTING state requires both a pump and a start_delay_ if (this->start_delay_is_valve_delay_) { this->pump_on_(); - } else if (!this->pump_switch()->state()) { // if the pump is already on, wait to switch on the valve - this->valve_on_(); // to ensure consistent run time + } else if (!this->pump_switch()->state) { // if the pump is already on, wait to switch on the valve + this->valve_on_(); // to ensure consistent run time } } else { this->run_(); // there is no start_delay_, so just start the pump and valve @@ -240,8 +176,8 @@ void SprinklerValveOperator::stop() { } else { this->valve_off_(); } - if (this->pump_switch()->state()) { // if the pump is still on at this point, it may be in use... - this->valve_off_(); // ...so just switch the valve off now to ensure consistent run time + if (this->pump_switch()->state) { // if the pump is still on at this point, it may be in use... + this->valve_off_(); // ...so just switch the valve off now to ensure consistent run time } } else { this->kill_(); // there is no stop_delay_, so just stop the pump and valve @@ -274,7 +210,7 @@ uint32_t SprinklerValveOperator::time_remaining() { SprinklerState SprinklerValveOperator::state() { return this->state_; } -SprinklerSwitch *SprinklerValveOperator::pump_switch() { +switch_::Switch *SprinklerValveOperator::pump_switch() { if ((this->controller_ == nullptr) || (this->valve_ == nullptr)) { return nullptr; } @@ -285,48 +221,50 @@ SprinklerSwitch *SprinklerValveOperator::pump_switch() { } void SprinklerValveOperator::pump_off_() { - if ((this->valve_ == nullptr) || (this->pump_switch() == nullptr)) { // safety first! + auto *pump = this->pump_switch(); + if ((this->valve_ == nullptr) || (pump == nullptr)) { // safety first! return; } if (this->controller_ == nullptr) { // safety first! - this->pump_switch()->turn_off(); // if no controller was set, just switch off the pump + pump->turn_off(); // if no controller was set, just switch off the pump } else { // ...otherwise, do it "safely" auto state = this->state_; // this is silly, but... this->state_ = BYPASS; // ...exclude me from the pump-in-use check that set_pump_state() does - this->controller_->set_pump_state(this->pump_switch(), false); + this->controller_->set_pump_state(pump, false); this->state_ = state; } } void SprinklerValveOperator::pump_on_() { - if ((this->valve_ == nullptr) || (this->pump_switch() == nullptr)) { // safety first! + auto *pump = this->pump_switch(); + if ((this->valve_ == nullptr) || (pump == nullptr)) { // safety first! return; } if (this->controller_ == nullptr) { // safety first! - this->pump_switch()->turn_on(); // if no controller was set, just switch on the pump + pump->turn_on(); // if no controller was set, just switch on the pump } else { // ...otherwise, do it "safely" auto state = this->state_; // this is silly, but... this->state_ = BYPASS; // ...exclude me from the pump-in-use check that set_pump_state() does - this->controller_->set_pump_state(this->pump_switch(), true); + this->controller_->set_pump_state(pump, true); this->state_ = state; } } void SprinklerValveOperator::valve_off_() { - if (this->valve_ == nullptr) { // safety first! + if ((this->valve_ == nullptr) || (this->valve_->valve_switch == nullptr)) { // safety first! return; } - if (this->valve_->valve_switch.state()) { - this->valve_->valve_switch.turn_off(); + if (this->valve_->valve_switch->state) { + this->valve_->valve_switch->turn_off(); } } void SprinklerValveOperator::valve_on_() { - if (this->valve_ == nullptr) { // safety first! + if ((this->valve_ == nullptr) || (this->valve_->valve_switch == nullptr)) { // safety first! return; } - if (!this->valve_->valve_switch.state()) { - this->valve_->valve_switch.turn_on(); + if (!this->valve_->valve_switch->state) { + this->valve_->valve_switch->turn_on(); } } @@ -401,12 +339,6 @@ Sprinkler::Sprinkler(const std::string &name) { void Sprinkler::setup() { this->all_valves_off_(true); } void Sprinkler::loop() { - for (auto &p : this->pump_) { - p.loop(); - } - for (auto &v : this->valve_) { - v.valve_switch.loop(); - } for (auto &vo : this->valve_op_) { vo.loop(); } @@ -423,10 +355,15 @@ void Sprinkler::add_valve(SprinklerControllerSwitch *valve_sw, SprinklerControll new_valve->controller_switch = valve_sw; new_valve->controller_switch->set_state_lambda([this, new_valve_number]() -> optional { - if (this->valve_pump_switch(new_valve_number) != nullptr) { - return this->valve_switch(new_valve_number)->state() && this->valve_pump_switch(new_valve_number)->state(); + auto *valve = this->valve_switch(new_valve_number); + auto *pump = this->valve_pump_switch(new_valve_number); + if (valve == nullptr) { + return false; } - return this->valve_switch(new_valve_number)->state(); + if (pump != nullptr) { + return valve->state && pump->state; + } + return valve->state; }); new_valve->valve_turn_off_automation = @@ -496,18 +433,7 @@ void Sprinkler::set_controller_repeat_number(SprinklerControllerNumber *repeat_n void Sprinkler::configure_valve_switch(size_t valve_number, switch_::Switch *valve_switch, uint32_t run_duration) { if (this->is_a_valid_valve(valve_number)) { - this->valve_[valve_number].valve_switch.set_on_switch(valve_switch); - this->valve_[valve_number].run_duration = run_duration; - } -} - -void Sprinkler::configure_valve_switch_pulsed(size_t valve_number, switch_::Switch *valve_switch_off, - switch_::Switch *valve_switch_on, uint32_t pulse_duration, - uint32_t run_duration) { - if (this->is_a_valid_valve(valve_number)) { - this->valve_[valve_number].valve_switch.set_off_switch(valve_switch_off); - this->valve_[valve_number].valve_switch.set_on_switch(valve_switch_on); - this->valve_[valve_number].valve_switch.set_pulse_duration(pulse_duration); + this->valve_[valve_number].valve_switch = valve_switch; this->valve_[valve_number].run_duration = run_duration; } } @@ -515,31 +441,12 @@ void Sprinkler::configure_valve_switch_pulsed(size_t valve_number, switch_::Swit void Sprinkler::configure_valve_pump_switch(size_t valve_number, switch_::Switch *pump_switch) { if (this->is_a_valid_valve(valve_number)) { for (size_t i = 0; i < this->pump_.size(); i++) { // check each existing registered pump - if (this->pump_[i].on_switch() == pump_switch) { // if the "new" pump matches one we already have... - this->valve_[valve_number].pump_switch_index = i; // ...save its index in the SprinklerSwitch vector pump_... + if (this->pump_[i] == pump_switch) { // if the "new" pump matches one we already have... + this->valve_[valve_number].pump_switch_index = i; // ...save its index in the pump vector... return; // ...and we are done } - } // if we end up here, no pumps matched, so add a new one and set the valve's SprinklerSwitch at it - this->pump_.resize(this->pump_.size() + 1); - this->pump_.back().set_on_switch(pump_switch); - this->valve_[valve_number].pump_switch_index = this->pump_.size() - 1; // save the index to the new pump - } -} - -void Sprinkler::configure_valve_pump_switch_pulsed(size_t valve_number, switch_::Switch *pump_switch_off, - switch_::Switch *pump_switch_on, uint32_t pulse_duration) { - if (this->is_a_valid_valve(valve_number)) { - for (size_t i = 0; i < this->pump_.size(); i++) { // check each existing registered pump - if ((this->pump_[i].off_switch() == pump_switch_off) && - (this->pump_[i].on_switch() == pump_switch_on)) { // if the "new" pump matches one we already have... - this->valve_[valve_number].pump_switch_index = i; // ...save its index in the SprinklerSwitch vector pump_... - return; // ...and we are done - } - } // if we end up here, no pumps matched, so add a new one and set the valve's SprinklerSwitch at it - this->pump_.resize(this->pump_.size() + 1); - this->pump_.back().set_off_switch(pump_switch_off); - this->pump_.back().set_on_switch(pump_switch_on); - this->pump_.back().set_pulse_duration(pulse_duration); + } // if we end up here, no pumps matched, so add a new one + this->pump_.push_back(pump_switch); this->valve_[valve_number].pump_switch_index = this->pump_.size() - 1; // save the index to the new pump } } @@ -1041,7 +948,7 @@ size_t Sprinkler::number_of_valves() { return this->valve_.size(); } bool Sprinkler::is_a_valid_valve(const size_t valve_number) { return (valve_number < this->number_of_valves()); } -bool Sprinkler::pump_in_use(SprinklerSwitch *pump_switch) { +bool Sprinkler::pump_in_use(switch_::Switch *pump_switch) { if (pump_switch == nullptr) { return false; // we can't do anything if there's nothing to check } @@ -1054,8 +961,7 @@ bool Sprinkler::pump_in_use(SprinklerSwitch *pump_switch) { for (auto &vo : this->valve_op_) { // first, check if any SprinklerValveOperator has a valve dependent on this pump if ((vo.state() != BYPASS) && (vo.pump_switch() != nullptr)) { // the SprinklerValveOperator is configured with a pump; now check if it is the pump of interest - if ((vo.pump_switch()->off_switch() == pump_switch->off_switch()) && - (vo.pump_switch()->on_switch() == pump_switch->on_switch())) { + if (vo.pump_switch() == pump_switch) { // now if the SprinklerValveOperator has a pump and it is either ACTIVE, is STARTING with a valve delay or // is STOPPING with a valve delay, its pump can be considered "in use", so just return indicating this now if ((vo.state() == ACTIVE) || @@ -1074,13 +980,12 @@ bool Sprinkler::pump_in_use(SprinklerSwitch *pump_switch) { if (valve_pump == nullptr) { return false; // valve has no pump, so this pump isn't in use by it } - return (pump_switch->off_switch() == valve_pump->off_switch()) && - (pump_switch->on_switch() == valve_pump->on_switch()); + return pump_switch == valve_pump; } return false; } -void Sprinkler::set_pump_state(SprinklerSwitch *pump_switch, bool state) { +void Sprinkler::set_pump_state(switch_::Switch *pump_switch, bool state) { if (pump_switch == nullptr) { return; // we can't do anything if there's nothing to check } @@ -1091,15 +996,10 @@ void Sprinkler::set_pump_state(SprinklerSwitch *pump_switch, bool state) { if (controller != this) { // dummy check if (controller->pump_in_use(pump_switch)) { hold_pump_on = true; // if another controller says it's using this pump, keep it on - // at this point we know if there exists another SprinklerSwitch that is "on" with its - // off_switch_ and on_switch_ pointers pointing to the same pair of switch objects } } } if (hold_pump_on) { - // at this point we know if there exists another SprinklerSwitch that is "on" with its - // off_switch_ and on_switch_ pointers pointing to the same pair of switch objects... - pump_switch->sync_valve_state(true); // ...so ensure our state is consistent ESP_LOGD(TAG, "Leaving pump on because another controller instance is using it"); } @@ -1107,8 +1007,6 @@ void Sprinkler::set_pump_state(SprinklerSwitch *pump_switch, bool state) { pump_switch->turn_on(); } else if (!hold_pump_on && !this->pump_in_use(pump_switch)) { pump_switch->turn_off(); - } else if (hold_pump_on) { // we must assume the other controller will switch off the pump when done... - pump_switch->sync_valve_state(false); // ...this only impacts latching valves } } @@ -1274,23 +1172,23 @@ SprinklerControllerSwitch *Sprinkler::enable_switch(size_t valve_number) { return nullptr; } -SprinklerSwitch *Sprinkler::valve_switch(const size_t valve_number) { +switch_::Switch *Sprinkler::valve_switch(const size_t valve_number) { if (this->is_a_valid_valve(valve_number)) { - return &this->valve_[valve_number].valve_switch; + return this->valve_[valve_number].valve_switch; } return nullptr; } -SprinklerSwitch *Sprinkler::valve_pump_switch(const size_t valve_number) { +switch_::Switch *Sprinkler::valve_pump_switch(const size_t valve_number) { if (this->is_a_valid_valve(valve_number) && this->valve_[valve_number].pump_switch_index.has_value()) { - return &this->pump_[this->valve_[valve_number].pump_switch_index.value()]; + return this->pump_[this->valve_[valve_number].pump_switch_index.value()]; } return nullptr; } -SprinklerSwitch *Sprinkler::valve_pump_switch_by_pump_index(size_t pump_index) { +switch_::Switch *Sprinkler::valve_pump_switch_by_pump_index(size_t pump_index) { if (pump_index < this->pump_.size()) { - return &this->pump_[pump_index]; + return this->pump_[pump_index]; } return nullptr; } @@ -1454,8 +1352,9 @@ void Sprinkler::start_valve_(SprinklerValveRunRequest *req) { void Sprinkler::all_valves_off_(const bool include_pump) { for (size_t valve_index = 0; valve_index < this->number_of_valves(); valve_index++) { - if (this->valve_[valve_index].valve_switch.state()) { - this->valve_[valve_index].valve_switch.turn_off(); + auto *valve_sw = this->valve_[valve_index].valve_switch; + if ((valve_sw != nullptr) && valve_sw->state) { + valve_sw->turn_off(); } if (include_pump) { this->set_pump_state(this->valve_pump_switch(valve_index), false); @@ -1754,10 +1653,6 @@ void Sprinkler::dump_config() { " Name: %s\n" " Run Duration: %" PRIu32 " seconds", valve_number, this->valve_name(valve_number), this->valve_run_duration(valve_number)); - if (this->valve_[valve_number].valve_switch.pulse_duration()) { - ESP_LOGCONFIG(TAG, " Pulse Duration: %" PRIu32 " milliseconds", - this->valve_[valve_number].valve_switch.pulse_duration()); - } } if (!this->pump_.empty()) { ESP_LOGCONFIG(TAG, " Total number of pumps: %zu", this->pump_.size()); diff --git a/esphome/components/sprinkler/sprinkler.h b/esphome/components/sprinkler/sprinkler.h index 7aa33c2df9..25e2d42446 100644 --- a/esphome/components/sprinkler/sprinkler.h +++ b/esphome/components/sprinkler/sprinkler.h @@ -35,7 +35,6 @@ enum SprinklerValveRunRequestOrigin : uint8_t { class Sprinkler; // this component class SprinklerControllerNumber; // number components that appear in the front end; based on number core class SprinklerControllerSwitch; // switches that appear in the front end; based on switch core -class SprinklerSwitch; // switches representing any valve or pump; provides abstraction for latching valves class SprinklerValveOperator; // manages all switching on/off of valves and associated pumps class SprinklerValveRunRequest; // tells the sprinkler controller what valve to run and for how long as well as what // SprinklerValveOperator is handling it @@ -43,34 +42,6 @@ template class StartSingleValveAction; template class ShutdownAction; template class ResumeOrStartAction; -class SprinklerSwitch { - public: - SprinklerSwitch(); - SprinklerSwitch(switch_::Switch *sprinkler_switch); - SprinklerSwitch(switch_::Switch *off_switch, switch_::Switch *on_switch, uint32_t pulse_duration); - - bool is_latching_valve(); // returns true if configured as a latching valve - void loop(); // called as a part of loop(), used for latching valve pulses - uint32_t pulse_duration() { return this->pulse_duration_; } - bool state(); // returns the switch's current state - void set_off_switch(switch_::Switch *off_switch) { this->off_switch_ = off_switch; } - void set_on_switch(switch_::Switch *on_switch) { this->on_switch_ = on_switch; } - void set_pulse_duration(uint32_t pulse_duration) { this->pulse_duration_ = pulse_duration; } - void sync_valve_state( - bool latch_state); // syncs internal state to switch; if latching valve, sets state to latch_state - void turn_off(); // sets internal flag and actuates the switch - void turn_on(); // sets internal flag and actuates the switch - switch_::Switch *off_switch() { return this->off_switch_; } - switch_::Switch *on_switch() { return this->on_switch_; } - - protected: - bool state_{false}; - uint32_t pulse_duration_{0}; - uint64_t pinned_millis_{0}; - switch_::Switch *off_switch_{nullptr}; // only used for latching valves - switch_::Switch *on_switch_{nullptr}; // used for both latching and non-latching valves -}; - struct SprinklerQueueItem { size_t valve_number; uint32_t run_duration; @@ -88,7 +59,7 @@ struct SprinklerValve { SprinklerControllerNumber *run_duration_number; SprinklerControllerSwitch *controller_switch; SprinklerControllerSwitch *enable_switch; - SprinklerSwitch valve_switch; + switch_::Switch *valve_switch; uint32_t run_duration; optional pump_switch_index; bool valve_cycle_complete; @@ -155,7 +126,7 @@ class SprinklerValveOperator { uint32_t run_duration(); // returns the desired run duration in seconds uint32_t time_remaining(); // returns seconds remaining (does not include stop_delay_) SprinklerState state(); // returns the valve's state/status - SprinklerSwitch *pump_switch(); // returns this SprinklerValveOperator's pump's SprinklerSwitch + switch_::Switch *pump_switch(); // returns this SprinklerValveOperator's pump switch protected: void pump_off_(); @@ -228,13 +199,9 @@ class Sprinkler : public Component { /// configure a valve's switch object and run duration. run_duration is time in seconds. void configure_valve_switch(size_t valve_number, switch_::Switch *valve_switch, uint32_t run_duration); - void configure_valve_switch_pulsed(size_t valve_number, switch_::Switch *valve_switch_off, - switch_::Switch *valve_switch_on, uint32_t pulse_duration, uint32_t run_duration); /// configure a valve's associated pump switch object void configure_valve_pump_switch(size_t valve_number, switch_::Switch *pump_switch); - void configure_valve_pump_switch_pulsed(size_t valve_number, switch_::Switch *pump_switch_off, - switch_::Switch *pump_switch_on, uint32_t pulse_duration); /// configure a valve's run duration number component void configure_valve_run_duration_number(size_t valve_number, SprinklerControllerNumber *run_duration_number); @@ -383,10 +350,10 @@ class Sprinkler : public Component { bool is_a_valid_valve(size_t valve_number); /// returns true if the pump the pointer points to is in use - bool pump_in_use(SprinklerSwitch *pump_switch); + bool pump_in_use(switch_::Switch *pump_switch); /// switches on/off a pump "safely" by checking that the new state will not conflict with another controller - void set_pump_state(SprinklerSwitch *pump_switch, bool state); + void set_pump_state(switch_::Switch *pump_switch, bool state); /// returns the amount of time in seconds required for all valves uint32_t total_cycle_time_all_valves(); @@ -419,13 +386,13 @@ class Sprinkler : public Component { SprinklerControllerSwitch *enable_switch(size_t valve_number); /// returns a pointer to a valve's switch object - SprinklerSwitch *valve_switch(size_t valve_number); + switch_::Switch *valve_switch(size_t valve_number); /// returns a pointer to a valve's pump switch object - SprinklerSwitch *valve_pump_switch(size_t valve_number); + switch_::Switch *valve_pump_switch(size_t valve_number); /// returns a pointer to a valve's pump switch object - SprinklerSwitch *valve_pump_switch_by_pump_index(size_t pump_index); + switch_::Switch *valve_pump_switch_by_pump_index(size_t pump_index); protected: /// returns true if valve number is enabled @@ -577,8 +544,8 @@ class Sprinkler : public Component { /// Queue of valves to activate next, regardless of auto-advance std::vector queued_valves_; - /// Sprinkler valve pump objects - std::vector pump_; + /// Sprinkler valve pump switches + std::vector pump_; /// Sprinkler valve objects std::vector valve_;