Fix thermostat supplemental actions (#6282)

This commit is contained in:
Keith Burzinski 2024-02-25 12:28:52 -06:00 committed by Jesse Hills
parent f3174c58bc
commit b1b8217713
No known key found for this signature in database
GPG key ID: BEAAE804EFD8E83A
2 changed files with 30 additions and 26 deletions

View file

@ -1,6 +1,5 @@
#include "thermostat_climate.h" #include "thermostat_climate.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include <cinttypes>
namespace esphome { namespace esphome {
namespace thermostat { namespace thermostat {
@ -63,6 +62,15 @@ void ThermostatClimate::setup() {
this->publish_state(); this->publish_state();
} }
void ThermostatClimate::loop() {
for (auto &timer : this->timer_) {
if (timer.active && (timer.started + timer.time < millis())) {
timer.active = false;
timer.func();
}
}
}
float ThermostatClimate::cool_deadband() { return this->cooling_deadband_; } float ThermostatClimate::cool_deadband() { return this->cooling_deadband_; }
float ThermostatClimate::cool_overrun() { return this->cooling_overrun_; } float ThermostatClimate::cool_overrun() { return this->cooling_overrun_; }
float ThermostatClimate::heat_deadband() { return this->heating_deadband_; } float ThermostatClimate::heat_deadband() { return this->heating_deadband_; }
@ -439,6 +447,7 @@ void ThermostatClimate::switch_to_action_(climate::ClimateAction action, bool pu
this->start_timer_(thermostat::TIMER_FANNING_ON); this->start_timer_(thermostat::TIMER_FANNING_ON);
trig_fan = this->fan_only_action_trigger_; trig_fan = this->fan_only_action_trigger_;
} }
this->cooling_max_runtime_exceeded_ = false;
trig = this->cool_action_trigger_; trig = this->cool_action_trigger_;
ESP_LOGVV(TAG, "Switching to COOLING action"); ESP_LOGVV(TAG, "Switching to COOLING action");
action_ready = true; action_ready = true;
@ -452,6 +461,7 @@ void ThermostatClimate::switch_to_action_(climate::ClimateAction action, bool pu
this->start_timer_(thermostat::TIMER_FANNING_ON); this->start_timer_(thermostat::TIMER_FANNING_ON);
trig_fan = this->fan_only_action_trigger_; trig_fan = this->fan_only_action_trigger_;
} }
this->heating_max_runtime_exceeded_ = false;
trig = this->heat_action_trigger_; trig = this->heat_action_trigger_;
ESP_LOGVV(TAG, "Switching to HEATING action"); ESP_LOGVV(TAG, "Switching to HEATING action");
action_ready = true; action_ready = true;
@ -752,15 +762,15 @@ bool ThermostatClimate::heating_action_ready_() {
void ThermostatClimate::start_timer_(const ThermostatClimateTimerIndex timer_index) { void ThermostatClimate::start_timer_(const ThermostatClimateTimerIndex timer_index) {
if (this->timer_duration_(timer_index) > 0) { if (this->timer_duration_(timer_index) > 0) {
this->set_timeout(this->timer_[timer_index].name, this->timer_duration_(timer_index), this->timer_[timer_index].started = millis();
this->timer_cbf_(timer_index));
this->timer_[timer_index].active = true; this->timer_[timer_index].active = true;
} }
} }
bool ThermostatClimate::cancel_timer_(ThermostatClimateTimerIndex timer_index) { bool ThermostatClimate::cancel_timer_(ThermostatClimateTimerIndex timer_index) {
auto ret = this->timer_[timer_index].active;
this->timer_[timer_index].active = false; this->timer_[timer_index].active = false;
return this->cancel_timeout(this->timer_[timer_index].name); return ret;
} }
bool ThermostatClimate::timer_active_(ThermostatClimateTimerIndex timer_index) { bool ThermostatClimate::timer_active_(ThermostatClimateTimerIndex timer_index) {
@ -777,7 +787,6 @@ std::function<void()> ThermostatClimate::timer_cbf_(ThermostatClimateTimerIndex
void ThermostatClimate::cooling_max_run_time_timer_callback_() { void ThermostatClimate::cooling_max_run_time_timer_callback_() {
ESP_LOGVV(TAG, "cooling_max_run_time timer expired"); ESP_LOGVV(TAG, "cooling_max_run_time timer expired");
this->timer_[thermostat::TIMER_COOLING_MAX_RUN_TIME].active = false;
this->cooling_max_runtime_exceeded_ = true; this->cooling_max_runtime_exceeded_ = true;
this->trigger_supplemental_action_(); this->trigger_supplemental_action_();
this->switch_to_supplemental_action_(this->compute_supplemental_action_()); this->switch_to_supplemental_action_(this->compute_supplemental_action_());
@ -785,21 +794,18 @@ void ThermostatClimate::cooling_max_run_time_timer_callback_() {
void ThermostatClimate::cooling_off_timer_callback_() { void ThermostatClimate::cooling_off_timer_callback_() {
ESP_LOGVV(TAG, "cooling_off timer expired"); ESP_LOGVV(TAG, "cooling_off timer expired");
this->timer_[thermostat::TIMER_COOLING_OFF].active = false;
this->switch_to_action_(this->compute_action_()); this->switch_to_action_(this->compute_action_());
this->switch_to_supplemental_action_(this->compute_supplemental_action_()); this->switch_to_supplemental_action_(this->compute_supplemental_action_());
} }
void ThermostatClimate::cooling_on_timer_callback_() { void ThermostatClimate::cooling_on_timer_callback_() {
ESP_LOGVV(TAG, "cooling_on timer expired"); ESP_LOGVV(TAG, "cooling_on timer expired");
this->timer_[thermostat::TIMER_COOLING_ON].active = false;
this->switch_to_action_(this->compute_action_()); this->switch_to_action_(this->compute_action_());
this->switch_to_supplemental_action_(this->compute_supplemental_action_()); this->switch_to_supplemental_action_(this->compute_supplemental_action_());
} }
void ThermostatClimate::fan_mode_timer_callback_() { void ThermostatClimate::fan_mode_timer_callback_() {
ESP_LOGVV(TAG, "fan_mode timer expired"); ESP_LOGVV(TAG, "fan_mode timer expired");
this->timer_[thermostat::TIMER_FAN_MODE].active = false;
this->switch_to_fan_mode_(this->fan_mode.value_or(climate::CLIMATE_FAN_ON)); this->switch_to_fan_mode_(this->fan_mode.value_or(climate::CLIMATE_FAN_ON));
if (this->supports_fan_only_action_uses_fan_mode_timer_) if (this->supports_fan_only_action_uses_fan_mode_timer_)
this->switch_to_action_(this->compute_action_()); this->switch_to_action_(this->compute_action_());
@ -807,19 +813,16 @@ void ThermostatClimate::fan_mode_timer_callback_() {
void ThermostatClimate::fanning_off_timer_callback_() { void ThermostatClimate::fanning_off_timer_callback_() {
ESP_LOGVV(TAG, "fanning_off timer expired"); ESP_LOGVV(TAG, "fanning_off timer expired");
this->timer_[thermostat::TIMER_FANNING_OFF].active = false;
this->switch_to_action_(this->compute_action_()); this->switch_to_action_(this->compute_action_());
} }
void ThermostatClimate::fanning_on_timer_callback_() { void ThermostatClimate::fanning_on_timer_callback_() {
ESP_LOGVV(TAG, "fanning_on timer expired"); ESP_LOGVV(TAG, "fanning_on timer expired");
this->timer_[thermostat::TIMER_FANNING_ON].active = false;
this->switch_to_action_(this->compute_action_()); this->switch_to_action_(this->compute_action_());
} }
void ThermostatClimate::heating_max_run_time_timer_callback_() { void ThermostatClimate::heating_max_run_time_timer_callback_() {
ESP_LOGVV(TAG, "heating_max_run_time timer expired"); ESP_LOGVV(TAG, "heating_max_run_time timer expired");
this->timer_[thermostat::TIMER_HEATING_MAX_RUN_TIME].active = false;
this->heating_max_runtime_exceeded_ = true; this->heating_max_runtime_exceeded_ = true;
this->trigger_supplemental_action_(); this->trigger_supplemental_action_();
this->switch_to_supplemental_action_(this->compute_supplemental_action_()); this->switch_to_supplemental_action_(this->compute_supplemental_action_());
@ -827,21 +830,18 @@ void ThermostatClimate::heating_max_run_time_timer_callback_() {
void ThermostatClimate::heating_off_timer_callback_() { void ThermostatClimate::heating_off_timer_callback_() {
ESP_LOGVV(TAG, "heating_off timer expired"); ESP_LOGVV(TAG, "heating_off timer expired");
this->timer_[thermostat::TIMER_HEATING_OFF].active = false;
this->switch_to_action_(this->compute_action_()); this->switch_to_action_(this->compute_action_());
this->switch_to_supplemental_action_(this->compute_supplemental_action_()); this->switch_to_supplemental_action_(this->compute_supplemental_action_());
} }
void ThermostatClimate::heating_on_timer_callback_() { void ThermostatClimate::heating_on_timer_callback_() {
ESP_LOGVV(TAG, "heating_on timer expired"); ESP_LOGVV(TAG, "heating_on timer expired");
this->timer_[thermostat::TIMER_HEATING_ON].active = false;
this->switch_to_action_(this->compute_action_()); this->switch_to_action_(this->compute_action_());
this->switch_to_supplemental_action_(this->compute_supplemental_action_()); this->switch_to_supplemental_action_(this->compute_supplemental_action_());
} }
void ThermostatClimate::idle_on_timer_callback_() { void ThermostatClimate::idle_on_timer_callback_() {
ESP_LOGVV(TAG, "idle_on timer expired"); ESP_LOGVV(TAG, "idle_on timer expired");
this->timer_[thermostat::TIMER_IDLE_ON].active = false;
this->switch_to_action_(this->compute_action_()); this->switch_to_action_(this->compute_action_());
this->switch_to_supplemental_action_(this->compute_supplemental_action_()); this->switch_to_supplemental_action_(this->compute_supplemental_action_());
} }

View file

@ -1,10 +1,12 @@
#pragma once #pragma once
#include "esphome/core/component.h"
#include "esphome/core/automation.h" #include "esphome/core/automation.h"
#include "esphome/core/component.h"
#include "esphome/core/hal.h"
#include "esphome/components/climate/climate.h" #include "esphome/components/climate/climate.h"
#include "esphome/components/sensor/sensor.h" #include "esphome/components/sensor/sensor.h"
#include <cinttypes>
#include <map> #include <map>
#include <vector> #include <vector>
@ -26,9 +28,9 @@ enum ThermostatClimateTimerIndex : size_t {
enum OnBootRestoreFrom : size_t { MEMORY = 0, DEFAULT_PRESET = 1 }; enum OnBootRestoreFrom : size_t { MEMORY = 0, DEFAULT_PRESET = 1 };
struct ThermostatClimateTimer { struct ThermostatClimateTimer {
const std::string name;
bool active; bool active;
uint32_t time; uint32_t time;
uint32_t started;
std::function<void()> func; std::function<void()> func;
}; };
@ -59,6 +61,7 @@ class ThermostatClimate : public climate::Climate, public Component {
ThermostatClimate(); ThermostatClimate();
void setup() override; void setup() override;
void dump_config() override; void dump_config() override;
void loop() override;
void set_default_preset(const std::string &custom_preset); void set_default_preset(const std::string &custom_preset);
void set_default_preset(climate::ClimatePreset preset); void set_default_preset(climate::ClimatePreset preset);
@ -441,16 +444,17 @@ class ThermostatClimate : public climate::Climate, public Component {
/// Climate action timers /// Climate action timers
std::vector<ThermostatClimateTimer> timer_{ std::vector<ThermostatClimateTimer> timer_{
{"cool_run", false, 0, std::bind(&ThermostatClimate::cooling_max_run_time_timer_callback_, this)}, {false, 0, 0, std::bind(&ThermostatClimate::cooling_max_run_time_timer_callback_, this)},
{"cool_off", false, 0, std::bind(&ThermostatClimate::cooling_off_timer_callback_, this)}, {false, 0, 0, std::bind(&ThermostatClimate::cooling_off_timer_callback_, this)},
{"cool_on", false, 0, std::bind(&ThermostatClimate::cooling_on_timer_callback_, this)}, {false, 0, 0, std::bind(&ThermostatClimate::cooling_on_timer_callback_, this)},
{"fan_mode", false, 0, std::bind(&ThermostatClimate::fan_mode_timer_callback_, this)}, {false, 0, 0, std::bind(&ThermostatClimate::fan_mode_timer_callback_, this)},
{"fan_off", false, 0, std::bind(&ThermostatClimate::fanning_off_timer_callback_, this)}, {false, 0, 0, std::bind(&ThermostatClimate::fanning_off_timer_callback_, this)},
{"fan_on", false, 0, std::bind(&ThermostatClimate::fanning_on_timer_callback_, this)}, {false, 0, 0, std::bind(&ThermostatClimate::fanning_on_timer_callback_, this)},
{"heat_run", false, 0, std::bind(&ThermostatClimate::heating_max_run_time_timer_callback_, this)}, {false, 0, 0, std::bind(&ThermostatClimate::heating_max_run_time_timer_callback_, this)},
{"heat_off", false, 0, std::bind(&ThermostatClimate::heating_off_timer_callback_, this)}, {false, 0, 0, std::bind(&ThermostatClimate::heating_off_timer_callback_, this)},
{"heat_on", false, 0, std::bind(&ThermostatClimate::heating_on_timer_callback_, this)}, {false, 0, 0, std::bind(&ThermostatClimate::heating_on_timer_callback_, this)},
{"idle_on", false, 0, std::bind(&ThermostatClimate::idle_on_timer_callback_, this)}}; {false, 0, 0, std::bind(&ThermostatClimate::idle_on_timer_callback_, this)},
};
/// The set of standard preset configurations this thermostat supports (Eg. AWAY, ECO, etc) /// The set of standard preset configurations this thermostat supports (Eg. AWAY, ECO, etc)
std::map<climate::ClimatePreset, ThermostatClimateTargetTempConfig> preset_config_{}; std::map<climate::ClimatePreset, ThermostatClimateTargetTempConfig> preset_config_{};