10 static const char *
const TAG =
"he60r.cover";
11 static const uint8_t QUERY_BYTE = 0x38;
12 static const uint8_t TOGGLE_BYTE = 0x30;
17 auto restore = this->restore_state_();
19 if (restore.has_value()) {
21 this->publish_state(
false);
27 this->last_recompute_time_ = this->start_dir_time_ =
millis();
28 this->set_interval(300, [
this]() { this->update_(); });
33 traits.set_supports_stop(
true);
34 traits.set_supports_position(
true);
35 traits.set_supports_toggle(
true);
36 traits.set_is_assumed_state(
false);
41 LOG_COVER(
"",
"HE60R Cover",
this);
43 ESP_LOGCONFIG(TAG,
" Open Duration: %.1fs", this->open_duration_ / 1e3f);
44 ESP_LOGCONFIG(TAG,
" Close Duration: %.1fs", this->close_duration_ / 1e3f);
45 auto restore = this->restore_state_();
46 if (restore.has_value())
47 ESP_LOGCONFIG(TAG,
" Saved position %d%%", (
int) (restore->position * 100.f));
51 const uint32_t now =
millis();
58 if (this->last_command_ == operation) {
59 float dur = (float) (now - this->start_dir_time_) / 1e3f;
60 ESP_LOGD(TAG,
"'%s' - %s endstop reached. Took %.1fs.", this->name_.c_str(),
63 this->publish_state();
68 if (this->current_operation != operation) {
69 this->current_operation = operation;
71 this->last_recompute_time_ =
millis();
76 ESP_LOGV(TAG,
"Process RX data %X", data);
77 if (!this->query_seen_) {
78 this->query_seen_ = data == QUERY_BYTE;
79 if (!this->query_seen_)
80 ESP_LOGD(TAG,
"RX Byte %02X", data);
128 if (this->toggles_needed_ != 0) {
129 if ((this->counter_++ & 0x3) == 0) {
130 this->toggles_needed_--;
131 ESP_LOGD(TAG,
"Writing byte 0x30, still needed=%u", this->toggles_needed_);
132 this->write_byte(TOGGLE_BYTE);
134 this->write_byte(QUERY_BYTE);
137 this->write_byte(QUERY_BYTE);
141 this->recompute_position_();
145 if (this->is_at_target_()) {
155 while (this->available() > 0) {
156 if (this->read_byte(&data)) {
157 this->process_rx_(data);
170 this->toggles_needed_++;
179 this->target_position_ = pos;
196 switch (this->last_command_) {
198 return this->
position >= this->target_position_;
200 return this->
position <= this->target_position_;
208 this->last_command_ = dir;
209 if (this->current_operation == dir)
211 ESP_LOGD(TAG,
"'%s' - Direction '%s' requested.", this->name_.c_str(),
216 if (dir == this->next_direction_) {
218 this->toggles_needed_ = 1;
222 this->toggles_needed_ = 3;
225 this->toggles_needed_ = 2;
227 ESP_LOGD(TAG,
"'%s' - Reversing direction.", this->name_.c_str());
229 this->start_dir_time_ =
millis();
236 const uint32_t now =
millis();
237 if (now > this->last_recompute_time_) {
238 auto diff = (unsigned) (now - last_recompute_time_);
240 switch (this->current_operation) {
242 delta = (float) diff / (
float) this->open_duration_;
245 delta = -(float) diff / (
float) this->close_duration_;
253 ESP_LOGD(TAG,
"Recompute %ums, dir=%u, delta=%f, pos=%f", diff, this->current_operation, delta, new_position);
254 this->last_recompute_time_ = now;
255 if (this->
position != new_position) {
257 this->publish_state();
CoverOperation
Enum encoding the current operation of a cover.
void set_current_operation_(cover::CoverOperation operation)
The cover is currently closing.
void dump_config() override
constexpr const T & clamp(const T &v, const T &lo, const T &hi, Compare comp)
uint32_t IRAM_ATTR HOT millis()
bool is_at_target_() const
Check if the cover has reached or passed the target position.
const optional< bool > & get_toggle() const
void process_rx_(uint8_t data)
void endstop_reached_(cover::CoverOperation operation)
cover::CoverTraits get_traits() override
void start_direction_(cover::CoverOperation dir)
void control(const cover::CoverCall &call) override
Implementation of SPI Controller mode.
The cover is currently opening.
const optional< float > & get_position() const
void recompute_position_()