ESPHome  2023.3.0
fan.cpp
Go to the documentation of this file.
1 #include "fan.h"
2 #include "esphome/core/log.h"
3 
4 namespace esphome {
5 namespace fan {
6 
7 static const char *const TAG = "fan";
8 
10  switch (direction) {
12  return LOG_STR("FORWARD");
14  return LOG_STR("REVERSE");
15  default:
16  return LOG_STR("UNKNOWN");
17  }
18 }
19 
21  ESP_LOGD(TAG, "'%s' - Setting:", this->parent_.get_name().c_str());
22  this->validate_();
23  if (this->binary_state_.has_value()) {
24  ESP_LOGD(TAG, " State: %s", ONOFF(*this->binary_state_));
25  }
26  if (this->oscillating_.has_value()) {
27  ESP_LOGD(TAG, " Oscillating: %s", YESNO(*this->oscillating_));
28  }
29  if (this->speed_.has_value()) {
30  ESP_LOGD(TAG, " Speed: %d", *this->speed_);
31  }
32  if (this->direction_.has_value()) {
33  ESP_LOGD(TAG, " Direction: %s", LOG_STR_ARG(fan_direction_to_string(*this->direction_)));
34  }
35 
36  this->parent_.control(*this);
37 }
39  auto traits = this->parent_.get_traits();
40 
41  if (this->speed_.has_value())
42  this->speed_ = clamp(*this->speed_, 1, traits.supported_speed_count());
43 
44  if (this->binary_state_.has_value() && *this->binary_state_) {
45  // when turning on, if current speed is zero, set speed to 100%
46  if (traits.supports_speed() && !this->parent_.state && this->parent_.speed == 0) {
47  this->speed_ = traits.supported_speed_count();
48  }
49  }
50 
51  if (this->oscillating_.has_value() && !traits.supports_oscillation()) {
52  ESP_LOGW(TAG, "'%s' - This fan does not support oscillation!", this->parent_.get_name().c_str());
53  this->oscillating_.reset();
54  }
55 
56  if (this->speed_.has_value() && !traits.supports_speed()) {
57  ESP_LOGW(TAG, "'%s' - This fan does not support speeds!", this->parent_.get_name().c_str());
58  this->speed_.reset();
59  }
60 
61  if (this->direction_.has_value() && !traits.supports_direction()) {
62  ESP_LOGW(TAG, "'%s' - This fan does not support directions!", this->parent_.get_name().c_str());
63  this->direction_.reset();
64  }
65 }
66 
68  auto call = fan.make_call();
69  call.set_state(this->state);
70  call.set_oscillating(this->oscillating);
71  call.set_speed(this->speed);
72  call.set_direction(this->direction);
73  return call;
74 }
76  fan.state = this->state;
77  fan.oscillating = this->oscillating;
78  fan.speed = this->speed;
79  fan.direction = this->direction;
80  fan.publish_state();
81 }
82 
83 Fan::Fan() : EntityBase("") {}
84 Fan::Fan(const std::string &name) : EntityBase(name) {}
85 
86 FanCall Fan::turn_on() { return this->make_call().set_state(true); }
87 FanCall Fan::turn_off() { return this->make_call().set_state(false); }
88 FanCall Fan::toggle() { return this->make_call().set_state(!this->state); }
89 FanCall Fan::make_call() { return FanCall(*this); }
90 
91 void Fan::add_on_state_callback(std::function<void()> &&callback) { this->state_callback_.add(std::move(callback)); }
93  auto traits = this->get_traits();
94 
95  ESP_LOGD(TAG, "'%s' - Sending state:", this->name_.c_str());
96  ESP_LOGD(TAG, " State: %s", ONOFF(this->state));
97  if (traits.supports_speed()) {
98  ESP_LOGD(TAG, " Speed: %d", this->speed);
99  }
100  if (traits.supports_oscillation()) {
101  ESP_LOGD(TAG, " Oscillating: %s", YESNO(this->oscillating));
102  }
103  if (traits.supports_direction()) {
104  ESP_LOGD(TAG, " Direction: %s", LOG_STR_ARG(fan_direction_to_string(this->direction)));
105  }
106 
107  this->state_callback_.call();
108  this->save_state_();
109 }
110 
111 // Random 32-bit value, change this every time the layout of the FanRestoreState struct changes.
112 constexpr uint32_t RESTORE_STATE_VERSION = 0x71700ABA;
114  FanRestoreState recovered{};
116  bool restored = this->rtc_.load(&recovered);
117 
118  switch (this->restore_mode_) {
120  return {};
122  recovered.state = false;
123  return recovered;
125  recovered.state = true;
126  return recovered;
128  recovered.state = restored ? recovered.state : false;
129  return recovered;
131  recovered.state = restored ? recovered.state : true;
132  return recovered;
134  recovered.state = restored ? !recovered.state : false;
135  return recovered;
137  recovered.state = restored ? !recovered.state : true;
138  return recovered;
139  }
140 
141  return {};
142 }
145  state.state = this->state;
146  state.oscillating = this->oscillating;
147  state.speed = this->speed;
148  state.direction = this->direction;
149  this->rtc_.save(&state);
150 }
151 
152 void Fan::dump_traits_(const char *tag, const char *prefix) {
153  if (this->get_traits().supports_speed()) {
154  ESP_LOGCONFIG(tag, "%s Speed: YES", prefix);
155  ESP_LOGCONFIG(tag, "%s Speed count: %d", prefix, this->get_traits().supported_speed_count());
156  }
157  if (this->get_traits().supports_oscillation()) {
158  ESP_LOGCONFIG(tag, "%s Oscillation: YES", prefix);
159  }
160  if (this->get_traits().supports_direction()) {
161  ESP_LOGCONFIG(tag, "%s Direction: YES", prefix);
162  }
163 }
164 
165 } // namespace fan
166 } // namespace esphome
bool state
The current on/off state of the fan.
Definition: fan.h:107
const char * name
Definition: stm32flash.h:78
bool oscillating
The current oscillation state of the fan.
Definition: fan.h:109
optional< bool > oscillating_
Definition: fan.h:83
void apply(Fan &fan)
Apply these settings to the fan.
Definition: fan.cpp:75
FanDirection direction
The current direction of the fan.
Definition: fan.h:113
void publish_state()
Definition: fan.cpp:92
void save_state_()
Definition: fan.cpp:143
std::string name_
Definition: entity_base.h:54
virtual FanTraits get_traits()=0
int speed
Definition: fan.h:35
const std::string & get_name() const
Definition: entity_base.cpp:11
optional< FanRestoreState > restore_state_()
Definition: fan.cpp:113
bool has_value() const
Definition: optional.h:87
constexpr const T & clamp(const T &v, const T &lo, const T &hi, Compare comp)
Definition: helpers.h:92
constexpr uint32_t RESTORE_STATE_VERSION
Definition: fan.cpp:112
bool save(const T *src)
Definition: preferences.h:21
void add_on_state_callback(std::function< void()> &&callback)
Register a callback that will be called each time the state changes.
Definition: fan.cpp:91
optional< int > speed_
Definition: fan.h:84
FanDirection direction
Definition: fan.h:37
FanCall turn_off()
Definition: fan.cpp:87
FanCall & set_speed(int speed)
Definition: fan.h:59
virtual void control(const FanCall &call)=0
FanCall toggle()
Definition: fan.cpp:88
optional< bool > binary_state_
Definition: fan.h:82
FanDirection
Simple enum to represent the direction of a fan.
Definition: fan.h:20
ESPPreferences * global_preferences
int speed
The current fan speed level.
Definition: fan.h:111
FanCall & set_oscillating(bool oscillating)
Definition: fan.h:50
CallbackManager< void()> state_callback_
Definition: fan.h:140
void validate_()
Definition: fan.cpp:38
FanRestoreMode restore_mode_
Definition: fan.h:142
FanCall to_call(Fan &fan)
Convert this struct to a fan call that can be performed.
Definition: fan.cpp:67
ESPPreferenceObject rtc_
Definition: fan.h:141
FanCall & set_state(bool binary_state)
Definition: fan.h:41
optional< FanDirection > direction_
Definition: fan.h:85
virtual ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash)=0
FanCall make_call()
Definition: fan.cpp:89
bool oscillating
Definition: fan.h:36
Definition: a4988.cpp:4
friend FanCall
Definition: fan.h:131
const LogString * fan_direction_to_string(FanDirection direction)
Definition: fan.cpp:9
uint32_t get_object_id_hash()
Definition: entity_base.cpp:42
FanCall & set_direction(FanDirection direction)
Definition: fan.h:66
bool state
Definition: fan.h:34
void dump_traits_(const char *tag, const char *prefix)
Definition: fan.cpp:152
FanCall turn_on()
Definition: fan.cpp:86