From 4c2ed4e7c09abe224ad03cb199efa94a3bd016d7 Mon Sep 17 00:00:00 2001 From: mulcmu Date: Thu, 18 Jan 2024 17:25:08 -0500 Subject: [PATCH] feat: add learn and clear capability (#149) Co-authored-by: Marius Muja Co-authored-by: J. Nick Koston --- base.yaml | 32 +++++ components/ratgdo/ratgdo.cpp | 130 ++++++++++++++++++++- components/ratgdo/ratgdo.h | 26 ++++- components/ratgdo/ratgdo_state.cpp | 14 +++ components/ratgdo/ratgdo_state.h | 15 +++ components/ratgdo/sensor/__init__.py | 6 + components/ratgdo/sensor/ratgdo_sensor.cpp | 50 ++++++-- components/ratgdo/sensor/ratgdo_sensor.h | 7 +- components/ratgdo/switch/__init__.py | 35 ++++++ components/ratgdo/switch/ratgdo_switch.cpp | 39 +++++++ components/ratgdo/switch/ratgdo_switch.h | 28 +++++ 11 files changed, 370 insertions(+), 12 deletions(-) create mode 100644 components/ratgdo/switch/__init__.py create mode 100644 components/ratgdo/switch/ratgdo_switch.cpp create mode 100644 components/ratgdo/switch/ratgdo_switch.h diff --git a/base.yaml b/base.yaml index 68e8977..d73687a 100644 --- a/base.yaml +++ b/base.yaml @@ -22,6 +22,24 @@ ratgdo: title: "${friendly_name} sync failed" message: "Failed to communicate with garage opener on startup; Check the ${friendly_name} Rolling code counter number entity history and set the entity to one number larger than the largest value in history. [ESPHome devices](/config/devices/dashboard?domain=esphome)" notification_id: "esphome_ratgdo_${id_prefix}_sync_failed" +api: + services: + - service: wipe_devices_from_gdo_memory + variables: + devices_to_wipe: string + then: + - lambda: !lambda |- + if(devices_to_wipe.compare("all") == 0) { + id($id_prefix).clear_paired_devices(ratgdo::PairedDevice::ALL); + } else if (devices_to_wipe.compare("remote") == 0) { + id($id_prefix).clear_paired_devices(ratgdo::PairedDevice::REMOTE); + } else if (devices_to_wipe.compare("keypad") == 0) { + id($id_prefix).clear_paired_devices(ratgdo::PairedDevice::KEYPAD); + } else if (devices_to_wipe.compare("wall") == 0) { + id($id_prefix).clear_paired_devices(ratgdo::PairedDevice::WALL_CONTROL); + } else if (devices_to_wipe.compare("accessory") == 0) { + id($id_prefix).clear_paired_devices(ratgdo::PairedDevice::ACCESSORY); + } sensor: - platform: ratgdo @@ -32,6 +50,13 @@ sensor: name: "Openings" unit_of_measurement: "openings" icon: mdi:open-in-app + - platform: ratgdo + id: ${id_prefix}_paired_devices_total + type: paired_devices_total + entity_category: diagnostic + ratgdo_id: ${id_prefix} + name: "Paired Devices" + icon: mdi:remote lock: - platform: ratgdo @@ -58,6 +83,13 @@ switch: output: true name: "Status obstruction" entity_category: diagnostic + - platform: ratgdo + id: "${id_prefix}_learn" + type: learn + ratgdo_id: ${id_prefix} + name: "Learn" + icon: mdi:plus-box + entity_category: config binary_sensor: - platform: ratgdo diff --git a/components/ratgdo/ratgdo.cpp b/components/ratgdo/ratgdo.cpp index 21b97ca..d43ec74 100644 --- a/components/ratgdo/ratgdo.cpp +++ b/components/ratgdo/ratgdo.cpp @@ -194,6 +194,14 @@ 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 + auto learn_state = static_cast((byte2 >> 5) & 1); + if (*this->learn_state != learn_state) { + if (learn_state == LearnState::INACTIVE) { + this->query_paired_devices(); + } + this->learn_state = learn_state; + } + if (this->obstruction_from_status_) { // ESP_LOGD(TAG, "Obstruction: reading from byte2, bit2, status=%d", ((byte2 >> 2) & 1) == 1); this->obstruction_state = static_cast((byte1 >> 6) & 1); @@ -207,10 +215,12 @@ namespace ratgdo { this->send_command(Command::GET_OPENINGS); } - ESP_LOGD(TAG, "Status: door=%s light=%s lock=%s", + ESP_LOGD(TAG, "Status: door=%s light=%s lock=%s learn=%s", DoorState_to_string(*this->door_state), LightState_to_string(*this->light_state), - LockState_to_string(*this->lock_state)); + LockState_to_string(*this->lock_state), + LearnState_to_string(*this->learn_state)); + } else if (cmd == Command::LIGHT) { if (nibble == 0) { this->light_state = LightState::OFF; @@ -250,6 +260,18 @@ namespace ratgdo { } else if (cmd == Command::SET_TTC) { auto seconds = (byte1 << 8) | byte2; ESP_LOGD(TAG, "Time to close (TTC): %ds", seconds); + } else if (cmd == Command::PAIRED_DEVICES) { + if (nibble == static_cast(PairedDevice::ALL)) { + this->paired_total = byte2; + } else if (nibble == static_cast(PairedDevice::REMOTE)) { + this->paired_remotes = byte2; + } else if (nibble == static_cast(PairedDevice::KEYPAD)) { + this->paired_keypads = byte2; + } else if (nibble == static_cast(PairedDevice::WALL_CONTROL)) { + this->paired_wall_controls = byte2; + } else if (nibble == static_cast(PairedDevice::ACCESSORY)) { + this->paired_accessories = byte2; + } } return cmd; @@ -454,6 +476,49 @@ namespace ratgdo { send_command(Command::GET_OPENINGS); } + void RATGDOComponent::query_paired_devices() + { + 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(PairedDevice kind) + { + 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); }); + } + } + void RATGDOComponent::send_command(Command command, uint32_t data, bool increment) { ESP_LOG1(TAG, "Send command: %s, data: %08" PRIx32, Command_to_string(command), data); @@ -528,6 +593,26 @@ namespace ratgdo { this->send_command(Command::GET_OPENINGS); return RetryResult::RETRY; } + 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; }; @@ -724,6 +809,23 @@ namespace ratgdo { return *this->light_state; } + // Learn functions + void RATGDOComponent::activate_learn() + { + // Send LEARN with nibble = 0 then nibble = 1 to mimic wall control learn button + this->send_command(Command::LEARN, 0); + set_timeout(150, [=] { this->send_command(Command::LEARN, 1); }); + set_timeout(500, [=] { this->send_command(Command::GET_STATUS); }); + } + + void RATGDOComponent::inactivate_learn() + { + // Send LEARN twice with nibble = 0 to inactivate learn and get status to update switch state + this->send_command(Command::LEARN, 0); + set_timeout(150, [=] { this->send_command(Command::LEARN, 0); }); + set_timeout(500, [=] { this->send_command(Command::GET_STATUS); }); + } + void RATGDOComponent::subscribe_rolling_code_counter(std::function&& f) { // change update to children is defered until after component loop @@ -742,6 +844,26 @@ namespace ratgdo { { this->openings.subscribe([=](uint16_t state) { defer("openings", [=] { f(state); }); }); } + void RATGDOComponent::subscribe_paired_devices_total(std::function&& f) + { + this->paired_total.subscribe([=](uint16_t state) { defer("paired_total", [=] { f(state); }); }); + } + void RATGDOComponent::subscribe_paired_remotes(std::function&& f) + { + this->paired_remotes.subscribe([=](uint16_t state) { defer("paired_remotes", [=] { f(state); }); }); + } + void RATGDOComponent::subscribe_paired_keypads(std::function&& f) + { + this->paired_keypads.subscribe([=](uint16_t state) { defer("paired_keypads", [=] { f(state); }); }); + } + void RATGDOComponent::subscribe_paired_wall_controls(std::function&& f) + { + this->paired_wall_controls.subscribe([=](uint16_t state) { defer("paired_wall_controls", [=] { f(state); }); }); + } + void RATGDOComponent::subscribe_paired_accessories(std::function&& f) + { + this->paired_accessories.subscribe([=](uint16_t state) { defer("paired_accessories", [=] { f(state); }); }); + } void RATGDOComponent::subscribe_door_state(std::function&& f) { this->door_state.subscribe([=](DoorState state) { @@ -779,6 +901,10 @@ namespace ratgdo { { this->sync_failed.subscribe(std::move(f)); } + void RATGDOComponent::subscribe_learn_state(std::function&& f) + { + this->learn_state.subscribe([=](LearnState state) { defer("learn_state", [=] { f(state); }); }); + } } // namespace ratgdo } // namespace esphome diff --git a/components/ratgdo/ratgdo.h b/components/ratgdo/ratgdo.h index 147b012..7ee555a 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; @@ -64,13 +65,17 @@ namespace ratgdo { (PAIR_3, 0x0a0), (PAIR_3_RESP, 0x0a1), - (LEARN_2, 0x181), + (LEARN, 0x181), (LOCK, 0x18c), (DOOR_ACTION, 0x280), (LIGHT, 0x281), (MOTOR_ON, 0x284), (MOTION, 0x285), + (GET_PAIRED_DEVICES, 0x307), // nibble 0 for total, 1 wireless, 2 keypads, 3 wall, 4 accessories. + (PAIRED_DEVICES, 0x308), // byte2 holds number of paired devices + (CLEAR_PAIRED_DEVICES, 0x30D), // nibble 0 to clear remotes, 1 keypads, 2 wall, 3 accessories (offset from above) + (LEARN_1, 0x391), (PING, 0x392), (PING_RESP, 0x393), @@ -110,6 +115,11 @@ namespace ratgdo { observable closing_duration { 0 }; observable openings { 0 }; // number of times the door has been opened + 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 }; @@ -124,6 +134,7 @@ namespace ratgdo { observable motor_state { MotorState::UNKNOWN }; observable button_state { ButtonState::UNKNOWN }; observable motion_state { MotionState::UNKNOWN }; + observable learn_state { LearnState::UNKNOWN }; OnceCallbacks door_state_received; OnceCallbacks command_sent; @@ -173,6 +184,13 @@ namespace ratgdo { void lock(); void unlock(); + // Learn & Paired + void activate_learn(); + void inactivate_learn(); + void query_paired_devices(); + void query_paired_devices(PairedDevice kind); + void clear_paired_devices(PairedDevice kind); + // button functionality void query_status(); void query_openings(); @@ -183,6 +201,11 @@ namespace ratgdo { void subscribe_opening_duration(std::function&& f); void subscribe_closing_duration(std::function&& f); void subscribe_openings(std::function&& f); + void subscribe_paired_devices_total(std::function&& f); + void subscribe_paired_remotes(std::function&& f); + void subscribe_paired_keypads(std::function&& f); + void subscribe_paired_wall_controls(std::function&& f); + void subscribe_paired_accessories(std::function&& f); void subscribe_door_state(std::function&& f); void subscribe_light_state(std::function&& f); void subscribe_lock_state(std::function&& f); @@ -191,6 +214,7 @@ namespace ratgdo { void subscribe_button_state(std::function&& f); void subscribe_motion_state(std::function&& f); void subscribe_sync_failed(std::function&& f); + void subscribe_learn_state(std::function&& f); protected: // tx data diff --git a/components/ratgdo/ratgdo_state.cpp b/components/ratgdo/ratgdo_state.cpp index 2a6ba40..f5b2054 100644 --- a/components/ratgdo/ratgdo_state.cpp +++ b/components/ratgdo/ratgdo_state.cpp @@ -31,5 +31,19 @@ namespace ratgdo { } } + LearnState learn_state_toggle(LearnState state) + { + switch (state) { + case LearnState::ACTIVE: + return LearnState::INACTIVE; + case LearnState::INACTIVE: + return LearnState::ACTIVE; + // 2 and 3 appears sometimes + case LearnState::UNKNOWN: + default: + return LearnState::UNKNOWN; + } + } + } // namespace ratgdo } // namespace esphome diff --git a/components/ratgdo/ratgdo_state.h b/components/ratgdo/ratgdo_state.h index e347279..891e270 100644 --- a/components/ratgdo/ratgdo_state.h +++ b/components/ratgdo/ratgdo_state.h @@ -64,5 +64,20 @@ namespace ratgdo { (RELEASED, 1), (UNKNOWN, 2)) + /// Enum for learn states. + ENUM(LearnState, uint8_t, + (INACTIVE, 0), + (ACTIVE, 1), + (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/sensor/__init__.py b/components/ratgdo/sensor/__init__.py index 981c16f..a2f9758 100644 --- a/components/ratgdo/sensor/__init__.py +++ b/components/ratgdo/sensor/__init__.py @@ -13,6 +13,11 @@ RATGDOSensorType = ratgdo_ns.enum("RATGDOSensorType") CONF_TYPE = "type" TYPES = { "openings": RATGDOSensorType.RATGDO_OPENINGS, + "paired_devices_total": RATGDOSensorType.RATGDO_PAIRED_DEVICES_TOTAL, + "paired_devices_remotes": RATGDOSensorType.RATGDO_PAIRED_REMOTES, + "paired_devices_keypads": RATGDOSensorType.RATGDO_PAIRED_KEYPADS, + "paired_devices_wall_controls": RATGDOSensorType.RATGDO_PAIRED_WALL_CONTROLS, + "paired_devices_accessories": RATGDOSensorType.RATGDO_PAIRED_ACCESSORIES, } @@ -33,3 +38,4 @@ async def to_code(config): await cg.register_component(var, config) cg.add(var.set_ratgdo_sensor_type(config[CONF_TYPE])) await register_ratgdo_child(var, config) + diff --git a/components/ratgdo/sensor/ratgdo_sensor.cpp b/components/ratgdo/sensor/ratgdo_sensor.cpp index c2312b9..e28290a 100644 --- a/components/ratgdo/sensor/ratgdo_sensor.cpp +++ b/components/ratgdo/sensor/ratgdo_sensor.cpp @@ -7,17 +7,51 @@ namespace ratgdo { static const char* const TAG = "ratgdo.sensor"; + void RATGDOSensor::setup() + { + if (this->ratgdo_sensor_type_ == RATGDOSensorType::RATGDO_OPENINGS) { + this->parent_->subscribe_openings([=](uint16_t value) { + this->publish_state(value); + }); + } else if (this->ratgdo_sensor_type_ == RATGDOSensorType::RATGDO_PAIRED_DEVICES_TOTAL) { + this->parent_->subscribe_paired_devices_total([=](uint16_t value) { + this->publish_state(value); + }); + } else if (this->ratgdo_sensor_type_ == RATGDOSensorType::RATGDO_PAIRED_REMOTES) { + this->parent_->subscribe_paired_remotes([=](uint16_t value) { + this->publish_state(value); + }); + } else if (this->ratgdo_sensor_type_ == RATGDOSensorType::RATGDO_PAIRED_KEYPADS) { + this->parent_->subscribe_paired_keypads([=](uint16_t value) { + this->publish_state(value); + }); + } else if (this->ratgdo_sensor_type_ == RATGDOSensorType::RATGDO_PAIRED_WALL_CONTROLS) { + this->parent_->subscribe_paired_wall_controls([=](uint16_t value) { + this->publish_state(value); + }); + } else if (this->ratgdo_sensor_type_ == RATGDOSensorType::RATGDO_PAIRED_ACCESSORIES) { + this->parent_->subscribe_paired_accessories([=](uint16_t value) { + this->publish_state(value); + }); + } + } + void RATGDOSensor::dump_config() { LOG_SENSOR("", "RATGDO Sensor", this); - ESP_LOGCONFIG(TAG, " Type: Openings"); - } - - void RATGDOSensor::setup() - { - this->parent_->subscribe_openings([=](uint16_t value) { - this->publish_state(value); - }); + if (this->ratgdo_sensor_type_ == RATGDOSensorType::RATGDO_OPENINGS) { + ESP_LOGCONFIG(TAG, " Type: Openings"); + } else if (this->ratgdo_sensor_type_ == RATGDOSensorType::RATGDO_PAIRED_DEVICES_TOTAL) { + ESP_LOGCONFIG(TAG, " Type: Paired Devices"); + } else if (this->ratgdo_sensor_type_ == RATGDOSensorType::RATGDO_PAIRED_REMOTES) { + ESP_LOGCONFIG(TAG, " Type: Paired Remotes"); + } else if (this->ratgdo_sensor_type_ == RATGDOSensorType::RATGDO_PAIRED_KEYPADS) { + ESP_LOGCONFIG(TAG, " Type: Paired Keypads"); + } else if (this->ratgdo_sensor_type_ == RATGDOSensorType::RATGDO_PAIRED_WALL_CONTROLS) { + ESP_LOGCONFIG(TAG, " Type: Paired Wall Controls"); + } else if (this->ratgdo_sensor_type_ == RATGDOSensorType::RATGDO_PAIRED_ACCESSORIES) { + ESP_LOGCONFIG(TAG, " Type: Paired Accessories"); + } } } // namespace ratgdo diff --git a/components/ratgdo/sensor/ratgdo_sensor.h b/components/ratgdo/sensor/ratgdo_sensor.h index 26f2618..3a3517c 100644 --- a/components/ratgdo/sensor/ratgdo_sensor.h +++ b/components/ratgdo/sensor/ratgdo_sensor.h @@ -9,7 +9,12 @@ namespace esphome { namespace ratgdo { enum RATGDOSensorType { - RATGDO_OPENINGS + RATGDO_OPENINGS, + RATGDO_PAIRED_DEVICES_TOTAL, + RATGDO_PAIRED_REMOTES, + RATGDO_PAIRED_KEYPADS, + RATGDO_PAIRED_WALL_CONTROLS, + RATGDO_PAIRED_ACCESSORIES }; class RATGDOSensor : public sensor::Sensor, public RATGDOClient, public Component { diff --git a/components/ratgdo/switch/__init__.py b/components/ratgdo/switch/__init__.py new file mode 100644 index 0000000..9028cca --- /dev/null +++ b/components/ratgdo/switch/__init__.py @@ -0,0 +1,35 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import switch +from esphome.const import CONF_ID + +from .. import RATGDO_CLIENT_SCHMEA, ratgdo_ns, register_ratgdo_child + +DEPENDENCIES = ["ratgdo"] + +RATGDOSwitch = ratgdo_ns.class_("RATGDOSwitch", switch.Switch, cg.Component) +SwitchType = ratgdo_ns.enum("SwitchType") + +CONF_TYPE = "type" +TYPES = { + "learn": SwitchType.RATGDO_LEARN, +} + + +CONFIG_SCHEMA = ( + switch.switch_schema(RATGDOSwitch) + .extend( + { + cv.Required(CONF_TYPE): cv.enum(TYPES, lower=True), + } + ) + .extend(RATGDO_CLIENT_SCHMEA) +) + + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await switch.register_switch(var, config) + await cg.register_component(var, config) + cg.add(var.set_switch_type(config[CONF_TYPE])) + await register_ratgdo_child(var, config) diff --git a/components/ratgdo/switch/ratgdo_switch.cpp b/components/ratgdo/switch/ratgdo_switch.cpp new file mode 100644 index 0000000..0c20af7 --- /dev/null +++ b/components/ratgdo/switch/ratgdo_switch.cpp @@ -0,0 +1,39 @@ +#include "ratgdo_switch.h" +#include "../ratgdo_state.h" +#include "esphome/core/log.h" + +namespace esphome { +namespace ratgdo { + + static const char* const TAG = "ratgdo.switch"; + + void RATGDOSwitch::dump_config() + { + LOG_SWITCH("", "RATGDO Switch", this); + if (this->switch_type_ == SwitchType::RATGDO_LEARN) { + ESP_LOGCONFIG(TAG, " Type: Learn"); + } + } + + void RATGDOSwitch::setup() + { + if (this->switch_type_ == SwitchType::RATGDO_LEARN) { + this->parent_->subscribe_learn_state([=](LearnState state) { + this->publish_state(state==LearnState::ACTIVE); + }); + } + } + + void RATGDOSwitch::write_state(bool state) + { + if (this->switch_type_ == SwitchType::RATGDO_LEARN) { + if (state) { + this->parent_->activate_learn(); + } else { + this->parent_->inactivate_learn(); + } + } + } + +} // namespace ratgdo +} // namespace esphome diff --git a/components/ratgdo/switch/ratgdo_switch.h b/components/ratgdo/switch/ratgdo_switch.h new file mode 100644 index 0000000..3640bec --- /dev/null +++ b/components/ratgdo/switch/ratgdo_switch.h @@ -0,0 +1,28 @@ +#pragma once + +#include "../ratgdo.h" +#include "../ratgdo_state.h" +#include "esphome/components/switch/switch.h" +#include "esphome/core/component.h" + +namespace esphome { +namespace ratgdo { + + enum SwitchType { + RATGDO_LEARN + }; + + class RATGDOSwitch : public switch_::Switch, public RATGDOClient, public Component { + public: + void dump_config() override; + void setup() override; + void set_switch_type(SwitchType switch_type_) { this->switch_type_ = switch_type_; } + + void write_state(bool state) override; + + protected: + SwitchType switch_type_; + }; + +} // namespace ratgdo +} // namespace esphome