ESPHome  2022.9.2
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  if (this->oscillating_.has_value())
26  ESP_LOGD(TAG, " Oscillating: %s", YESNO(*this->oscillating_));
27  if (this->speed_.has_value())
28  ESP_LOGD(TAG, " Speed: %d", *this->speed_);
29  if (this->direction_.has_value())
30  ESP_LOGD(TAG, " Direction: %s", LOG_STR_ARG(fan_direction_to_string(*this->direction_)));
31 
32  this->parent_.control(*this);
33 }
35  auto traits = this->parent_.get_traits();
36 
37  if (this->speed_.has_value())
38  this->speed_ = clamp(*this->speed_, 1, traits.supported_speed_count());
39 
40  if (this->binary_state_.has_value() && *this->binary_state_) {
41  // when turning on, if current speed is zero, set speed to 100%
42  if (traits.supports_speed() && !this->parent_.state && this->parent_.speed == 0) {
43  this->speed_ = traits.supported_speed_count();
44  }
45  }
46 
47  if (this->oscillating_.has_value() && !traits.supports_oscillation()) {
48  ESP_LOGW(TAG, "'%s' - This fan does not support oscillation!", this->parent_.get_name().c_str());
49  this->oscillating_.reset();
50  }
51 
52  if (this->speed_.has_value() && !traits.supports_speed()) {
53  ESP_LOGW(TAG, "'%s' - This fan does not support speeds!", this->parent_.get_name().c_str());
54  this->speed_.reset();
55  }
56 
57  if (this->direction_.has_value() && !traits.supports_direction()) {
58  ESP_LOGW(TAG, "'%s' - This fan does not support directions!", this->parent_.get_name().c_str());
59  this->direction_.reset();
60  }
61 }
62 
64  auto call = fan.make_call();
65  call.set_state(this->state);
66  call.set_oscillating(this->oscillating);
67  call.set_speed(this->speed);
68  call.set_direction(this->direction);
69  return call;
70 }
72  fan.state = this->state;
73  fan.oscillating = this->oscillating;
74  fan.speed = this->speed;
75  fan.direction = this->direction;
76  fan.publish_state();
77 }
78 
79 Fan::Fan() : EntityBase("") {}
80 Fan::Fan(const std::string &name) : EntityBase(name) {}
81 
82 FanCall Fan::turn_on() { return this->make_call().set_state(true); }
83 FanCall Fan::turn_off() { return this->make_call().set_state(false); }
84 FanCall Fan::toggle() { return this->make_call().set_state(!this->state); }
85 FanCall Fan::make_call() { return FanCall(*this); }
86 
87 void Fan::add_on_state_callback(std::function<void()> &&callback) { this->state_callback_.add(std::move(callback)); }
89  auto traits = this->get_traits();
90 
91  ESP_LOGD(TAG, "'%s' - Sending state:", this->name_.c_str());
92  ESP_LOGD(TAG, " State: %s", ONOFF(this->state));
93  if (traits.supports_speed())
94  ESP_LOGD(TAG, " Speed: %d", this->speed);
95  if (traits.supports_oscillation())
96  ESP_LOGD(TAG, " Oscillating: %s", YESNO(this->oscillating));
97  if (traits.supports_direction())
98  ESP_LOGD(TAG, " Direction: %s", LOG_STR_ARG(fan_direction_to_string(this->direction)));
99 
100  this->state_callback_.call();
101  this->save_state_();
102 }
103 
104 // Random 32-bit value, change this every time the layout of the FanRestoreState struct changes.
105 constexpr uint32_t RESTORE_STATE_VERSION = 0x71700ABA;
107  FanRestoreState recovered{};
109  bool restored = this->rtc_.load(&recovered);
110 
111  switch (this->restore_mode_) {
113  return {};
115  recovered.state = false;
116  return recovered;
118  recovered.state = true;
119  return recovered;
121  recovered.state = restored ? recovered.state : false;
122  return recovered;
124  recovered.state = restored ? recovered.state : true;
125  return recovered;
127  recovered.state = restored ? !recovered.state : false;
128  return recovered;
130  recovered.state = restored ? !recovered.state : true;
131  return recovered;
132  }
133 
134  return {};
135 }
138  state.state = this->state;
139  state.oscillating = this->oscillating;
140  state.speed = this->speed;
141  state.direction = this->direction;
142  this->rtc_.save(&state);
143 }
144 
145 void Fan::dump_traits_(const char *tag, const char *prefix) {
146  if (this->get_traits().supports_speed()) {
147  ESP_LOGCONFIG(tag, "%s Speed: YES", prefix);
148  ESP_LOGCONFIG(tag, "%s Speed count: %d", prefix, this->get_traits().supported_speed_count());
149  }
150  if (this->get_traits().supports_oscillation())
151  ESP_LOGCONFIG(tag, "%s Oscillation: YES", prefix);
152  if (this->get_traits().supports_direction())
153  ESP_LOGCONFIG(tag, "%s Direction: YES", prefix);
154 }
155 
156 } // namespace fan
157 } // 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:71
FanDirection direction
The current direction of the fan.
Definition: fan.h:113
void publish_state()
Definition: fan.cpp:88
void save_state_()
Definition: fan.cpp:136
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:106
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:84
constexpr uint32_t RESTORE_STATE_VERSION
Definition: fan.cpp:105
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:87
optional< int > speed_
Definition: fan.h:84
FanDirection direction
Definition: fan.h:37
FanCall turn_off()
Definition: fan.cpp:83
FanCall & set_speed(int speed)
Definition: fan.h:59
virtual void control(const FanCall &call)=0
FanCall toggle()
Definition: fan.cpp:84
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:34
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:63
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:85
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:145
FanCall turn_on()
Definition: fan.cpp:82