diff --git a/esphome/components/climate/climate.cpp b/esphome/components/climate/climate.cpp index f3c93ed44e..24a3fe6d5a 100644 --- a/esphome/components/climate/climate.cpp +++ b/esphome/components/climate/climate.cpp @@ -6,6 +6,42 @@ namespace climate { static const char *const TAG = "climate"; +// Memory-efficient lookup tables +struct StringToUint8 { + const char *str; + const uint8_t value; +}; + +constexpr StringToUint8 CLIMATE_MODES_BY_STR[] = { + {"OFF", CLIMATE_MODE_OFF}, + {"AUTO", CLIMATE_MODE_AUTO}, + {"COOL", CLIMATE_MODE_COOL}, + {"HEAT", CLIMATE_MODE_HEAT}, + {"FAN_ONLY", CLIMATE_MODE_FAN_ONLY}, + {"DRY", CLIMATE_MODE_DRY}, + {"HEAT_COOL", CLIMATE_MODE_HEAT_COOL}, +}; + +constexpr StringToUint8 CLIMATE_FAN_MODES_BY_STR[] = { + {"ON", CLIMATE_FAN_ON}, {"OFF", CLIMATE_FAN_OFF}, {"AUTO", CLIMATE_FAN_AUTO}, + {"LOW", CLIMATE_FAN_LOW}, {"MEDIUM", CLIMATE_FAN_MEDIUM}, {"HIGH", CLIMATE_FAN_HIGH}, + {"MIDDLE", CLIMATE_FAN_MIDDLE}, {"FOCUS", CLIMATE_FAN_FOCUS}, {"DIFFUSE", CLIMATE_FAN_DIFFUSE}, + {"QUIET", CLIMATE_FAN_QUIET}, +}; + +constexpr StringToUint8 CLIMATE_PRESETS_BY_STR[] = { + {"ECO", CLIMATE_PRESET_ECO}, {"AWAY", CLIMATE_PRESET_AWAY}, {"BOOST", CLIMATE_PRESET_BOOST}, + {"COMFORT", CLIMATE_PRESET_COMFORT}, {"HOME", CLIMATE_PRESET_HOME}, {"SLEEP", CLIMATE_PRESET_SLEEP}, + {"ACTIVITY", CLIMATE_PRESET_ACTIVITY}, {"NONE", CLIMATE_PRESET_NONE}, +}; + +constexpr StringToUint8 CLIMATE_SWING_MODES_BY_STR[] = { + {"OFF", CLIMATE_SWING_OFF}, + {"BOTH", CLIMATE_SWING_BOTH}, + {"VERTICAL", CLIMATE_SWING_VERTICAL}, + {"HORIZONTAL", CLIMATE_SWING_HORIZONTAL}, +}; + void ClimateCall::perform() { this->parent_->control_callback_.call(*this); ESP_LOGD(TAG, "'%s' - Setting", this->parent_->get_name().c_str()); @@ -50,47 +86,46 @@ void ClimateCall::perform() { } this->parent_->control(*this); } + void ClimateCall::validate_() { auto traits = this->parent_->get_traits(); if (this->mode_.has_value()) { auto mode = *this->mode_; if (!traits.supports_mode(mode)) { - ESP_LOGW(TAG, " Mode %s is not supported by this device!", LOG_STR_ARG(climate_mode_to_string(mode))); + ESP_LOGW(TAG, " Mode %s not supported", LOG_STR_ARG(climate_mode_to_string(mode))); this->mode_.reset(); } } if (this->custom_fan_mode_.has_value()) { auto custom_fan_mode = *this->custom_fan_mode_; if (!traits.supports_custom_fan_mode(custom_fan_mode)) { - ESP_LOGW(TAG, " Fan Mode %s is not supported by this device!", custom_fan_mode.c_str()); + ESP_LOGW(TAG, " Fan Mode %s not supported", custom_fan_mode.c_str()); this->custom_fan_mode_.reset(); } } else if (this->fan_mode_.has_value()) { auto fan_mode = *this->fan_mode_; if (!traits.supports_fan_mode(fan_mode)) { - ESP_LOGW(TAG, " Fan Mode %s is not supported by this device!", - LOG_STR_ARG(climate_fan_mode_to_string(fan_mode))); + ESP_LOGW(TAG, " Fan Mode %s not supported", LOG_STR_ARG(climate_fan_mode_to_string(fan_mode))); this->fan_mode_.reset(); } } if (this->custom_preset_.has_value()) { auto custom_preset = *this->custom_preset_; if (!traits.supports_custom_preset(custom_preset)) { - ESP_LOGW(TAG, " Preset %s is not supported by this device!", custom_preset.c_str()); + ESP_LOGW(TAG, " Preset %s not supported", custom_preset.c_str()); this->custom_preset_.reset(); } } else if (this->preset_.has_value()) { auto preset = *this->preset_; if (!traits.supports_preset(preset)) { - ESP_LOGW(TAG, " Preset %s is not supported by this device!", LOG_STR_ARG(climate_preset_to_string(preset))); + ESP_LOGW(TAG, " Preset %s not supported", LOG_STR_ARG(climate_preset_to_string(preset))); this->preset_.reset(); } } if (this->swing_mode_.has_value()) { auto swing_mode = *this->swing_mode_; if (!traits.supports_swing_mode(swing_mode)) { - ESP_LOGW(TAG, " Swing Mode %s is not supported by this device!", - LOG_STR_ARG(climate_swing_mode_to_string(swing_mode))); + ESP_LOGW(TAG, " Swing Mode %s not supported", LOG_STR_ARG(climate_swing_mode_to_string(swing_mode))); this->swing_mode_.reset(); } } @@ -99,159 +134,127 @@ void ClimateCall::validate_() { if (traits.has_feature_flags(CLIMATE_SUPPORTS_TWO_POINT_TARGET_TEMPERATURE | CLIMATE_REQUIRES_TWO_POINT_TARGET_TEMPERATURE)) { ESP_LOGW(TAG, " Cannot set target temperature for climate device " - "with two-point target temperature!"); + "with two-point target temperature"); this->target_temperature_.reset(); } else if (std::isnan(target)) { - ESP_LOGW(TAG, " Target temperature must not be NAN!"); + ESP_LOGW(TAG, " Target temperature must not be NAN"); this->target_temperature_.reset(); } } if (this->target_temperature_low_.has_value() || this->target_temperature_high_.has_value()) { if (!traits.has_feature_flags(CLIMATE_SUPPORTS_TWO_POINT_TARGET_TEMPERATURE | CLIMATE_REQUIRES_TWO_POINT_TARGET_TEMPERATURE)) { - ESP_LOGW(TAG, " Cannot set low/high target temperature for this device!"); + ESP_LOGW(TAG, " Cannot set low/high target temperature"); this->target_temperature_low_.reset(); this->target_temperature_high_.reset(); } } if (this->target_temperature_low_.has_value() && std::isnan(*this->target_temperature_low_)) { - ESP_LOGW(TAG, " Target temperature low must not be NAN!"); + ESP_LOGW(TAG, " Target temperature low must not be NAN"); this->target_temperature_low_.reset(); } if (this->target_temperature_high_.has_value() && std::isnan(*this->target_temperature_high_)) { - ESP_LOGW(TAG, " Target temperature low must not be NAN!"); + ESP_LOGW(TAG, " Target temperature high must not be NAN"); this->target_temperature_high_.reset(); } if (this->target_temperature_low_.has_value() && this->target_temperature_high_.has_value()) { float low = *this->target_temperature_low_; float high = *this->target_temperature_high_; if (low > high) { - ESP_LOGW(TAG, " Target temperature low %.2f must be smaller than target temperature high %.2f!", low, high); + ESP_LOGW(TAG, " Target temperature low %.2f must be less than target temperature high %.2f", low, high); this->target_temperature_low_.reset(); this->target_temperature_high_.reset(); } } } + ClimateCall &ClimateCall::set_mode(ClimateMode mode) { this->mode_ = mode; return *this; } + ClimateCall &ClimateCall::set_mode(const std::string &mode) { - if (str_equals_case_insensitive(mode, "OFF")) { - this->set_mode(CLIMATE_MODE_OFF); - } else if (str_equals_case_insensitive(mode, "AUTO")) { - this->set_mode(CLIMATE_MODE_AUTO); - } else if (str_equals_case_insensitive(mode, "COOL")) { - this->set_mode(CLIMATE_MODE_COOL); - } else if (str_equals_case_insensitive(mode, "HEAT")) { - this->set_mode(CLIMATE_MODE_HEAT); - } else if (str_equals_case_insensitive(mode, "FAN_ONLY")) { - this->set_mode(CLIMATE_MODE_FAN_ONLY); - } else if (str_equals_case_insensitive(mode, "DRY")) { - this->set_mode(CLIMATE_MODE_DRY); - } else if (str_equals_case_insensitive(mode, "HEAT_COOL")) { - this->set_mode(CLIMATE_MODE_HEAT_COOL); - } else { - ESP_LOGW(TAG, "'%s' - Unrecognized mode %s", this->parent_->get_name().c_str(), mode.c_str()); + for (const auto &mode_entry : CLIMATE_MODES_BY_STR) { + if (str_equals_case_insensitive(mode, mode_entry.str)) { + this->set_mode(static_cast(mode_entry.value)); + return *this; + } } + ESP_LOGW(TAG, "'%s' - Unrecognized mode %s", this->parent_->get_name().c_str(), mode.c_str()); return *this; } + ClimateCall &ClimateCall::set_fan_mode(ClimateFanMode fan_mode) { this->fan_mode_ = fan_mode; this->custom_fan_mode_.reset(); return *this; } + ClimateCall &ClimateCall::set_fan_mode(const std::string &fan_mode) { - if (str_equals_case_insensitive(fan_mode, "ON")) { - this->set_fan_mode(CLIMATE_FAN_ON); - } else if (str_equals_case_insensitive(fan_mode, "OFF")) { - this->set_fan_mode(CLIMATE_FAN_OFF); - } else if (str_equals_case_insensitive(fan_mode, "AUTO")) { - this->set_fan_mode(CLIMATE_FAN_AUTO); - } else if (str_equals_case_insensitive(fan_mode, "LOW")) { - this->set_fan_mode(CLIMATE_FAN_LOW); - } else if (str_equals_case_insensitive(fan_mode, "MEDIUM")) { - this->set_fan_mode(CLIMATE_FAN_MEDIUM); - } else if (str_equals_case_insensitive(fan_mode, "HIGH")) { - this->set_fan_mode(CLIMATE_FAN_HIGH); - } else if (str_equals_case_insensitive(fan_mode, "MIDDLE")) { - this->set_fan_mode(CLIMATE_FAN_MIDDLE); - } else if (str_equals_case_insensitive(fan_mode, "FOCUS")) { - this->set_fan_mode(CLIMATE_FAN_FOCUS); - } else if (str_equals_case_insensitive(fan_mode, "DIFFUSE")) { - this->set_fan_mode(CLIMATE_FAN_DIFFUSE); - } else if (str_equals_case_insensitive(fan_mode, "QUIET")) { - this->set_fan_mode(CLIMATE_FAN_QUIET); - } else { - if (this->parent_->get_traits().supports_custom_fan_mode(fan_mode)) { - this->custom_fan_mode_ = fan_mode; - this->fan_mode_.reset(); - } else { - ESP_LOGW(TAG, "'%s' - Unrecognized fan mode %s", this->parent_->get_name().c_str(), fan_mode.c_str()); + for (const auto &mode_entry : CLIMATE_FAN_MODES_BY_STR) { + if (str_equals_case_insensitive(fan_mode, mode_entry.str)) { + this->set_fan_mode(static_cast(mode_entry.value)); + return *this; } } + if (this->parent_->get_traits().supports_custom_fan_mode(fan_mode)) { + this->custom_fan_mode_ = fan_mode; + this->fan_mode_.reset(); + } else { + ESP_LOGW(TAG, "'%s' - Unrecognized fan mode %s", this->parent_->get_name().c_str(), fan_mode.c_str()); + } return *this; } + ClimateCall &ClimateCall::set_fan_mode(optional fan_mode) { if (fan_mode.has_value()) { this->set_fan_mode(fan_mode.value()); } return *this; } + ClimateCall &ClimateCall::set_preset(ClimatePreset preset) { this->preset_ = preset; this->custom_preset_.reset(); return *this; } + ClimateCall &ClimateCall::set_preset(const std::string &preset) { - if (str_equals_case_insensitive(preset, "ECO")) { - this->set_preset(CLIMATE_PRESET_ECO); - } else if (str_equals_case_insensitive(preset, "AWAY")) { - this->set_preset(CLIMATE_PRESET_AWAY); - } else if (str_equals_case_insensitive(preset, "BOOST")) { - this->set_preset(CLIMATE_PRESET_BOOST); - } else if (str_equals_case_insensitive(preset, "COMFORT")) { - this->set_preset(CLIMATE_PRESET_COMFORT); - } else if (str_equals_case_insensitive(preset, "HOME")) { - this->set_preset(CLIMATE_PRESET_HOME); - } else if (str_equals_case_insensitive(preset, "SLEEP")) { - this->set_preset(CLIMATE_PRESET_SLEEP); - } else if (str_equals_case_insensitive(preset, "ACTIVITY")) { - this->set_preset(CLIMATE_PRESET_ACTIVITY); - } else if (str_equals_case_insensitive(preset, "NONE")) { - this->set_preset(CLIMATE_PRESET_NONE); - } else { - if (this->parent_->get_traits().supports_custom_preset(preset)) { - this->custom_preset_ = preset; - this->preset_.reset(); - } else { - ESP_LOGW(TAG, "'%s' - Unrecognized preset %s", this->parent_->get_name().c_str(), preset.c_str()); + for (const auto &preset_entry : CLIMATE_PRESETS_BY_STR) { + if (str_equals_case_insensitive(preset, preset_entry.str)) { + this->set_preset(static_cast(preset_entry.value)); + return *this; } } + if (this->parent_->get_traits().supports_custom_preset(preset)) { + this->custom_preset_ = preset; + this->preset_.reset(); + } else { + ESP_LOGW(TAG, "'%s' - Unrecognized preset %s", this->parent_->get_name().c_str(), preset.c_str()); + } return *this; } + ClimateCall &ClimateCall::set_preset(optional preset) { if (preset.has_value()) { this->set_preset(preset.value()); } return *this; } + ClimateCall &ClimateCall::set_swing_mode(ClimateSwingMode swing_mode) { this->swing_mode_ = swing_mode; return *this; } + ClimateCall &ClimateCall::set_swing_mode(const std::string &swing_mode) { - if (str_equals_case_insensitive(swing_mode, "OFF")) { - this->set_swing_mode(CLIMATE_SWING_OFF); - } else if (str_equals_case_insensitive(swing_mode, "BOTH")) { - this->set_swing_mode(CLIMATE_SWING_BOTH); - } else if (str_equals_case_insensitive(swing_mode, "VERTICAL")) { - this->set_swing_mode(CLIMATE_SWING_VERTICAL); - } else if (str_equals_case_insensitive(swing_mode, "HORIZONTAL")) { - this->set_swing_mode(CLIMATE_SWING_HORIZONTAL); - } else { - ESP_LOGW(TAG, "'%s' - Unrecognized swing mode %s", this->parent_->get_name().c_str(), swing_mode.c_str()); + for (const auto &mode_entry : CLIMATE_SWING_MODES_BY_STR) { + if (str_equals_case_insensitive(swing_mode, mode_entry.str)) { + this->set_swing_mode(static_cast(mode_entry.value)); + return *this; + } } + ESP_LOGW(TAG, "'%s' - Unrecognized swing mode %s", this->parent_->get_name().c_str(), swing_mode.c_str()); return *this; } @@ -259,59 +262,71 @@ ClimateCall &ClimateCall::set_target_temperature(float target_temperature) { this->target_temperature_ = target_temperature; return *this; } + ClimateCall &ClimateCall::set_target_temperature_low(float target_temperature_low) { this->target_temperature_low_ = target_temperature_low; return *this; } + ClimateCall &ClimateCall::set_target_temperature_high(float target_temperature_high) { this->target_temperature_high_ = target_temperature_high; return *this; } + ClimateCall &ClimateCall::set_target_humidity(float target_humidity) { this->target_humidity_ = target_humidity; return *this; } -const optional &ClimateCall::get_mode() const { return this->mode_; } const optional &ClimateCall::get_target_temperature() const { return this->target_temperature_; } const optional &ClimateCall::get_target_temperature_low() const { return this->target_temperature_low_; } const optional &ClimateCall::get_target_temperature_high() const { return this->target_temperature_high_; } const optional &ClimateCall::get_target_humidity() const { return this->target_humidity_; } + +const optional &ClimateCall::get_mode() const { return this->mode_; } const optional &ClimateCall::get_fan_mode() const { return this->fan_mode_; } -const optional &ClimateCall::get_custom_fan_mode() const { return this->custom_fan_mode_; } -const optional &ClimateCall::get_preset() const { return this->preset_; } -const optional &ClimateCall::get_custom_preset() const { return this->custom_preset_; } const optional &ClimateCall::get_swing_mode() const { return this->swing_mode_; } +const optional &ClimateCall::get_preset() const { return this->preset_; } +const optional &ClimateCall::get_custom_fan_mode() const { return this->custom_fan_mode_; } +const optional &ClimateCall::get_custom_preset() const { return this->custom_preset_; } + ClimateCall &ClimateCall::set_target_temperature_high(optional target_temperature_high) { this->target_temperature_high_ = target_temperature_high; return *this; } + ClimateCall &ClimateCall::set_target_temperature_low(optional target_temperature_low) { this->target_temperature_low_ = target_temperature_low; return *this; } + ClimateCall &ClimateCall::set_target_temperature(optional target_temperature) { this->target_temperature_ = target_temperature; return *this; } + ClimateCall &ClimateCall::set_target_humidity(optional target_humidity) { this->target_humidity_ = target_humidity; return *this; } + ClimateCall &ClimateCall::set_mode(optional mode) { this->mode_ = mode; return *this; } + ClimateCall &ClimateCall::set_fan_mode(optional fan_mode) { this->fan_mode_ = fan_mode; this->custom_fan_mode_.reset(); return *this; } + ClimateCall &ClimateCall::set_preset(optional preset) { this->preset_ = preset; this->custom_preset_.reset(); return *this; } + ClimateCall &ClimateCall::set_swing_mode(optional swing_mode) { this->swing_mode_ = swing_mode; return *this; @@ -336,6 +351,7 @@ optional Climate::restore_state_() { return {}; return recovered; } + void Climate::save_state_() { #if (defined(USE_ESP_IDF) || (defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE >= VERSION_CODE(3, 0, 0))) && \ !defined(CLANG_TIDY) @@ -398,6 +414,7 @@ void Climate::save_state_() { this->rtc_.save(&state); } + void Climate::publish_state() { ESP_LOGD(TAG, "'%s' - Sending state:", this->name_.c_str()); auto traits = this->get_traits(); @@ -469,16 +486,20 @@ ClimateTraits Climate::get_traits() { void Climate::set_visual_min_temperature_override(float visual_min_temperature_override) { this->visual_min_temperature_override_ = visual_min_temperature_override; } + void Climate::set_visual_max_temperature_override(float visual_max_temperature_override) { this->visual_max_temperature_override_ = visual_max_temperature_override; } + void Climate::set_visual_temperature_step_override(float target, float current) { this->visual_target_temperature_step_override_ = target; this->visual_current_temperature_step_override_ = current; } + void Climate::set_visual_min_humidity_override(float visual_min_humidity_override) { this->visual_min_humidity_override_ = visual_min_humidity_override; } + void Climate::set_visual_max_humidity_override(float visual_max_humidity_override) { this->visual_max_humidity_override_ = visual_max_humidity_override; } @@ -510,6 +531,7 @@ ClimateCall ClimateDeviceRestoreState::to_call(Climate *climate) { } return call; } + void ClimateDeviceRestoreState::apply(Climate *climate) { auto traits = climate->get_traits(); climate->mode = this->mode; @@ -579,68 +601,68 @@ void Climate::dump_traits_(const char *tag) { auto traits = this->get_traits(); ESP_LOGCONFIG(tag, "ClimateTraits:"); ESP_LOGCONFIG(tag, - " [x] Visual settings:\n" - " - Min temperature: %.1f\n" - " - Max temperature: %.1f\n" - " - Temperature step:\n" - " Target: %.1f", + " Visual settings:\n" + " - Min temperature: %.1f\n" + " - Max temperature: %.1f\n" + " - Temperature step:\n" + " Target: %.1f", traits.get_visual_min_temperature(), traits.get_visual_max_temperature(), traits.get_visual_target_temperature_step()); if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_CURRENT_TEMPERATURE)) { - ESP_LOGCONFIG(tag, " Current: %.1f", traits.get_visual_current_temperature_step()); + ESP_LOGCONFIG(tag, " Current: %.1f", traits.get_visual_current_temperature_step()); } if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_TARGET_HUMIDITY | climate::CLIMATE_SUPPORTS_CURRENT_HUMIDITY)) { ESP_LOGCONFIG(tag, - " - Min humidity: %.0f\n" - " - Max humidity: %.0f", + " - Min humidity: %.0f\n" + " - Max humidity: %.0f", traits.get_visual_min_humidity(), traits.get_visual_max_humidity()); } if (traits.has_feature_flags(CLIMATE_SUPPORTS_TWO_POINT_TARGET_TEMPERATURE | CLIMATE_REQUIRES_TWO_POINT_TARGET_TEMPERATURE)) { - ESP_LOGCONFIG(tag, " [x] Supports two-point target temperature"); + ESP_LOGCONFIG(tag, " Supports two-point target temperature"); } if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_CURRENT_TEMPERATURE)) { - ESP_LOGCONFIG(tag, " [x] Supports current temperature"); + ESP_LOGCONFIG(tag, " Supports current temperature"); } if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_TARGET_HUMIDITY)) { - ESP_LOGCONFIG(tag, " [x] Supports target humidity"); + ESP_LOGCONFIG(tag, " Supports target humidity"); } if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_CURRENT_HUMIDITY)) { - ESP_LOGCONFIG(tag, " [x] Supports current humidity"); + ESP_LOGCONFIG(tag, " Supports current humidity"); } if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_ACTION)) { - ESP_LOGCONFIG(tag, " [x] Supports action"); + ESP_LOGCONFIG(tag, " Supports action"); } if (!traits.get_supported_modes().empty()) { - ESP_LOGCONFIG(tag, " [x] Supported modes:"); + ESP_LOGCONFIG(tag, " Supported modes:"); for (ClimateMode m : traits.get_supported_modes()) - ESP_LOGCONFIG(tag, " - %s", LOG_STR_ARG(climate_mode_to_string(m))); + ESP_LOGCONFIG(tag, " - %s", LOG_STR_ARG(climate_mode_to_string(m))); } if (!traits.get_supported_fan_modes().empty()) { - ESP_LOGCONFIG(tag, " [x] Supported fan modes:"); + ESP_LOGCONFIG(tag, " Supported fan modes:"); for (ClimateFanMode m : traits.get_supported_fan_modes()) - ESP_LOGCONFIG(tag, " - %s", LOG_STR_ARG(climate_fan_mode_to_string(m))); + ESP_LOGCONFIG(tag, " - %s", LOG_STR_ARG(climate_fan_mode_to_string(m))); } if (!traits.get_supported_custom_fan_modes().empty()) { - ESP_LOGCONFIG(tag, " [x] Supported custom fan modes:"); + ESP_LOGCONFIG(tag, " Supported custom fan modes:"); for (const std::string &s : traits.get_supported_custom_fan_modes()) - ESP_LOGCONFIG(tag, " - %s", s.c_str()); + ESP_LOGCONFIG(tag, " - %s", s.c_str()); } if (!traits.get_supported_presets().empty()) { - ESP_LOGCONFIG(tag, " [x] Supported presets:"); + ESP_LOGCONFIG(tag, " Supported presets:"); for (ClimatePreset p : traits.get_supported_presets()) - ESP_LOGCONFIG(tag, " - %s", LOG_STR_ARG(climate_preset_to_string(p))); + ESP_LOGCONFIG(tag, " - %s", LOG_STR_ARG(climate_preset_to_string(p))); } if (!traits.get_supported_custom_presets().empty()) { - ESP_LOGCONFIG(tag, " [x] Supported custom presets:"); + ESP_LOGCONFIG(tag, " Supported custom presets:"); for (const std::string &s : traits.get_supported_custom_presets()) - ESP_LOGCONFIG(tag, " - %s", s.c_str()); + ESP_LOGCONFIG(tag, " - %s", s.c_str()); } if (!traits.get_supported_swing_modes().empty()) { - ESP_LOGCONFIG(tag, " [x] Supported swing modes:"); + ESP_LOGCONFIG(tag, " Supported swing modes:"); for (ClimateSwingMode m : traits.get_supported_swing_modes()) - ESP_LOGCONFIG(tag, " - %s", LOG_STR_ARG(climate_swing_mode_to_string(m))); + ESP_LOGCONFIG(tag, " - %s", LOG_STR_ARG(climate_swing_mode_to_string(m))); } } diff --git a/esphome/components/climate/climate.h b/esphome/components/climate/climate.h index b31a2eedf6..495464c6a2 100644 --- a/esphome/components/climate/climate.h +++ b/esphome/components/climate/climate.h @@ -93,30 +93,31 @@ class ClimateCall { void perform(); - const optional &get_mode() const; const optional &get_target_temperature() const; const optional &get_target_temperature_low() const; const optional &get_target_temperature_high() const; const optional &get_target_humidity() const; + + const optional &get_mode() const; const optional &get_fan_mode() const; const optional &get_swing_mode() const; - const optional &get_custom_fan_mode() const; const optional &get_preset() const; + const optional &get_custom_fan_mode() const; const optional &get_custom_preset() const; protected: void validate_(); Climate *const parent_; - optional mode_; optional target_temperature_; optional target_temperature_low_; optional target_temperature_high_; optional target_humidity_; + optional mode_; optional fan_mode_; optional swing_mode_; - optional custom_fan_mode_; optional preset_; + optional custom_fan_mode_; optional custom_preset_; }; @@ -169,47 +170,6 @@ class Climate : public EntityBase { public: Climate() {} - /// The active mode of the climate device. - ClimateMode mode{CLIMATE_MODE_OFF}; - - /// The active state of the climate device. - ClimateAction action{CLIMATE_ACTION_OFF}; - - /// The current temperature of the climate device, as reported from the integration. - float current_temperature{NAN}; - - /// The current humidity of the climate device, as reported from the integration. - float current_humidity{NAN}; - - union { - /// The target temperature of the climate device. - float target_temperature; - struct { - /// The minimum target temperature of the climate device, for climate devices with split target temperature. - float target_temperature_low{NAN}; - /// The maximum target temperature of the climate device, for climate devices with split target temperature. - float target_temperature_high{NAN}; - }; - }; - - /// The target humidity of the climate device. - float target_humidity; - - /// The active fan mode of the climate device. - optional fan_mode; - - /// The active swing mode of the climate device. - ClimateSwingMode swing_mode; - - /// The active custom fan mode of the climate device. - optional custom_fan_mode; - - /// The active preset of the climate device. - optional preset; - - /// The active custom preset mode of the climate device. - optional custom_preset; - /** Add a callback for the climate device state, each time the state of the climate device is updated * (using publish_state), this callback will be called. * @@ -251,6 +211,47 @@ class Climate : public EntityBase { void set_visual_min_humidity_override(float visual_min_humidity_override); void set_visual_max_humidity_override(float visual_max_humidity_override); + /// The current temperature of the climate device, as reported from the integration. + float current_temperature{NAN}; + + /// The current humidity of the climate device, as reported from the integration. + float current_humidity{NAN}; + + union { + /// The target temperature of the climate device. + float target_temperature; + struct { + /// The minimum target temperature of the climate device, for climate devices with split target temperature. + float target_temperature_low{NAN}; + /// The maximum target temperature of the climate device, for climate devices with split target temperature. + float target_temperature_high{NAN}; + }; + }; + + /// The target humidity of the climate device. + float target_humidity; + + /// The active fan mode of the climate device. + optional fan_mode; + + /// The active preset of the climate device. + optional preset; + + /// The active custom fan mode of the climate device. + optional custom_fan_mode; + + /// The active custom preset mode of the climate device. + optional custom_preset; + + /// The active mode of the climate device. + ClimateMode mode{CLIMATE_MODE_OFF}; + + /// The active state of the climate device. + ClimateAction action{CLIMATE_ACTION_OFF}; + + /// The active swing mode of the climate device. + ClimateSwingMode swing_mode{CLIMATE_SWING_OFF}; + protected: friend ClimateCall;