10 static const char *
const TAG =
"tormatic.cover";
15 auto restore = this->restore_state_();
16 if (restore.has_value()) {
27 traits.set_supports_stop(
true);
28 traits.set_supports_position(
true);
29 traits.set_is_assumed_state(
false);
33 void Tormatic::dump_config() {
34 LOG_COVER(
"",
"Tormatic Cover",
this);
37 ESP_LOGCONFIG(TAG,
" Open Duration: %.1fs", this->open_duration_ / 1e3f);
38 ESP_LOGCONFIG(TAG,
" Close Duration: %.1fs", this->close_duration_ / 1e3f);
40 auto restore = this->restore_state_();
41 if (restore.has_value()) {
42 ESP_LOGCONFIG(TAG,
" Saved position %d%%", (
int) (restore->position * 100.f));
46 void Tormatic::update() { this->request_gate_status_(); }
49 auto o_status = this->read_gate_status_();
51 auto status = o_status.value();
53 this->recalibrate_duration_(
status);
54 this->handle_gate_status_(
status);
57 this->recompute_position_();
58 this->stop_at_target_();
63 this->send_gate_command_(
PAUSED);
69 this->control_position_(pos);
76 void Tormatic::publish_state(
bool save, uint32_t ratelimit) {
78 if ((now - this->last_publish_time_) < ratelimit) {
81 this->last_publish_time_ = now;
83 Cover::publish_state(save);
89 if (this->current_status_ == s) {
94 auto old = this->current_status_;
100 ESP_LOGD(TAG,
"Gate paused, clearing direction start time");
101 this->direction_start_time_ = 0;
108 ESP_LOGD(TAG,
"Gate started moving from fully open or closed state");
109 this->direction_start_time_ = now;
114 if (this->direction_start_time_ == 0) {
119 this->open_duration_ = now - this->direction_start_time_;
120 ESP_LOGI(TAG,
"Recalibrated the gate's open duration to %dms", this->open_duration_);
123 this->close_duration_ = now - this->direction_start_time_;
124 ESP_LOGI(TAG,
"Recalibrated the gate's close duration to %dms", this->close_duration_);
127 this->direction_start_time_ = 0;
133 if (this->current_status_ == s) {
144 this->send_gate_command_(
PAUSED);
155 this->current_status_ = s;
158 this->publish_state(
true);
163 this->last_recompute_time_ =
millis();
168 void Tormatic::recompute_position_() {
173 const uint32_t now =
millis();
174 uint32_t diff = now - this->last_recompute_time_;
177 uint32_t
duration = this->open_duration_;
180 duration = this->close_duration_;
187 this->last_recompute_time_ = now;
189 this->publish_state(
true, 250);
193 void Tormatic::control_position_(
float target) {
199 ESP_LOGI(TAG,
"Fully opening gate");
200 this->send_gate_command_(
OPENED);
204 ESP_LOGI(TAG,
"Fully closing gate");
205 this->send_gate_command_(
CLOSED);
211 this->target_position_ = target;
214 ESP_LOGI(TAG,
"Opening gate towards %.1f", target);
215 this->send_gate_command_(
OPENED);
220 ESP_LOGI(TAG,
"Closing gate towards %.1f", target);
221 this->send_gate_command_(
CLOSED);
229 void Tormatic::stop_at_target_() {
233 if (!this->target_position_) {
236 auto target = this->target_position_.value();
245 this->send_gate_command_(
PAUSED);
246 this->target_position_.reset();
256 auto o_hdr = this->read_data_<MessageHeader>();
258 ESP_LOGE(TAG,
"Timeout reading message header");
261 auto hdr = o_hdr.value();
266 ESP_LOGE(TAG,
"Header specifies payload size %d but size of StatusReply is %d", hdr.payload_size(),
271 auto o_status = this->read_data_<StatusReply>();
275 auto status = o_status.value();
291 ESP_LOGE(TAG,
"Reading remaining %d payload bytes of unknown type 0x%x", hdr.payload_size(), hdr.type);
296 this->drain_rx_(hdr.payload_size());
302 void Tormatic::request_gate_status_() {
303 ESP_LOGV(TAG,
"Requesting gate status");
320 out.insert(out.end(), reqv.begin(), reqv.end());
322 this->write_array(out);
327 uint32_t start =
millis();
329 auto ok = this->read_array((uint8_t *) &obj,
sizeof(obj));
336 ESP_LOGV(TAG,
"Read %s in %d ms", obj.print().c_str(),
millis() - start);
341 void Tormatic::drain_rx_(uint16_t n) {
344 while (this->available()) {
345 this->read_byte(&data);
348 if (n > 0 && count >= n) {
value_type const & value() const
The cover is currently closing.
const char * gate_status_to_str(GateStatus s)
constexpr const T & clamp(const T &v, const T &lo, const T &hi, Compare comp)
uint32_t IRAM_ATTR HOT millis()
std::vector< uint8_t > serialize(T obj)
send_message_t * send_message_
Implementation of SPI Controller mode.
CoverOperation gate_status_to_cover_operation(GateStatus s)
The cover is currently opening.
const optional< float > & get_position() const