From 3cf299680650478abdf0b762eb2720cc396cd461 Mon Sep 17 00:00:00 2001 From: Marius Muja Date: Tue, 26 Dec 2023 01:18:49 -0800 Subject: [PATCH] Added enum for paired device types and improved initial sync for paired devices. --- base.yaml | 12 +-- components/ratgdo/ratgdo.cpp | 100 ++++++++++++++------- components/ratgdo/ratgdo.h | 14 +-- components/ratgdo/ratgdo_state.h | 8 ++ components/ratgdo/switch/ratgdo_switch.cpp | 12 +-- components/ratgdo/switch/ratgdo_switch.h | 1 - 6 files changed, 91 insertions(+), 56 deletions(-) diff --git a/base.yaml b/base.yaml index 0e3d07c..82f2265 100644 --- a/base.yaml +++ b/base.yaml @@ -30,15 +30,15 @@ api: then: - lambda: !lambda |- if(devices_to_wipe.compare("all") == 0) { - id($id_prefix).clear_paired_devices(0); + id($id_prefix).clear_paired_devices(ratgdo::PairedDevice::ALL); } else if (devices_to_wipe.compare("remote") == 0) { - id($id_prefix).clear_paired_devices(1); + id($id_prefix).clear_paired_devices(ratgdo::PairedDevice::REMOTE); } else if (devices_to_wipe.compare("keypad") == 0) { - id($id_prefix).clear_paired_devices(2); + id($id_prefix).clear_paired_devices(ratgdo::PairedDevice::KEYPAD); } else if (devices_to_wipe.compare("wall") == 0) { - id($id_prefix).clear_paired_devices(3); + id($id_prefix).clear_paired_devices(ratgdo::PairedDevice::WALL_CONTROL); } else if (devices_to_wipe.compare("accessory") == 0) { - id($id_prefix).clear_paired_devices(4); + id($id_prefix).clear_paired_devices(ratgdo::PairedDevice::ACCESSORY); } sensor: @@ -121,7 +121,7 @@ switch: ratgdo_id: ${id_prefix} name: "Learn" icon: mdi:plus-box - entity_category: diagnostic + entity_category: config binary_sensor: - platform: ratgdo diff --git a/components/ratgdo/ratgdo.cpp b/components/ratgdo/ratgdo.cpp index 3d81554..8d765f6 100644 --- a/components/ratgdo/ratgdo.cpp +++ b/components/ratgdo/ratgdo.cpp @@ -194,14 +194,18 @@ namespace ratgdo { this->motion_state = MotionState::CLEAR; // when the status message is read, reset motion state to 0|clear this->motor_state = MotorState::OFF; // when the status message is read, reset motor state to 0|off - if (*this->learn_state != static_cast((byte2 >> 5) & 1)) { - this->learn_state = static_cast((byte2 >> 5) & 1); - if (*this->learn_state == LearnState::ACTIVE && this->learn_poll_status_) { + auto learn_state = static_cast((byte2 >> 5) & 1); + if (*this->learn_state != learn_state) { + if (learn_state == LearnState::ACTIVE && this->learn_poll_status_) { set_interval("learn_poll", 1000, [=] { this->send_command(Command::GET_STATUS); }); } else { cancel_interval("learn_poll"); - learn_poll_status_ = true; + this->learn_poll_status_ = true; } + if (learn_state == LearnState::INACTIVE) { + this->query_paired_devices(); + } + this->learn_state = learn_state; } if (this->obstruction_from_status_) { @@ -269,15 +273,15 @@ namespace ratgdo { learn_poll_status_ = false; } } else if (cmd == Command::PAIRED_DEVICES) { - if (nibble == 0x0) { + if (nibble == static_cast(PairedDevice::ALL)) { this->paired_total = byte2; - } else if (nibble == 0x1) { + } else if (nibble == static_cast(PairedDevice::REMOTE)) { this->paired_remotes = byte2; - } else if (nibble == 0x2) { + } else if (nibble == static_cast(PairedDevice::KEYPAD)) { this->paired_keypads = byte2; - } else if (nibble == 0x3) { + } else if (nibble == static_cast(PairedDevice::WALL_CONTROL)) { this->paired_wall_controls = byte2; - } else if (nibble == 0x4) { + } else if (nibble == static_cast(PairedDevice::ACCESSORY)) { this->paired_accessories = byte2; } } @@ -486,31 +490,44 @@ namespace ratgdo { void RATGDOComponent::query_paired_devices() { - ESP_LOGD(TAG, "start query_paired_devices"); - set_timeout(200, [=] { this->send_command(Command::GET_PAIRED_DEVICES, 0); }); // total - set_timeout(400, [=] { this->send_command(Command::GET_PAIRED_DEVICES, 1); }); // wireless - set_timeout(600, [=] { this->send_command(Command::GET_PAIRED_DEVICES, 2); }); // keypads - set_timeout(800, [=] { this->send_command(Command::GET_PAIRED_DEVICES, 3); }); // wall controls - set_timeout(1000, [=] { this->send_command(Command::GET_PAIRED_DEVICES, 4); }); // accessories + const auto kinds = { + PairedDevice::ALL, + PairedDevice::REMOTE, + PairedDevice::KEYPAD, + PairedDevice::WALL_CONTROL, + PairedDevice::ACCESSORY + }; + uint32_t timeout = 0; + for (auto kind : kinds) { + timeout += 200; + set_timeout(timeout, [=] { this->query_paired_devices(kind); }); + } + } + + void RATGDOComponent::query_paired_devices(PairedDevice kind) + { + ESP_LOGD(TAG, "Query paired devices of type: %s", PairedDevice_to_string(kind)); + this->send_command(Command::GET_PAIRED_DEVICES, static_cast(kind)); } // wipe devices from memory based on get paired devices nibble values - void RATGDOComponent::clear_paired_devices(uint16_t wipe) + void RATGDOComponent::clear_paired_devices(PairedDevice kind) { - if (wipe < 5) { - ESP_LOGW(TAG, "clear_paired_devices: %d", wipe); - if (wipe == 0) { - set_timeout(200, [=] { this->send_command(Command::CLEAR_PAIRED_DEVICES, 0); }); // wireless - set_timeout(400, [=] { this->send_command(Command::CLEAR_PAIRED_DEVICES, 1); }); // keypads - set_timeout(600, [=] { this->send_command(Command::CLEAR_PAIRED_DEVICES, 2); }); // wall controls - set_timeout(800, [=] { this->send_command(Command::CLEAR_PAIRED_DEVICES, 3); }); // accessories - set_timeout(1000, [=] { this->query_status(); }); - set_timeout(1200, [=] { this->query_paired_devices(); }); - } else { - this->send_command(Command::CLEAR_PAIRED_DEVICES, wipe - 1); // just requested device - set_timeout(200, [=] { this->query_status(); }); - set_timeout(400, [=] { this->query_paired_devices(); }); - } + if (kind == PairedDevice::UNKNOWN) { + return; + } + ESP_LOGW(TAG, "Clear paired devices of type: %s", PairedDevice_to_string(kind)); + if (kind == PairedDevice::ALL) { + set_timeout(200, [=] { this->send_command(Command::CLEAR_PAIRED_DEVICES, static_cast(PairedDevice::REMOTE)-1); }); // wireless + set_timeout(400, [=] { this->send_command(Command::CLEAR_PAIRED_DEVICES, static_cast(PairedDevice::KEYPAD)-1); }); // keypads + set_timeout(600, [=] { this->send_command(Command::CLEAR_PAIRED_DEVICES, static_cast(PairedDevice::WALL_CONTROL)-1); }); // wall controls + set_timeout(800, [=] { this->send_command(Command::CLEAR_PAIRED_DEVICES, static_cast(PairedDevice::ACCESSORY)-1); }); // accessories + set_timeout(1000, [=] { this->query_status(); }); + set_timeout(1200, [=] { this->query_paired_devices(); }); + } else { + this->send_command(Command::CLEAR_PAIRED_DEVICES, static_cast(kind) - 1); // just requested device + set_timeout(200, [=] { this->query_status(); }); + set_timeout(400, [=] { this->query_paired_devices(kind); }); } } @@ -588,7 +605,26 @@ namespace ratgdo { this->send_command(Command::GET_OPENINGS); return RetryResult::RETRY; } - query_paired_devices(); + if (*this->paired_total == PAIRED_DEVICES_UNKNOWN) { + this->query_paired_devices(PairedDevice::ALL); + return RetryResult::RETRY; + } + if (*this->paired_remotes == PAIRED_DEVICES_UNKNOWN) { + this->query_paired_devices(PairedDevice::REMOTE); + return RetryResult::RETRY; + } + if (*this->paired_keypads == PAIRED_DEVICES_UNKNOWN) { + this->query_paired_devices(PairedDevice::KEYPAD); + return RetryResult::RETRY; + } + if (*this->paired_wall_controls == PAIRED_DEVICES_UNKNOWN) { + this->query_paired_devices(PairedDevice::WALL_CONTROL); + return RetryResult::RETRY; + } + if (*this->paired_accessories == PAIRED_DEVICES_UNKNOWN) { + this->query_paired_devices(PairedDevice::ACCESSORY); + return RetryResult::RETRY; + } return RetryResult::DONE; }; @@ -789,7 +825,7 @@ namespace ratgdo { void RATGDOComponent::activate_learn() { // Send LEARN with nibble = 0 then nibble = 1 to mimic wall control learn button - learn_poll_status_ = true; + this->learn_poll_status_ = true; this->send_command(Command::LEARN, 0); set_timeout(150, [=] { this->send_command(Command::LEARN, 1); }); set_timeout(500, [=] { this->send_command(Command::GET_STATUS); }); diff --git a/components/ratgdo/ratgdo.h b/components/ratgdo/ratgdo.h index 3934b5d..4752b65 100644 --- a/components/ratgdo/ratgdo.h +++ b/components/ratgdo/ratgdo.h @@ -38,6 +38,7 @@ namespace ratgdo { const float DOOR_POSITION_UNKNOWN = -1.0; const float DOOR_DELTA_UNKNOWN = -2.0; + const uint16_t PAIRED_DEVICES_UNKNOWN = 0xFF; namespace data { const uint32_t LIGHT_OFF = 0; @@ -114,11 +115,11 @@ namespace ratgdo { observable closing_duration { 0 }; observable openings { 0 }; // number of times the door has been opened - observable paired_total { 0xFF }; - observable paired_remotes { 0xFF }; - observable paired_keypads { 0xFF }; - observable paired_wall_controls { 0xFF }; - observable paired_accessories { 0xFF }; + observable paired_total { PAIRED_DEVICES_UNKNOWN }; + observable paired_remotes { PAIRED_DEVICES_UNKNOWN }; + observable paired_keypads { PAIRED_DEVICES_UNKNOWN }; + observable paired_wall_controls { PAIRED_DEVICES_UNKNOWN }; + observable paired_accessories { PAIRED_DEVICES_UNKNOWN }; observable door_state { DoorState::UNKNOWN }; observable door_position { DOOR_POSITION_UNKNOWN }; @@ -187,7 +188,8 @@ namespace ratgdo { void activate_learn(); void inactivate_learn(); void query_paired_devices(); - void clear_paired_devices(uint16_t wipe); + void query_paired_devices(PairedDevice kind); + void clear_paired_devices(PairedDevice kind); // button functionality void query_status(); diff --git a/components/ratgdo/ratgdo_state.h b/components/ratgdo/ratgdo_state.h index e994045..891e270 100644 --- a/components/ratgdo/ratgdo_state.h +++ b/components/ratgdo/ratgdo_state.h @@ -71,5 +71,13 @@ namespace ratgdo { (UNKNOWN, 2)) LearnState learn_state_toggle(LearnState state); + ENUM(PairedDevice, uint8_t, + (ALL, 0), + (REMOTE, 1), + (KEYPAD, 2), + (WALL_CONTROL, 3), + (ACCESSORY, 4), + (UNKNOWN, 0xff)) + } // namespace ratgdo } // namespace esphome diff --git a/components/ratgdo/switch/ratgdo_switch.cpp b/components/ratgdo/switch/ratgdo_switch.cpp index 9872e65..0c20af7 100644 --- a/components/ratgdo/switch/ratgdo_switch.cpp +++ b/components/ratgdo/switch/ratgdo_switch.cpp @@ -19,21 +19,11 @@ namespace ratgdo { { if (this->switch_type_ == SwitchType::RATGDO_LEARN) { this->parent_->subscribe_learn_state([=](LearnState state) { - this->on_learn_state(state); + this->publish_state(state==LearnState::ACTIVE); }); } } - void RATGDOSwitch::on_learn_state(LearnState state) - { - bool value = state == LearnState::ACTIVE; - this->state = value; - this->publish_state(value); - if (value == false) { - this->parent_->query_paired_devices(); - } - } - void RATGDOSwitch::write_state(bool state) { if (this->switch_type_ == SwitchType::RATGDO_LEARN) { diff --git a/components/ratgdo/switch/ratgdo_switch.h b/components/ratgdo/switch/ratgdo_switch.h index 42ef1d4..3640bec 100644 --- a/components/ratgdo/switch/ratgdo_switch.h +++ b/components/ratgdo/switch/ratgdo_switch.h @@ -18,7 +18,6 @@ namespace ratgdo { void setup() override; void set_switch_type(SwitchType switch_type_) { this->switch_type_ = switch_type_; } - void on_learn_state(LearnState state); void write_state(bool state) override; protected: