7 static const char *
const TAG =
"thermostat.climate";
29 auto use_default_preset =
true;
34 if (restore.has_value()) {
35 use_default_preset =
false;
36 restore->to_call(
this).perform();
41 if (use_default_preset) {
119 if (this->target_temperature < this->
get_traits().get_visual_min_temperature())
140 if (this->target_temperature_low < this->
get_traits().get_visual_min_temperature())
279 if ((!ignore_timers) &&
288 switch (this->
mode) {
331 return target_action;
344 switch (this->
mode) {
373 return target_action;
394 bool action_ready =
false;
413 ESP_LOGVV(TAG,
"Switching to IDLE/OFF action");
428 ESP_LOGVV(TAG,
"Switching to COOLING action");
441 ESP_LOGVV(TAG,
"Switching to HEATING action");
453 ESP_LOGVV(TAG,
"Switching to FAN_ONLY action");
462 ESP_LOGVV(TAG,
"Switching to DRYING action");
480 assert(trig !=
nullptr);
483 if (trig_fan !=
nullptr) {
484 ESP_LOGVV(TAG,
"Calling FAN_ONLY action with HEATING/COOLING action");
514 ESP_LOGVV(TAG,
"Updating supplemental action...");
528 ESP_LOGVV(TAG,
"Calling supplemental COOLING action");
535 ESP_LOGVV(TAG,
"Calling supplemental HEATING action");
541 if (trig !=
nullptr) {
542 assert(trig !=
nullptr);
563 ESP_LOGVV(TAG,
"Switching to FAN_ON mode");
567 ESP_LOGVV(TAG,
"Switching to FAN_OFF mode");
571 ESP_LOGVV(TAG,
"Switching to FAN_AUTO mode");
575 ESP_LOGVV(TAG,
"Switching to FAN_LOW mode");
579 ESP_LOGVV(TAG,
"Switching to FAN_MEDIUM mode");
583 ESP_LOGVV(TAG,
"Switching to FAN_HIGH mode");
587 ESP_LOGVV(TAG,
"Switching to FAN_MIDDLE mode");
591 ESP_LOGVV(TAG,
"Switching to FAN_FOCUS mode");
595 ESP_LOGVV(TAG,
"Switching to FAN_DIFFUSE mode");
608 assert(trig !=
nullptr);
652 assert(trig !=
nullptr);
673 switch (swing_mode) {
692 assert(trig !=
nullptr);
738 this->
timer_[timer_index].active =
true;
743 this->
timer_[timer_index].active =
false;
748 return this->
timer_[timer_index].active;
752 return this->
timer_[timer_index].time;
756 return this->
timer_[timer_index].func;
760 ESP_LOGVV(TAG,
"cooling_max_run_time timer expired");
768 ESP_LOGVV(TAG,
"cooling_off timer expired");
775 ESP_LOGVV(TAG,
"cooling_on timer expired");
782 ESP_LOGVV(TAG,
"fan_mode timer expired");
790 ESP_LOGVV(TAG,
"fanning_off timer expired");
796 ESP_LOGVV(TAG,
"fanning_on timer expired");
802 ESP_LOGVV(TAG,
"heating_max_run_time timer expired");
810 ESP_LOGVV(TAG,
"heating_off timer expired");
817 ESP_LOGVV(TAG,
"heating_on timer expired");
824 ESP_LOGVV(TAG,
"idle_on timer expired");
851 assert(trig !=
nullptr);
862 }
else if (this->current_temperature < temperature - this->
cooling_overrun_) {
883 }
else if (this->current_temperature < temperature - this->
cooling_overrun_) {
939 bool is_default_preset) {
940 ESP_LOGCONFIG(TAG,
" %s Is Default: %s", preset_name, YESNO(is_default_preset));
944 ESP_LOGCONFIG(TAG,
" %s Default Target Temperature Low: %.1f°C", preset_name,
947 ESP_LOGCONFIG(TAG,
" %s Default Target Temperature Low: %.1f°C", preset_name, config.
default_temperature);
952 ESP_LOGCONFIG(TAG,
" %s Default Target Temperature High: %.1f°C", preset_name,
955 ESP_LOGCONFIG(TAG,
" %s Default Target Temperature High: %.1f°C", preset_name, config.
default_temperature);
960 ESP_LOGCONFIG(TAG,
" %s Default Mode: %s", preset_name,
964 ESP_LOGCONFIG(TAG,
" %s Default Fan Mode: %s", preset_name,
968 ESP_LOGCONFIG(TAG,
" %s Default Swing Mode: %s", preset_name,
979 this->preset.value() !=
preset) {
982 assert(trig !=
nullptr);
1001 ESP_LOGI(TAG,
"Custom preset %s requested", custom_preset.c_str());
1006 assert(trig !=
nullptr);
1010 ESP_LOGI(TAG,
"Custom preset %s applied", custom_preset.c_str());
1012 ESP_LOGI(TAG,
"No changes required to apply custom preset %s", custom_preset.c_str());
1017 ESP_LOGE(TAG,
"Custom Preset %s is not configured, ignoring.", custom_preset.c_str());
1022 bool something_changed =
false;
1027 something_changed =
true;
1031 something_changed =
true;
1036 something_changed =
true;
1045 something_changed =
true;
1051 something_changed =
true;
1057 something_changed =
true;
1060 return something_changed;
1171 bool supports_fan_only_action_uses_fan_mode_timer) {
1261 LOG_CLIMATE(
"",
"Thermostat",
this);
1268 ESP_LOGCONFIG(TAG,
" Cooling Parameters:");
1273 ESP_LOGCONFIG(TAG,
" Maximum Run Time: %us",
1280 ESP_LOGCONFIG(TAG,
" Heating Parameters:");
1285 ESP_LOGCONFIG(TAG,
" Maximum Run Time: %us",
1298 ESP_LOGCONFIG(TAG,
" Minimum Fan Mode Switching Time: %us",
1302 ESP_LOGCONFIG(TAG,
" Supports AUTO: %s", YESNO(this->
supports_auto_));
1304 ESP_LOGCONFIG(TAG,
" Supports COOL: %s", YESNO(this->
supports_cool_));
1305 ESP_LOGCONFIG(TAG,
" Supports DRY: %s", YESNO(this->
supports_dry_));
1307 ESP_LOGCONFIG(TAG,
" Supports FAN_ONLY_ACTION_USES_FAN_MODE_TIMER: %s",
1316 ESP_LOGCONFIG(TAG,
" Supports HEAT: %s", YESNO(this->
supports_heat_));
1332 ESP_LOGCONFIG(TAG,
" Supported PRESETS: ");
1336 ESP_LOGCONFIG(TAG,
" Supports %s: %s", preset_name, YESNO(
true));
1340 ESP_LOGCONFIG(TAG,
" Supported CUSTOM PRESETS: ");
1342 const auto *preset_name = it.first.c_str();
1344 ESP_LOGCONFIG(TAG,
" Supports %s: %s", preset_name, YESNO(
true));
1345 this->
dump_preset_config_(preset_name, it.second, it.first == this->default_custom_preset_);
1347 ESP_LOGCONFIG(TAG,
" On boot, restore from: %s",
1354 : default_temperature(default_temperature) {}
1358 : default_temperature_low(default_temperature_low), default_temperature_high(default_temperature_high) {}
Trigger * swing_mode_vertical_trigger_
The trigger to call when the controller should switch the swing mode to "vertical".
float set_point_minimum_differential_
Minimum differential required between set points.
This class is used to encode all control actions on a climate device.
void set_supports_swing_mode_horizontal(bool supports_swing_mode_horizontal)
The fan mode is set to Low.
value_type const & value() const
The climate device is off (inactive or no power)
Trigger * cool_action_trigger_
The trigger to call when the controller should switch to cooling action/mode.
Trigger * get_cool_action_trigger() const
ClimateSwingMode swing_mode
The active swing mode of the climate device.
climate::ClimateTraits traits() override
Return the traits of this controller.
void control(const climate::ClimateCall &call) override
Override control to change settings of the climate device.
void add_on_state_callback(std::function< void(float)> &&callback)
Add a callback that will be called every time a filtered value arrives.
void set_supports_cool(bool supports_cool)
Trigger * swing_mode_both_trigger_
The trigger to call when the controller should switch the swing mode to "both".
void set_cooling_minimum_run_time_in_sec(uint32_t time)
std::map< std::string, ThermostatClimateTargetTempConfig > custom_preset_config_
The set of custom preset configurations this thermostat supports (eg. "My Custom Preset") ...
Trigger * prev_fan_mode_trigger_
void set_supports_fan_mode_on(bool supports_fan_mode_on)
void set_cooling_maximum_run_time_in_sec(uint32_t time)
void validate_target_temperatures()
The fan mode is set to Both.
void idle_on_timer_callback_()
ClimatePreset
Enum for all preset modes.
The climate device is drying.
bool cancel_timeout(const std::string &name)
Cancel a timeout function.
void set_supports_fan_mode_auto(bool supports_fan_mode_auto)
Trigger * get_auto_mode_trigger() const
void switch_to_action_(climate::ClimateAction action, bool publish_state=true)
Switch the climate device to the given climate action.
Trigger * prev_mode_trigger_
Trigger * prev_action_trigger_
A reference to the trigger that was previously active.
Trigger * fan_mode_auto_trigger_
The trigger to call when the controller should switch the fan to "auto" mode.
bool supports_fan_with_heating_
float target_temperature
The target temperature of the climate device.
Trigger * get_fan_mode_low_trigger() const
void set_supports_fan_with_cooling(bool supports_fan_with_cooling)
void set_sensor(sensor::Sensor *sensor)
Trigger * dry_action_trigger_
The trigger to call when the controller should switch to dry (dehumidification) mode.
bool supports_fan_mode_auto_
Whether the controller supports fan auto mode.
bool supports_fan_mode_middle_
void switch_to_supplemental_action_(climate::ClimateAction action)
The climate device is in fan only mode.
void set_supports_fan_only(bool supports_fan_only)
const optional< ClimateMode > & get_mode() const
The fan mode is set to Middle.
float prev_target_temperature_
Store previously-known temperatures.
void heating_on_timer_callback_()
void validate_target_temperature_high()
This class contains all static data for climate devices.
bool supports_auto_
Whether the controller supports auto/cooling/drying/fanning/heating.
bool supports_fan_mode_off_
Trigger * fan_mode_middle_trigger_
The trigger to call when the controller should switch the fan to "middle" position.
Trigger * get_swing_mode_off_trigger() const
climate::ClimateMode prev_mode_
const LogString * climate_mode_to_string(ClimateMode mode)
Convert the given ClimateMode to a human-readable string.
void set_supports_fan_mode_diffuse(bool supports_fan_mode_diffuse)
void add_supported_custom_preset(const std::string &preset)
The climate device is set to heat to reach the target temperature.
Trigger * off_mode_trigger_
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
bool supplemental_heating_required_()
Trigger * supplemental_heat_action_trigger_
Trigger * get_fan_mode_diffuse_trigger() const
Trigger * prev_swing_mode_trigger_
ClimateMode mode
The active mode of the climate device.
Trigger * heat_action_trigger_
The trigger to call when the controller should switch to heating action/mode.
void set_supports_fan_mode_medium(bool supports_fan_mode_medium)
float default_temperature_high
void set_supports_fan_mode_middle(bool supports_fan_mode_middle)
const optional< float > & get_target_temperature_low() const
float target_temperature_high
The maximum target temperature of the climate device, for climate devices with split target temperatu...
float current_temperature
The current temperature of the climate device, as reported from the integration.
Trigger * get_preset_change_trigger() const
The fan mode is set to Diffuse.
bool supports_swing_mode_vertical_
float get_visual_max_temperature() const
Trigger * get_dry_action_trigger() const
void set_supports_two_points(bool supports_two_points)
The climate device is set to dry/humidity mode.
optional< climate::ClimateSwingMode > swing_mode_
void fanning_on_timer_callback_()
void set_cool_deadband(float deadband)
void set_supports_swing_mode_vertical(bool supports_swing_mode_vertical)
void set_supports_fan_mode_focus(bool supports_fan_mode_focus)
void set_cooling_minimum_off_time_in_sec(uint32_t time)
void validate_target_temperature_low()
thermostat::OnBootRestoreFrom on_boot_restore_from_
If set to DEFAULT_PRESET then the default preset is always used.
void set_fan_mode_minimum_switching_time_in_sec(uint32_t time)
climate::ClimateAction compute_supplemental_action_()
void set_default_preset(const std::string &custom_preset)
void refresh()
Call triggers based on updated climate states (modes/actions)
bool heating_max_runtime_exceeded_
Trigger * get_off_mode_trigger() const
void heating_off_timer_callback_()
void set_supports_fan_only_action_uses_fan_mode_timer(bool fan_only_action_uses_fan_mode_timer)
void switch_to_swing_mode_(climate::ClimateSwingMode swing_mode, bool publish_state=true)
Switch the climate device to the given climate swing mode.
bool supplemental_cooling_required_()
bool hysteresis_valid()
Set point and hysteresis validation.
ClimateSwingMode
Enum for all modes a climate swing can be in.
void trigger(Ts... x)
Inform the parent automation that the event has triggered.
std::string default_custom_preset_
Default custom preset to use on start up.
uint32_t timer_duration_(ThermostatClimateTimerIndex timer_index)
bool fan_mode_change_delayed()
bool supports_fan_mode_high_
Trigger * preset_change_trigger_
The triggr to call when the preset mode changes.
bool cooling_action_ready_()
void add_supported_preset(ClimatePreset preset)
Trigger * get_dry_mode_trigger() const
void set_supports_heat_cool(bool supports_heat_cool)
Trigger * fan_mode_high_trigger_
The trigger to call when the controller should switch the fan to "high" speed.
Trigger * cool_mode_trigger_
float cooling_deadband_
Hysteresis values used for computing climate actions.
Trigger * dry_mode_trigger_
Trigger * supplemental_cool_action_trigger_
bool supports_fan_with_cooling_
Special flags – enables fan_only action to be called with cooling/heating actions.
void add_supported_swing_mode(ClimateSwingMode mode)
void set_supports_swing_mode_off(bool supports_swing_mode_off)
const optional< std::string > & get_custom_preset() const
The fan mode is set to Horizontal.
void set_supports_auto(bool supports_auto)
The climate device is set to cool to reach the target temperature.
float state
This member variable stores the last state that has passed through all filters.
void set_supports_fan_only_cooling(bool supports_fan_only_cooling)
Trigger * get_fan_mode_high_trigger() const
void set_supplemental_heat_delta(float delta)
const optional< ClimatePreset > & get_preset() const
float default_temperature
The fan mode is set to Auto.
void cooling_max_run_time_timer_callback_()
set_timeout() callbacks for various actions (see above)
float get_visual_min_temperature() const
void set_fanning_minimum_run_time_in_sec(uint32_t time)
optional< ClimatePreset > preset
The active preset of the climate device.
Trigger * get_fan_only_action_trigger() const
bool supports_fan_mode_low_
Whether the controller supports various fan speeds and/or positions.
Trigger * fan_mode_low_trigger_
The trigger to call when the controller should switch the fan to "low" speed.
void set_supports_dry(bool supports_dry)
Trigger * fan_only_action_trigger_
The trigger to call when the controller should switch to fan-only action/mode.
void set_on_boot_restore_from(thermostat::OnBootRestoreFrom on_boot_restore_from)
bool idle_action_ready_()
Is the action ready to be called? Returns true if so.
void set_custom_preset_config(const std::string &name, const ThermostatClimateTargetTempConfig &config)
Trigger * temperature_change_trigger_
The trigger to call when the target temperature(s) change(es).
bool cooling_required_()
Check if cooling/fanning/heating actions are required; returns true if so.
bool supports_swing_mode_both_
Whether the controller supports various swing modes.
ClimateAction
Enum for the current action of the climate device. Values match those of ClimateMode.
ThermostatClimateTargetTempConfig()
ClimateTraits get_traits()
Get the traits of this climate device with all overrides applied.
bool heating_action_ready_()
bool cancel_timer_(ThermostatClimateTimerIndex timer_index)
Trigger * fan_mode_medium_trigger_
The trigger to call when the controller should switch the fan to "medium" speed.
Trigger * get_fan_mode_auto_trigger() const
Trigger * get_temperature_change_trigger() const
Trigger * get_supplemental_heat_action_trigger() const
float supplemental_heat_delta_
const LogString * climate_preset_to_string(ClimatePreset preset)
Convert the given PresetMode to a human-readable string.
The climate device is adjusting the temperatre dynamically.
Trigger * swing_mode_off_trigger_
The trigger to call when the controller should switch the swing mode to "off".
float default_temperature_low
The climate device is set to heat/cool to reach the target temperature.
The fan mode is set to Vertical.
bool timer_active_(ThermostatClimateTimerIndex timer_index)
The climate device is actively heating.
The fan mode is set to Focus.
climate::ClimateAction supplemental_action_
Store previously-known states.
void set_supplemental_cool_delta(float delta)
The fan mode is set to Off.
void add_supported_fan_mode(ClimateFanMode mode)
Trigger * idle_action_trigger_
The trigger to call when the controller should switch to idle action/off mode.
Trigger * auto_mode_trigger_
The trigger to call when the controller should switch to auto mode.
const optional< float > & get_target_temperature() const
climate::ClimateAction delayed_climate_action()
Returns the climate action that is being delayed (check climate_action_change_delayed(), first!)
Trigger * get_fan_mode_medium_trigger() const
void publish_state()
Publish the state of the climate device, to be called from integrations.
void heating_max_run_time_timer_callback_()
void set_supports_heat(bool supports_heat)
Trigger * fan_mode_off_trigger_
The trigger to call when the controller should switch off the fan.
void set_preset_config(climate::ClimatePreset preset, const ThermostatClimateTargetTempConfig &config)
The fan mode is set to High.
void set_fanning_minimum_off_time_in_sec(uint32_t time)
bool supports_fan_mode_focus_
ClimateMode
Enum for all modes a climate device can be in.
The swing mode is set to Off.
The climate device is off.
void set_use_startup_delay(bool use_startup_delay)
bool climate_action_change_delayed()
Returns true if a climate action/fan mode transition is being delayed.
Trigger * heat_mode_trigger_
void set_heating_maximum_run_time_in_sec(uint32_t time)
void set_supports_fan_with_heating(bool supports_fan_with_heating)
void set_supports_action(bool supports_action)
void change_custom_preset_(const std::string &custom_preset)
Change to a provided custom preset setting; will reset temperature, mode, fan, and swing modes accord...
void fanning_off_timer_callback_()
optional< std::string > custom_preset
The active custom preset mode of the climate device.
Trigger * get_fan_mode_focus_trigger() const
const LogString * climate_fan_mode_to_string(ClimateFanMode fan_mode)
Convert the given ClimateFanMode to a human-readable string.
bool cooling_max_runtime_exceeded_
Flags indicating if maximum allowable run time was exceeded.
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
void set_cool_overrun(float overrun)
void set_heat_overrun(float overrun)
climate::ClimateFanMode prev_fan_mode_
void switch_to_fan_mode_(climate::ClimateFanMode fan_mode, bool publish_state=true)
Switch the climate device to the given climate fan mode.
void set_heating_minimum_off_time_in_sec(uint32_t time)
const optional< ClimateFanMode > & get_fan_mode() const
Trigger * get_fan_only_mode_trigger() const
Trigger * get_swing_mode_horizontal_trigger() const
void set_supports_fan_mode_low(bool supports_fan_mode_low)
Trigger * fan_only_mode_trigger_
Trigger * get_idle_action_trigger() const
void fan_mode_timer_callback_()
Trigger * get_heat_mode_trigger() const
Trigger * fan_mode_focus_trigger_
The trigger to call when the controller should switch the fan to "focus" position.
void cooling_off_timer_callback_()
The fan mode is set to On.
climate::ClimateAction compute_action_(bool ignore_timers=false)
Re-compute the required action of this climate controller.
float cool_deadband()
Get current hysteresis values.
Trigger * swing_mode_horizontal_trigger_
The trigger to call when the controller should switch the swing mode to "horizontal".
std::function< void()> timer_cbf_(ThermostatClimateTimerIndex timer_index)
void set_supports_fan_mode_off(bool supports_fan_mode_off)
sensor::Sensor * sensor_
The sensor used for getting the current temperature.
std::vector< ThermostatClimateTimer > timer_
Climate action timers.
void start_timer_(ThermostatClimateTimerIndex timer_index)
Start/cancel/get status of climate action timer.
float supplemental_cool_delta_
Maximum allowable temperature deltas before engauging supplemental cooling/heating actions...
void dump_config() override
const optional< ClimateSwingMode > & get_swing_mode() const
std::map< climate::ClimatePreset, ThermostatClimateTargetTempConfig > preset_config_
The set of standard preset configurations this thermostat supports (Eg. AWAY, ECO, etc)
climate::ClimateSwingMode prev_swing_mode_
bool change_preset_internal_(const ThermostatClimateTargetTempConfig &config)
Applies the temperature, mode, fan, and swing modes of the provided config.
bool supports_two_points_
Whether the controller supports two set points.
climate::ClimateFanMode locked_fan_mode()
Returns the fan mode that is locked in (check fan_mode_change_delayed(), first!)
void set_set_point_minimum_differential(float differential)
void check_temperature_change_trigger_()
Check if the temperature change trigger should be called.
void switch_to_mode_(climate::ClimateMode mode, bool publish_state=true)
Switch the climate device to the given climate mode.
Trigger * get_fan_mode_middle_trigger() const
The climate device is idle (monitoring climate but no action needed)
void set_heat_deadband(float deadband)
void set_supports_two_point_target_temperature(bool supports_two_point_target_temperature)
optional< ClimateDeviceRestoreState > restore_state_()
Restore the state of the climate device, call this from your setup() method.
Trigger * get_swing_mode_both_trigger() const
Trigger * fan_mode_on_trigger_
The trigger to call when the controller should switch on the fan.
void validate_target_temperature()
bool supports_fan_mode_on_
Whether the controller supports turning on or off just the fan.
Trigger * fan_mode_diffuse_trigger_
The trigger to call when the controller should switch the fan to "diffuse" position.
void set_supports_current_temperature(bool supports_current_temperature)
void set_idle_minimum_time_in_sec(uint32_t time)
The fan mode is set to Medium.
const optional< float > & get_target_temperature_high() const
Trigger * get_heat_action_trigger() const
bool supports_fan_only_action_uses_fan_mode_timer_
Special flag – enables fan_modes to share timer with fan_only climate action.
bool supports_swing_mode_off_
Base-class for all sensors.
void cooling_on_timer_callback_()
void set_supports_fan_mode_high(bool supports_fan_mode_high)
float prev_target_temperature_low_
bool fanning_action_ready_()
void trigger_supplemental_action_()
ThermostatClimateTimerIndex
Trigger * get_fan_mode_on_trigger() const
void dump_preset_config_(const char *preset_name, const ThermostatClimateTargetTempConfig &config, bool is_default_preset)
void set_supports_swing_mode_both(bool supports_swing_mode_both)
void set_heating_minimum_run_time_in_sec(uint32_t time)
The climate device only has the fan enabled, no heating or cooling is taking place.
bool supports_fan_mode_medium_
const uint8_t min_timer_duration_
Minimum allowable duration in seconds for action timers.
void change_preset_(climate::ClimatePreset preset)
Change to a provided preset setting; will reset temperature, mode, fan, and swing modes accordingly...
Trigger * get_swing_mode_vertical_trigger() const
The climate device is actively cooling.
float prev_target_temperature_high_
value_type value_or(U const &v) const
void add_supported_mode(ClimateMode mode)
float target_temperature_low
The minimum target temperature of the climate device, for climate devices with split target temperatu...
void stop_action()
Stop any action connected to this trigger.
bool use_startup_delay_
Used to start "off" delay timers at boot.
bool supports_fan_mode_diffuse_
Trigger * get_supplemental_cool_action_trigger() const
Trigger * get_cool_mode_trigger() const
Trigger * get_fan_mode_off_trigger() const
optional< climate::ClimateFanMode > fan_mode_
ClimateAction action
The active state of the climate device.
bool supports_swing_mode_horizontal_
bool setup_complete_
setup_complete_ blocks modifying/resetting the temps immediately after boot
climate::ClimatePreset default_preset_
Default standard preset to use on start up.
optional< climate::ClimateMode > mode_
const LogString * climate_swing_mode_to_string(ClimateSwingMode swing_mode)
Convert the given ClimateSwingMode to a human-readable string.
bool supports_fan_only_cooling_
Special flag – enables fan to be switched based on target_temperature_high.
bool drying_action_ready_()