diff --git a/esphome/components/fan/fan.cpp b/esphome/components/fan/fan.cpp index 659abf70a9..f486c40ca4 100644 --- a/esphome/components/fan/fan.cpp +++ b/esphome/components/fan/fan.cpp @@ -148,9 +148,9 @@ const char *Fan::find_preset_mode_(const char *preset_mode) { } const char *Fan::find_preset_mode_(const char *preset_mode, size_t len) { - if (preset_mode == nullptr || len == 0) + if (preset_mode == nullptr || len == 0 || !this->supported_preset_modes_) return nullptr; - for (const char *mode : this->supported_preset_modes_) { + for (const char *mode : *this->supported_preset_modes_) { if (strncmp(mode, preset_mode, len) == 0 && mode[len] == '\0') return mode; } @@ -274,10 +274,10 @@ void Fan::save_state_() { state.direction = this->direction; state.preset_mode = FanRestoreState::NO_PRESET; - if (this->has_preset_mode()) { + if (this->has_preset_mode() && this->supported_preset_modes_) { // Find index of current preset mode (pointer comparison is safe since preset is from our vector) - for (size_t i = 0; i < this->supported_preset_modes_.size(); i++) { - if (this->supported_preset_modes_[i] == this->preset_mode_) { + for (size_t i = 0; i < this->supported_preset_modes_->size(); i++) { + if ((*this->supported_preset_modes_)[i] == this->preset_mode_) { state.preset_mode = i; break; } diff --git a/esphome/components/fan/fan.h b/esphome/components/fan/fan.h index 42999d16f7..2b76fa24da 100644 --- a/esphome/components/fan/fan.h +++ b/esphome/components/fan/fan.h @@ -132,10 +132,15 @@ class Fan : public EntityBase { /// Set the supported preset modes (stored on Fan, referenced by FanTraits via pointer). void set_supported_preset_modes(std::initializer_list preset_modes) { - this->supported_preset_modes_ = preset_modes; + if (!this->supported_preset_modes_) + this->supported_preset_modes_ = + new std::vector(); // NOLINT - intentional leak, entity lives forever + *this->supported_preset_modes_ = preset_modes; } void set_supported_preset_modes(const std::vector &preset_modes) { - this->supported_preset_modes_ = preset_modes; + if (!this->supported_preset_modes_) + this->supported_preset_modes_ = new std::vector(); // NOLINT + *this->supported_preset_modes_ = preset_modes; } /// Set the restore mode of this fan. @@ -179,8 +184,8 @@ class Fan : public EntityBase { ESPPreferenceObject rtc_; FanRestoreMode restore_mode_; - /// Preset mode storage — owned by Fan, referenced by FanTraits via pointer. - std::vector supported_preset_modes_; + /// Preset mode storage — allocated on first use, never freed (entity lives forever). + std::vector *supported_preset_modes_{nullptr}; private: const char *preset_mode_{nullptr};