mirror of
https://github.com/esphome/esphome.git
synced 2024-11-25 08:28:12 +01:00
climate: add on_control callbacks (#4511)
This lets downstream components respond to climate configuration changes, which take place through ClimateCall objects, without also being notified every time the state changes, which happens every time the input sensor announces a new value. FIXES https://github.com/esphome/feature-requests/issues/2136
This commit is contained in:
parent
3773c385c7
commit
05ab49a615
6 changed files with 31 additions and 0 deletions
|
@ -20,6 +20,7 @@ from esphome.const import (
|
||||||
CONF_MODE,
|
CONF_MODE,
|
||||||
CONF_MODE_COMMAND_TOPIC,
|
CONF_MODE_COMMAND_TOPIC,
|
||||||
CONF_MODE_STATE_TOPIC,
|
CONF_MODE_STATE_TOPIC,
|
||||||
|
CONF_ON_CONTROL,
|
||||||
CONF_ON_STATE,
|
CONF_ON_STATE,
|
||||||
CONF_PRESET,
|
CONF_PRESET,
|
||||||
CONF_PRESET_COMMAND_TOPIC,
|
CONF_PRESET_COMMAND_TOPIC,
|
||||||
|
@ -127,6 +128,7 @@ def single_visual_temperature(value):
|
||||||
# Actions
|
# Actions
|
||||||
ControlAction = climate_ns.class_("ControlAction", automation.Action)
|
ControlAction = climate_ns.class_("ControlAction", automation.Action)
|
||||||
StateTrigger = climate_ns.class_("StateTrigger", automation.Trigger.template())
|
StateTrigger = climate_ns.class_("StateTrigger", automation.Trigger.template())
|
||||||
|
ControlTrigger = climate_ns.class_("ControlTrigger", automation.Trigger.template())
|
||||||
|
|
||||||
VISUAL_TEMPERATURE_STEP_SCHEMA = cv.Any(
|
VISUAL_TEMPERATURE_STEP_SCHEMA = cv.Any(
|
||||||
single_visual_temperature,
|
single_visual_temperature,
|
||||||
|
@ -203,6 +205,11 @@ CLIMATE_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).
|
||||||
cv.Optional(CONF_TARGET_TEMPERATURE_LOW_STATE_TOPIC): cv.All(
|
cv.Optional(CONF_TARGET_TEMPERATURE_LOW_STATE_TOPIC): cv.All(
|
||||||
cv.requires_component("mqtt"), cv.publish_topic
|
cv.requires_component("mqtt"), cv.publish_topic
|
||||||
),
|
),
|
||||||
|
cv.Optional(CONF_ON_CONTROL): automation.validate_automation(
|
||||||
|
{
|
||||||
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ControlTrigger),
|
||||||
|
}
|
||||||
|
),
|
||||||
cv.Optional(CONF_ON_STATE): automation.validate_automation(
|
cv.Optional(CONF_ON_STATE): automation.validate_automation(
|
||||||
{
|
{
|
||||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(StateTrigger),
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(StateTrigger),
|
||||||
|
|
|
@ -42,6 +42,13 @@ template<typename... Ts> class ControlAction : public Action<Ts...> {
|
||||||
Climate *climate_;
|
Climate *climate_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ControlTrigger : public Trigger<> {
|
||||||
|
public:
|
||||||
|
ControlTrigger(Climate *climate) {
|
||||||
|
climate->add_on_control_callback([this]() { this->trigger(); });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class StateTrigger : public Trigger<> {
|
class StateTrigger : public Trigger<> {
|
||||||
public:
|
public:
|
||||||
StateTrigger(Climate *climate) {
|
StateTrigger(Climate *climate) {
|
||||||
|
|
|
@ -44,6 +44,7 @@ void ClimateCall::perform() {
|
||||||
if (this->target_temperature_high_.has_value()) {
|
if (this->target_temperature_high_.has_value()) {
|
||||||
ESP_LOGD(TAG, " Target Temperature High: %.2f", *this->target_temperature_high_);
|
ESP_LOGD(TAG, " Target Temperature High: %.2f", *this->target_temperature_high_);
|
||||||
}
|
}
|
||||||
|
this->parent_->control_callback_.call();
|
||||||
this->parent_->control(*this);
|
this->parent_->control(*this);
|
||||||
}
|
}
|
||||||
void ClimateCall::validate_() {
|
void ClimateCall::validate_() {
|
||||||
|
@ -317,6 +318,10 @@ void Climate::add_on_state_callback(std::function<void()> &&callback) {
|
||||||
this->state_callback_.add(std::move(callback));
|
this->state_callback_.add(std::move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Climate::add_on_control_callback(std::function<void()> &&callback) {
|
||||||
|
this->control_callback_.add(std::move(callback));
|
||||||
|
}
|
||||||
|
|
||||||
// Random 32bit value; If this changes existing restore preferences are invalidated
|
// Random 32bit value; If this changes existing restore preferences are invalidated
|
||||||
static const uint32_t RESTORE_STATE_VERSION = 0x848EA6ADUL;
|
static const uint32_t RESTORE_STATE_VERSION = 0x848EA6ADUL;
|
||||||
|
|
||||||
|
|
|
@ -219,6 +219,14 @@ class Climate : public EntityBase {
|
||||||
*/
|
*/
|
||||||
void add_on_state_callback(std::function<void()> &&callback);
|
void add_on_state_callback(std::function<void()> &&callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a callback for the climate device configuration; each time the configuration parameters of a climate device
|
||||||
|
* is updated (using perform() of a ClimateCall), this callback will be called, before any on_state callback.
|
||||||
|
*
|
||||||
|
* @param callback The callback to call.
|
||||||
|
*/
|
||||||
|
void add_on_control_callback(std::function<void()> &&callback);
|
||||||
|
|
||||||
/** Make a climate device control call, this is used to control the climate device, see the ClimateCall description
|
/** Make a climate device control call, this is used to control the climate device, see the ClimateCall description
|
||||||
* for more info.
|
* for more info.
|
||||||
* @return A new ClimateCall instance targeting this climate device.
|
* @return A new ClimateCall instance targeting this climate device.
|
||||||
|
@ -285,6 +293,7 @@ class Climate : public EntityBase {
|
||||||
void dump_traits_(const char *tag);
|
void dump_traits_(const char *tag);
|
||||||
|
|
||||||
CallbackManager<void()> state_callback_{};
|
CallbackManager<void()> state_callback_{};
|
||||||
|
CallbackManager<void()> control_callback_{};
|
||||||
ESPPreferenceObject rtc_;
|
ESPPreferenceObject rtc_;
|
||||||
optional<float> visual_min_temperature_override_{};
|
optional<float> visual_min_temperature_override_{};
|
||||||
optional<float> visual_max_temperature_override_{};
|
optional<float> visual_max_temperature_override_{};
|
||||||
|
|
|
@ -447,6 +447,7 @@ CONF_ON_BLE_SERVICE_DATA_ADVERTISE = "on_ble_service_data_advertise"
|
||||||
CONF_ON_BOOT = "on_boot"
|
CONF_ON_BOOT = "on_boot"
|
||||||
CONF_ON_CLICK = "on_click"
|
CONF_ON_CLICK = "on_click"
|
||||||
CONF_ON_CONNECT = "on_connect"
|
CONF_ON_CONNECT = "on_connect"
|
||||||
|
CONF_ON_CONTROL = "on_control"
|
||||||
CONF_ON_DISCONNECT = "on_disconnect"
|
CONF_ON_DISCONNECT = "on_disconnect"
|
||||||
CONF_ON_DOUBLE_CLICK = "on_double_click"
|
CONF_ON_DOUBLE_CLICK = "on_double_click"
|
||||||
CONF_ON_ENROLLMENT_DONE = "on_enrollment_done"
|
CONF_ON_ENROLLMENT_DONE = "on_enrollment_done"
|
||||||
|
|
|
@ -2052,6 +2052,8 @@ climate:
|
||||||
name: Midea IR
|
name: Midea IR
|
||||||
use_fahrenheit: true
|
use_fahrenheit: true
|
||||||
- platform: midea
|
- platform: midea
|
||||||
|
on_control:
|
||||||
|
logger.log: Control message received!
|
||||||
on_state:
|
on_state:
|
||||||
logger.log: State changed!
|
logger.log: State changed!
|
||||||
id: midea_unit
|
id: midea_unit
|
||||||
|
|
Loading…
Reference in a new issue