add device count and clear memory

This commit is contained in:
mulcmu 2023-12-22 14:12:20 -05:00
parent 39b545124b
commit 68086fef1e
7 changed files with 196 additions and 10 deletions

View File

@ -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(0);
} else if (devices_to_wipe.compare("remote") == 0) {
id($id_prefix).clear_paired_devices(1);
} else if (devices_to_wipe.compare("keypad") == 0) {
id($id_prefix).clear_paired_devices(2);
} else if (devices_to_wipe.compare("wall") == 0) {
id($id_prefix).clear_paired_devices(3);
} else if (devices_to_wipe.compare("accessory") == 0) {
id($id_prefix).clear_paired_devices(4);
}
sensor:
- platform: ratgdo
@ -32,6 +50,45 @@ 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
- platform: ratgdo
id: ${id_prefix}_paired_devices_remotes
type: paired_devices_remotes
entity_category: diagnostic
ratgdo_id: ${id_prefix}
name: "Paired Remotes"
disabled_by_default: true
icon: mdi:remote
- platform: ratgdo
id: ${id_prefix}_paired_devices_keypads
type: paired_devices_keypads
entity_category: diagnostic
ratgdo_id: ${id_prefix}
name: "Paired Keypads"
disabled_by_default: true
icon: mdi:dialpad
- platform: ratgdo
id: ${id_prefix}_paired_devices_wall_controls
type: paired_devices_wall_controls
entity_category: diagnostic
ratgdo_id: ${id_prefix}
name: "Paired Wall Controls"
disabled_by_default: true
icon: mdi:pan-vertical
- platform: ratgdo
id: ${id_prefix}_paired_devices_accessories
type: paired_devices_accessories
entity_category: diagnostic
ratgdo_id: ${id_prefix}
name: "Paired Accessories"
disabled_by_default: true
icon: mdi:cloud-cancel-outline
lock:
- platform: ratgdo

View File

@ -264,9 +264,22 @@ namespace ratgdo {
ESP_LOGD(TAG, "Time to close (TTC): %ds", seconds);
}
if (cmd == Command::LEARN) {
if (nibble == 1) { // LEARN sent from wall control, it will poll status every second
if (nibble == 1) { // LEARN sent from wall control, it will poll status every second.
// otherwise if ratgdo or gdo initiated ratgdo needs to poll
learn_poll_status_ = false;
}
} else if (cmd == Command::PAIRED_DEVICES) {
if (nibble == 0x0) {
this->paired_total = byte2;
} else if (nibble == 0x1) {
this->paired_remotes = byte2;
} else if (nibble == 0x2) {
this->paired_keypads = byte2;
} else if (nibble == 0x3) {
this->paired_wall_controls = byte2;
} else if (nibble == 0x4) {
this->paired_accessories = byte2;
}
}
return cmd;
@ -471,6 +484,36 @@ namespace ratgdo {
send_command(Command::GET_OPENINGS);
}
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
}
// wipe devices from memory based on get paired devices nibble values
void RATGDOComponent::clear_paired_devices(uint16_t wipe)
{
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(); });
}
}
}
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);
@ -545,6 +588,7 @@ namespace ratgdo {
this->send_command(Command::GET_OPENINGS);
return RetryResult::RETRY;
}
query_paired_devices();
return RetryResult::DONE;
};
@ -777,6 +821,26 @@ namespace ratgdo {
{
this->openings.subscribe([=](uint16_t state) { defer("openings", [=] { f(state); }); });
}
void RATGDOComponent::subscribe_paired_devices_total(std::function<void(uint16_t)>&& f)
{
this->paired_total.subscribe([=](uint16_t state) { defer("paired_total", [=] { f(state); }); });
}
void RATGDOComponent::subscribe_paired_remotes(std::function<void(uint16_t)>&& f)
{
this->paired_remotes.subscribe([=](uint16_t state) { defer("paired_remotes", [=] { f(state); }); });
}
void RATGDOComponent::subscribe_paired_keypads(std::function<void(uint16_t)>&& f)
{
this->paired_keypads.subscribe([=](uint16_t state) { defer("paired_keypads", [=] { f(state); }); });
}
void RATGDOComponent::subscribe_paired_wall_controls(std::function<void(uint16_t)>&& f)
{
this->paired_wall_controls.subscribe([=](uint16_t state) { defer("paired_wall_controls", [=] { f(state); }); });
}
void RATGDOComponent::subscribe_paired_accessories(std::function<void(uint16_t)>&& f)
{
this->paired_accessories.subscribe([=](uint16_t state) { defer("paired_accessories", [=] { f(state); }); });
}
void RATGDOComponent::subscribe_door_state(std::function<void(DoorState, float)>&& f)
{
this->door_state.subscribe([=](DoorState state) {

View File

@ -71,6 +71,10 @@ namespace ratgdo {
(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 +114,11 @@ namespace ratgdo {
observable<float> closing_duration { 0 };
observable<uint16_t> openings { 0 }; // number of times the door has been opened
observable<uint16_t> paired_total { 0xFF };
observable<uint16_t> paired_remotes { 0xFF };
observable<uint16_t> paired_keypads { 0xFF };
observable<uint16_t> paired_wall_controls { 0xFF };
observable<uint16_t> paired_accessories { 0xFF };
observable<DoorState> door_state { DoorState::UNKNOWN };
observable<float> door_position { DOOR_POSITION_UNKNOWN };
@ -174,8 +183,11 @@ namespace ratgdo {
void lock();
void unlock();
// Learn & Paired
void activate_learn();
void inactivate_learn();
void query_paired_devices();
void clear_paired_devices(uint16_t wipe);
// button functionality
void query_status();
@ -187,6 +199,11 @@ namespace ratgdo {
void subscribe_opening_duration(std::function<void(float)>&& f);
void subscribe_closing_duration(std::function<void(float)>&& f);
void subscribe_openings(std::function<void(uint16_t)>&& f);
void subscribe_paired_devices_total(std::function<void(uint16_t)>&& f);
void subscribe_paired_remotes(std::function<void(uint16_t)>&& f);
void subscribe_paired_keypads(std::function<void(uint16_t)>&& f);
void subscribe_paired_wall_controls(std::function<void(uint16_t)>&& f);
void subscribe_paired_accessories(std::function<void(uint16_t)>&& f);
void subscribe_door_state(std::function<void(DoorState, float)>&& f);
void subscribe_light_state(std::function<void(LightState)>&& f);
void subscribe_lock_state(std::function<void(LockState)>&& f);

View File

@ -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)

View File

@ -7,17 +7,51 @@ namespace ratgdo {
static const char* const TAG = "ratgdo.sensor";
void RATGDOSensor::dump_config()
{
LOG_SENSOR("", "RATGDO Sensor", this);
ESP_LOGCONFIG(TAG, " Type: Openings");
}
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);
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

View File

@ -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 {

View File

@ -29,6 +29,9 @@ namespace ratgdo {
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)