7 static const char *
const TAG =
"climate";
15 ESP_LOGD(TAG,
" Mode: %s", LOG_STR_ARG(mode_s));
24 ESP_LOGD(TAG,
" Fan: %s", LOG_STR_ARG(fan_mode_s));
33 ESP_LOGD(TAG,
" Preset: %s", LOG_STR_ARG(preset_s));
37 ESP_LOGD(TAG,
" Swing: %s", LOG_STR_ARG(swing_mode_s));
57 if (!traits.supports_mode(
mode)) {
65 ESP_LOGW(TAG,
" Fan Mode %s is not supported by this device!",
custom_fan_mode.c_str());
70 if (!traits.supports_fan_mode(
fan_mode)) {
71 ESP_LOGW(TAG,
" Fan Mode %s is not supported by this device!",
79 ESP_LOGW(TAG,
" Preset %s is not supported by this device!",
custom_preset.c_str());
84 if (!traits.supports_preset(
preset)) {
92 ESP_LOGW(TAG,
" Swing Mode %s is not supported by this device!",
99 if (traits.get_supports_two_point_target_temperature()) {
100 ESP_LOGW(TAG,
" Cannot set target temperature for climate device " 101 "with two-point target temperature!");
103 }
else if (std::isnan(target)) {
104 ESP_LOGW(TAG,
" Target temperature must not be NAN!");
109 if (!traits.get_supports_two_point_target_temperature()) {
110 ESP_LOGW(TAG,
" Cannot set low/high target temperature for this device!");
116 ESP_LOGW(TAG,
" Target temperature low must not be NAN!");
120 ESP_LOGW(TAG,
" Target temperature low must not be NAN!");
127 ESP_LOGW(TAG,
" Target temperature low %.2f must be smaller than target temperature high %.2f!", low, high);
188 ESP_LOGW(TAG,
"'%s' - Unrecognized fan mode %s", this->
parent_->
get_name().
c_str(), fan_mode.c_str());
226 ESP_LOGW(TAG,
"'%s' - Unrecognized preset %s", this->
parent_->
get_name().
c_str(), preset.c_str());
251 ESP_LOGW(TAG,
"'%s' - Unrecognized swing mode %s", this->
parent_->
get_name().
c_str(), swing_mode.c_str());
319 this->state_callback_.add(std::move(callback));
323 this->control_callback_.add(std::move(callback));
327 static const uint32_t RESTORE_STATE_VERSION = 0x848EA6ADUL;
331 RESTORE_STATE_VERSION);
333 if (!this->rtc_.load(&recovered))
338 #if (defined(USE_ESP_IDF) || (defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE >= VERSION_CODE(3, 0, 0))) && \ 340 #pragma GCC diagnostic ignored "-Wclass-memaccess" 341 #define TEMP_IGNORE_MEMACCESS 346 #ifdef TEMP_IGNORE_MEMACCESS 347 #pragma GCC diagnostic pop 348 #undef TEMP_IGNORE_MEMACCESS 352 auto traits = this->get_traits();
353 if (traits.get_supports_two_point_target_temperature()) {
359 if (traits.get_supports_target_humidity()) {
362 if (traits.get_supports_fan_modes() &&
fan_mode.has_value()) {
363 state.uses_custom_fan_mode =
false;
366 if (!traits.get_supported_custom_fan_modes().empty() &&
custom_fan_mode.has_value()) {
367 state.uses_custom_fan_mode =
true;
368 const auto &supported = traits.get_supported_custom_fan_modes();
369 std::vector<std::string> vec{supported.begin(), supported.end()};
371 if (it != vec.end()) {
372 state.custom_fan_mode = std::distance(vec.begin(), it);
375 if (traits.get_supports_presets() &&
preset.has_value()) {
376 state.uses_custom_preset =
false;
379 if (!traits.get_supported_custom_presets().empty() &&
custom_preset.has_value()) {
380 state.uses_custom_preset =
true;
381 const auto &supported = traits.get_supported_custom_presets();
382 std::vector<std::string> vec{supported.begin(), supported.end()};
385 if (it != vec.cend()) {
386 state.custom_preset = std::distance(vec.begin(), it);
389 if (traits.get_supports_swing_modes()) {
393 this->rtc_.save(&
state);
396 ESP_LOGD(TAG,
"'%s' - Sending state:", this->name_.c_str());
397 auto traits = this->get_traits();
400 if (traits.get_supports_action()) {
403 if (traits.get_supports_fan_modes() && this->
fan_mode.has_value()) {
406 if (!traits.get_supported_custom_fan_modes().empty() && this->
custom_fan_mode.has_value()) {
407 ESP_LOGD(TAG,
" Custom Fan Mode: %s", this->
custom_fan_mode.value().c_str());
409 if (traits.get_supports_presets() && this->
preset.has_value()) {
412 if (!traits.get_supported_custom_presets().empty() && this->
custom_preset.has_value()) {
413 ESP_LOGD(TAG,
" Custom Preset: %s", this->
custom_preset.value().c_str());
415 if (traits.get_supports_swing_modes()) {
418 if (traits.get_supports_current_temperature()) {
419 ESP_LOGD(TAG,
" Current Temperature: %.2f°C", this->current_temperature);
421 if (traits.get_supports_two_point_target_temperature()) {
427 if (traits.get_supports_current_humidity()) {
428 ESP_LOGD(TAG,
" Current Humidity: %.0f%%", this->current_humidity);
430 if (traits.get_supports_target_humidity()) {
435 this->state_callback_.call(*
this);
441 auto traits = this->traits();
442 if (this->visual_min_temperature_override_.has_value()) {
443 traits.set_visual_min_temperature(*this->visual_min_temperature_override_);
445 if (this->visual_max_temperature_override_.has_value()) {
446 traits.set_visual_max_temperature(*this->visual_max_temperature_override_);
448 if (this->visual_target_temperature_step_override_.has_value()) {
449 traits.set_visual_target_temperature_step(*this->visual_target_temperature_step_override_);
450 traits.set_visual_current_temperature_step(*this->visual_current_temperature_step_override_);
452 if (this->visual_min_humidity_override_.has_value()) {
453 traits.set_visual_min_humidity(*this->visual_min_humidity_override_);
455 if (this->visual_max_humidity_override_.has_value()) {
456 traits.set_visual_max_humidity(*this->visual_max_humidity_override_);
463 this->visual_min_temperature_override_ = visual_min_temperature_override;
466 this->visual_max_temperature_override_ = visual_max_temperature_override;
469 this->visual_target_temperature_step_override_ = target;
470 this->visual_current_temperature_step_override_ = current;
473 this->visual_min_humidity_override_ = visual_min_humidity_override;
476 this->visual_max_humidity_override_ = visual_max_humidity_override;
484 call.set_mode(this->
mode);
485 if (traits.get_supports_two_point_target_temperature()) {
491 if (traits.get_supports_target_humidity()) {
494 if (traits.get_supports_fan_modes() || !traits.get_supported_custom_fan_modes().empty()) {
497 if (traits.get_supports_presets() || !traits.get_supported_custom_presets().empty()) {
498 call.set_preset(this->
preset);
500 if (traits.get_supports_swing_modes()) {
508 if (traits.get_supports_two_point_target_temperature()) {
514 if (traits.get_supports_target_humidity()) {
522 const auto &modes = traits.get_supported_custom_fan_modes();
523 std::vector<std::string> modes_vec{modes.begin(), modes.end()};
533 const auto &presets = traits.get_supported_custom_presets();
534 std::vector<std::string> presets_vec{presets.begin(), presets.end()};
539 if (traits.get_supports_swing_modes()) {
548 if (is_changed || dst != src) {
570 auto traits = this->get_traits();
571 ESP_LOGCONFIG(tag,
"ClimateTraits:");
572 ESP_LOGCONFIG(tag,
" [x] Visual settings:");
573 ESP_LOGCONFIG(tag,
" - Min temperature: %.1f", traits.get_visual_min_temperature());
574 ESP_LOGCONFIG(tag,
" - Max temperature: %.1f", traits.get_visual_max_temperature());
575 ESP_LOGCONFIG(tag,
" - Temperature step:");
576 ESP_LOGCONFIG(tag,
" Target: %.1f", traits.get_visual_target_temperature_step());
577 if (traits.get_supports_current_temperature()) {
578 ESP_LOGCONFIG(tag,
" Current: %.1f", traits.get_visual_current_temperature_step());
580 if (traits.get_supports_target_humidity() || traits.get_supports_current_humidity()) {
581 ESP_LOGCONFIG(tag,
" - Min humidity: %.0f", traits.get_visual_min_humidity());
582 ESP_LOGCONFIG(tag,
" - Max humidity: %.0f", traits.get_visual_max_humidity());
584 if (traits.get_supports_two_point_target_temperature()) {
585 ESP_LOGCONFIG(tag,
" [x] Supports two-point target temperature");
587 if (traits.get_supports_current_temperature()) {
588 ESP_LOGCONFIG(tag,
" [x] Supports current temperature");
590 if (traits.get_supports_target_humidity()) {
591 ESP_LOGCONFIG(tag,
" [x] Supports target humidity");
593 if (traits.get_supports_current_humidity()) {
594 ESP_LOGCONFIG(tag,
" [x] Supports current humidity");
596 if (traits.get_supports_action()) {
597 ESP_LOGCONFIG(tag,
" [x] Supports action");
599 if (!traits.get_supported_modes().empty()) {
600 ESP_LOGCONFIG(tag,
" [x] Supported modes:");
604 if (!traits.get_supported_fan_modes().empty()) {
605 ESP_LOGCONFIG(tag,
" [x] Supported fan modes:");
609 if (!traits.get_supported_custom_fan_modes().empty()) {
610 ESP_LOGCONFIG(tag,
" [x] Supported custom fan modes:");
611 for (
const std::string &s : traits.get_supported_custom_fan_modes())
612 ESP_LOGCONFIG(tag,
" - %s", s.c_str());
614 if (!traits.get_supported_presets().empty()) {
615 ESP_LOGCONFIG(tag,
" [x] Supported presets:");
619 if (!traits.get_supported_custom_presets().empty()) {
620 ESP_LOGCONFIG(tag,
" [x] Supported custom presets:");
621 for (
const std::string &s : traits.get_supported_custom_presets())
622 ESP_LOGCONFIG(tag,
" - %s", s.c_str());
624 if (!traits.get_supported_swing_modes().empty()) {
625 ESP_LOGCONFIG(tag,
" [x] Supported swing modes:");
This class is used to encode all control actions on a climate device.
The fan mode is set to Low.
value_type const & value() const
The fan mode is set to Quiet.
ClimateSwingMode swing_mode
The active swing mode of the climate device.
float target_temperature_low
optional< std::string > custom_preset_
The fan mode is set to Both.
ClimatePreset
Enum for all preset modes.
float target_temperature
The target temperature of the climate device.
Device is in home preset.
const optional< ClimateMode > & get_mode() const
optional< float > target_temperature_
The fan mode is set to Middle.
This class contains all static data for climate devices.
void set_visual_min_humidity_override(float visual_min_humidity_override)
const LogString * climate_mode_to_string(ClimateMode mode)
Convert the given ClimateMode to a human-readable string.
The climate device is set to heat to reach the target temperature.
CallbackManager< void(ClimateCall &)> control_callback_
Struct used to save the state of the climate device in restore memory.
ClimateMode mode
The active mode of the climate device.
bool set_alternative(optional< T1 > &dst, optional< T2 > &alt, const T1 &src)
optional< ClimateFanMode > fan_mode_
const optional< float > & get_target_temperature_low() const
void add_on_control_callback(std::function< void(ClimateCall &)> &&callback)
Add a callback for the climate device configuration; each time the configuration parameters of a clim...
float target_temperature_high
The maximum target temperature of the climate device, for climate devices with split target temperatu...
The fan mode is set to Diffuse.
optional< float > target_temperature_high_
The climate device is set to dry/humidity mode.
float target_temperature_high
bool uses_custom_fan_mode
float target_humidity
The target humidity of the climate device.
ClimateCall & set_swing_mode(ClimateSwingMode swing_mode)
Set the swing mode of the climate device.
void set_visual_max_humidity_override(float visual_max_humidity_override)
ClimateSwingMode swing_mode
ClimateSwingMode
Enum for all modes a climate swing can be in.
bool supports_custom_preset(const std::string &custom_preset) const
Device is prepared for sleep.
optional< std::string > custom_fan_mode
The active custom fan mode of the climate device.
Device is in away preset.
bool supports_custom_fan_mode(const std::string &custom_fan_mode) const
void apply(Climate *climate)
Apply these settings to the climate device.
ClimateCall & set_target_temperature_low(float target_temperature_low)
Set the low point target temperature of the climate device.
ClimateCall make_call()
Make a climate device control call, this is used to control the climate device, see the ClimateCall d...
Device is in comfort preset.
const optional< std::string > & get_custom_preset() const
ClimateCall & set_target_temperature(float target_temperature)
Set the target temperature of the climate device.
The fan mode is set to Horizontal.
The climate device is set to cool to reach the target temperature.
optional< ClimateSwingMode > swing_mode_
Device is reacting to activity (e.g., movement sensors)
const optional< ClimatePreset > & get_preset() const
The fan mode is set to Auto.
optional< ClimatePreset > preset
The active preset of the climate device.
ESPPreferences * global_preferences
optional< ClimatePreset > preset_
ClimateCall & set_preset(ClimatePreset preset)
Set the preset of the climate device.
BedjetMode mode
BedJet operating mode.
virtual void control(const ClimateCall &call)=0
Control the climate device, this is a virtual method that each climate integration must implement...
ClimateCall & set_fan_mode(ClimateFanMode fan_mode)
Set the fan mode of the climate device.
ClimateTraits get_traits()
Get the traits of this climate device with all overrides applied.
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.
The climate device is set to heat/cool to reach the target temperature.
The fan mode is set to Vertical.
void set_visual_max_temperature_override(float visual_max_temperature_override)
The fan mode is set to Focus.
const optional< std::string > & get_custom_fan_mode() const
void set_visual_min_temperature_override(float visual_min_temperature_override)
The fan mode is set to Off.
const optional< float > & get_target_temperature() const
optional< std::string > custom_fan_mode_
void publish_state()
Publish the state of the climate device, to be called from integrations.
bool set_custom_fan_mode_(const std::string &mode)
Set custom fan mode. Reset primary fan mode. Return true if fan mode has been changed.
The fan mode is set to High.
ClimateCall & set_target_humidity(float target_humidity)
Set the target humidity of the climate device.
ClimateMode
Enum for all modes a climate device can be in.
The swing mode is set to Off.
The climate device is off.
constexpr const char * c_str() const
void add_on_state_callback(std::function< void(Climate &)> &&callback)
Add a callback for the climate device state, each time the state of the climate device is updated (us...
optional< std::string > custom_preset
The active custom preset mode of the climate device.
ClimateCall & set_target_temperature_high(float target_temperature_high)
Set the high point target temperature of the climate device.
const LogString * climate_fan_mode_to_string(ClimateFanMode fan_mode)
Convert the given ClimateFanMode to a human-readable string.
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
void set_visual_temperature_step_override(float target, float current)
const optional< ClimateFanMode > & get_fan_mode() const
optional< float > target_humidity_
Device is in boost preset.
virtual ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash)=0
ClimateCall & set_mode(ClimateMode mode)
Set the mode of the climate device.
The fan mode is set to On.
bool set_custom_preset_(const std::string &preset)
Set custom preset. Reset primary preset. Return true if preset has been changed.
const optional< ClimateSwingMode > & get_swing_mode() const
void save_state_()
Internal method to save the state of the climate device to recover memory.
Implementation of SPI Controller mode.
optional< ClimateMode > mode_
ClimateCall(Climate *parent)
void dump_traits_(const char *tag)
Device is running an energy-saving preset.
optional< ClimateDeviceRestoreState > restore_state_()
Restore the state of the climate device, call this from your setup() method.
The fan mode is set to Medium.
const optional< float > & get_target_temperature_high() const
The climate device only has the fan enabled, no heating or cooling is taking place.
const LogString * climate_action_to_string(ClimateAction action)
Convert the given ClimateAction to a human-readable string.
bool set_preset_(ClimatePreset preset)
Set preset. Reset custom preset. Return true if preset has been changed.
optional< float > target_temperature_low_
const optional< float > & get_target_humidity() const
ClimateCall to_call(Climate *climate)
Convert this struct to a climate call that can be performed.
float target_temperature_low
The minimum target temperature of the climate device, for climate devices with split target temperatu...
const StringRef & get_name() const
bool set_fan_mode_(ClimateFanMode mode)
Set fan mode. Reset custom fan mode. Return true if fan mode has been changed.
ClimateDevice - This is the base class for all climate integrations.
bool str_equals_case_insensitive(const std::string &a, const std::string &b)
Compare strings for equality in case-insensitive manner.
const LogString * climate_swing_mode_to_string(ClimateSwingMode swing_mode)
Convert the given ClimateSwingMode to a human-readable string.