From 993765d732e0c67dec192bb73577ea30aad2cb29 Mon Sep 17 00:00:00 2001 From: Douwe <61123717+dhoeben@users.noreply.github.com> Date: Sun, 25 Jan 2026 02:18:13 +0100 Subject: [PATCH] [water_heater] Remove Component inheritance from base class (#13510) Co-authored-by: J. Nick Koston Co-authored-by: Claude Opus 4.5 --- .../template/water_heater/__init__.py | 33 +++++++++++-------- .../water_heater/template_water_heater.cpp | 2 +- .../water_heater/template_water_heater.h | 2 +- esphome/components/water_heater/__init__.py | 6 ++-- .../components/water_heater/water_heater.cpp | 7 ++-- .../components/water_heater/water_heater.h | 9 +++-- 6 files changed, 29 insertions(+), 30 deletions(-) diff --git a/esphome/components/template/water_heater/__init__.py b/esphome/components/template/water_heater/__init__.py index 716289035a..bddd378b23 100644 --- a/esphome/components/template/water_heater/__init__.py +++ b/esphome/components/template/water_heater/__init__.py @@ -20,7 +20,7 @@ from .. import template_ns CONF_CURRENT_TEMPERATURE = "current_temperature" TemplateWaterHeater = template_ns.class_( - "TemplateWaterHeater", water_heater.WaterHeater + "TemplateWaterHeater", cg.Component, water_heater.WaterHeater ) TemplateWaterHeaterPublishAction = template_ns.class_( @@ -36,24 +36,29 @@ RESTORE_MODES = { "RESTORE_AND_CALL": TemplateWaterHeaterRestoreMode.WATER_HEATER_RESTORE_AND_CALL, } -CONFIG_SCHEMA = water_heater.water_heater_schema(TemplateWaterHeater).extend( - { - cv.Optional(CONF_OPTIMISTIC, default=True): cv.boolean, - cv.Optional(CONF_SET_ACTION): automation.validate_automation(single=True), - cv.Optional(CONF_RESTORE_MODE, default="NO_RESTORE"): cv.enum( - RESTORE_MODES, upper=True - ), - cv.Optional(CONF_CURRENT_TEMPERATURE): cv.returning_lambda, - cv.Optional(CONF_MODE): cv.returning_lambda, - cv.Optional(CONF_SUPPORTED_MODES): cv.ensure_list( - water_heater.validate_water_heater_mode - ), - } +CONFIG_SCHEMA = ( + water_heater.water_heater_schema(TemplateWaterHeater) + .extend( + { + cv.Optional(CONF_OPTIMISTIC, default=True): cv.boolean, + cv.Optional(CONF_SET_ACTION): automation.validate_automation(single=True), + cv.Optional(CONF_RESTORE_MODE, default="NO_RESTORE"): cv.enum( + RESTORE_MODES, upper=True + ), + cv.Optional(CONF_CURRENT_TEMPERATURE): cv.returning_lambda, + cv.Optional(CONF_MODE): cv.returning_lambda, + cv.Optional(CONF_SUPPORTED_MODES): cv.ensure_list( + water_heater.validate_water_heater_mode + ), + } + ) + .extend(cv.COMPONENT_SCHEMA) ) async def to_code(config: ConfigType) -> None: var = cg.new_Pvariable(config[CONF_ID]) + await cg.register_component(var, config) await water_heater.register_water_heater(var, config) cg.add(var.set_optimistic(config[CONF_OPTIMISTIC])) diff --git a/esphome/components/template/water_heater/template_water_heater.cpp b/esphome/components/template/water_heater/template_water_heater.cpp index 5ae5c30f36..e89c96ca48 100644 --- a/esphome/components/template/water_heater/template_water_heater.cpp +++ b/esphome/components/template/water_heater/template_water_heater.cpp @@ -10,7 +10,7 @@ TemplateWaterHeater::TemplateWaterHeater() : set_trigger_(new Trigger<>()) {} void TemplateWaterHeater::setup() { if (this->restore_mode_ == TemplateWaterHeaterRestoreMode::WATER_HEATER_RESTORE || this->restore_mode_ == TemplateWaterHeaterRestoreMode::WATER_HEATER_RESTORE_AND_CALL) { - auto restore = this->restore_state(); + auto restore = this->restore_state_(); if (restore.has_value()) { restore->perform(); diff --git a/esphome/components/template/water_heater/template_water_heater.h b/esphome/components/template/water_heater/template_water_heater.h index e5f51b72dc..c2a2dcbb23 100644 --- a/esphome/components/template/water_heater/template_water_heater.h +++ b/esphome/components/template/water_heater/template_water_heater.h @@ -13,7 +13,7 @@ enum TemplateWaterHeaterRestoreMode { WATER_HEATER_RESTORE_AND_CALL, }; -class TemplateWaterHeater : public water_heater::WaterHeater { +class TemplateWaterHeater : public Component, public water_heater::WaterHeater { public: TemplateWaterHeater(); diff --git a/esphome/components/water_heater/__init__.py b/esphome/components/water_heater/__init__.py index 5420e7c435..db32c2d919 100644 --- a/esphome/components/water_heater/__init__.py +++ b/esphome/components/water_heater/__init__.py @@ -18,7 +18,7 @@ CODEOWNERS = ["@dhoeben"] IS_PLATFORM_COMPONENT = True water_heater_ns = cg.esphome_ns.namespace("water_heater") -WaterHeater = water_heater_ns.class_("WaterHeater", cg.EntityBase, cg.Component) +WaterHeater = water_heater_ns.class_("WaterHeater", cg.EntityBase) WaterHeaterCall = water_heater_ns.class_("WaterHeaterCall") WaterHeaterTraits = water_heater_ns.class_("WaterHeaterTraits") @@ -46,7 +46,7 @@ _WATER_HEATER_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend( } ), } -).extend(cv.COMPONENT_SCHEMA) +) _WATER_HEATER_SCHEMA.add_extra(entity_duplicate_validator("water_heater")) @@ -91,8 +91,6 @@ async def register_water_heater(var: cg.Pvariable, config: ConfigType) -> cg.Pva cg.add_define("USE_WATER_HEATER") - await cg.register_component(var, config) - cg.add(cg.App.register_water_heater(var)) CORE.register_platform_component("water_heater", var) diff --git a/esphome/components/water_heater/water_heater.cpp b/esphome/components/water_heater/water_heater.cpp index 7b947057e1..fbb4181209 100644 --- a/esphome/components/water_heater/water_heater.cpp +++ b/esphome/components/water_heater/water_heater.cpp @@ -146,10 +146,6 @@ void WaterHeaterCall::validate_() { } } -void WaterHeater::setup() { - this->pref_ = global_preferences->make_preference(this->get_preference_hash()); -} - void WaterHeater::publish_state() { auto traits = this->get_traits(); ESP_LOGD(TAG, @@ -188,7 +184,8 @@ void WaterHeater::publish_state() { this->pref_.save(&saved); } -optional WaterHeater::restore_state() { +optional WaterHeater::restore_state_() { + this->pref_ = global_preferences->make_preference(this->get_preference_hash()); SavedWaterHeaterState recovered{}; if (!this->pref_.load(&recovered)) return {}; diff --git a/esphome/components/water_heater/water_heater.h b/esphome/components/water_heater/water_heater.h index e223dd59b2..84fc46d208 100644 --- a/esphome/components/water_heater/water_heater.h +++ b/esphome/components/water_heater/water_heater.h @@ -177,7 +177,7 @@ class WaterHeaterTraits { WaterHeaterModeMask supported_modes_; }; -class WaterHeater : public EntityBase, public Component { +class WaterHeater : public EntityBase { public: WaterHeaterMode get_mode() const { return this->mode_; } float get_current_temperature() const { return this->current_temperature_; } @@ -204,16 +204,15 @@ class WaterHeater : public EntityBase, public Component { #endif virtual void control(const WaterHeaterCall &call) = 0; - void setup() override; - - optional restore_state(); - protected: virtual WaterHeaterTraits traits() = 0; /// Log the traits of this water heater for dump_config(). void dump_traits_(const char *tag); + /// Restore the state of the water heater, call this from your setup() method. + optional restore_state_(); + /// Set the mode of the water heater. Should only be called from control(). void set_mode_(WaterHeaterMode mode) { this->mode_ = mode; } /// Set the target temperature of the water heater. Should only be called from control().