From 1274ef91724258fd806bed7fbfab31eee096d711 Mon Sep 17 00:00:00 2001 From: Marius Muja Date: Thu, 11 Jan 2024 15:10:51 -0800 Subject: [PATCH] Refactorings, query door status at end of an open/close operation in case the status is not received --- base.yaml | 2 +- base_secplusv1.yaml | 2 +- components/ratgdo/cover/ratgdo_cover.cpp | 8 +- components/ratgdo/ratgdo.cpp | 111 ++++++++++++++--------- components/ratgdo/ratgdo.h | 15 +-- 5 files changed, 81 insertions(+), 57 deletions(-) diff --git a/base.yaml b/base.yaml index 97495f6..9ec04af 100644 --- a/base.yaml +++ b/base.yaml @@ -264,4 +264,4 @@ button: on_press: then: lambda: !lambda |- - id($id_prefix).toggle_door(); + id($id_prefix).door_toggle(); diff --git a/base_secplusv1.yaml b/base_secplusv1.yaml index d50f227..5af8e6e 100644 --- a/base_secplusv1.yaml +++ b/base_secplusv1.yaml @@ -233,4 +233,4 @@ button: on_press: then: lambda: !lambda |- - id($id_prefix).toggle_door(); + id($id_prefix).door_toggle(); diff --git a/components/ratgdo/cover/ratgdo_cover.cpp b/components/ratgdo/cover/ratgdo_cover.cpp index 6ff1c8c..e71e0bb 100644 --- a/components/ratgdo/cover/ratgdo_cover.cpp +++ b/components/ratgdo/cover/ratgdo_cover.cpp @@ -70,17 +70,17 @@ namespace ratgdo { void RATGDOCover::control(const CoverCall& call) { if (call.get_stop()) { - this->parent_->stop_door(); + this->parent_->door_stop(); } if (call.get_toggle()) { - this->parent_->toggle_door(); + this->parent_->door_toggle(); } if (call.get_position().has_value()) { auto pos = *call.get_position(); if (pos == COVER_OPEN) { - this->parent_->open_door(); + this->parent_->door_open(); } else if (pos == COVER_CLOSED) { - this->parent_->close_door(); + this->parent_->door_close(); } else { this->parent_->door_move_to_position(pos); } diff --git a/components/ratgdo/ratgdo.cpp b/components/ratgdo/ratgdo.cpp index 0413c6e..b41e7bd 100644 --- a/components/ratgdo/ratgdo.cpp +++ b/components/ratgdo/ratgdo.cpp @@ -152,6 +152,7 @@ namespace ratgdo { this->door_position = 0.5; // best guess } this->cancel_position_sync_callbacks(); + cancel_timeout("door_query_state"); } else if (door_state == DoorState::OPEN) { this->door_position = 1.0; this->cancel_position_sync_callbacks(); @@ -377,16 +378,23 @@ namespace ratgdo { this->protocol_->sync(); } - void RATGDOComponent::open_door() + void RATGDOComponent::door_open() { if (*this->door_state == DoorState::OPENING) { return; // gets ignored by opener } - this->protocol_->door_action(DoorAction::OPEN); + this->door_action(DoorAction::OPEN); + + // query state in case we don't get a status message + set_timeout("door_query_state", (*this->opening_duration + 2)*1000, [=]() { + if (*this->door_state != DoorState::OPEN && *this->door_state != DoorState::STOPPED) { + this->query_status(); + } + }); } - void RATGDOComponent::close_door() + void RATGDOComponent::door_close() { if (*this->door_state == DoorState::CLOSING) { return; // gets ignored by opener @@ -394,10 +402,10 @@ namespace ratgdo { if (*this->door_state == DoorState::OPENING) { // have to stop door first, otherwise close command is ignored - this->protocol_->door_action(DoorAction::STOP); + this->door_action(DoorAction::STOP); this->door_state_received.then([=](DoorState s) { if (s == DoorState::STOPPED) { - this->protocol_->door_action(DoorAction::CLOSE); + this->door_action(DoorAction::CLOSE); } else { ESP_LOGW(TAG, "Door did not stop, ignoring close command"); } @@ -405,27 +413,66 @@ namespace ratgdo { return; } - this->protocol_->door_action(DoorAction::CLOSE); + this->door_action(DoorAction::CLOSE); + + // query state in case we don't get a status message + set_timeout("door_query_state", (*this->closing_duration + 2)*1000, [=]() { + if (*this->door_state != DoorState::CLOSED && *this->door_state != DoorState::STOPPED) { + this->query_status(); + } + }); } - void RATGDOComponent::stop_door() + void RATGDOComponent::door_stop() { if (*this->door_state != DoorState::OPENING && *this->door_state != DoorState::CLOSING) { ESP_LOGW(TAG, "The door is not moving."); return; } - this->protocol_->door_action(DoorAction::STOP); + this->door_action(DoorAction::STOP); } - void RATGDOComponent::toggle_door() + void RATGDOComponent::door_toggle() { - this->protocol_->door_action(DoorAction::TOGGLE); + this->door_action(DoorAction::TOGGLE); + } + + void RATGDOComponent::door_action(DoorAction action) + { + this->protocol_->door_action(action); + } + + void RATGDOComponent::ensure_door_action(DoorAction action, uint32_t delay) + { + if (action == DoorAction::TOGGLE) { + ESP_LOGW(TAG, "It's not recommended to use ensure_door_action with non-idempotent commands such as DOOR_TOGGLE"); + } + auto prev_door_state = *this->door_state; + this->door_state_received.then([=](DoorState s) { + if ((action == DoorAction::STOP) && (s != DoorState::STOPPED) && !(prev_door_state == DoorState::OPENING && s == DoorState::OPEN) && !(prev_door_state == DoorState::CLOSING && s == DoorState::CLOSED)) { + return; + } + if (action == DoorAction::OPEN && !(s == DoorState::OPENING || s == DoorState::OPEN)) { + return; + } + if (action == DoorAction::CLOSE && !(s == DoorState::CLOSED || s == DoorState::CLOSING)) { + return; + } + + ESP_LOG1(TAG, "Received door status, cancel door command retry"); + cancel_timeout("door_command_retry"); + }); + this->door_action(action); + ESP_LOG1(TAG, "Ensure door command, setup door command retry"); + set_timeout("door_command_retry", delay, [=]() { + this->ensure_door_action(action); + }); } void RATGDOComponent::door_move_to_position(float position) { if (*this->door_state == DoorState::OPENING || *this->door_state == DoorState::CLOSING) { - this->protocol_->door_action(DoorAction::STOP); + this->door_action(DoorAction::STOP); this->door_state_received.then([=](DoorState s) { if (s == DoorState::STOPPED) { this->door_move_to_position(position); @@ -450,7 +497,7 @@ namespace ratgdo { this->door_move_delta = delta; ESP_LOGD(TAG, "Moving to position %.2f in %.1fs", position, operation_time / 1000.0); - this->protocol_->door_action(delta > 0 ? DoorAction::OPEN : DoorAction::CLOSE); + this->door_action(delta > 0 ? DoorAction::OPEN : DoorAction::CLOSE); set_timeout("move_to_position", operation_time, [=] { this->ensure_door_action(DoorAction::STOP); }); @@ -469,32 +516,6 @@ namespace ratgdo { } } - void RATGDOComponent::ensure_door_action(DoorAction action, uint32_t delay) - { - if (action == DoorAction::TOGGLE) { - ESP_LOGW(TAG, "It's not recommended to use ensure_door_action with non-idempotent commands such as DOOR_TOGGLE"); - } - auto prev_door_state = *this->door_state; - this->door_state_received.then([=](DoorState s) { - if ((action == DoorAction::STOP) && (s != DoorState::STOPPED) && !(prev_door_state == DoorState::OPENING && s == DoorState::OPEN) && !(prev_door_state == DoorState::CLOSING && s == DoorState::CLOSED)) { - return; - } - if (action == DoorAction::OPEN && !(s == DoorState::OPENING || s == DoorState::OPEN)) { - return; - } - if (action == DoorAction::CLOSE && !(s == DoorState::CLOSED || s == DoorState::CLOSING)) { - return; - } - - ESP_LOG1(TAG, "Received door status, cancel door command retry"); - cancel_timeout("door_command_retry"); - }); - this->protocol_->door_action(action); - ESP_LOG1(TAG, "Ensure door command, setup door command retry"); - set_timeout("door_command_retry", delay, [=]() { - this->ensure_door_action(action); - }); - } void RATGDOComponent::light_on() { @@ -508,12 +529,17 @@ namespace ratgdo { this->protocol_->light_action(LightAction::OFF); } - void RATGDOComponent::toggle_light() + void RATGDOComponent::light_toggle() { this->light_state = light_state_toggle(*this->light_state); this->protocol_->light_action(LightAction::TOGGLE); } + LightState RATGDOComponent::get_light_state() const + { + return *this->light_state; + } + // Lock functions void RATGDOComponent::lock() { @@ -527,17 +553,12 @@ namespace ratgdo { this->protocol_->lock_action(LockAction::UNLOCK); } - void RATGDOComponent::toggle_lock() + void RATGDOComponent::lock_toggle() { this->lock_state = lock_state_toggle(*this->lock_state); this->protocol_->lock_action(LockAction::TOGGLE); } - LightState RATGDOComponent::get_light_state() const - { - return *this->light_state; - } - // Learn functions void RATGDOComponent::activate_learn() { diff --git a/components/ratgdo/ratgdo.h b/components/ratgdo/ratgdo.h index 92fe116..41f0cbe 100644 --- a/components/ratgdo/ratgdo.h +++ b/components/ratgdo/ratgdo.h @@ -108,11 +108,13 @@ namespace ratgdo { void received(const PairedDeviceCount pdc); // door + void door_toggle(); + void door_open(); + void door_close(); + void door_stop(); + + void door_action(DoorAction action); void ensure_door_action(DoorAction action, uint32_t delay = 1500); - void toggle_door(); - void open_door(); - void close_door(); - void stop_door(); void door_move_to_position(float position); void set_door_position(float door_position) { this->door_position = door_position; } void set_opening_duration(float duration); @@ -121,14 +123,15 @@ namespace ratgdo { void door_position_update(); void cancel_position_sync_callbacks(); + // light - void toggle_light(); + void light_toggle(); void light_on(); void light_off(); LightState get_light_state() const; // lock - void toggle_lock(); + void lock_toggle(); void lock(); void unlock();