diff --git a/esphome/components/api/api_connection.cpp b/esphome/components/api/api_connection.cpp index 2914f15b4d..7413b0c419 100644 --- a/esphome/components/api/api_connection.cpp +++ b/esphome/components/api/api_connection.cpp @@ -638,13 +638,13 @@ uint16_t APIConnection::try_send_climate_state(EntityBase *entity, APIConnection if (traits.get_supports_fan_modes() && climate->fan_mode.has_value()) resp.fan_mode = static_cast(climate->fan_mode.value()); if (!traits.get_supported_custom_fan_modes().empty() && climate->has_custom_fan_mode()) { - resp.set_custom_fan_mode(StringRef(climate->custom_fan_mode)); + resp.set_custom_fan_mode(StringRef(climate->get_custom_fan_mode())); } if (traits.get_supports_presets() && climate->preset.has_value()) { resp.preset = static_cast(climate->preset.value()); } if (!traits.get_supported_custom_presets().empty() && climate->has_custom_preset()) { - resp.set_custom_preset(StringRef(climate->custom_preset)); + resp.set_custom_preset(StringRef(climate->get_custom_preset())); } if (traits.get_supports_swing_modes()) resp.swing_mode = static_cast(climate->swing_mode); diff --git a/esphome/components/bedjet/climate/bedjet_climate.cpp b/esphome/components/bedjet/climate/bedjet_climate.cpp index 65fa092e8e..302229f254 100644 --- a/esphome/components/bedjet/climate/bedjet_climate.cpp +++ b/esphome/components/bedjet/climate/bedjet_climate.cpp @@ -79,7 +79,7 @@ void BedJetClimate::reset_state_() { this->target_temperature = NAN; this->current_temperature = NAN; this->preset.reset(); - this->custom_preset.reset(); + this->clear_custom_preset_(); this->publish_state(); } @@ -184,8 +184,7 @@ void BedJetClimate::control(const ClimateCall &call) { } if (result) { - this->custom_preset = preset; - this->preset.reset(); + this->set_custom_preset_(preset.c_str()); } } @@ -207,8 +206,7 @@ void BedJetClimate::control(const ClimateCall &call) { } if (result) { - this->fan_mode = fan_mode; - this->custom_fan_mode.reset(); + this->set_fan_mode_(fan_mode); } } else if (call.get_custom_fan_mode().has_value()) { auto fan_mode = *call.get_custom_fan_mode(); @@ -218,8 +216,7 @@ void BedJetClimate::control(const ClimateCall &call) { fan_index); bool result = this->parent_->set_fan_index(fan_index); if (result) { - this->custom_fan_mode = fan_mode; - this->fan_mode.reset(); + this->set_custom_fan_mode_(fan_mode.c_str()); } } } @@ -245,7 +242,7 @@ void BedJetClimate::on_status(const BedjetStatusPacket *data) { const auto *fan_mode_name = bedjet_fan_step_to_fan_mode(data->fan_step); if (fan_mode_name != nullptr) { - this->custom_fan_mode = *fan_mode_name; + this->set_custom_fan_mode_(fan_mode_name); } // TODO: Get biorhythm data to determine which preset (M1-3) is running, if any. @@ -255,7 +252,7 @@ void BedJetClimate::on_status(const BedjetStatusPacket *data) { this->mode = CLIMATE_MODE_OFF; this->action = CLIMATE_ACTION_IDLE; this->fan_mode = CLIMATE_FAN_OFF; - this->custom_preset.reset(); + this->clear_custom_preset_(); this->preset.reset(); break; @@ -266,7 +263,7 @@ void BedJetClimate::on_status(const BedjetStatusPacket *data) { if (this->heating_mode_ == HEAT_MODE_EXTENDED) { this->set_custom_preset_("LTD HT"); } else { - this->custom_preset.reset(); + this->clear_custom_preset_(); } break; @@ -275,7 +272,7 @@ void BedJetClimate::on_status(const BedjetStatusPacket *data) { this->action = CLIMATE_ACTION_HEATING; this->preset.reset(); if (this->heating_mode_ == HEAT_MODE_EXTENDED) { - this->custom_preset.reset(); + this->clear_custom_preset_(); } else { this->set_custom_preset_("EXT HT"); } @@ -284,20 +281,20 @@ void BedJetClimate::on_status(const BedjetStatusPacket *data) { case MODE_COOL: this->mode = CLIMATE_MODE_FAN_ONLY; this->action = CLIMATE_ACTION_COOLING; - this->custom_preset.reset(); + this->clear_custom_preset_(); this->preset.reset(); break; case MODE_DRY: this->mode = CLIMATE_MODE_DRY; this->action = CLIMATE_ACTION_DRYING; - this->custom_preset.reset(); + this->clear_custom_preset_(); this->preset.reset(); break; case MODE_TURBO: this->preset = CLIMATE_PRESET_BOOST; - this->custom_preset.reset(); + this->clear_custom_preset_(); this->mode = CLIMATE_MODE_HEAT; this->action = CLIMATE_ACTION_HEATING; break; diff --git a/esphome/components/climate/climate.cpp b/esphome/components/climate/climate.cpp index 9f9a0ca5d6..5bf32e4c28 100644 --- a/esphome/components/climate/climate.cpp +++ b/esphome/components/climate/climate.cpp @@ -398,7 +398,7 @@ void Climate::save_state_() { // std::vector maintains insertion order size_t i = 0; for (const char *mode : supported) { - if (strcmp(mode, custom_fan_mode) == 0) { + if (strcmp(mode, this->custom_fan_mode_) == 0) { state.custom_fan_mode = i; break; } @@ -415,7 +415,7 @@ void Climate::save_state_() { // std::vector maintains insertion order size_t i = 0; for (const char *preset : supported) { - if (strcmp(preset, custom_preset) == 0) { + if (strcmp(preset, this->custom_preset_) == 0) { state.custom_preset = i; break; } @@ -441,13 +441,13 @@ void Climate::publish_state() { ESP_LOGD(TAG, " Fan Mode: %s", LOG_STR_ARG(climate_fan_mode_to_string(this->fan_mode.value()))); } if (!traits.get_supported_custom_fan_modes().empty() && this->has_custom_fan_mode()) { - ESP_LOGD(TAG, " Custom Fan Mode: %s", this->custom_fan_mode); + ESP_LOGD(TAG, " Custom Fan Mode: %s", this->custom_fan_mode_); } if (traits.get_supports_presets() && this->preset.has_value()) { ESP_LOGD(TAG, " Preset: %s", LOG_STR_ARG(climate_preset_to_string(this->preset.value()))); } if (!traits.get_supported_custom_presets().empty() && this->has_custom_preset()) { - ESP_LOGD(TAG, " Custom Preset: %s", this->custom_preset); + ESP_LOGD(TAG, " Custom Preset: %s", this->custom_preset_); } if (traits.get_supports_swing_modes()) { ESP_LOGD(TAG, " Swing Mode: %s", LOG_STR_ARG(climate_swing_mode_to_string(this->swing_mode))); @@ -572,20 +572,20 @@ void ClimateDeviceRestoreState::apply(Climate *climate) { if (this->uses_custom_fan_mode) { if (this->custom_fan_mode < traits.get_supported_custom_fan_modes().size()) { climate->fan_mode.reset(); - climate->custom_fan_mode = traits.get_supported_custom_fan_modes()[this->custom_fan_mode]; + climate->custom_fan_mode_ = traits.get_supported_custom_fan_modes()[this->custom_fan_mode]; } } else if (traits.supports_fan_mode(this->fan_mode)) { climate->fan_mode = this->fan_mode; - climate->custom_fan_mode = nullptr; + climate->clear_custom_fan_mode_(); } if (this->uses_custom_preset) { if (this->custom_preset < traits.get_supported_custom_presets().size()) { climate->preset.reset(); - climate->custom_preset = traits.get_supported_custom_presets()[this->custom_preset]; + climate->custom_preset_ = traits.get_supported_custom_presets()[this->custom_preset]; } } else if (traits.supports_preset(this->preset)) { climate->preset = this->preset; - climate->custom_preset = nullptr; + climate->clear_custom_preset_(); } if (traits.supports_swing_mode(this->swing_mode)) { climate->swing_mode = this->swing_mode; @@ -617,18 +617,18 @@ template bool set_alternative(T1 &dst, T2 } bool Climate::set_fan_mode_(ClimateFanMode mode) { - return set_alternative(this->fan_mode, this->custom_fan_mode, mode); + return set_alternative(this->fan_mode, this->custom_fan_mode_, mode); } bool Climate::set_custom_fan_mode_(const char *mode) { auto traits = this->get_traits(); const char *mode_ptr = traits.find_custom_fan_mode_(mode); if (mode_ptr != nullptr) { - return set_alternative(this->custom_fan_mode, this->fan_mode, mode_ptr); + return set_alternative(this->custom_fan_mode_, this->fan_mode, mode_ptr); } // Mode not found in supported custom modes, clear it if currently set if (this->has_custom_fan_mode()) { - this->custom_fan_mode = nullptr; + this->custom_fan_mode_ = nullptr; return true; } return false; @@ -636,17 +636,19 @@ bool Climate::set_custom_fan_mode_(const char *mode) { bool Climate::set_custom_fan_mode_(const std::string &mode) { return this->set_custom_fan_mode_(mode.c_str()); } -bool Climate::set_preset_(ClimatePreset preset) { return set_alternative(this->preset, this->custom_preset, preset); } +void Climate::clear_custom_fan_mode_() { this->custom_fan_mode_ = nullptr; } + +bool Climate::set_preset_(ClimatePreset preset) { return set_alternative(this->preset, this->custom_preset_, preset); } bool Climate::set_custom_preset_(const char *preset) { auto traits = this->get_traits(); const char *preset_ptr = traits.find_custom_preset_(preset); if (preset_ptr != nullptr) { - return set_alternative(this->custom_preset, this->preset, preset_ptr); + return set_alternative(this->custom_preset_, this->preset, preset_ptr); } // Preset not found in supported custom presets, clear it if currently set if (this->has_custom_preset()) { - this->custom_preset = nullptr; + this->custom_preset_ = nullptr; return true; } return false; @@ -654,6 +656,8 @@ bool Climate::set_custom_preset_(const char *preset) { bool Climate::set_custom_preset_(const std::string &preset) { return this->set_custom_preset_(preset.c_str()); } +void Climate::clear_custom_preset_() { this->custom_preset_ = nullptr; } + const char *Climate::find_custom_fan_mode_(const char *custom_fan_mode) { auto traits = this->get_traits(); return traits.find_custom_fan_mode_(custom_fan_mode); diff --git a/esphome/components/climate/climate.h b/esphome/components/climate/climate.h index 495d9f700f..0c3393028a 100644 --- a/esphome/components/climate/climate.h +++ b/esphome/components/climate/climate.h @@ -273,6 +273,8 @@ class Climate : public EntityBase { bool set_custom_fan_mode_(const char *mode); /// Set custom fan mode. Reset primary fan mode. Return true if fan mode has been changed. bool set_custom_fan_mode_(const std::string &mode); + /// Clear custom fan mode. + void clear_custom_fan_mode_(); /// Set preset. Reset custom preset. Return true if preset has been changed. bool set_preset_(ClimatePreset preset); @@ -281,6 +283,8 @@ class Climate : public EntityBase { bool set_custom_preset_(const char *preset); /// Set custom preset. Reset primary preset. Return true if preset has been changed. bool set_custom_preset_(const std::string &preset); + /// Clear custom preset. + void clear_custom_preset_(); /// Find and return the matching custom fan mode pointer from traits, or nullptr if not found. const char *find_custom_fan_mode_(const char *custom_fan_mode); diff --git a/esphome/components/thermostat/thermostat_climate.cpp b/esphome/components/thermostat/thermostat_climate.cpp index 4e9c7e4d71..2c8e3e4d9a 100644 --- a/esphome/components/thermostat/thermostat_climate.cpp +++ b/esphome/components/thermostat/thermostat_climate.cpp @@ -1172,7 +1172,7 @@ void ThermostatClimate::change_preset_(climate::ClimatePreset preset) { } else { ESP_LOGI(TAG, "No changes required to apply preset %s", LOG_STR_ARG(climate::climate_preset_to_string(preset))); } - this->custom_preset = nullptr; + this->clear_custom_preset_(); this->preset = preset; } else { ESP_LOGW(TAG, "Preset %s not configured; ignoring", LOG_STR_ARG(climate::climate_preset_to_string(preset))); @@ -1185,7 +1185,7 @@ void ThermostatClimate::change_custom_preset_(const std::string &custom_preset) if (config != this->custom_preset_config_.end()) { ESP_LOGV(TAG, "Custom preset %s requested", custom_preset.c_str()); if (this->change_preset_internal_(config->second) || !this->has_custom_preset() || - strcmp(this->custom_preset, custom_preset.c_str()) != 0) { + strcmp(this->get_custom_preset(), custom_preset.c_str()) != 0) { // Fire any preset changed trigger if defined Trigger<> *trig = this->preset_change_trigger_; // Use the base class method which handles pointer lookup and preset reset internally diff --git a/esphome/components/web_server/web_server.cpp b/esphome/components/web_server/web_server.cpp index 7901869b2f..a1bba22cdb 100644 --- a/esphome/components/web_server/web_server.cpp +++ b/esphome/components/web_server/web_server.cpp @@ -1334,13 +1334,13 @@ std::string WebServer::climate_json(climate::Climate *obj, JsonDetail start_conf root["fan_mode"] = PSTR_LOCAL(climate_fan_mode_to_string(obj->fan_mode.value())); } if (!traits.get_supported_custom_fan_modes().empty() && obj->has_custom_fan_mode()) { - root["custom_fan_mode"] = obj->custom_fan_mode; + root["custom_fan_mode"] = obj->get_custom_fan_mode(); } if (traits.get_supports_presets() && obj->preset.has_value()) { root["preset"] = PSTR_LOCAL(climate_preset_to_string(obj->preset.value())); } if (!traits.get_supported_custom_presets().empty() && obj->has_custom_preset()) { - root["custom_preset"] = obj->custom_preset; + root["custom_preset"] = obj->get_custom_preset(); } if (traits.get_supports_swing_modes()) { root["swing_mode"] = PSTR_LOCAL(climate_swing_mode_to_string(obj->swing_mode));