Merge branch 'main' into ttc_beep

This commit is contained in:
mulcmu 2023-12-16 18:27:42 -05:00
commit f9422929f2
9 changed files with 142 additions and 147 deletions

View File

@ -47,19 +47,13 @@ select:
ratgdo_id: ${id_prefix}
name: "Time to close"
switch:
lock:
- platform: ratgdo
id: ${id_prefix}_lock_remotes
type: lock
entity_category: config
ratgdo_id: ${id_prefix}
name: "Lock remotes"
- platform: ratgdo
id: ${id_prefix}_TTC_hold
type: hold
entity_category: config
ratgdo_id: ${id_prefix}
name: "TTC Hold Open"
switch:
- platform: gpio
id: "${id_prefix}_status_door"
internal: true

View File

@ -0,0 +1,26 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import lock
from esphome.const import CONF_ID
from .. import RATGDO_CLIENT_SCHMEA, ratgdo_ns, register_ratgdo_child
DEPENDENCIES = ["ratgdo"]
RATGDOLock = ratgdo_ns.class_("RATGDOLock", lock.Lock, cg.Component)
CONFIG_SCHEMA = (
lock.LOCK_SCHEMA
.extend(
{
cv.GenerateID(): cv.declare_id(RATGDOLock),
}
)
.extend(RATGDO_CLIENT_SCHMEA)
)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await lock.register_lock(var, config)
await cg.register_component(var, config)
await register_ratgdo_child(var, config)

View File

@ -0,0 +1,55 @@
#include "ratgdo_lock.h"
#include "../ratgdo_state.h"
#include "esphome/core/log.h"
namespace esphome {
namespace ratgdo {
static const char* const TAG = "ratgdo.lock";
void RATGDOLock::dump_config()
{
LOG_LOCK("", "RATGDO Lock", this);
ESP_LOGCONFIG(TAG, " Type: Lock");
}
void RATGDOLock::setup()
{
this->parent_->subscribe_lock_state([=](LockState state) {
this->on_lock_state(state);
});
}
void RATGDOLock::on_lock_state(LockState state)
{
if (state == LockState::LOCKED && this->state == lock::LockState::LOCK_STATE_LOCKED) {
return;
}
if (state == LockState::UNLOCKED && this->state == lock::LockState::LOCK_STATE_UNLOCKED) {
return;
}
auto call = this->make_call();
if (state == LockState::LOCKED) {
call.set_state(lock::LockState::LOCK_STATE_LOCKED);
} else if (state == LockState::UNLOCKED) {
call.set_state(lock::LockState::LOCK_STATE_UNLOCKED);
}
this->control(call);
}
void RATGDOLock::control(const lock::LockCall& call)
{
auto state = *call.get_state();
if (state == lock::LockState::LOCK_STATE_LOCKED) {
this->parent_->lock();
} else if (state == lock::LockState::LOCK_STATE_UNLOCKED) {
this->parent_->unlock();
}
this->publish_state(state);
}
} // namespace ratgdo
} // namespace esphome

View File

@ -0,0 +1,21 @@
#pragma once
#include "../ratgdo.h"
#include "../ratgdo_state.h"
#include "esphome/components/lock/lock.h"
#include "esphome/core/component.h"
namespace esphome {
namespace ratgdo {
class RATGDOLock : public lock::Lock, public RATGDOClient, public Component {
public:
void dump_config() override;
void setup() override;
void on_lock_state(LockState state);
void control(const lock::LockCall& call) override;
};
} // namespace ratgdo
} // namespace esphome

View File

