9static const char *
const TAG =
"climate";
51 if (this->
mode_.has_value()) {
53 ESP_LOGV(TAG,
" Mode: %s", LOG_STR_ARG(mode_s));
55 if (this->custom_fan_mode_ !=
nullptr) {
57 ESP_LOGV(TAG,
" Custom Fan: %s", this->custom_fan_mode_);
60 this->custom_fan_mode_ =
nullptr;
62 ESP_LOGV(TAG,
" Fan: %s", LOG_STR_ARG(fan_mode_s));
64 if (this->custom_preset_ !=
nullptr) {
66 ESP_LOGV(TAG,
" Custom Preset: %s", this->custom_preset_);
68 if (this->
preset_.has_value()) {
69 this->custom_preset_ =
nullptr;
71 ESP_LOGV(TAG,
" Preset: %s", LOG_STR_ARG(preset_s));
75 ESP_LOGV(TAG,
" Swing: %s", LOG_STR_ARG(swing_mode_s));
94 if (this->
mode_.has_value()) {
96 if (!traits.supports_mode(
mode)) {
101 if (this->custom_fan_mode_ !=
nullptr) {
102 if (!traits.supports_custom_fan_mode(this->custom_fan_mode_)) {
103 ESP_LOGW(TAG,
" Fan Mode %s not supported", this->custom_fan_mode_);
104 this->custom_fan_mode_ =
nullptr;
106 }
else if (this->
fan_mode_.has_value()) {
108 if (!traits.supports_fan_mode(
fan_mode)) {
113 if (this->custom_preset_ !=
nullptr) {
114 if (!traits.supports_custom_preset(this->custom_preset_)) {
115 ESP_LOGW(TAG,
" Preset %s not supported", this->custom_preset_);
116 this->custom_preset_ =
nullptr;
118 }
else if (this->
preset_.has_value()) {
120 if (!traits.supports_preset(
preset)) {
127 if (!traits.supports_swing_mode(
swing_mode)) {
136 ESP_LOGW(TAG,
" Cannot set target temperature for climate device "
137 "with two-point target temperature");
139 }
else if (std::isnan(target)) {
140 ESP_LOGW(TAG,
" Target temperature must not be NAN");
147 ESP_LOGW(TAG,
" Cannot set low/high target temperature");
153 ESP_LOGW(TAG,
" Target temperature low must not be NAN");
157 ESP_LOGW(TAG,
" Target temperature high must not be NAN");
164 ESP_LOGW(TAG,
" Target temperature low %.2f must be less than target temperature high %.2f", low, high);
192 this->custom_fan_mode_ =
nullptr;
213 this->custom_fan_mode_ = mode_ptr;
230 this->custom_preset_ =
nullptr;
245 if (strncasecmp(
custom_preset, preset_entry.str,
len) == 0 && preset_entry.str[
len] ==
'\0') {
251 this->custom_preset_ = preset_ptr;
344 this->custom_fan_mode_ =
nullptr;
350 this->custom_preset_ =
nullptr;
360static const uint32_t RESTORE_STATE_VERSION = 0x848EA6ADUL;
371#if (defined(USE_ESP32) || (defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE >= VERSION_CODE(3, 0, 0))) && \
373#pragma GCC diagnostic ignored "-Wclass-memaccess"
374#define TEMP_IGNORE_MEMACCESS
379#ifdef TEMP_IGNORE_MEMACCESS
380#pragma GCC diagnostic pop
381#undef TEMP_IGNORE_MEMACCESS
396 state.uses_custom_fan_mode =
false;
400 state.uses_custom_fan_mode =
true;
404 for (
const char *
mode : supported) {
405 if (strcmp(
mode, this->custom_fan_mode_) == 0) {
406 state.custom_fan_mode = i;
413 state.uses_custom_preset =
false;
417 state.uses_custom_preset =
true;
421 for (
const char *
preset : supported) {
422 if (strcmp(
preset, this->custom_preset_) == 0) {
423 state.custom_preset = i;
437 ESP_LOGV(TAG,
"'%s' >>", this->
name_.
c_str());
448 ESP_LOGV(TAG,
" Custom Fan Mode: %s", this->custom_fan_mode_);
454 ESP_LOGV(TAG,
" Custom Preset: %s", this->custom_preset_);
478#if defined(USE_CLIMATE) && defined(USE_CONTROLLER_REGISTRY)
479 ControllerRegistry::notify_climate_update(
this);
488 if (this->supported_custom_fan_modes_)
490 if (this->supported_custom_presets_)
492#ifdef USE_CLIMATE_VISUAL_OVERRIDES
513#ifdef USE_CLIMATE_VISUAL_OVERRIDES
541 call.set_mode(this->
mode);
553 if (this->
custom_fan_mode < traits.get_supported_custom_fan_modes().size()) {
554 call.fan_mode_.reset();
555 call.custom_fan_mode_ = traits.get_supported_custom_fan_modes()[this->
custom_fan_mode];
557 }
else if (traits.supports_fan_mode(this->fan_mode)) {
561 if (this->
custom_preset < traits.get_supported_custom_presets().size()) {
562 call.preset_.reset();
563 call.custom_preset_ = traits.get_supported_custom_presets()[this->
custom_preset];
565 }
else if (traits.supports_preset(this->preset)) {
566 call.set_preset(this->
preset);
568 if (traits.supports_swing_mode(this->swing_mode)) {
588 if (this->
custom_fan_mode < traits.get_supported_custom_fan_modes().size()) {
590 climate->custom_fan_mode_ = traits.get_supported_custom_fan_modes()[this->
custom_fan_mode];
592 }
else if (traits.supports_fan_mode(this->fan_mode)) {
597 if (this->
custom_preset < traits.get_supported_custom_presets().size()) {
599 climate->custom_preset_ = traits.get_supported_custom_presets()[this->
custom_preset];
601 }
else if (traits.supports_preset(this->preset)) {
605 if (traits.supports_swing_mode(this->swing_mode)) {
630template<
typename T>
bool set_primary_mode(optional<T> &primary,
const char *&custom_ptr, T value) {
632 bool changed = custom_ptr !=
nullptr;
633 custom_ptr =
nullptr;
635 if (changed || !primary.has_value() || primary.value() != value) {
664bool set_custom_mode(
const char *&custom_ptr, optional<T> &primary,
const char *found_ptr,
bool has_custom) {
665 if (found_ptr !=
nullptr) {
667 bool changed = primary.has_value();
670 if (changed || custom_ptr != found_ptr) {
671 custom_ptr = found_ptr;
678 custom_ptr =
nullptr;
709 if (this->supported_custom_fan_modes_) {
721 if (this->supported_custom_presets_) {
730 ESP_LOGCONFIG(
tag,
"ClimateTraits:");
732 " Visual settings:\n"
733 " - Min temperature: %.1f\n"
734 " - Max temperature: %.1f\n"
735 " - Temperature step:\n"
745 " - Min humidity: %.0f\n"
746 " - Max humidity: %.0f",
751 ESP_LOGCONFIG(
tag,
" Supports two-point target temperature");
754 ESP_LOGCONFIG(
tag,
" Supports current temperature");
757 ESP_LOGCONFIG(
tag,
" Supports target humidity");
760 ESP_LOGCONFIG(
tag,
" Supports current humidity");
763 ESP_LOGCONFIG(
tag,
" Supports action");
766 ESP_LOGCONFIG(
tag,
" Supported modes:");
771 ESP_LOGCONFIG(
tag,
" Supported fan modes:");
776 ESP_LOGCONFIG(
tag,
" Supported custom fan modes:");
778 ESP_LOGCONFIG(
tag,
" - %s", s);
781 ESP_LOGCONFIG(
tag,
" Supported presets:");
786 ESP_LOGCONFIG(
tag,
" Supported custom presets:");
788 ESP_LOGCONFIG(
tag,
" - %s", s);
791 ESP_LOGCONFIG(
tag,
" Supported swing modes:");
BedjetMode mode
BedJet operating mode.
const StringRef & get_name() const
ESPPreferenceObject make_entity_preference(uint32_t version=0)
Create a preference object for storing this entity's state/settings.
constexpr bool empty() const
Check if the set is empty.
StringRef is a reference to a string owned by something else.
constexpr const char * c_str() const
This class is used to encode all control actions on a climate device.
const optional< ClimateSwingMode > & get_swing_mode() const
optional< float > target_temperature_high_
const optional< float > & get_target_humidity() const
ClimateCall & set_target_temperature(float target_temperature)
Set the target temperature of the climate device.
const optional< float > & get_target_temperature_low() const
ClimateCall & set_swing_mode(ClimateSwingMode swing_mode)
Set the swing mode of the climate device.
optional< ClimateFanMode > fan_mode_
ClimateCall & set_target_temperature_low(float target_temperature_low)
Set the low point target temperature of the climate device.
optional< float > target_temperature_
const optional< float > & get_target_temperature() const
const optional< ClimatePreset > & get_preset() const
optional< ClimateSwingMode > swing_mode_
optional< ClimateMode > mode_
ClimateCall & set_preset(ClimatePreset preset)
Set the preset of the climate device.
const optional< float > & get_target_temperature_high() const
const optional< ClimateFanMode > & get_fan_mode() const
optional< float > target_humidity_
ClimateCall & set_fan_mode(ClimateFanMode fan_mode)
Set the fan mode of the climate device.
optional< ClimatePreset > preset_
ClimateCall & set_target_humidity(float target_humidity)
Set the target humidity of the climate device.
optional< float > target_temperature_low_
ClimateCall & set_target_temperature_high(float target_temperature_high)
Set the high point target temperature of the climate device.
ClimateCall & set_mode(ClimateMode mode)
Set the mode of the climate device.
const optional< ClimateMode > & get_mode() const
ClimateDevice - This is the base class for all climate integrations.
ClimateMode mode
The active mode of the climate device.
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
ClimateTraits get_traits()
Get the traits of this climate device with all overrides applied.
float target_temperature
The target temperature of the climate device.
float current_humidity
The current humidity of the climate device, as reported from the integration.
float visual_min_humidity_override_
float visual_target_temperature_step_override_
void set_visual_min_humidity_override(float visual_min_humidity_override)
void dump_traits_(const char *tag)
ClimateSwingMode swing_mode
The active swing mode of the climate device.
float target_temperature_low
The minimum target temperature of the climate device, for climate devices with split target temperatu...
void set_visual_max_humidity_override(float visual_max_humidity_override)
float visual_current_temperature_step_override_
virtual ClimateTraits traits()=0
Get the default traits of this climate device.
bool set_preset_(ClimatePreset preset)
Set preset. Reset custom preset. Return true if preset has been changed.
bool set_custom_preset_(const char *preset)
Set custom preset. Reset primary preset. Return true if preset has been changed.
const char * find_custom_fan_mode_(const char *custom_fan_mode)
Find and return the matching custom fan mode pointer from traits, or nullptr if not found.
float visual_min_temperature_override_
void set_visual_max_temperature_override(float visual_max_temperature_override)
void clear_custom_preset_()
Clear custom preset.
bool set_fan_mode_(ClimateFanMode mode)
Set fan mode. Reset custom fan mode. Return true if fan mode has been changed.
LazyCallbackManager< void(Climate &)> state_callback_
bool has_custom_preset() const
Check if a custom preset is currently active.
const char * find_custom_preset_(const char *custom_preset)
Find and return the matching custom preset pointer from traits, or nullptr if not found.
void clear_custom_fan_mode_()
Clear custom fan mode.
float current_temperature
The current temperature of the climate device, as reported from the integration.
float visual_max_humidity_override_
ClimateAction action
The active state of the climate device.
LazyCallbackManager< void(ClimateCall &)> control_callback_
ClimateCall make_call()
Make a climate device control call, this is used to control the climate device, see the ClimateCall d...
float visual_max_temperature_override_
virtual void control(const ClimateCall &call)=0
Control the climate device, this is a virtual method that each climate integration must implement.
void publish_state()
Publish the state of the climate device, to be called from integrations.
void set_visual_temperature_step_override(float target, float current)
bool has_custom_fan_mode() const
Check if a custom fan mode is currently active.
optional< ClimatePreset > preset
The active preset of the climate device.
void set_visual_min_temperature_override(float visual_min_temperature_override)
optional< ClimateDeviceRestoreState > restore_state_()
Restore the state of the climate device, call this from your setup() method.
float target_humidity
The target humidity of the climate device.
bool set_custom_fan_mode_(const char *mode)
Set custom fan mode. Reset primary fan mode. Return true if fan mode has been changed.
float target_temperature_high
The maximum target temperature of the climate device, for climate devices with split target temperatu...
void set_visual_max_temperature(float visual_max_temperature)
const ClimatePresetMask & get_supported_presets() const
float get_visual_min_humidity() const
bool get_supports_swing_modes() const
const std::vector< const char * > & get_supported_custom_fan_modes() const
const ClimateSwingModeMask & get_supported_swing_modes() const
void set_visual_target_temperature_step(float temperature_step)
float get_visual_current_temperature_step() const
void set_visual_min_temperature(float visual_min_temperature)
bool get_supports_fan_modes() const
const ClimateFanModeMask & get_supported_fan_modes() const
float get_visual_target_temperature_step() const
void set_supported_custom_presets_(const std::vector< const char * > *presets)
void set_visual_min_humidity(float visual_min_humidity)
void set_visual_current_temperature_step(float temperature_step)
void set_supported_custom_fan_modes_(const std::vector< const char * > *modes)
Set custom mode pointers (only Climate::get_traits() should call these).
bool has_feature_flags(uint32_t feature_flags) const
void set_visual_max_humidity(float visual_max_humidity)
float get_visual_max_humidity() const
const char * find_custom_fan_mode_(const char *custom_fan_mode) const
Find and return the matching custom fan mode pointer from supported modes, or nullptr if not found Th...
const char * find_custom_preset_(const char *custom_preset) const
Find and return the matching custom preset pointer from supported presets, or nullptr if not found Th...
const std::vector< const char * > & get_supported_custom_presets() const
const ClimateModeMask & get_supported_modes() const
bool get_supports_presets() const
float get_visual_max_temperature() const
float get_visual_min_temperature() const
float target_temperature_high
ClimateSwingMode swing_mode
float target_temperature_low
const LogString * climate_action_to_string(ClimateAction action)
Convert the given ClimateAction to a human-readable string.
constexpr StringToUint8 CLIMATE_MODES_BY_STR[]
@ CLIMATE_SUPPORTS_CURRENT_HUMIDITY
@ CLIMATE_SUPPORTS_TARGET_HUMIDITY
@ CLIMATE_SUPPORTS_TWO_POINT_TARGET_TEMPERATURE
@ CLIMATE_SUPPORTS_CURRENT_TEMPERATURE
@ CLIMATE_SUPPORTS_ACTION
@ CLIMATE_REQUIRES_TWO_POINT_TARGET_TEMPERATURE
const LogString * climate_swing_mode_to_string(ClimateSwingMode swing_mode)
Convert the given ClimateSwingMode to a human-readable string.
constexpr StringToUint8 CLIMATE_PRESETS_BY_STR[]
const LogString * climate_preset_to_string(ClimatePreset preset)
Convert the given PresetMode to a human-readable string.
ClimatePreset
Enum for all preset modes NOTE: If adding values, update ClimatePresetMask in climate_traits....
@ CLIMATE_PRESET_NONE
No preset is active.
@ CLIMATE_PRESET_COMFORT
Device is in comfort preset.
@ CLIMATE_PRESET_AWAY
Device is in away preset.
@ CLIMATE_PRESET_BOOST
Device is in boost preset.
@ CLIMATE_PRESET_ACTIVITY
Device is reacting to activity (e.g., movement sensors)
@ CLIMATE_PRESET_SLEEP
Device is prepared for sleep.
@ CLIMATE_PRESET_HOME
Device is in home preset.
@ CLIMATE_PRESET_ECO
Device is running an energy-saving preset.
const LogString * climate_fan_mode_to_string(ClimateFanMode fan_mode)
Convert the given ClimateFanMode to a human-readable string.
constexpr StringToUint8 CLIMATE_FAN_MODES_BY_STR[]
ClimateSwingMode
Enum for all modes a climate swing can be in NOTE: If adding values, update ClimateSwingModeMask in c...
@ CLIMATE_SWING_OFF
The swing mode is set to Off.
@ CLIMATE_SWING_HORIZONTAL
The fan mode is set to Horizontal.
@ CLIMATE_SWING_VERTICAL
The fan mode is set to Vertical.
@ CLIMATE_SWING_BOTH
The fan mode is set to Both.
ClimateMode
Enum for all modes a climate device can be in.
@ CLIMATE_MODE_DRY
The climate device is set to dry/humidity mode.
@ CLIMATE_MODE_FAN_ONLY
The climate device only has the fan enabled, no heating or cooling is taking place.
@ CLIMATE_MODE_HEAT
The climate device is set to heat to reach the target temperature.
@ CLIMATE_MODE_COOL
The climate device is set to cool to reach the target temperature.
@ CLIMATE_MODE_HEAT_COOL
The climate device is set to heat/cool to reach the target temperature.
@ CLIMATE_MODE_OFF
The climate device is off.
@ CLIMATE_MODE_AUTO
The climate device is adjusting the temperature dynamically.
const LogString * climate_mode_to_string(ClimateMode mode)
Convert the given ClimateMode to a human-readable string.
bool set_primary_mode(optional< T > &primary, const char *&custom_ptr, T value)
Template helper for setting primary modes (fan_mode, preset) with mutual exclusion.
constexpr StringToUint8 CLIMATE_SWING_MODES_BY_STR[]
bool set_custom_mode(const char *&custom_ptr, optional< T > &primary, const char *found_ptr, bool has_custom)
Template helper for setting custom modes (custom_fan_mode_, custom_preset_) with mutual exclusion.
ClimateFanMode
NOTE: If adding values, update ClimateFanModeMask in climate_traits.h to use the new last value.
@ CLIMATE_FAN_MEDIUM
The fan mode is set to Medium.
@ CLIMATE_FAN_DIFFUSE
The fan mode is set to Diffuse.
@ CLIMATE_FAN_ON
The fan mode is set to On.
@ CLIMATE_FAN_AUTO
The fan mode is set to Auto.
@ CLIMATE_FAN_FOCUS
The fan mode is set to Focus.
@ CLIMATE_FAN_LOW
The fan mode is set to Low.
@ CLIMATE_FAN_MIDDLE
The fan mode is set to Middle.
@ CLIMATE_FAN_QUIET
The fan mode is set to Quiet.
@ CLIMATE_FAN_OFF
The fan mode is set to Off.
@ CLIMATE_FAN_HIGH
The fan mode is set to High.
const char * vector_find(const std::vector< const char * > &vec, const char *value, size_t len)
bool str_equals_case_insensitive(const std::string &a, const std::string &b)
Compare strings for equality in case-insensitive manner.
Struct used to save the state of the climate device in restore memory.
ClimateCall to_call(Climate *climate)
Convert this struct to a climate call that can be performed.
float target_temperature_high
void apply(Climate *climate)
Apply these settings to the climate device.
bool uses_custom_fan_mode
ClimateSwingMode swing_mode
float target_temperature_low