ESPHome  2023.11.6
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 FanCall Fan::turn_on() { return this->make_call().set_state(true); }
84 FanCall Fan::turn_off() { return this->make_call().set_state(false); }
85 FanCall Fan::toggle() { return this->make_call().set_state(!this->state); }
86 FanCall Fan::make_call() { return FanCall(*this); }
87 
88 void Fan::add_on_state_callback(std::function<void()> &&callback) { this->state_callback_.add(std::move(callback)); }
90  auto traits = this->get_traits();
91 
92  ESP_LOGD(TAG, "'%s' - Sending state:", this->name_.c_str());
93  ESP_LOGD(TAG, " State: %s", ONOFF(this->state));
94  if (traits.supports_speed()) {
95  ESP_LOGD(TAG, " Speed: %d", this->speed);
96  }
97  if (traits.supports_oscillation()) {
98  ESP_LOGD(TAG, " Oscillating: %s", YESNO(this->oscillating));
99  }
100  if (traits.supports_direction()) {
101  ESP_LOGD(TAG, " Direction: %s", LOG_STR_ARG(fan_direction_to_string(this->direction)));
102  }
103 
104  this->state_callback_.call();
105  this->save_state_();
106 }
107 
108 // Random 32-bit value, change this every time the layout of the FanRestoreState struct changes.
109 constexpr uint32_t RESTORE_STATE_VERSION = 0x71700ABA;
111  FanRestoreState recovered{};
112  this->rtc_ = global_preferences->make_preference<FanRestoreState>(this->get_object_id_hash() ^ RESTORE_STATE_VERSION);
113  bool restored = this->rtc_.load(&recovered);
114 
115  switch (this->restore_mode_) {
117  return {};
119  recovered.state = false;
120  return recovered;
122  recovered.state = true;
123  return recovered;
125  recovered.state = restored ? recovered.state : false;
126  return recovered;
128  recovered.state = restored ? recovered.state : true;
129  return recovered;
131  recovered.state = restored ? !recovered.state : false;
132  return recovered;
134  recovered.state = restored ? !recovered.state : true;
135  return recovered;
136  }
137 
138  return {};
139 }
142  state.state = this->state;
143  state.oscillating = this->oscillating;
144  state.speed = this->speed;
145  state.direction = this->direction;
146  this->rtc_.save(&state);
147 }
148 
149 void Fan::dump_traits_(const char *tag, const char *prefix) {
150  if (this->get_traits().supports_speed()) {
151  ESP_LOGCONFIG(tag, "%s Speed: YES", prefix);
152  ESP_LOGCONFIG(tag, "%s Speed count: %d", prefix, this->get_traits().supported_speed_count());
153  }
154  if (this->get_traits().supports_oscillation()) {
155  ESP_LOGCONFIG(tag, "%s Oscillation: YES", prefix);
156  }
157  if (this->get_traits().supports_direction()) {
158  ESP_LOGCONFIG(tag, "%s Direction: YES", prefix);
159  }
160 }
161 
162 } // namespace fan
163 } // namespace esphome
bool state
The current on/off state of the fan.
Definition: fan.h:103
bool oscillating
The current oscillation state of the fan.
Definition: fan.h:105
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:109
void publish_state()
Definition: fan.cpp:89
void save_state_()
Definition: fan.cpp:140
virtual FanTraits get_traits()=0
int speed
Definition: fan.h:35
optional< FanRestoreState > restore_state_()
Definition: fan.cpp:110
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
FanCall(Fan &parent)
Definition: fan.h:39
constexpr uint32_t RESTORE_STATE_VERSION
Definition: fan.cpp:109
void add_on_state_callback(std::function< void()> &&callback)
Register a callback that will be called each time the state changes.
Definition: fan.cpp:88
optional< int > speed_
Definition: fan.h:84
FanDirection direction
Definition: fan.h:37
FanCall turn_off()
Definition: fan.cpp:84
FanCall & set_speed(int speed)
Definition: fan.h:59
virtual void control(const FanCall &call)=0
FanCall toggle()
Definition: fan.cpp:85
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:107
FanCall & set_oscillating(bool oscillating)
Definition: fan.h:50
void validate_()
Definition: fan.cpp:38
FanCall to_call(Fan &fan)
Convert this struct to a fan call that can be performed.
Definition: fan.cpp:67
constexpr const char * c_str() const
Definition: string_ref.h:68
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:86
bool oscillating
Definition: fan.h:36
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
const LogString * fan_direction_to_string(FanDirection direction)
Definition: fan.cpp:9
const StringRef & get_name() const
Definition: entity_base.cpp:10
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:149
FanCall turn_on()
Definition: fan.cpp:83