diff --git a/components/ratgdo/__init__.py b/components/ratgdo/__init__.py index 6b52ddc..15154c7 100644 --- a/components/ratgdo/__init__.py +++ b/components/ratgdo/__init__.py @@ -3,6 +3,7 @@ import esphome.config_validation as cv import voluptuous as vol from esphome import automation, pins from esphome.const import CONF_ID, CONF_TRIGGER_ID +from esphome.components import binary_sensor DEPENDENCIES = ["preferences"] MULTI_CONF = True @@ -36,6 +37,9 @@ PROTOCOL_SECPLUSV2 = "secplusv2" PROTOCOL_DRYCONTACT = "drycontact" SUPPORTED_PROTOCOLS = [PROTOCOL_SECPLUSV1, PROTOCOL_SECPLUSV2, PROTOCOL_DRYCONTACT] +DOOR_CLOSED = "door_closed" +DOOR_OPEN = "door_open" + CONFIG_SCHEMA = cv.Schema( { cv.GenerateID(): cv.declare_id(RATGDO), @@ -56,6 +60,12 @@ CONFIG_SCHEMA = cv.Schema( cv.Optional(CONF_PROTOCOL, default=PROTOCOL_SECPLUSV2): vol.In( SUPPORTED_PROTOCOLS ), + cv.Optional(DOOR_CLOSED): cv.Any( + cv.none, cv.use_id(binary_sensor.BinarySensor) + ), + cv.Optional(DOOR_OPEN): cv.Any( + cv.none, cv.use_id(binary_sensor.BinarySensor) + ), } ).extend(cv.COMPONENT_SCHEMA) @@ -104,3 +114,10 @@ async def to_code(config): elif config[CONF_PROTOCOL] == PROTOCOL_DRYCONTACT: cg.add_define("PROTOCOL_DRYCONTACT") cg.add(var.init_protocol()) + if DOOR_CLOSED in config and config[DOOR_CLOSED] is not None: + door_closed = await cg.get_variable(config[DOOR_CLOSED]) + cg.add(var.set_door_closed_sensor(door_closed)) + if DOOR_OPEN in config and config[DOOR_OPEN] is not None: + door_open = await cg.get_variable(config[DOOR_OPEN]) + cg.add(var.set_door_open_sensor(door_open)) + diff --git a/components/ratgdo/common.h b/components/ratgdo/common.h index 1926c22..8f4d225 100644 --- a/components/ratgdo/common.h +++ b/components/ratgdo/common.h @@ -1,4 +1,4 @@ #pragma once #define ESP_LOG1 ESP_LOGD -#define ESP_LOG2 ESP_LOGD \ No newline at end of file +#define ESP_LOG2 ESP_LOGD diff --git a/components/ratgdo/ratgdo.cpp b/components/ratgdo/ratgdo.cpp index 8b35690..f476710 100644 --- a/components/ratgdo/ratgdo.cpp +++ b/components/ratgdo/ratgdo.cpp @@ -21,6 +21,7 @@ #include "esphome/core/application.h" #include "esphome/core/gpio.h" #include "esphome/core/log.h" +#include "esphome/components/binary_sensor/binary_sensor.h" namespace esphome { namespace ratgdo { @@ -48,6 +49,43 @@ namespace ratgdo { this->input_obst_pin_->attach_interrupt(RATGDOStore::isr_obstruction, &this->isr_store_, gpio::INTERRUPT_FALLING_EDGE); } + if (this->door_open_sensor_ != nullptr) { + this->door_open_sensor_->add_on_state_callback([=](bool state) { + ESP_LOGD(TAG, "Door open sensor: %d", state); + if (state) { + // this->sensor_door_state_ = DoorState::OPEN; + this->received(DoorState::OPEN); + } else { + this->received(DoorState::CLOSING); + if (*this->closing_duration != 0 && this->door_closed_sensor_ != nullptr) { + this->set_timeout((*this->closing_duration +1)*1000, [=] { + if (!this->door_closed_sensor_->state) { + this->received(DoorState::STOPPED); + } + }); + } + } + }); + } + if (this->door_closed_sensor_ != nullptr) { + this->door_closed_sensor_->add_on_state_callback([=](bool state) { + ESP_LOGD(TAG, "Door closed sensor: %d", state); + if (state) { + // this->sensor_door_state_ = DoorState::OPEN; + this->received(DoorState::CLOSED); + } else { + this->received(DoorState::OPENING); + if (*this->opening_duration != 0 && this->door_open_sensor_ != nullptr) { + this->set_timeout((*this->opening_duration + 1)*1000, [=] { + if (!this->door_open_sensor_->state) { + this->received(DoorState::STOPPED); + } + }); + } + } + }); + } + this->protocol_->setup(this, &App.scheduler, this->input_gdo_pin_, this->output_gdo_pin_); // many things happening at startup, use some delay for sync @@ -304,7 +342,7 @@ namespace ratgdo { { ESP_LOG1(TAG, "Schedule position sync: delta %f, start position: %f, start moving: %d", this->door_move_delta, this->door_start_position, this->door_start_moving); - auto duration = this->door_move_delta > 0 ? *this->opening_duration : *this->closing_duration; + auto duration = this->door_move_delta * (this->door_move_delta > 0 ? *this->opening_duration : *this->closing_duration); if (duration == 0) { return; } diff --git a/components/ratgdo/ratgdo.h b/components/ratgdo/ratgdo.h index 510f636..205e45f 100644 --- a/components/ratgdo/ratgdo.h +++ b/components/ratgdo/ratgdo.h @@ -25,6 +25,9 @@ namespace esphome { class InternalGPIOPin; +namespace binary_sensor { +class BinarySensor; +} namespace ratgdo { class RATGDOComponent; @@ -91,6 +94,9 @@ namespace ratgdo { void set_input_gdo_pin(InternalGPIOPin* pin) { this->input_gdo_pin_ = pin; } void set_input_obst_pin(InternalGPIOPin* pin) { this->input_obst_pin_ = pin; } + void set_door_open_sensor(binary_sensor::BinarySensor* sensor) { this->door_open_sensor_ = sensor; } + void set_door_closed_sensor(binary_sensor::BinarySensor* sensor) { this->door_closed_sensor_ = sensor; } + Result call_protocol(Args args); void received(const DoorState door_state); @@ -171,6 +177,10 @@ namespace ratgdo { protocol::Protocol* protocol_; bool obstruction_from_status_ { false }; + DoorState sensor_door_state_ { DoorState::UNKNOWN }; + binary_sensor::BinarySensor* door_open_sensor_; + binary_sensor::BinarySensor* door_closed_sensor_; + InternalGPIOPin* output_gdo_pin_; InternalGPIOPin* input_gdo_pin_; InternalGPIOPin* input_obst_pin_;