mirror of
https://github.com/esphome/esphome.git
synced 2026-05-27 20:53:46 +08:00
[fan] Fix preset_mode not restored on boot (#14002)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -221,12 +221,17 @@ void Fan::publish_state() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Random 32-bit value, change this every time the layout of the FanRestoreState struct changes.
|
// Random 32-bit value, change this every time the layout of the FanRestoreState struct changes.
|
||||||
constexpr uint32_t RESTORE_STATE_VERSION = 0x71700ABA;
|
constexpr uint32_t RESTORE_STATE_VERSION = 0x71700ABB;
|
||||||
optional<FanRestoreState> Fan::restore_state_() {
|
optional<FanRestoreState> Fan::restore_state_() {
|
||||||
FanRestoreState recovered{};
|
FanRestoreState recovered{};
|
||||||
this->rtc_ = this->make_entity_preference<FanRestoreState>(RESTORE_STATE_VERSION);
|
this->rtc_ = this->make_entity_preference<FanRestoreState>(RESTORE_STATE_VERSION);
|
||||||
bool restored = this->rtc_.load(&recovered);
|
bool restored = this->rtc_.load(&recovered);
|
||||||
|
|
||||||
|
if (!restored) {
|
||||||
|
// No valid saved data; ensure preset_mode sentinel is set
|
||||||
|
recovered.preset_mode = FanRestoreState::NO_PRESET;
|
||||||
|
}
|
||||||
|
|
||||||
switch (this->restore_mode_) {
|
switch (this->restore_mode_) {
|
||||||
case FanRestoreMode::NO_RESTORE:
|
case FanRestoreMode::NO_RESTORE:
|
||||||
return {};
|
return {};
|
||||||
@@ -264,6 +269,7 @@ void Fan::save_state_() {
|
|||||||
state.oscillating = this->oscillating;
|
state.oscillating = this->oscillating;
|
||||||
state.speed = this->speed;
|
state.speed = this->speed;
|
||||||
state.direction = this->direction;
|
state.direction = this->direction;
|
||||||
|
state.preset_mode = FanRestoreState::NO_PRESET;
|
||||||
|
|
||||||
if (this->has_preset_mode()) {
|
if (this->has_preset_mode()) {
|
||||||
const auto &preset_modes = traits.supported_preset_modes();
|
const auto &preset_modes = traits.supported_preset_modes();
|
||||||
|
|||||||
@@ -91,11 +91,13 @@ class FanCall {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct FanRestoreState {
|
struct FanRestoreState {
|
||||||
|
static constexpr uint8_t NO_PRESET = UINT8_MAX;
|
||||||
|
|
||||||
bool state;
|
bool state;
|
||||||
int speed;
|
int speed;
|
||||||
bool oscillating;
|
bool oscillating;
|
||||||
FanDirection direction;
|
FanDirection direction;
|
||||||
uint8_t preset_mode;
|
uint8_t preset_mode{NO_PRESET};
|
||||||
|
|
||||||
/// Convert this struct to a fan call that can be performed.
|
/// Convert this struct to a fan call that can be performed.
|
||||||
FanCall to_call(Fan &fan);
|
FanCall to_call(Fan &fan);
|
||||||
|
|||||||
@@ -28,15 +28,15 @@ fan::FanCall HBridgeFan::brake() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HBridgeFan::setup() {
|
void HBridgeFan::setup() {
|
||||||
|
// Construct traits before restore so preset modes can be looked up by index
|
||||||
|
this->traits_ = fan::FanTraits(this->oscillating_ != nullptr, true, true, this->speed_count_);
|
||||||
|
this->traits_.set_supported_preset_modes(this->preset_modes_);
|
||||||
|
|
||||||
auto restore = this->restore_state_();
|
auto restore = this->restore_state_();
|
||||||
if (restore.has_value()) {
|
if (restore.has_value()) {
|
||||||
restore->apply(*this);
|
restore->apply(*this);
|
||||||
this->write_state_();
|
this->write_state_();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct traits
|
|
||||||
this->traits_ = fan::FanTraits(this->oscillating_ != nullptr, true, true, this->speed_count_);
|
|
||||||
this->traits_.set_supported_preset_modes(this->preset_modes_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HBridgeFan::dump_config() {
|
void HBridgeFan::dump_config() {
|
||||||
|
|||||||
@@ -7,15 +7,15 @@ namespace speed {
|
|||||||
static const char *const TAG = "speed.fan";
|
static const char *const TAG = "speed.fan";
|
||||||
|
|
||||||
void SpeedFan::setup() {
|
void SpeedFan::setup() {
|
||||||
|
// Construct traits before restore so preset modes can be looked up by index
|
||||||
|
this->traits_ = fan::FanTraits(this->oscillating_ != nullptr, true, this->direction_ != nullptr, this->speed_count_);
|
||||||
|
this->traits_.set_supported_preset_modes(this->preset_modes_);
|
||||||
|
|
||||||
auto restore = this->restore_state_();
|
auto restore = this->restore_state_();
|
||||||
if (restore.has_value()) {
|
if (restore.has_value()) {
|
||||||
restore->apply(*this);
|
restore->apply(*this);
|
||||||
this->write_state_();
|
this->write_state_();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct traits
|
|
||||||
this->traits_ = fan::FanTraits(this->oscillating_ != nullptr, true, this->direction_ != nullptr, this->speed_count_);
|
|
||||||
this->traits_.set_supported_preset_modes(this->preset_modes_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpeedFan::dump_config() { LOG_FAN("", "Speed Fan", this); }
|
void SpeedFan::dump_config() { LOG_FAN("", "Speed Fan", this); }
|
||||||
|
|||||||
@@ -6,15 +6,15 @@ namespace esphome::template_ {
|
|||||||
static const char *const TAG = "template.fan";
|
static const char *const TAG = "template.fan";
|
||||||
|
|
||||||
void TemplateFan::setup() {
|
void TemplateFan::setup() {
|
||||||
|
// Construct traits before restore so preset modes can be looked up by index
|
||||||
|
this->traits_ =
|
||||||
|
fan::FanTraits(this->has_oscillating_, this->speed_count_ > 0, this->has_direction_, this->speed_count_);
|
||||||
|
this->traits_.set_supported_preset_modes(this->preset_modes_);
|
||||||
|
|
||||||
auto restore = this->restore_state_();
|
auto restore = this->restore_state_();
|
||||||
if (restore.has_value()) {
|
if (restore.has_value()) {
|
||||||
restore->apply(*this);
|
restore->apply(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct traits
|
|
||||||
this->traits_ =
|
|
||||||
fan::FanTraits(this->has_oscillating_, this->speed_count_ > 0, this->has_direction_, this->speed_count_);
|
|
||||||
this->traits_.set_supported_preset_modes(this->preset_modes_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TemplateFan::dump_config() { LOG_FAN("", "Template Fan", this); }
|
void TemplateFan::dump_config() { LOG_FAN("", "Template Fan", this); }
|
||||||
|
|||||||
Reference in New Issue
Block a user