mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Fix thermostat supplemental actions (#6282)
This commit is contained in:
		
				
					committed by
					
						 Jesse Hills
						Jesse Hills
					
				
			
			
				
	
			
			
			
						parent
						
							f3174c58bc
						
					
				
				
					commit
					b1b8217713
				
			| @@ -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_()); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -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_{}; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user