@ -359,8 +359,7 @@ if (this->input_obst_pin_ == nullptr || this->input_obst_pin_->get_pin() == 0) {
void RATGDOComponent::print_packet(const WirePacket& packet) const
{
ESP_LOGV(TAG, "Counter: %d Send code: [%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X]",
*this->rolling_code_counter,
ESP_LOG2(TAG, "Packet: [%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X]",
packet[0],
packet[1],
packet[2],
@ -431,12 +430,15 @@ if (this->input_obst_pin_ == nullptr || this->input_obst_pin_->get_pin() == 0) {
static uint32_t msg_start = 0;
static uint16_t byte_count = 0;
static WirePacket rx_packet;
static uint32_t last_read = 0;
if (!reading_msg) {
while (this->sw_serial_.available()) {
uint8_t ser_byte = this->sw_serial_.read();
last_read = millis();
if (ser_byte != 0x55 && ser_byte != 0x01 && ser_byte != 0x00) {
ESP_LOG2(TAG, "Ignoring byte: %02X, baud: %d", ser_byte, this->sw_serial_.baudRate());
ESP_LOG2(TAG, "Ignoring byte (%d): %02X, baud: %d", byte_count, ser_byte, this->sw_serial_.baudRate());
byte_count = 0;
continue;
}
@ -458,16 +460,28 @@ if (this->input_obst_pin_ == nullptr || this->input_obst_pin_->get_pin() == 0) {
if (reading_msg) {
while (this->sw_serial_.available()) {
uint8_t ser_byte = this->sw_serial_.read();
last_read = millis();
rx_packet[byte_count] = ser_byte;
byte_count++;
// ESP_LOG2(TAG, "Received byte (%d): %02X, baud: %d", byte_count, ser_byte, this->sw_serial_.baudRate());
if (byte_count == PACKET_LENGTH) {
reading_msg = false;
byte_count = 0;
this->print_packet(rx_packet);
this->decode_packet(rx_packet);
return;
}
}
if (millis() - last_read > 100) {
// if we have a partial packet and it's been over 100ms since last byte was read,
// the rest is not coming (a full packet should be received in ~20ms),
// discard it so we can read the following packet correctly
ESP_LOGW(TAG, "Discard incomplete packet, length: %d", byte_count);
reading_msg = false;
byte_count = 0;
}
}
}
@ -531,9 +545,13 @@ if (this->input_obst_pin_ == nullptr || this->input_obst_pin_->get_pin() == 0) {
if (!this->transmit_pending_) { // have an untransmitted packet
this->encode_packet(command, data, increment, this->tx_packet_);
} else {
// unlikely this would happed, we're ensuring any pending packet
// unlikely this would happed (unless not connected to GDO), we're ensuring any pending packet
// is transmitted each loop before doing anyting else
ESP_LOGW(TAG, "Have untransmitted packet, ignoring command: %s", Command_to_string(command));
if (this->transmit_pending_start_ > 0) {
ESP_LOGW(TAG, "Have untransmitted packet, ignoring command: %s", Command_to_string(command));
} else {
ESP_LOGW(TAG, "Not connected to GDO, ignoring command: %s", Command_to_string(command));
}
}
this->transmit_packet();
}
@ -547,10 +565,20 @@ if (this->input_obst_pin_ == nullptr || this->input_obst_pin_->get_pin() == 0) {
bool RATGDOComponent::transmit_packet()
{
auto now = micros();
while (micros() - now < 1300) {
if (this->input_gdo_pin_->digital_read()) {
ESP_LOGD(TAG, "Collision detected, waiting to send packet");
this->transmit_pending_ = true;
if (!this->transmit_pending_) {
this->transmit_pending_ = true;
this->transmit_pending_start_ = millis();
ESP_LOGD(TAG, "Collision detected, waiting to send packet");
} else {
if (millis() - this->transmit_pending_start_ < 5000) {
ESP_LOGD(TAG, "Collision detected, waiting to send packet");
} else {
this->transmit_pending_start_ = 0; // to indicate GDO not connected state
}
}
return false;
}
delayMicroseconds(100);
@ -569,6 +597,7 @@ if (this->input_obst_pin_ == nullptr || this->input_obst_pin_->get_pin() == 0) {
this->sw_serial_.write(this->tx_packet_, PACKET_LENGTH);
this->transmit_pending_ = false;
this->transmit_pending_start_ = 0;
this->command_sent();
return true;
}

View File

@ -227,6 +227,7 @@ namespace ratgdo {
protected:
// tx data
bool transmit_pending_ { false };
uint32_t transmit_pending_start_ { 0 };
WirePacket tx_packet_;
RATGDOStore isr_store_ {};

View File

@ -1,36 +0,0 @@
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 = {
"lock": SwitchType.RATGDO_LOCK,
"hold": SwitchType.RATGDO_HOLDOPEN,
}
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)

View File

@ -1,64 +0,0 @@
#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_LOCK) {
ESP_LOGCONFIG(TAG, " Type: Lock");
} else if (this->switch_type_ == SwitchType::RATGDO_HOLDOPEN) {
ESP_LOGCONFIG(TAG, " Type: Hold Open");
}
}
void RATGDOSwitch::setup()
{
if (this->switch_type_ == SwitchType::RATGDO_LOCK) {
this->parent_->subscribe_lock_state([=](LockState state) {
this->on_lock_state(state);
});
} else if (this->switch_type_ == SwitchType::RATGDO_HOLDOPEN) {
this->parent_->subscribe_hold_state([=](HoldState state) {
this->on_hold_state(state);
});
}
}
void RATGDOSwitch::on_lock_state(LockState state)
{
bool value = state == LockState::LOCKED;
this->state = value;
this->publish_state(value);
}
void RATGDOSwitch::on_hold_state(HoldState state)
{
bool value = state == HoldState::HOLD_ENABLED;
this->state = value;
this->publish_state(value);
}
void RATGDOSwitch::write_state(bool state)
{
if (this->switch_type_ == SwitchType::RATGDO_LOCK) {
if (state) {
this->parent_->lock();
} else {
this->parent_->unlock();
}
} else if (this->switch_type_ == SwitchType::RATGDO_HOLDOPEN) {
if (state) {
this->parent_->hold_enable();
} else {
this->parent_->hold_disable();
}
}
}
} // namespace ratgdo
} // namespace esphome

View File

@ -1,31 +0,0 @@
#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_LOCK,
RATGDO_HOLDOPEN
};
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 on_lock_state(LockState state);
void on_hold_state(HoldState state);
void write_state(bool state) override;
protected:
SwitchType switch_type_;
};
} // namespace ratgdo
} // namespace esphome