diff --git a/esphome/components/bedjet/bedjet_const.h b/esphome/components/bedjet/bedjet_const.h index 0693be1092..10f403dd1a 100644 --- a/esphome/components/bedjet/bedjet_const.h +++ b/esphome/components/bedjet/bedjet_const.h @@ -100,7 +100,6 @@ enum BedjetCommand : uint8_t { static const uint8_t BEDJET_FAN_SPEED_COUNT = 20; static constexpr const char *const BEDJET_FAN_STEP_NAMES[BEDJET_FAN_SPEED_COUNT] = BEDJET_FAN_STEP_NAMES_; -static const std::string BEDJET_FAN_STEP_NAME_STRINGS[BEDJET_FAN_SPEED_COUNT] = BEDJET_FAN_STEP_NAMES_; } // namespace bedjet } // namespace esphome diff --git a/esphome/components/bedjet/climate/bedjet_climate.cpp b/esphome/components/bedjet/climate/bedjet_climate.cpp index 877fd6f771..716d4d4241 100644 --- a/esphome/components/bedjet/climate/bedjet_climate.cpp +++ b/esphome/components/bedjet/climate/bedjet_climate.cpp @@ -8,15 +8,15 @@ namespace bedjet { using namespace esphome::climate; -static const std::string *bedjet_fan_step_to_fan_mode(const uint8_t fan_step) { +static const char *bedjet_fan_step_to_fan_mode(const uint8_t fan_step) { if (fan_step < BEDJET_FAN_SPEED_COUNT) - return &BEDJET_FAN_STEP_NAME_STRINGS[fan_step]; + return BEDJET_FAN_STEP_NAMES[fan_step]; return nullptr; } -static uint8_t bedjet_fan_speed_to_step(const std::string &fan_step_percent) { +static uint8_t bedjet_fan_speed_to_step(const char *fan_step_percent) { for (int i = 0; i < BEDJET_FAN_SPEED_COUNT; i++) { - if (fan_step_percent == BEDJET_FAN_STEP_NAME_STRINGS[i]) { + if (strcmp(BEDJET_FAN_STEP_NAMES[i], fan_step_percent) == 0) { return i; } } @@ -163,27 +163,27 @@ void BedJetClimate::control(const ClimateCall &call) { ESP_LOGW(TAG, "Unsupported preset: %d", preset); return; } - } else if (call.get_custom_preset().has_value()) { - std::string preset = *call.get_custom_preset(); + } else if (call.has_custom_preset()) { + const char *preset = call.get_custom_preset(); bool result; - if (preset == "M1") { + if (strcmp(preset, "M1") == 0) { result = this->parent_->button_memory1(); - } else if (preset == "M2") { + } else if (strcmp(preset, "M2") == 0) { result = this->parent_->button_memory2(); - } else if (preset == "M3") { + } else if (strcmp(preset, "M3") == 0) { result = this->parent_->button_memory3(); - } else if (preset == "LTD HT") { + } else if (strcmp(preset, "LTD HT") == 0) { result = this->parent_->button_heat(); - } else if (preset == "EXT HT") { + } else if (strcmp(preset, "EXT HT") == 0) { result = this->parent_->button_ext_heat(); } else { - ESP_LOGW(TAG, "Unsupported preset: %s", preset.c_str()); + ESP_LOGW(TAG, "Unsupported preset: %s", preset); return; } if (result) { - this->set_custom_preset_(preset.c_str()); + this->set_custom_preset_(preset); } } @@ -207,15 +207,14 @@ void BedJetClimate::control(const ClimateCall &call) { if (result) { this->set_fan_mode_(fan_mode); } - } else if (call.get_custom_fan_mode().has_value()) { - auto fan_mode = *call.get_custom_fan_mode(); + } else if (call.has_custom_fan_mode()) { + const char *fan_mode = call.get_custom_fan_mode(); auto fan_index = bedjet_fan_speed_to_step(fan_mode); if (fan_index <= 19) { - ESP_LOGV(TAG, "[%s] Converted fan mode %s to bedjet fan step %d", this->get_name().c_str(), fan_mode.c_str(), - fan_index); + ESP_LOGV(TAG, "[%s] Converted fan mode %s to bedjet fan step %d", this->get_name().c_str(), fan_mode, fan_index); bool result = this->parent_->set_fan_index(fan_index); if (result) { - this->set_custom_fan_mode_(fan_mode.c_str()); + this->set_custom_fan_mode_(fan_mode); } } } @@ -241,7 +240,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->set_custom_fan_mode_(fan_mode_name->c_str()); + this->set_custom_fan_mode_(fan_mode_name); } // TODO: Get biorhythm data to determine which preset (M1-3) is running, if any. diff --git a/esphome/components/climate/climate.cpp b/esphome/components/climate/climate.cpp index e596582de8..7df38758dc 100644 --- a/esphome/components/climate/climate.cpp +++ b/esphome/components/climate/climate.cpp @@ -292,14 +292,6 @@ const optional &ClimateCall::get_fan_mode() const { return this- const optional &ClimateCall::get_swing_mode() const { return this->swing_mode_; } const optional &ClimateCall::get_preset() const { return this->preset_; } -optional ClimateCall::get_custom_fan_mode() const { - return this->custom_fan_mode_ != nullptr ? std::string(this->custom_fan_mode_) : optional{}; -} - -optional ClimateCall::get_custom_preset() const { - return this->custom_preset_ != nullptr ? std::string(this->custom_preset_) : optional{}; -} - ClimateCall &ClimateCall::set_target_temperature_high(optional target_temperature_high) { this->target_temperature_high_ = target_temperature_high; return *this; diff --git a/esphome/components/climate/climate.h b/esphome/components/climate/climate.h index 091483a033..b277877c3e 100644 --- a/esphome/components/climate/climate.h +++ b/esphome/components/climate/climate.h @@ -107,8 +107,10 @@ class ClimateCall { const optional &get_fan_mode() const; const optional &get_swing_mode() const; const optional &get_preset() const; - optional get_custom_fan_mode() const; - optional get_custom_preset() const; + const char *get_custom_fan_mode() const { return this->custom_fan_mode_; } + const char *get_custom_preset() const { return this->custom_preset_; } + bool has_custom_fan_mode() const { return this->custom_fan_mode_ != nullptr; } + bool has_custom_preset() const { return this->custom_preset_ != nullptr; } protected: void validate_(); @@ -122,6 +124,8 @@ class ClimateCall { optional fan_mode_; optional swing_mode_; optional preset_; + + private: const char *custom_fan_mode_{nullptr}; const char *custom_preset_{nullptr}; }; diff --git a/esphome/components/demo/demo_climate.h b/esphome/components/demo/demo_climate.h index f8944b0735..e2dfb0142b 100644 --- a/esphome/components/demo/demo_climate.h +++ b/esphome/components/demo/demo_climate.h @@ -63,14 +63,14 @@ class DemoClimate : public climate::Climate, public Component { if (call.get_swing_mode().has_value()) { this->swing_mode = *call.get_swing_mode(); } - if (call.get_custom_fan_mode().has_value()) { - this->set_custom_fan_mode_(call.get_custom_fan_mode()->c_str()); + if (call.has_custom_fan_mode()) { + this->set_custom_fan_mode_(call.get_custom_fan_mode()); } if (call.get_preset().has_value()) { this->set_preset_(*call.get_preset()); } - if (call.get_custom_preset().has_value()) { - this->set_custom_preset_(call.get_custom_preset()->c_str()); + if (call.has_custom_preset()) { + this->set_custom_preset_(call.get_custom_preset()); } this->publish_state(); } diff --git a/esphome/components/midea/ac_adapter.cpp b/esphome/components/midea/ac_adapter.cpp index dca4038f04..d903db4a1b 100644 --- a/esphome/components/midea/ac_adapter.cpp +++ b/esphome/components/midea/ac_adapter.cpp @@ -117,8 +117,8 @@ const char *Converters::to_custom_climate_fan_mode(MideaFanMode mode) { } } -MideaFanMode Converters::to_midea_fan_mode(const std::string &mode) { - if (mode == Constants::SILENT) +MideaFanMode Converters::to_midea_fan_mode(const char *mode) { + if (strcmp(mode, Constants::SILENT) == 0) return MideaFanMode::FAN_SILENT; return MideaFanMode::FAN_TURBO; } @@ -153,7 +153,7 @@ bool Converters::is_custom_midea_preset(MideaPreset preset) { return preset == M const char *Converters::to_custom_climate_preset(MideaPreset preset) { return Constants::FREEZE_PROTECTION; } -MideaPreset Converters::to_midea_preset(const std::string &preset) { return MideaPreset::PRESET_FREEZE_PROTECTION; } +MideaPreset Converters::to_midea_preset(const char *preset) { return MideaPreset::PRESET_FREEZE_PROTECTION; } void Converters::to_climate_traits(ClimateTraits &traits, const dudanov::midea::ac::Capabilities &capabilities) { if (capabilities.supportAutoMode()) diff --git a/esphome/components/midea/ac_adapter.h b/esphome/components/midea/ac_adapter.h index d52f421331..b0589a37f9 100644 --- a/esphome/components/midea/ac_adapter.h +++ b/esphome/components/midea/ac_adapter.h @@ -32,12 +32,12 @@ class Converters { static MideaSwingMode to_midea_swing_mode(ClimateSwingMode mode); static ClimateSwingMode to_climate_swing_mode(MideaSwingMode mode); static MideaPreset to_midea_preset(ClimatePreset preset); - static MideaPreset to_midea_preset(const std::string &preset); + static MideaPreset to_midea_preset(const char *preset); static bool is_custom_midea_preset(MideaPreset preset); static ClimatePreset to_climate_preset(MideaPreset preset); static const char *to_custom_climate_preset(MideaPreset preset); static MideaFanMode to_midea_fan_mode(ClimateFanMode fan_mode); - static MideaFanMode to_midea_fan_mode(const std::string &fan_mode); + static MideaFanMode to_midea_fan_mode(const char *fan_mode); static bool is_custom_midea_fan_mode(MideaFanMode fan_mode); static ClimateFanMode to_climate_fan_mode(MideaFanMode fan_mode); static const char *to_custom_climate_fan_mode(MideaFanMode fan_mode); diff --git a/esphome/components/midea/air_conditioner.cpp b/esphome/components/midea/air_conditioner.cpp index 97eacb936c..a6a8d52549 100644 --- a/esphome/components/midea/air_conditioner.cpp +++ b/esphome/components/midea/air_conditioner.cpp @@ -64,13 +64,13 @@ void AirConditioner::control(const ClimateCall &call) { ctrl.mode = Converters::to_midea_mode(call.get_mode().value()); if (call.get_preset().has_value()) { ctrl.preset = Converters::to_midea_preset(call.get_preset().value()); - } else if (call.get_custom_preset().has_value()) { - ctrl.preset = Converters::to_midea_preset(call.get_custom_preset().value()); + } else if (call.has_custom_preset()) { + ctrl.preset = Converters::to_midea_preset(call.get_custom_preset()); } if (call.get_fan_mode().has_value()) { ctrl.fanMode = Converters::to_midea_fan_mode(call.get_fan_mode().value()); - } else if (call.get_custom_fan_mode().has_value()) { - ctrl.fanMode = Converters::to_midea_fan_mode(call.get_custom_fan_mode().value()); + } else if (call.has_custom_fan_mode()) { + ctrl.fanMode = Converters::to_midea_fan_mode(call.get_custom_fan_mode()); } this->base_.control(ctrl); } diff --git a/esphome/components/thermostat/thermostat_climate.cpp b/esphome/components/thermostat/thermostat_climate.cpp index 8258fa9d65..d533ef93ec 100644 --- a/esphome/components/thermostat/thermostat_climate.cpp +++ b/esphome/components/thermostat/thermostat_climate.cpp @@ -54,7 +54,7 @@ void ThermostatClimate::setup() { if (this->default_preset_ != climate::ClimatePreset::CLIMATE_PRESET_NONE) { this->change_preset_(this->default_preset_); } else if (!this->default_custom_preset_.empty()) { - this->change_custom_preset_(this->default_custom_preset_); + this->change_custom_preset_(this->default_custom_preset_.c_str()); } } @@ -218,13 +218,13 @@ void ThermostatClimate::control(const climate::ClimateCall &call) { this->preset = call.get_preset().value(); } } - if (call.get_custom_preset().has_value()) { + if (call.has_custom_preset()) { // setup_complete_ blocks modifying/resetting the temps immediately after boot if (this->setup_complete_) { - this->change_custom_preset_(call.get_custom_preset().value()); + this->change_custom_preset_(call.get_custom_preset()); } else { // Use the base class method which handles pointer lookup internally - this->set_custom_preset_(call.get_custom_preset().value().c_str()); + this->set_custom_preset_(call.get_custom_preset()); } } @@ -1177,31 +1177,31 @@ void ThermostatClimate::change_preset_(climate::ClimatePreset preset) { } } -void ThermostatClimate::change_custom_preset_(const std::string &custom_preset) { +void ThermostatClimate::change_custom_preset_(const char *custom_preset) { auto config = this->custom_preset_config_.find(custom_preset); if (config != this->custom_preset_config_.end()) { - ESP_LOGV(TAG, "Custom preset %s requested", custom_preset.c_str()); + ESP_LOGV(TAG, "Custom preset %s requested", custom_preset); if (this->change_preset_internal_(config->second) || !this->has_custom_preset() || - strcmp(this->get_custom_preset(), custom_preset.c_str()) != 0) { + strcmp(this->get_custom_preset(), custom_preset) != 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 - this->set_custom_preset_(custom_preset.c_str()); + this->set_custom_preset_(custom_preset); if (trig != nullptr) { trig->trigger(); } this->refresh(); - ESP_LOGI(TAG, "Custom preset %s applied", custom_preset.c_str()); + ESP_LOGI(TAG, "Custom preset %s applied", custom_preset); } else { - ESP_LOGI(TAG, "No changes required to apply custom preset %s", custom_preset.c_str()); + ESP_LOGI(TAG, "No changes required to apply custom preset %s", custom_preset); + // Note: set_custom_preset_() above handles preset.reset() and custom_preset_ assignment internally. + // The old code had these lines here unconditionally, which was a bug (double assignment, state modification + // even when no changes were needed). Now properly handled by the protected setter with mutual exclusion. } - // Note: set_custom_preset_() above handles preset.reset() and custom_preset_ assignment internally. - // The old code had these lines here unconditionally, which was a bug (double assignment, state modification - // even when no changes were needed). Now properly handled by the protected setter with mutual exclusion. } else { - ESP_LOGW(TAG, "Custom preset %s not configured; ignoring", custom_preset.c_str()); + ESP_LOGW(TAG, "Custom preset %s not configured; ignoring", custom_preset); } } diff --git a/esphome/components/thermostat/thermostat_climate.h b/esphome/components/thermostat/thermostat_climate.h index 42adab7751..c9795d9666 100644 --- a/esphome/components/thermostat/thermostat_climate.h +++ b/esphome/components/thermostat/thermostat_climate.h @@ -199,7 +199,7 @@ class ThermostatClimate : public climate::Climate, public Component { /// Change to a provided preset setting; will reset temperature, mode, fan, and swing modes accordingly void change_preset_(climate::ClimatePreset preset); /// Change to a provided custom preset setting; will reset temperature, mode, fan, and swing modes accordingly - void change_custom_preset_(const std::string &custom_preset); + void change_custom_preset_(const char *custom_preset); /// Applies the temperature, mode, fan, and swing modes of the provided config. /// This is agnostic of custom vs built in preset diff --git a/requirements.txt b/requirements.txt index 660b18c933..33fa2b64eb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,7 @@ platformio==6.1.18 # When updating platformio, also update /docker/Dockerfile esptool==5.1.0 click==8.1.7 esphome-dashboard==20251013.0 -aioesphomeapi==42.5.0 +aioesphomeapi==42.6.0 zeroconf==0.148.0 puremagic==1.30 ruamel.yaml==0.18.16 # dashboard_import