[thermostat] Memory optimizations (#9259)

This commit is contained in:
Keith Burzinski 2025-06-29 06:16:34 -05:00 committed by GitHub
parent 86c0fb48a3
commit 0c249a7006
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 77 additions and 70 deletions

View File

@ -997,7 +997,7 @@ void ThermostatClimate::change_preset_(climate::ClimatePreset preset) {
auto config = this->preset_config_.find(preset); auto config = this->preset_config_.find(preset);
if (config != this->preset_config_.end()) { if (config != this->preset_config_.end()) {
ESP_LOGI(TAG, "Preset %s requested", LOG_STR_ARG(climate::climate_preset_to_string(preset))); ESP_LOGV(TAG, "Preset %s requested", LOG_STR_ARG(climate::climate_preset_to_string(preset)));
if (this->change_preset_internal_(config->second) || (!this->preset.has_value()) || if (this->change_preset_internal_(config->second) || (!this->preset.has_value()) ||
this->preset.value() != preset) { this->preset.value() != preset) {
// Fire any preset changed trigger if defined // Fire any preset changed trigger if defined
@ -1015,7 +1015,7 @@ void ThermostatClimate::change_preset_(climate::ClimatePreset preset) {
this->custom_preset.reset(); this->custom_preset.reset();
this->preset = preset; this->preset = preset;
} else { } else {
ESP_LOGE(TAG, "Preset %s is not configured, ignoring.", LOG_STR_ARG(climate::climate_preset_to_string(preset))); ESP_LOGW(TAG, "Preset %s not configured; ignoring", LOG_STR_ARG(climate::climate_preset_to_string(preset)));
} }
} }
@ -1023,7 +1023,7 @@ void ThermostatClimate::change_custom_preset_(const std::string &custom_preset)
auto config = this->custom_preset_config_.find(custom_preset); auto config = this->custom_preset_config_.find(custom_preset);
if (config != this->custom_preset_config_.end()) { if (config != this->custom_preset_config_.end()) {
ESP_LOGI(TAG, "Custom preset %s requested", custom_preset.c_str()); ESP_LOGV(TAG, "Custom preset %s requested", custom_preset.c_str());
if (this->change_preset_internal_(config->second) || (!this->custom_preset.has_value()) || if (this->change_preset_internal_(config->second) || (!this->custom_preset.has_value()) ||
this->custom_preset.value() != custom_preset) { this->custom_preset.value() != custom_preset) {
// Fire any preset changed trigger if defined // Fire any preset changed trigger if defined
@ -1041,7 +1041,7 @@ void ThermostatClimate::change_custom_preset_(const std::string &custom_preset)
this->preset.reset(); this->preset.reset();
this->custom_preset = custom_preset; this->custom_preset = custom_preset;
} else { } else {
ESP_LOGE(TAG, "Custom Preset %s is not configured, ignoring.", custom_preset.c_str()); ESP_LOGW(TAG, "Custom preset %s not configured; ignoring", custom_preset.c_str());
} }
} }
@ -1298,7 +1298,7 @@ void ThermostatClimate::dump_config() {
if (this->supports_two_points_) { if (this->supports_two_points_) {
ESP_LOGCONFIG(TAG, " Minimum Set Point Differential: %.1f°C", this->set_point_minimum_differential_); ESP_LOGCONFIG(TAG, " Minimum Set Point Differential: %.1f°C", this->set_point_minimum_differential_);
} }
ESP_LOGCONFIG(TAG, " Start-up Delay Enabled: %s", YESNO(this->use_startup_delay_)); ESP_LOGCONFIG(TAG, " Use Start-up Delay: %s", YESNO(this->use_startup_delay_));
if (this->supports_cool_) { if (this->supports_cool_) {
ESP_LOGCONFIG(TAG, ESP_LOGCONFIG(TAG,
" Cooling Parameters:\n" " Cooling Parameters:\n"
@ -1353,44 +1353,47 @@ void ThermostatClimate::dump_config() {
} }
ESP_LOGCONFIG(TAG, " Minimum Idle Time: %" PRIu32 "s", this->timer_[thermostat::TIMER_IDLE_ON].time / 1000); ESP_LOGCONFIG(TAG, " Minimum Idle Time: %" PRIu32 "s", this->timer_[thermostat::TIMER_IDLE_ON].time / 1000);
ESP_LOGCONFIG(TAG, ESP_LOGCONFIG(TAG,
" Supports AUTO: %s\n" " Supported MODES:\n"
" Supports HEAT/COOL: %s\n" " AUTO: %s\n"
" Supports COOL: %s\n" " HEAT/COOL: %s\n"
" Supports DRY: %s\n" " HEAT: %s\n"
" Supports FAN_ONLY: %s\n" " COOL: %s\n"
" Supports FAN_ONLY_ACTION_USES_FAN_MODE_TIMER: %s\n" " DRY: %s\n"
" Supports FAN_ONLY_COOLING: %s", " FAN_ONLY: %s\n"
YESNO(this->supports_auto_), YESNO(this->supports_heat_cool_), YESNO(this->supports_cool_), " FAN_ONLY_ACTION_USES_FAN_MODE_TIMER: %s\n"
YESNO(this->supports_dry_), YESNO(this->supports_fan_only_), " FAN_ONLY_COOLING: %s",
YESNO(this->supports_auto_), YESNO(this->supports_heat_cool_), YESNO(this->supports_heat_),
YESNO(this->supports_cool_), YESNO(this->supports_dry_), YESNO(this->supports_fan_only_),
YESNO(this->supports_fan_only_action_uses_fan_mode_timer_), YESNO(this->supports_fan_only_cooling_)); YESNO(this->supports_fan_only_action_uses_fan_mode_timer_), YESNO(this->supports_fan_only_cooling_));
if (this->supports_cool_) { if (this->supports_cool_) {
ESP_LOGCONFIG(TAG, " Supports FAN_WITH_COOLING: %s", YESNO(this->supports_fan_with_cooling_)); ESP_LOGCONFIG(TAG, " FAN_WITH_COOLING: %s", YESNO(this->supports_fan_with_cooling_));
} }
if (this->supports_heat_) { if (this->supports_heat_) {
ESP_LOGCONFIG(TAG, " Supports FAN_WITH_HEATING: %s", YESNO(this->supports_fan_with_heating_)); ESP_LOGCONFIG(TAG, " FAN_WITH_HEATING: %s", YESNO(this->supports_fan_with_heating_));
} }
ESP_LOGCONFIG(TAG, " Supports HEAT: %s", YESNO(this->supports_heat_));
ESP_LOGCONFIG(TAG, ESP_LOGCONFIG(TAG,
" Supports FAN MODE ON: %s\n" " Supported FAN MODES:\n"
" Supports FAN MODE OFF: %s\n" " ON: %s\n"
" Supports FAN MODE AUTO: %s\n" " OFF: %s\n"
" Supports FAN MODE LOW: %s\n" " AUTO: %s\n"
" Supports FAN MODE MEDIUM: %s\n" " LOW: %s\n"
" Supports FAN MODE HIGH: %s\n" " MEDIUM: %s\n"
" Supports FAN MODE MIDDLE: %s\n" " HIGH: %s\n"
" Supports FAN MODE FOCUS: %s\n" " MIDDLE: %s\n"
" Supports FAN MODE DIFFUSE: %s\n" " FOCUS: %s\n"
" Supports FAN MODE QUIET: %s", " DIFFUSE: %s\n"
" QUIET: %s",
YESNO(this->supports_fan_mode_on_), YESNO(this->supports_fan_mode_off_), YESNO(this->supports_fan_mode_on_), YESNO(this->supports_fan_mode_off_),
YESNO(this->supports_fan_mode_auto_), YESNO(this->supports_fan_mode_low_), YESNO(this->supports_fan_mode_auto_), YESNO(this->supports_fan_mode_low_),
YESNO(this->supports_fan_mode_medium_), YESNO(this->supports_fan_mode_high_), YESNO(this->supports_fan_mode_medium_), YESNO(this->supports_fan_mode_high_),
YESNO(this->supports_fan_mode_middle_), YESNO(this->supports_fan_mode_focus_), YESNO(this->supports_fan_mode_middle_), YESNO(this->supports_fan_mode_focus_),
YESNO(this->supports_fan_mode_diffuse_), YESNO(this->supports_fan_mode_quiet_)); YESNO(this->supports_fan_mode_diffuse_), YESNO(this->supports_fan_mode_quiet_));
ESP_LOGCONFIG(TAG, ESP_LOGCONFIG(TAG,
" Supports SWING MODE BOTH: %s\n" " Supported SWING MODES:\n"
" Supports SWING MODE OFF: %s\n" " BOTH: %s\n"
" Supports SWING MODE HORIZONTAL: %s\n" " OFF: %s\n"
" Supports SWING MODE VERTICAL: %s\n" " HORIZONTAL: %s\n"
" VERTICAL: %s\n"
" Supports TWO SET POINTS: %s", " Supports TWO SET POINTS: %s",
YESNO(this->supports_swing_mode_both_), YESNO(this->supports_swing_mode_off_), YESNO(this->supports_swing_mode_both_), YESNO(this->supports_swing_mode_off_),
YESNO(this->supports_swing_mode_horizontal_), YESNO(this->supports_swing_mode_vertical_), YESNO(this->supports_swing_mode_horizontal_), YESNO(this->supports_swing_mode_vertical_),

View File

@ -13,7 +13,7 @@
namespace esphome { namespace esphome {
namespace thermostat { namespace thermostat {
enum ThermostatClimateTimerIndex : size_t { enum ThermostatClimateTimerIndex : uint8_t {
TIMER_COOLING_MAX_RUN_TIME = 0, TIMER_COOLING_MAX_RUN_TIME = 0,
TIMER_COOLING_OFF = 1, TIMER_COOLING_OFF = 1,
TIMER_COOLING_ON = 2, TIMER_COOLING_ON = 2,
@ -26,7 +26,11 @@ enum ThermostatClimateTimerIndex : size_t {
TIMER_IDLE_ON = 9, TIMER_IDLE_ON = 9,
}; };
enum OnBootRestoreFrom : size_t { MEMORY = 0, DEFAULT_PRESET = 1 }; enum OnBootRestoreFrom : uint8_t {
MEMORY = 0,
DEFAULT_PRESET = 1,
};
struct ThermostatClimateTimer { struct ThermostatClimateTimer {
bool active; bool active;
uint32_t time; uint32_t time;
@ -65,7 +69,7 @@ class ThermostatClimate : public climate::Climate, public Component {
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);
void set_on_boot_restore_from(thermostat::OnBootRestoreFrom on_boot_restore_from); void set_on_boot_restore_from(OnBootRestoreFrom on_boot_restore_from);
void set_set_point_minimum_differential(float differential); void set_set_point_minimum_differential(float differential);
void set_cool_deadband(float deadband); void set_cool_deadband(float deadband);
void set_cool_overrun(float overrun); void set_cool_overrun(float overrun);
@ -240,10 +244,8 @@ class ThermostatClimate : public climate::Climate, public Component {
void dump_preset_config_(const char *preset_name, const ThermostatClimateTargetTempConfig &config, void dump_preset_config_(const char *preset_name, const ThermostatClimateTargetTempConfig &config,
bool is_default_preset); bool is_default_preset);
/// The sensor used for getting the current temperature /// Minimum allowable duration in seconds for action timers
sensor::Sensor *sensor_{nullptr}; const uint8_t min_timer_duration_{1};
/// The sensor used for getting the current humidity
sensor::Sensor *humidity_sensor_{nullptr};
/// Whether the controller supports auto/cooling/drying/fanning/heating. /// Whether the controller supports auto/cooling/drying/fanning/heating.
/// ///
@ -310,6 +312,31 @@ class ThermostatClimate : public climate::Climate, public Component {
/// setup_complete_ blocks modifying/resetting the temps immediately after boot /// setup_complete_ blocks modifying/resetting the temps immediately after boot
bool setup_complete_{false}; bool setup_complete_{false};
/// Store previously-known temperatures
///
/// These are used to determine when the temperature change trigger/action needs to be called
float prev_target_temperature_{NAN};
float prev_target_temperature_low_{NAN};
float prev_target_temperature_high_{NAN};
/// Minimum differential required between set points
float set_point_minimum_differential_{0};
/// Hysteresis values used for computing climate actions
float cooling_deadband_{0};
float cooling_overrun_{0};
float heating_deadband_{0};
float heating_overrun_{0};
/// Maximum allowable temperature deltas before engaging supplemental cooling/heating actions
float supplemental_cool_delta_{0};
float supplemental_heat_delta_{0};
/// The sensor used for getting the current temperature
sensor::Sensor *sensor_{nullptr};
/// The sensor used for getting the current humidity
sensor::Sensor *humidity_sensor_{nullptr};
/// The trigger to call when the controller should switch to cooling action/mode. /// The trigger to call when the controller should switch to cooling action/mode.
/// ///
/// A null value for this attribute means that the controller has no cooling action /// A null value for this attribute means that the controller has no cooling action
@ -399,7 +426,7 @@ class ThermostatClimate : public climate::Climate, public Component {
/// The trigger to call when the target temperature(s) change(es). /// The trigger to call when the target temperature(s) change(es).
Trigger<> *temperature_change_trigger_{nullptr}; Trigger<> *temperature_change_trigger_{nullptr};
/// The triggr to call when the preset mode changes /// The trigger to call when the preset mode changes
Trigger<> *preset_change_trigger_{nullptr}; Trigger<> *preset_change_trigger_{nullptr};
/// A reference to the trigger that was previously active. /// A reference to the trigger that was previously active.
@ -411,6 +438,10 @@ class ThermostatClimate : public climate::Climate, public Component {
Trigger<> *prev_mode_trigger_{nullptr}; Trigger<> *prev_mode_trigger_{nullptr};
Trigger<> *prev_swing_mode_trigger_{nullptr}; Trigger<> *prev_swing_mode_trigger_{nullptr};
/// If set to DEFAULT_PRESET then the default preset is always used. When MEMORY prior
/// state will attempt to be restored if possible
OnBootRestoreFrom on_boot_restore_from_{OnBootRestoreFrom::MEMORY};
/// Store previously-known states /// Store previously-known states
/// ///
/// These are used to determine when a trigger/action needs to be called /// These are used to determine when a trigger/action needs to be called
@ -419,28 +450,10 @@ class ThermostatClimate : public climate::Climate, public Component {
climate::ClimateMode prev_mode_{climate::CLIMATE_MODE_OFF}; climate::ClimateMode prev_mode_{climate::CLIMATE_MODE_OFF};
climate::ClimateSwingMode prev_swing_mode_{climate::CLIMATE_SWING_OFF}; climate::ClimateSwingMode prev_swing_mode_{climate::CLIMATE_SWING_OFF};
/// Store previously-known temperatures /// Default standard preset to use on start up
/// climate::ClimatePreset default_preset_{};
/// These are used to determine when the temperature change trigger/action needs to be called /// Default custom preset to use on start up
float prev_target_temperature_{NAN}; std::string default_custom_preset_{};
float prev_target_temperature_low_{NAN};
float prev_target_temperature_high_{NAN};
/// Minimum differential required between set points
float set_point_minimum_differential_{0};
/// Hysteresis values used for computing climate actions
float cooling_deadband_{0};
float cooling_overrun_{0};
float heating_deadband_{0};
float heating_overrun_{0};
/// Maximum allowable temperature deltas before engauging supplemental cooling/heating actions
float supplemental_cool_delta_{0};
float supplemental_heat_delta_{0};
/// Minimum allowable duration in seconds for action timers
const uint8_t min_timer_duration_{1};
/// Climate action timers /// Climate action timers
std::vector<ThermostatClimateTimer> timer_{ std::vector<ThermostatClimateTimer> timer_{
@ -460,15 +473,6 @@ class ThermostatClimate : public climate::Climate, public Component {
std::map<climate::ClimatePreset, ThermostatClimateTargetTempConfig> preset_config_{}; std::map<climate::ClimatePreset, ThermostatClimateTargetTempConfig> preset_config_{};
/// The set of custom preset configurations this thermostat supports (eg. "My Custom Preset") /// The set of custom preset configurations this thermostat supports (eg. "My Custom Preset")
std::map<std::string, ThermostatClimateTargetTempConfig> custom_preset_config_{}; std::map<std::string, ThermostatClimateTargetTempConfig> custom_preset_config_{};
/// Default standard preset to use on start up
climate::ClimatePreset default_preset_{};
/// Default custom preset to use on start up
std::string default_custom_preset_{};
/// If set to DEFAULT_PRESET then the default preset is always used. When MEMORY prior
/// state will attempt to be restored if possible
thermostat::OnBootRestoreFrom on_boot_restore_from_{thermostat::OnBootRestoreFrom::MEMORY};
}; };
} // namespace thermostat } // namespace thermostat