ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
ecocomfort2_fan.cpp
Go to the documentation of this file.
2#ifdef USE_ESP32
3#include "ecocomfort2_fan.h"
4#include "esphome/core/log.h"
5
6#include <iterator>
7
8namespace esphome::ecocomfort2 {
9
10ESPHOME_LOG_TAG(TAG, "ecocomfort2.fan");
11
12static constexpr int SPEED_COUNT = SPEED_VEL3;
13
14struct Preset {
15 const char *name;
16 uint8_t mode;
17 bool auto_mode;
18};
19
20// Order matters: the fan core persists the preset as an index into this list.
21static constexpr Preset PRESETS[] = {
22 {"In", OPER_IN, false},
23 {"Out", OPER_OUT, false},
24 {"In-Out", OPER_IN_OUT, false},
25 {"Sensor", OPER_SENSOR_OR_AUTO, false},
26 {"Auto", OPER_SENSOR_OR_AUTO, true},
27};
28static constexpr const Preset &PRESET_IN_OUT = PRESETS[2];
29static constexpr const Preset &PRESET_SENSOR = PRESETS[3];
30
31static const Preset *find_preset(const char *name) {
32 for (const auto &preset : PRESETS) {
33 if (preset.name == name)
34 return &preset;
35 }
36 return nullptr;
37}
38
39static const Preset *find_preset(uint8_t mode, bool auto_mode) {
40 for (const auto &preset : PRESETS) {
41 if (preset.mode == mode && preset.auto_mode == auto_mode)
42 return &preset;
43 }
44 return nullptr;
45}
46
49 {PRESETS[0].name, PRESETS[1].name, PRESETS[2].name, PRESETS[3].name, PRESETS[4].name});
50 // Restore the last preset and speed so turning on resumes them; on/off comes from the device.
51 auto restore = this->restore_state_();
52 if (restore.has_value()) {
53 this->speed = restore->speed;
54 if (restore->preset_mode < std::size(PRESETS))
55 this->set_preset_mode_(PRESETS[restore->preset_mode].name);
56 }
57}
58
59void Ecocomfort2Fan::dump_config() { LOG_FAN("", "Ecocomfort2 Fan", this); }
60
62 fan::FanTraits traits;
63 traits.set_speed(true);
64 traits.set_supported_speed_count(SPEED_COUNT);
65 this->wire_preset_modes_(traits);
66 return traits;
67}
68
70 if (!this->parent_->is_ready()) {
71 ESP_LOGW(TAG, "Not ready, cannot handle control call");
72 return;
73 }
74
75 // Any call that does not turn the fan off turns it on
76 auto state = call.get_state();
77 this->state = !state.has_value() || *state;
78 // The core clears the preset in a speed call; here the preset is the air flow mode, so keep it.
79 if (call.has_preset_mode())
81
82 const Preset *preset = find_preset(this->get_preset_mode().c_str());
83 if (preset == nullptr) {
84 preset = &PRESET_IN_OUT;
85 this->set_preset_mode_(preset->name);
86 }
87 auto speed = call.get_speed();
88 if (speed.has_value()) {
89 this->speed = *speed;
90 // A manual speed leaves automatic speed control
91 if (preset->auto_mode) {
92 preset = &PRESET_SENSOR;
93 this->set_preset_mode_(preset->name);
94 }
95 }
96 this->speed = clamp(this->speed, 1, SPEED_COUNT);
97
98 if (!this->state) {
99 this->parent_->write_oper(OPER_OFF, SPEED_OFF);
100 } else {
101 this->parent_->write_oper(preset->mode, preset->auto_mode ? FLAG_AUTO : static_cast<uint8_t>(this->speed));
102 }
103 this->publish_state();
104}
105
107 uint8_t mode = this->parent_->get_mode();
108 uint8_t raw_speed = this->parent_->get_speed();
109
110 // Off keeps the preset and speed so turning on resumes them
111 if (mode == OPER_OFF) {
112 if (!this->state)
113 return;
114 this->state = false;
115 this->publish_state();
116 return;
117 }
118
119 int new_speed = this->speed;
120 uint8_t base_speed = raw_speed & SPEED_MASK;
121 if (base_speed >= SPEED_SLEEP && base_speed <= SPEED_VEL3)
122 new_speed = base_speed;
123 const Preset *preset = find_preset(mode, (raw_speed & FLAG_AUTO) != 0);
124 const char *new_preset = preset != nullptr ? preset->name : nullptr;
125 bool same_preset = new_preset == nullptr ? !this->has_preset_mode() : this->get_preset_mode().c_str() == new_preset;
126 if (this->state && this->speed == new_speed && same_preset)
127 return;
128
129 this->state = true;
130 this->speed = new_speed;
131 if (new_preset != nullptr) {
132 this->set_preset_mode_(new_preset);
133 } else {
134 this->clear_preset_mode_();
135 }
136 this->publish_state();
137}
138
139} // namespace esphome::ecocomfort2
140
141#endif // USE_ESP32
BedjetMode mode
BedJet operating mode.
constexpr const char * c_str() const
Definition string_ref.h:78
void control(const fan::FanCall &call) override
fan::FanTraits get_traits() override
const char * get_preset_mode() const
Definition fan.h:76
bool has_preset_mode() const
Definition fan.h:77
void set_supported_preset_modes(std::initializer_list< const char * > preset_modes)
Set the supported preset modes (stored on Fan, referenced by FanTraits via pointer).
Definition fan.h:133
void publish_state()
Definition fan.cpp:218
void clear_preset_mode_()
Clear the preset mode.
Definition fan.cpp:207
bool set_preset_mode_(const char *preset_mode, size_t len)
Set the preset mode (finds and stores pointer from traits).
Definition fan.cpp:176
StringRef get_preset_mode() const
Get the current preset mode.
Definition fan.h:147
bool state
The current on/off state of the fan.
Definition fan.h:110
void wire_preset_modes_(FanTraits &traits)
Wire the Fan-owned preset modes pointer into the given traits object.
Definition fan.h:178
bool has_preset_mode() const
Check if a preset mode is currently active.
Definition fan.h:150
int speed
The current fan speed level.
Definition fan.h:114
optional< FanRestoreState > restore_state_()
Definition fan.cpp:246
void set_speed(bool speed)
Set whether this fan supports speed levels.
Definition fan_traits.h:27
void set_supported_speed_count(int speed_count)
Set how many speed levels this fan has.
Definition fan_traits.h:31
ClimatePreset preset
Definition climate.h:8
ESPHOME_LOG_TAG(TAG, "ecocomfort2.fan")