From 0932dc2ad8bc542b218dd396b2481b93d62e6415 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 9 Jun 2023 17:36:56 -0500 Subject: [PATCH] openings --- base.yml | 9 ++++++ components/ratgdo/ratgdo.cpp | 28 ++++++++++++----- components/ratgdo/ratgdo.h | 8 +++-- components/ratgdo/ratgdo_child.cpp | 1 + components/ratgdo/ratgdo_child.h | 1 + components/ratgdo/sensor/__init__.py | 35 ++++++++++++++++++++++ components/ratgdo/sensor/ratgdo_sensor.cpp | 21 +++++++++++++ components/ratgdo/sensor/ratgdo_sensor.h | 29 ++++++++++++++++++ 8 files changed, 122 insertions(+), 10 deletions(-) create mode 100644 components/ratgdo/sensor/__init__.py create mode 100644 components/ratgdo/sensor/ratgdo_sensor.cpp create mode 100644 components/ratgdo/sensor/ratgdo_sensor.h diff --git a/base.yml b/base.yml index b323380..335f301 100644 --- a/base.yml +++ b/base.yml @@ -30,6 +30,15 @@ uart: inverted: true baud_rate: 9600 +sensor: + - platform: ratgdo + id: ${id_prefix}_openings + type: openings + entity_category: diagnostic + ratgdo_id: ${id_prefix} + name: "${friendly_name} Openings" + unit_of_measurement: "openings" + switch: - platform: ratgdo id: ${id_prefix}_lock_remotes diff --git a/components/ratgdo/ratgdo.cpp b/components/ratgdo/ratgdo.cpp index d748e23..a31aa5b 100644 --- a/components/ratgdo/ratgdo.cpp +++ b/components/ratgdo/ratgdo.cpp @@ -74,7 +74,7 @@ namespace ratgdo { ESP_LOGCONFIG(TAG, " Rolling Code Counter: %d", this->rollingCodeCounter); } - void RATGDOComponent::readRollingCode(bool& isStatus, uint8_t& door, uint8_t& light, uint8_t& lock, uint8_t& motion, uint8_t& obstruction, uint8_t& motor) + void RATGDOComponent::readRollingCode(bool& isStatus, uint8_t& door, uint8_t& light, uint8_t& lock, uint8_t& motion, uint8_t& obstruction, uint8_t& motor, uint16_t& openings) { uint32_t rolling = 0; uint64_t fixed = 0; @@ -114,6 +114,7 @@ namespace ratgdo { } else if (cmd == 0x280) { ESP_LOGD(TAG, "Pressed: %s", byte1 == 1 ? "pressed" : "released"); } else if (cmd == 0x48c) { + openings = (byte1 << 8) | byte2; ESP_LOGD(TAG, "Openings: %d", (byte1 << 8) | byte2); } else if (cmd == 0x285) { motion = 1; // toggle bit @@ -259,7 +260,7 @@ namespace ratgdo { byteCount = 0; isStatus = false; - readRollingCode(isStatus, this->doorState, this->lightState, this->lockState, this->motionState, this->obstructionState, this->motorState); + readRollingCode(isStatus, this->doorState, this->lightState, this->lockState, this->motionState, this->obstructionState, this->motorState, this->openings); if (isStatus && this->forceUpdate_) { this->forceUpdate_ = false; this->previousDoorState = DoorState::DOOR_STATE_UNKNOWN; @@ -275,25 +276,28 @@ namespace ratgdo { { if (this->doorState != this->previousDoorState) sendDoorStatus(); + this->previousDoorState = this->doorState; if (this->lightState != this->previousLightState) sendLightStatus(); + this->previousLightState = this->lightState; if (this->lockState != this->previousLockState) sendLockStatus(); + this->previousLockState = this->lockState; if (this->obstructionState != this->previousObstructionState) sendObstructionStatus(); + this->previousObstructionState = this->obstructionState; if (this->motorState != this->previousMotorState) { sendMotorStatus(); + this->previousMotorState = this->motorState; } if (this->motionState == MotionState::MOTION_STATE_DETECTED) { sendMotionStatus(); this->motionState = MotionState::MOTION_STATE_CLEAR; } - - this->previousDoorState = this->doorState; - this->previousLightState = this->lightState; - this->previousLockState = this->lockState; - this->previousObstructionState = this->obstructionState; - this->previousMotorState = this->motorState; + if (this->openings != this->previousOpenings) { + sendOpenings(); + this->previousOpenings = this->openings; + } } void RATGDOComponent::query() @@ -302,6 +306,14 @@ namespace ratgdo { sendCommandAndSaveCounter(Command.REBOOT2); } + void RATGDOComponent::sendOpenings() + { + ESP_LOGD(TAG, "Openings: %d", this->openings); + for (auto* child : this->children_) { + child->on_openings_change(this->openings); + } + } + void RATGDOComponent::sendDoorStatus() { DoorState val = static_cast(this->doorState); diff --git a/components/ratgdo/ratgdo.h b/components/ratgdo/ratgdo.h index b152290..b3ae3c4 100644 --- a/components/ratgdo/ratgdo.h +++ b/components/ratgdo/ratgdo.h @@ -81,9 +81,11 @@ namespace ratgdo { void setup() override; void loop() override; void dump_config() override; - /********************************** GLOBAL VARS - * *****************************************/ + uint32_t rollingCodeCounter; + uint16_t previousOpenings { 0 }; // number of times the door has been opened + uint16_t openings; // number of times the door has been opened + uint8_t txRollingCode[CODE_LENGTH]; uint8_t rxRollingCode[CODE_LENGTH]; @@ -112,6 +114,8 @@ namespace ratgdo { void obstructionLoop(); void sendObstructionStatus(); + void sendOpenings(); + void toggleDoor(); void openDoor(); void closeDoor(); diff --git a/components/ratgdo/ratgdo_child.cpp b/components/ratgdo/ratgdo_child.cpp index aea7b0a..a4fc254 100644 --- a/components/ratgdo/ratgdo_child.cpp +++ b/components/ratgdo/ratgdo_child.cpp @@ -13,6 +13,7 @@ namespace ratgdo { void RATGDOClient::on_obstruction_state(ObstructionState state) {}; void RATGDOClient::on_motor_state(MotorState state) {}; void RATGDOClient::on_rolling_code_change(uint32_t rollingCodeCounter) {}; + void RATGDOClient::on_openings_change(uint32_t openings); } // namespace ratgdo } // namespace esphome diff --git a/components/ratgdo/ratgdo_child.h b/components/ratgdo/ratgdo_child.h index 3e9a509..f826c37 100644 --- a/components/ratgdo/ratgdo_child.h +++ b/components/ratgdo/ratgdo_child.h @@ -20,6 +20,7 @@ namespace ratgdo { virtual void on_obstruction_state(ObstructionState state); virtual void on_motor_state(MotorState state); virtual void on_rolling_code_change(uint32_t rollingCodeCounter); + virtual void on_openings_change(uint32_t openings); protected: friend RATGDOComponent; diff --git a/components/ratgdo/sensor/__init__.py b/components/ratgdo/sensor/__init__.py new file mode 100644 index 0000000..db17758 --- /dev/null +++ b/components/ratgdo/sensor/__init__.py @@ -0,0 +1,35 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import sensor +from esphome.const import CONF_ID + +from .. import RATGDO_CLIENT_SCHMEA, ratgdo_ns, register_ratgdo_child + +DEPENDENCIES = ["ratgdo"] + +RATGDOSensor = ratgdo_ns.class_("RATGDOSensor", sensor.Sensor, cg.Component) +SensorType = ratgdo_ns.enum("SensorType") + +CONF_TYPE = "type" +TYPES = { + "openings": SensorType.RATGDO_OPENINGS, +} + + +CONFIG_SCHEMA = ( + sensor.sensor_schema(RATGDOSensor) + .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 sensor.register_sensor(var, config) + await cg.register_component(var, config) + cg.add(var.set_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 new file mode 100644 index 0000000..b26f92a --- /dev/null +++ b/components/ratgdo/sensor/ratgdo_sensor.cpp @@ -0,0 +1,21 @@ +#include "ratgdo_sensor.h" +#include "../ratgdo_state.h" +#include "esphome/core/log.h" + +namespace esphome { +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::on_openings_change(uint32_t openings) + { + this->publish_state(openings); + } + +} // namespace ratgdo +} // namespace esphome diff --git a/components/ratgdo/sensor/ratgdo_sensor.h b/components/ratgdo/sensor/ratgdo_sensor.h new file mode 100644 index 0000000..aa160db --- /dev/null +++ b/components/ratgdo/sensor/ratgdo_sensor.h @@ -0,0 +1,29 @@ +#pragma once + +#include "../ratgdo.h" +#include "../ratgdo_child.h" +#include "../ratgdo_state.h" +#include "esphome/components/sensor/sensor.h" +#include "esphome/core/component.h" + +namespace esphome { +namespace ratgdo { + + enum SensorType { + RATGDO_OPENINGS + }; + + class RATGDOSensor : public sensor::Sensor, public RATGDOClient, public Component { + public: + void setup() override; + void dump_config() override; + void set_sensor_type(SensorType sensor_type_) { this->sensor_type_ = sensor_type_; } + + void on_openings_change(uint32_t openings) override; + + protected: + SensorType sensor_type_; + }; + +} // namespace ratgdo +} // namespace esphome