From a120a455bfa47da44643a881ae2ac7a4bd224cb5 Mon Sep 17 00:00:00 2001 From: Sergey Dudanov Date: Sun, 30 Jul 2023 23:52:01 +0400 Subject: [PATCH] climate triggers Climate and ClimateCall references (#5028) --- esphome/components/climate/__init__.py | 16 ++++++++++++---- esphome/components/climate/automation.h | 8 ++++---- esphome/components/climate/climate.cpp | 8 ++++---- esphome/components/climate/climate.h | 8 ++++---- esphome/components/mqtt/mqtt_climate.cpp | 2 +- esphome/core/controller.cpp | 2 +- tests/test1.yaml | 9 +++++++-- 7 files changed, 33 insertions(+), 20 deletions(-) diff --git a/esphome/components/climate/__init__.py b/esphome/components/climate/__init__.py index bf167fe837..85242eb344 100644 --- a/esphome/components/climate/__init__.py +++ b/esphome/components/climate/__init__.py @@ -127,8 +127,12 @@ def single_visual_temperature(value): # Actions ControlAction = climate_ns.class_("ControlAction", automation.Action) -StateTrigger = climate_ns.class_("StateTrigger", automation.Trigger.template()) -ControlTrigger = climate_ns.class_("ControlTrigger", automation.Trigger.template()) +StateTrigger = climate_ns.class_( + "StateTrigger", automation.Trigger.template(Climate.operator("ref")) +) +ControlTrigger = climate_ns.class_( + "ControlTrigger", automation.Trigger.template(ClimateCall.operator("ref")) +) VISUAL_TEMPERATURE_STEP_SCHEMA = cv.Any( single_visual_temperature, @@ -322,11 +326,15 @@ async def setup_climate_core_(var, config): for conf in config.get(CONF_ON_STATE, []): trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) - await automation.build_automation(trigger, [], conf) + await automation.build_automation( + trigger, [(Climate.operator("ref"), "x")], conf + ) for conf in config.get(CONF_ON_CONTROL, []): trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) - await automation.build_automation(trigger, [], conf) + await automation.build_automation( + trigger, [(ClimateCall.operator("ref"), "x")], conf + ) async def register_climate(var, config): diff --git a/esphome/components/climate/automation.h b/esphome/components/climate/automation.h index 9b06563eb4..382871e1e7 100644 --- a/esphome/components/climate/automation.h +++ b/esphome/components/climate/automation.h @@ -42,17 +42,17 @@ template class ControlAction : public Action { Climate *climate_; }; -class ControlTrigger : public Trigger<> { +class ControlTrigger : public Trigger { public: ControlTrigger(Climate *climate) { - climate->add_on_control_callback([this]() { this->trigger(); }); + climate->add_on_control_callback([this](ClimateCall &x) { this->trigger(x); }); } }; -class StateTrigger : public Trigger<> { +class StateTrigger : public Trigger { public: StateTrigger(Climate *climate) { - climate->add_on_state_callback([this]() { this->trigger(); }); + climate->add_on_state_callback([this](Climate &x) { this->trigger(x); }); } }; diff --git a/esphome/components/climate/climate.cpp b/esphome/components/climate/climate.cpp index a032596eb3..1680601279 100644 --- a/esphome/components/climate/climate.cpp +++ b/esphome/components/climate/climate.cpp @@ -7,6 +7,7 @@ namespace climate { static const char *const TAG = "climate"; void ClimateCall::perform() { + this->parent_->control_callback_.call(*this); ESP_LOGD(TAG, "'%s' - Setting", this->parent_->get_name().c_str()); this->validate_(); if (this->mode_.has_value()) { @@ -44,7 +45,6 @@ void ClimateCall::perform() { if (this->target_temperature_high_.has_value()) { ESP_LOGD(TAG, " Target Temperature High: %.2f", *this->target_temperature_high_); } - this->parent_->control_callback_.call(); this->parent_->control(*this); } void ClimateCall::validate_() { @@ -300,11 +300,11 @@ ClimateCall &ClimateCall::set_swing_mode(optional swing_mode) return *this; } -void Climate::add_on_state_callback(std::function &&callback) { +void Climate::add_on_state_callback(std::function &&callback) { this->state_callback_.add(std::move(callback)); } -void Climate::add_on_control_callback(std::function &&callback) { +void Climate::add_on_control_callback(std::function &&callback) { this->control_callback_.add(std::move(callback)); } @@ -408,7 +408,7 @@ void Climate::publish_state() { } // Send state to frontend - this->state_callback_.call(); + this->state_callback_.call(*this); // Save state this->save_state_(); } diff --git a/esphome/components/climate/climate.h b/esphome/components/climate/climate.h index 656e1c4852..f90db3f52a 100644 --- a/esphome/components/climate/climate.h +++ b/esphome/components/climate/climate.h @@ -198,7 +198,7 @@ class Climate : public EntityBase { * * @param callback The callback to call. */ - void add_on_state_callback(std::function &&callback); + void add_on_state_callback(std::function &&callback); /** * Add a callback for the climate device configuration; each time the configuration parameters of a climate device @@ -206,7 +206,7 @@ class Climate : public EntityBase { * * @param callback The callback to call. */ - void add_on_control_callback(std::function &&callback); + void add_on_control_callback(std::function &&callback); /** Make a climate device control call, this is used to control the climate device, see the ClimateCall description * for more info. @@ -273,8 +273,8 @@ class Climate : public EntityBase { void dump_traits_(const char *tag); - CallbackManager state_callback_{}; - CallbackManager control_callback_{}; + CallbackManager state_callback_{}; + CallbackManager control_callback_{}; ESPPreferenceObject rtc_; optional visual_min_temperature_override_{}; optional visual_max_temperature_override_{}; diff --git a/esphome/components/mqtt/mqtt_climate.cpp b/esphome/components/mqtt/mqtt_climate.cpp index d63885fa04..44c490c308 100644 --- a/esphome/components/mqtt/mqtt_climate.cpp +++ b/esphome/components/mqtt/mqtt_climate.cpp @@ -216,7 +216,7 @@ void MQTTClimateComponent::setup() { }); } - this->device_->add_on_state_callback([this]() { this->publish_state_(); }); + this->device_->add_on_state_callback([this](Climate & /*unused*/) { this->publish_state_(); }); } MQTTClimateComponent::MQTTClimateComponent(Climate *device) : device_(device) {} bool MQTTClimateComponent::send_initial_state() { return this->publish_state_(); } diff --git a/esphome/core/controller.cpp b/esphome/core/controller.cpp index 2ce471ead0..18d427b40c 100644 --- a/esphome/core/controller.cpp +++ b/esphome/core/controller.cpp @@ -50,7 +50,7 @@ void Controller::setup_controller(bool include_internal) { #ifdef USE_CLIMATE for (auto *obj : App.get_climates()) { if (include_internal || !obj->is_internal()) - obj->add_on_state_callback([this, obj]() { this->on_climate_update(obj); }); + obj->add_on_state_callback([this, obj](climate::Climate & /*unused*/) { this->on_climate_update(obj); }); } #endif #ifdef USE_NUMBER diff --git a/tests/test1.yaml b/tests/test1.yaml index 67e675ef3a..90c62c6b73 100644 --- a/tests/test1.yaml +++ b/tests/test1.yaml @@ -2200,9 +2200,14 @@ climate: use_fahrenheit: true - platform: midea on_control: - logger.log: Control message received! + - logger.log: Control message received! + - lambda: |- + x.set_mode(CLIMATE_MODE_FAN_ONLY); on_state: - logger.log: State changed! + - logger.log: State changed! + - lambda: |- + if (x.mode == CLIMATE_MODE_FAN_ONLY) + id(binary_sensor1).publish_state(true); id: midea_unit uart_id: uart_0 name: Midea Climate