ESPHome 2025.5.0
Loading...
Searching...
No Matches
cover.cpp
Go to the documentation of this file.
1#include "cover.h"
2#include "esphome/core/log.h"
3
4namespace esphome {
5namespace cover {
6
7static const char *const TAG = "cover";
8
9const float COVER_OPEN = 1.0f;
10const float COVER_CLOSED = 0.0f;
11
12const char *cover_command_to_str(float pos) {
13 if (pos == COVER_OPEN) {
14 return "OPEN";
15 } else if (pos == COVER_CLOSED) {
16 return "CLOSE";
17 } else {
18 return "UNKNOWN";
19 }
20}
22 switch (op) {
24 return "IDLE";
26 return "OPENING";
28 return "CLOSING";
29 default:
30 return "UNKNOWN";
31 }
32}
33
35
36CoverCall::CoverCall(Cover *parent) : parent_(parent) {}
37CoverCall &CoverCall::set_command(const char *command) {
38 if (strcasecmp(command, "OPEN") == 0) {
39 this->set_command_open();
40 } else if (strcasecmp(command, "CLOSE") == 0) {
41 this->set_command_close();
42 } else if (strcasecmp(command, "STOP") == 0) {
43 this->set_command_stop();
44 } else if (strcasecmp(command, "TOGGLE") == 0) {
45 this->set_command_toggle();
46 } else {
47 ESP_LOGW(TAG, "'%s' - Unrecognized command %s", this->parent_->get_name().c_str(), command);
48 }
49 return *this;
50}
52 this->position_ = COVER_OPEN;
53 return *this;
54}
56 this->position_ = COVER_CLOSED;
57 return *this;
58}
60 this->stop_ = true;
61 return *this;
62}
64 this->toggle_ = true;
65 return *this;
66}
68 this->position_ = position;
69 return *this;
70}
72 this->tilt_ = tilt;
73 return *this;
74}
76 ESP_LOGD(TAG, "'%s' - Setting", this->parent_->get_name().c_str());
77 auto traits = this->parent_->get_traits();
78 this->validate_();
79 if (this->stop_) {
80 ESP_LOGD(TAG, " Command: STOP");
81 }
82 if (this->position_.has_value()) {
83 if (traits.get_supports_position()) {
84 ESP_LOGD(TAG, " Position: %.0f%%", *this->position_ * 100.0f);
85 } else {
86 ESP_LOGD(TAG, " Command: %s", cover_command_to_str(*this->position_));
87 }
88 }
89 if (this->tilt_.has_value()) {
90 ESP_LOGD(TAG, " Tilt: %.0f%%", *this->tilt_ * 100.0f);
91 }
92 if (this->toggle_.has_value()) {
93 ESP_LOGD(TAG, " Command: TOGGLE");
94 }
95 this->parent_->control(*this);
96}
97const optional<float> &CoverCall::get_position() const { return this->position_; }
98const optional<float> &CoverCall::get_tilt() const { return this->tilt_; }
99const optional<bool> &CoverCall::get_toggle() const { return this->toggle_; }
101 auto traits = this->parent_->get_traits();
102 if (this->position_.has_value()) {
103 auto pos = *this->position_;
104 if (!traits.get_supports_position() && pos != COVER_OPEN && pos != COVER_CLOSED) {
105 ESP_LOGW(TAG, "'%s' - This cover device does not support setting position!", this->parent_->get_name().c_str());
106 this->position_.reset();
107 } else if (pos < 0.0f || pos > 1.0f) {
108 ESP_LOGW(TAG, "'%s' - Position %.2f is out of range [0.0 - 1.0]", this->parent_->get_name().c_str(), pos);
109 this->position_ = clamp(pos, 0.0f, 1.0f);
110 }
111 }
112 if (this->tilt_.has_value()) {
113 auto tilt = *this->tilt_;
114 if (!traits.get_supports_tilt()) {
115 ESP_LOGW(TAG, "'%s' - This cover device does not support tilt!", this->parent_->get_name().c_str());
116 this->tilt_.reset();
117 } else if (tilt < 0.0f || tilt > 1.0f) {
118 ESP_LOGW(TAG, "'%s' - Tilt %.2f is out of range [0.0 - 1.0]", this->parent_->get_name().c_str(), tilt);
119 this->tilt_ = clamp(tilt, 0.0f, 1.0f);
120 }
121 }
122 if (this->toggle_.has_value()) {
123 if (!traits.get_supports_toggle()) {
124 ESP_LOGW(TAG, "'%s' - This cover device does not support toggle!", this->parent_->get_name().c_str());
125 this->toggle_.reset();
126 }
127 }
128 if (this->stop_) {
129 if (this->position_.has_value()) {
130 ESP_LOGW(TAG, "Cannot set position when stopping a cover!");
131 this->position_.reset();
132 }
133 if (this->tilt_.has_value()) {
134 ESP_LOGW(TAG, "Cannot set tilt when stopping a cover!");
135 this->tilt_.reset();
136 }
137 if (this->toggle_.has_value()) {
138 ESP_LOGW(TAG, "Cannot set toggle when stopping a cover!");
139 this->toggle_.reset();
140 }
141 }
142}
144 this->stop_ = stop;
145 return *this;
146}
147bool CoverCall::get_stop() const { return this->stop_; }
148
149CoverCall Cover::make_call() { return {this}; }
150void Cover::open() {
151 auto call = this->make_call();
152 call.set_command_open();
153 call.perform();
154}
155void Cover::close() {
156 auto call = this->make_call();
157 call.set_command_close();
158 call.perform();
159}
160void Cover::stop() {
161 auto call = this->make_call();
162 call.set_command_stop();
163 call.perform();
164}
165void Cover::add_on_state_callback(std::function<void()> &&f) { this->state_callback_.add(std::move(f)); }
166void Cover::publish_state(bool save) {
167 this->position = clamp(this->position, 0.0f, 1.0f);
168 this->tilt = clamp(this->tilt, 0.0f, 1.0f);
169
170 ESP_LOGD(TAG, "'%s' - Publishing:", this->name_.c_str());
171 auto traits = this->get_traits();
172 if (traits.get_supports_position()) {
173 ESP_LOGD(TAG, " Position: %.0f%%", this->position * 100.0f);
174 } else {
175 if (this->position == COVER_OPEN) {
176 ESP_LOGD(TAG, " State: OPEN");
177 } else if (this->position == COVER_CLOSED) {
178 ESP_LOGD(TAG, " State: CLOSED");
179 } else {
180 ESP_LOGD(TAG, " State: UNKNOWN");
181 }
182 }
183 if (traits.get_supports_tilt()) {
184 ESP_LOGD(TAG, " Tilt: %.0f%%", this->tilt * 100.0f);
185 }
186 ESP_LOGD(TAG, " Current Operation: %s", cover_operation_to_str(this->current_operation));
187
188 this->state_callback_.call();
189
190 if (save) {
191 CoverRestoreState restore{};
192 memset(&restore, 0, sizeof(restore));
193 restore.position = this->position;
194 if (traits.get_supports_tilt()) {
195 restore.tilt = this->tilt;
196 }
197 this->rtc_.save(&restore);
198 }
199}
202 CoverRestoreState recovered{};
203 if (!this->rtc_.load(&recovered))
204 return {};
205 return recovered;
206}
207
208bool Cover::is_fully_open() const { return this->position == COVER_OPEN; }
209bool Cover::is_fully_closed() const { return this->position == COVER_CLOSED; }
210
212 auto call = cover->make_call();
213 auto traits = cover->get_traits();
214 call.set_position(this->position);
215 if (traits.get_supports_tilt())
216 call.set_tilt(this->tilt);
217 return call;
218}
220 cover->position = this->position;
221 cover->tilt = this->tilt;
222 cover->publish_state();
223}
224
225} // namespace cover
226} // namespace esphome
bool save(const T *src)
Definition preferences.h:21
virtual ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash)=0
uint32_t get_object_id_hash()
const StringRef & get_name() const
constexpr const char * c_str() const
Definition string_ref.h:68
const optional< float > & get_tilt() const
Definition cover.cpp:98
CoverCall & set_command_toggle()
Set the command to toggle the cover.
Definition cover.cpp:63
const optional< bool > & get_toggle() const
Definition cover.cpp:99
optional< float > tilt_
Definition cover.h:64
CoverCall & set_command_open()
Set the command to open the cover.
Definition cover.cpp:51
CoverCall & set_command_close()
Set the command to close the cover.
Definition cover.cpp:55
CoverCall & set_command(const char *command)
Set the command as a string, "STOP", "OPEN", "CLOSE", "TOGGLE".
Definition cover.cpp:37
void perform()
Perform the cover call.
Definition cover.cpp:75
CoverCall & set_position(float position)
Set the call to a certain target position.
Definition cover.cpp:67
CoverCall & set_command_stop()
Set the command to stop the cover.
Definition cover.cpp:59
bool get_stop() const
Definition cover.cpp:147
optional< float > position_
Definition cover.h:63
const optional< float > & get_position() const
Definition cover.cpp:97
CoverCall(Cover *parent)
Definition cover.cpp:36
CoverCall & set_tilt(float tilt)
Set the call to a certain target tilt.
Definition cover.cpp:71
optional< bool > toggle_
Definition cover.h:65
CoverCall & set_stop(bool stop)
Set whether this cover call should stop the cover.
Definition cover.cpp:143
Base class for all cover devices.
Definition cover.h:111
CoverOperation current_operation
The current operation of the cover (idle, opening, closing).
Definition cover.h:116
optional< CoverRestoreState > restore_state_()
Definition cover.cpp:200
void publish_state(bool save=true)
Publish the current state of the cover.
Definition cover.cpp:166
void add_on_state_callback(std::function< void()> &&f)
Definition cover.cpp:165
CoverCall make_call()
Construct a new cover call used to control the cover.
Definition cover.cpp:149
float tilt
The current tilt value of the cover from 0.0 to 1.0.
Definition cover.h:124
float position
The position of the cover from 0.0 (fully closed) to 1.0 (fully open).
Definition cover.h:122
bool is_fully_closed() const
Helper method to check if the cover is fully closed. Equivalent to comparing .position against 0....
Definition cover.cpp:209
CallbackManager< void()> state_callback_
Definition cover.h:173
ESPPreferenceObject rtc_
Definition cover.h:175
virtual CoverTraits get_traits()=0
bool is_fully_open() const
Helper method to check if the cover is fully open. Equivalent to comparing .position against 1....
Definition cover.cpp:208
virtual void control(const CoverCall &call)=0
bool has_value() const
Definition optional.h:87
float position
Definition cover.h:0
float tilt
Definition cover.h:1
const float COVER_CLOSED
Definition cover.cpp:10
const float COVER_OPEN
Definition cover.cpp:9
const char * cover_command_to_str(float pos)
Definition cover.cpp:12
const char * cover_operation_to_str(CoverOperation op)
Definition cover.cpp:21
CoverOperation
Enum encoding the current operation of a cover.
Definition cover.h:80
@ COVER_OPERATION_OPENING
The cover is currently opening.
Definition cover.h:84
@ COVER_OPERATION_CLOSING
The cover is currently closing.
Definition cover.h:86
@ COVER_OPERATION_IDLE
The cover is currently idle (not moving)
Definition cover.h:82
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
ESPPreferences * global_preferences
constexpr const T & clamp(const T &v, const T &lo, const T &hi, Compare comp)
Definition helpers.h:101
Struct used to store the restored state of a cover.
Definition cover.h:69
void apply(Cover *cover)
Apply these settings to the cover.
Definition cover.cpp:219
CoverCall to_call(Cover *cover)
Convert this struct to a cover call that can be performed.
Definition cover.cpp:211