This commit is contained in:
Paul Wieland 2024-10-28 13:56:16 -04:00
parent ec3ba31ce8
commit f68d126fb8
36 changed files with 1099 additions and 12 deletions

View File

@ -1,10 +1,12 @@
--- ---
external_components: external_components:
- source: - source:
type: git type: git
url: https://github.com/ratgdo/esphome-ratgdo url: https://github.com/ratgdo/esphome-ratgdo
refresh: 1s refresh: 1s
# - source:
# type: local
# path: components
safe_mode: safe_mode:

View File

@ -2,11 +2,12 @@
external_components: external_components:
- source: - source:
# type: local
# path: components
type: git type: git
url: https://github.com/ratgdo/esphome-ratgdo url: https://github.com/ratgdo/esphome-ratgdo
refresh: 1s refresh: 1s
# - source:
# type: local
# path: components
safe_mode: safe_mode:
@ -20,6 +21,7 @@ text_sensor:
ratgdo: ratgdo:
id: ${id_prefix} id: ${id_prefix}
output_gdo_pin: ${uart_tx_pin} output_gdo_pin: ${uart_tx_pin}
input_gdo_pin: ${uart_rx_pin}
input_obst_pin: ${input_obst_pin} input_obst_pin: ${input_obst_pin}
dry_contact_open_sensor: ${id_prefix}_dry_contact_open dry_contact_open_sensor: ${id_prefix}_dry_contact_open
dry_contact_close_sensor: ${id_prefix}_dry_contact_close dry_contact_close_sensor: ${id_prefix}_dry_contact_close

View File

@ -5,6 +5,9 @@ external_components:
type: git type: git
url: https://github.com/ratgdo/esphome-ratgdo url: https://github.com/ratgdo/esphome-ratgdo
refresh: 1s refresh: 1s
# - source:
# type: local
# path: components
safe_mode: safe_mode:

View File

@ -144,4 +144,4 @@ async def to_code(config):
cg.add(var.set_discrete_open_pin(pin)) cg.add(var.set_discrete_open_pin(pin))
if CONF_DISCRETE_CLOSE_PIN in config and config[CONF_DISCRETE_CLOSE_PIN]: if CONF_DISCRETE_CLOSE_PIN in config and config[CONF_DISCRETE_CLOSE_PIN]:
pin = await cg.gpio_pin_expression(config[CONF_DISCRETE_CLOSE_PIN]) pin = await cg.gpio_pin_expression(config[CONF_DISCRETE_CLOSE_PIN])
cg.add(var.set_discrete_close_pin(pin)) cg.add(var.set_discrete_close_pin(pin))

View File

@ -18,6 +18,9 @@ TYPES = {
"obstruction": SensorType.RATGDO_SENSOR_OBSTRUCTION, "obstruction": SensorType.RATGDO_SENSOR_OBSTRUCTION,
"motor": SensorType.RATGDO_SENSOR_MOTOR, "motor": SensorType.RATGDO_SENSOR_MOTOR,
"button": SensorType.RATGDO_SENSOR_BUTTON, "button": SensorType.RATGDO_SENSOR_BUTTON,
"vehicle_detected": SensorType.RATGDO_SENSOR_VEHICLE_DETECTED,
"vehicle_arriving": SensorType.RATGDO_SENSOR_VEHICLE_ARRIVING,
"vehicle_leaving": SensorType.RATGDO_SENSOR_VEHICLE_LEAVING,
} }

View File

@ -28,6 +28,22 @@ namespace ratgdo {
this->parent_->subscribe_button_state([=](ButtonState state) { this->parent_->subscribe_button_state([=](ButtonState state) {
this->publish_state(state == ButtonState::PRESSED); this->publish_state(state == ButtonState::PRESSED);
}); });
} else if(this->binary_sensor_type_ == SensorType::RATGDO_SENSOR_VEHICLE_DETECTED) {
this->publish_initial_state(false);
this->parent_->subscribe_vehicle_detected_state([=](VehicleDetectedState state) {
this->publish_state(state == VehicleDetectedState::YES);
this->parent_->presence_change(state == VehicleDetectedState::YES);
});
} else if(this->binary_sensor_type_ == SensorType::RATGDO_SENSOR_VEHICLE_ARRIVING) {
this->publish_initial_state(false);
this->parent_->subscribe_vehicle_arriving_state([=](VehicleArrivingState state) {
this->publish_state(state == VehicleArrivingState::YES);
});
} else if(this->binary_sensor_type_ == SensorType::RATGDO_SENSOR_VEHICLE_LEAVING) {
this->publish_initial_state(false);
this->parent_->subscribe_vehicle_leaving_state([=](VehicleLeavingState state) {
this->publish_state(state == VehicleLeavingState::YES);
});
} }
} }
@ -42,6 +58,12 @@ namespace ratgdo {
ESP_LOGCONFIG(TAG, " Type: Motor"); ESP_LOGCONFIG(TAG, " Type: Motor");
} else if (this->binary_sensor_type_ == SensorType::RATGDO_SENSOR_BUTTON) { } else if (this->binary_sensor_type_ == SensorType::RATGDO_SENSOR_BUTTON) {
ESP_LOGCONFIG(TAG, " Type: Button"); ESP_LOGCONFIG(TAG, " Type: Button");
} else if (this->binary_sensor_type_ == SensorType::RATGDO_SENSOR_VEHICLE_DETECTED) {
ESP_LOGCONFIG(TAG, " Type: VehicleDetected");
} else if (this->binary_sensor_type_ == SensorType::RATGDO_SENSOR_VEHICLE_ARRIVING) {
ESP_LOGCONFIG(TAG, " Type: VehicleArriving");
} else if (this->binary_sensor_type_ == SensorType::RATGDO_SENSOR_VEHICLE_LEAVING) {
ESP_LOGCONFIG(TAG, " Type: VehicleLeaving");
} }
} }

View File

@ -12,7 +12,10 @@ namespace ratgdo {
RATGDO_SENSOR_MOTION, RATGDO_SENSOR_MOTION,
RATGDO_SENSOR_OBSTRUCTION, RATGDO_SENSOR_OBSTRUCTION,
RATGDO_SENSOR_MOTOR, RATGDO_SENSOR_MOTOR,
RATGDO_SENSOR_BUTTON RATGDO_SENSOR_BUTTON,
RATGDO_SENSOR_VEHICLE_DETECTED,
RATGDO_SENSOR_VEHICLE_ARRIVING,
RATGDO_SENSOR_VEHICLE_LEAVING,
}; };
class RATGDOBinarySensor : public binary_sensor::BinarySensor, public RATGDOClient, public Component { class RATGDOBinarySensor : public binary_sensor::BinarySensor, public RATGDOClient, public Component {

View File

@ -16,6 +16,8 @@ TYPES = {
"rolling_code_counter": NumberType.RATGDO_ROLLING_CODE_COUNTER, "rolling_code_counter": NumberType.RATGDO_ROLLING_CODE_COUNTER,
"opening_duration": NumberType.RATGDO_OPENING_DURATION, "opening_duration": NumberType.RATGDO_OPENING_DURATION,
"closing_duration": NumberType.RATGDO_CLOSING_DURATION, "closing_duration": NumberType.RATGDO_CLOSING_DURATION,
"closing_delay": NumberType.RATGDO_CLOSING_DELAY,
"target_distance_measurement": NumberType.RATGDO_TARGET_DISTANCE_MEASUREMENT,
} }

View File

@ -30,6 +30,10 @@ namespace ratgdo {
ESP_LOGCONFIG(TAG, " Type: Opening Duration"); ESP_LOGCONFIG(TAG, " Type: Opening Duration");
} else if (this->number_type_ == RATGDO_CLOSING_DURATION) { } else if (this->number_type_ == RATGDO_CLOSING_DURATION) {
ESP_LOGCONFIG(TAG, " Type: Closing Duration"); ESP_LOGCONFIG(TAG, " Type: Closing Duration");
} else if (this->number_type_ == RATGDO_CLOSING_DELAY) {
ESP_LOGCONFIG(TAG, " Type: Closing Delay");
} else if (this->number_type_ == RATGDO_TARGET_DISTANCE_MEASUREMENT) {
ESP_LOGCONFIG(TAG, " Type: Target Distance Measurement");
} }
} }
@ -66,6 +70,14 @@ namespace ratgdo {
this->parent_->subscribe_closing_duration([=](float value) { this->parent_->subscribe_closing_duration([=](float value) {
this->update_state(value); this->update_state(value);
}); });
} else if (this->number_type_ == RATGDO_CLOSING_DELAY) {
this->parent_->subscribe_closing_delay([=](uint32_t value) {
this->update_state(value);
});
} else if (this->number_type_ == RATGDO_TARGET_DISTANCE_MEASUREMENT){
// this->parent_->subscribe_target_distance_measurement([=](float value) {
// this->update_state(value);
// });
} }
} }
@ -76,12 +88,20 @@ namespace ratgdo {
this->traits.set_step(0.1); this->traits.set_step(0.1);
this->traits.set_min_value(0.0); this->traits.set_min_value(0.0);
this->traits.set_max_value(180.0); this->traits.set_max_value(180.0);
} else if (this->number_type_ == RATGDO_CLOSING_DELAY) {
this->traits.set_step(1);
this->traits.set_min_value(0.0);
this->traits.set_max_value(180.0);
} else if (this->number_type_ == RATGDO_ROLLING_CODE_COUNTER) { } else if (this->number_type_ == RATGDO_ROLLING_CODE_COUNTER) {
this->traits.set_max_value(0xfffffff); this->traits.set_max_value(0xfffffff);
} else if (this->number_type_ == RATGDO_CLIENT_ID) { } else if (this->number_type_ == RATGDO_CLIENT_ID) {
this->traits.set_step(0x1000); this->traits.set_step(0x1000);
this->traits.set_min_value(0x539); this->traits.set_min_value(0x539);
this->traits.set_max_value(0x7ff539); this->traits.set_max_value(0x7ff539);
} else if(this->number_type_ == RATGDO_TARGET_DISTANCE_MEASUREMENT) {
this->traits.set_step(1);
this->traits.set_min_value(5);
this->traits.set_max_value(3500);
} }
} }
@ -102,9 +122,13 @@ namespace ratgdo {
this->parent_->set_opening_duration(value); this->parent_->set_opening_duration(value);
} else if (this->number_type_ == RATGDO_CLOSING_DURATION) { } else if (this->number_type_ == RATGDO_CLOSING_DURATION) {
this->parent_->set_closing_duration(value); this->parent_->set_closing_duration(value);
} else if (this->number_type_ == RATGDO_CLOSING_DELAY) {
this->parent_->set_closing_delay(value);
} else if (this->number_type_ == RATGDO_CLIENT_ID) { } else if (this->number_type_ == RATGDO_CLIENT_ID) {
value = normalize_client_id(value); value = normalize_client_id(value);
this->parent_->call_protocol(SetClientID { static_cast<uint32_t>(value) }); this->parent_->call_protocol(SetClientID { static_cast<uint32_t>(value) });
} else if (this->number_type_ == RATGDO_TARGET_DISTANCE_MEASUREMENT) {
this->parent_->set_target_distance_measurement(value);
} }
this->update_state(value); this->update_state(value);
} }

View File

@ -13,6 +13,8 @@ namespace ratgdo {
RATGDO_ROLLING_CODE_COUNTER, RATGDO_ROLLING_CODE_COUNTER,
RATGDO_OPENING_DURATION, RATGDO_OPENING_DURATION,
RATGDO_CLOSING_DURATION, RATGDO_CLOSING_DURATION,
RATGDO_CLOSING_DELAY,
RATGDO_TARGET_DISTANCE_MEASUREMENT,
}; };
class RATGDONumber : public number::Number, public RATGDOClient, public Component { class RATGDONumber : public number::Number, public RATGDOClient, public Component {

View File

@ -0,0 +1,36 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import rtttl
from esphome.const import CONF_ID
CONF_RTTTL = "rtttl"
CONF_SONG = "song"
from .. import RATGDO_CLIENT_SCHMEA, ratgdo_ns, register_ratgdo_child
DEPENDENCIES = ["esp32","ratgdo","rtttl"]
RATGDOOutput = ratgdo_ns.class_("RATGDOOutput", cg.Component)
OutputType = ratgdo_ns.enum("OutputType")
CONF_TYPE = "type"
TYPES = {
"beeper": OutputType.RATGDO_BEEPER
}
CONFIG_SCHEMA = cv.Schema(
{
cv.Required(CONF_ID): cv.declare_id(RATGDOOutput),
cv.Required(CONF_TYPE): cv.enum(TYPES, lower=True),
cv.Required(CONF_RTTTL): cv.use_id(rtttl),
cv.Required(CONF_SONG): cv.string
}
).extend(RATGDO_CLIENT_SCHMEA)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
rtttl = await cg.get_variable(config[CONF_RTTTL])
cg.add(var.set_rtttl(rtttl))
cg.add(var.set_song(config[CONF_SONG]))
await register_ratgdo_child(var, config)

View File

@ -0,0 +1,53 @@
#include "ratgdo_output.h"
#include "../ratgdo_state.h"
#include "esphome/core/log.h"
namespace esphome {
namespace ratgdo {
static const char *TAG = "ratgdo.output";
void RATGDOOutput::setup(){
ESP_LOGD(TAG,"Output was setup");
if(this->output_type_ == OutputType::RATGDO_BEEPER){
this->beeper_->add_on_finished_playback_callback([=] { this->finished_playback(); });
this->parent_->subscribe_vehicle_arriving_state([=](VehicleArrivingState state) {
if(state == VehicleArrivingState::YES){
this->play();
}
});
this->parent_->subscribe_door_action_delayed([=](DoorActionDelayed state) {
if(state == DoorActionDelayed::YES){
this->play();
this->repeat_ = true;
} else if(state == DoorActionDelayed::NO) {
this->repeat_ = false;
}
});
}
}
void RATGDOOutput::play(){
this->beeper_->play(this->rtttlSong_);
}
void RATGDOOutput::finished_playback(){
if(this->repeat_) this->play();
}
void RATGDOOutput::dump_config() {
if (this->output_type_ == OutputType::RATGDO_BEEPER) {
ESP_LOGCONFIG(TAG, " Type: Beeper");
}
}
void RATGDOOutput::set_output_type(OutputType output_type_) {
this->output_type_ = output_type_;
}
} //namespace ratgdo
} //namespace esphome

View File

@ -0,0 +1,32 @@
#pragma once
#include "../ratgdo.h"
#include "esphome/core/component.h"
#include "esphome/components/rtttl/rtttl.h"
namespace esphome {
namespace ratgdo {
enum OutputType {
RATGDO_BEEPER
};
class RATGDOOutput : public RATGDOClient, public Component {
public:
void setup() override;
void play();
void finished_playback();
void dump_config() override;
void set_output_type(OutputType output_type);
void set_song(std::string rtttlSong){ this->rtttlSong_ = rtttlSong; }
void set_rtttl(rtttl::Rtttl *output){ this->beeper_ = output; }
protected:
OutputType output_type_;
rtttl::Rtttl* beeper_;
std::string rtttlSong_;
bool repeat_;
};
} //namespace ratgdo
} //namespace esphome

View File

@ -30,6 +30,9 @@ namespace ratgdo {
static const char* const TAG = "ratgdo"; static const char* const TAG = "ratgdo";
static const int SYNC_DELAY = 1000; static const int SYNC_DELAY = 1000;
static const int CLEAR_PRESENCE = 60000; // how long to keep arriving/leaving active
static const int PRESENCE_DETECT_WINDOW = 300000; // how long to calculate presence after door state change
void RATGDOComponent::setup() void RATGDOComponent::setup()
{ {
this->output_gdo_pin_->setup(); this->output_gdo_pin_->setup();
@ -39,7 +42,11 @@ namespace ratgdo {
this->input_gdo_pin_->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP); this->input_gdo_pin_->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
this->input_obst_pin_->setup(); this->input_obst_pin_->setup();
#ifdef USE_ESP32
this->input_obst_pin_->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
#else
this->input_obst_pin_->pin_mode(gpio::FLAG_INPUT); this->input_obst_pin_->pin_mode(gpio::FLAG_INPUT);
#endif
this->input_obst_pin_->attach_interrupt(RATGDOStore::isr_obstruction, &this->isr_store_, gpio::INTERRUPT_FALLING_EDGE); this->input_obst_pin_->attach_interrupt(RATGDOStore::isr_obstruction, &this->isr_store_, gpio::INTERRUPT_FALLING_EDGE);
this->protocol_->setup(this, &App.scheduler, this->input_gdo_pin_, this->output_gdo_pin_); this->protocol_->setup(this, &App.scheduler, this->input_gdo_pin_, this->output_gdo_pin_);
@ -51,6 +58,24 @@ namespace ratgdo {
ESP_LOGD(TAG, "| -| | | | | | | | | | |"); ESP_LOGD(TAG, "| -| | | | | | | | | | |");
ESP_LOGD(TAG, "|__|__|__|__| |_| |_____|____/|_____|"); ESP_LOGD(TAG, "|__|__|__|__| |_| |_____|____/|_____|");
ESP_LOGD(TAG, "https://paulwieland.github.io/ratgdo/"); ESP_LOGD(TAG, "https://paulwieland.github.io/ratgdo/");
this->subscribe_door_state([=](DoorState state, float position) {
static DoorState lastState = DoorState::UNKNOWN;
if(lastState != DoorState::UNKNOWN && state != DoorState::CLOSED && !this->presence_detect_window_active_){
this->presence_detect_window_active_ = true;
set_timeout("presence_detect_window", PRESENCE_DETECT_WINDOW, [=] {
this->presence_detect_window_active_ = false;
});
}
if(state == DoorState::CLOSED){
this->presence_detect_window_active_ = false;
cancel_timeout("presence_detect_window");
}
lastState = state;
});
} }
// initializing protocol, this gets called before setup() because // initializing protocol, this gets called before setup() because
@ -335,6 +360,64 @@ namespace ratgdo {
this->closing_duration = duration; this->closing_duration = duration;
} }
void RATGDOComponent::set_target_distance_measurement(int16_t distance){
this->target_distance_measurement = distance;
}
void RATGDOComponent::set_distance_measurement(int16_t distance)
{
this->last_distance_measurement = distance;
// current value = [0], last value = [1]
this->distance_measurement.insert(this->distance_measurement.begin(), distance);
this->distance_measurement.pop_back();
this->calculate_presence();
}
void RATGDOComponent::calculate_presence()
{
bool all_in_range = true;
bool all_out_of_range = true;
// int16_t min = *this->target_distance_measurement - PRESENCE_DETECT_TOLERANCE;
// int16_t max = *this->target_distance_measurement + PRESENCE_DETECT_TOLERANCE;
for (int16_t value : this->distance_measurement) {
// if (value < min || value > max || value == -1) {
if (value >= *this->target_distance_measurement || value == -1) {
all_in_range = false;
}
if (value < *this->target_distance_measurement && value != -1) {
all_out_of_range = false;
}
}
if(all_in_range) this->vehicle_detected_state = VehicleDetectedState::YES;
if(all_out_of_range) this->vehicle_detected_state = VehicleDetectedState::NO;
// auto k = this->distance_measurement;
// ESP_LOGD(TAG,"measure: %i,%i,%i,%i,%i,%i,%i,%i,%i,%i; target: %i; all_in: %s; all_out: %s;", k[0],k[1],k[2],k[3],k[4],k[5],k[6],k[7],k[8],k[9], *this->target_distance_measurement, all_in_range ? "y" : "n", all_out_of_range ? "y" : "n");
}
void RATGDOComponent::presence_change(bool sensor_value)
{
if(this->presence_detect_window_active_){
if(sensor_value){
this->vehicle_arriving_state = VehicleArrivingState::YES;
this->vehicle_leaving_state = VehicleLeavingState::NO;
set_timeout(CLEAR_PRESENCE, [=] {
this->vehicle_arriving_state = VehicleArrivingState::NO;
});
}else{
this->vehicle_arriving_state = VehicleArrivingState::NO;
this->vehicle_leaving_state = VehicleLeavingState::YES;
set_timeout(CLEAR_PRESENCE, [=] {
this->vehicle_leaving_state = VehicleLeavingState::NO;
});
}
}
}
Result RATGDOComponent::call_protocol(Args args) Result RATGDOComponent::call_protocol(Args args)
{ {
return this->protocol_->call(args); return this->protocol_->call(args);
@ -359,7 +442,7 @@ namespace ratgdo {
if (current_millis - last_millis > CHECK_PERIOD) { if (current_millis - last_millis > CHECK_PERIOD) {
// ESP_LOGD(TAG, "%ld: Obstruction count: %d, expected: %d, since asleep: %ld", // ESP_LOGD(TAG, "%ld: Obstruction count: %d, expected: %d, since asleep: %ld",
// current_millis, this->isr_store_.obstruction_low_count, PULSES_EXPECTED, // current_millis, this->isr_store_.obstruction_low_count, PULSES_LOWER_LIMIT,
// current_millis - last_asleep // current_millis - last_asleep
// ); // );
@ -369,7 +452,11 @@ namespace ratgdo {
this->obstruction_sensor_detected_ = true; this->obstruction_sensor_detected_ = true;
} else if (this->isr_store_.obstruction_low_count == 0) { } else if (this->isr_store_.obstruction_low_count == 0) {
// if there have been no pulses the line is steady high or low // if there have been no pulses the line is steady high or low
#ifdef USE_ESP32
if (this->input_obst_pin_->digital_read()) {
#else
if (!this->input_obst_pin_->digital_read()) { if (!this->input_obst_pin_->digital_read()) {
#endif
// asleep // asleep
last_asleep = current_millis; last_asleep = current_millis;
} else { } else {
@ -494,7 +581,15 @@ namespace ratgdo {
void RATGDOComponent::door_action(DoorAction action) void RATGDOComponent::door_action(DoorAction action)
{ {
this->protocol_->door_action(action); if(*this->closing_delay > 0 && action == DoorAction::CLOSE){
this->door_action_delayed = DoorActionDelayed::YES;
set_timeout("door_action", *this->closing_delay * 1000, [=] {
this->door_action_delayed = DoorActionDelayed::NO;
this->protocol_->door_action(DoorAction::CLOSE);
});
}else{
this->protocol_->door_action(action);
}
} }
void RATGDOComponent::door_move_to_position(float position) void RATGDOComponent::door_move_to_position(float position)
@ -614,6 +709,10 @@ namespace ratgdo {
{ {
this->closing_duration.subscribe([=](float state) { defer("closing_duration", [=] { f(state); }); }); this->closing_duration.subscribe([=](float state) { defer("closing_duration", [=] { f(state); }); });
} }
void RATGDOComponent::subscribe_closing_delay(std::function<void(uint32_t)>&& f)
{
this->closing_delay.subscribe([=](uint32_t state) { defer("closing_delay", [=] { f(state); }); });
}
void RATGDOComponent::subscribe_openings(std::function<void(uint16_t)>&& f) void RATGDOComponent::subscribe_openings(std::function<void(uint16_t)>&& f)
{ {
this->openings.subscribe([=](uint16_t state) { defer("openings", [=] { f(state); }); }); this->openings.subscribe([=](uint16_t state) { defer("openings", [=] { f(state); }); });
@ -640,11 +739,14 @@ namespace ratgdo {
} }
void RATGDOComponent::subscribe_door_state(std::function<void(DoorState, float)>&& f) void RATGDOComponent::subscribe_door_state(std::function<void(DoorState, float)>&& f)
{ {
static int num = 0;
auto name = "door_state" + std::to_string(num++);
this->door_state.subscribe([=](DoorState state) { this->door_state.subscribe([=](DoorState state) {
defer("door_state", [=] { f(state, *this->door_position); }); defer(name, [=] { f(state, *this->door_position); });
}); });
this->door_position.subscribe([=](float position) { this->door_position.subscribe([=](float position) {
defer("door_state", [=] { f(*this->door_state, position); }); defer(name, [=] { f(*this->door_state, position); });
}); });
} }
void RATGDOComponent::subscribe_light_state(std::function<void(LightState)>&& f) void RATGDOComponent::subscribe_light_state(std::function<void(LightState)>&& f)
@ -679,6 +781,37 @@ namespace ratgdo {
{ {
this->learn_state.subscribe([=](LearnState state) { defer("learn_state", [=] { f(state); }); }); this->learn_state.subscribe([=](LearnState state) { defer("learn_state", [=] { f(state); }); });
} }
void RATGDOComponent::subscribe_door_action_delayed(std::function<void(DoorActionDelayed)>&& f)
{
static int num = 0;
auto name = "door_action_delayed" + std::to_string(num++);
this->door_action_delayed.subscribe([=](DoorActionDelayed state) { defer(name, [=] { f(state); }); });
}
void RATGDOComponent::subscribe_distance_measurement(std::function<void(int16_t)>&& f)
{
static int num = 0;
auto name = "last_distance_measurement" + std::to_string(num++);
this->last_distance_measurement.subscribe([=](int16_t state) { defer(name, [=] { f(state); }); });
}
void RATGDOComponent::subscribe_vehicle_detected_state(std::function<void(VehicleDetectedState)>&& f)
{
static int num = 0;
auto name = "vehicle_detected_state" + std::to_string(num++);
this->vehicle_detected_state.subscribe([=](VehicleDetectedState state) { defer(name, [=] { f(state); }); });
}
void RATGDOComponent::subscribe_vehicle_arriving_state(std::function<void(VehicleArrivingState)>&& f)
{
static int num = 0;
auto name = "vehicle_arriving_state" + std::to_string(num++);
this->vehicle_arriving_state.subscribe([=](VehicleArrivingState state) { defer(name, [=] { f(state); }); });
}
void RATGDOComponent::subscribe_vehicle_leaving_state(std::function<void(VehicleLeavingState)>&& f)
{
static int num = 0;
auto name = "vehicle_leaving_state" + std::to_string(num++);
this->vehicle_leaving_state.subscribe([=](VehicleLeavingState state) { defer(name, [=] { f(state); }); });
}
// dry contact methods // dry contact methods
void RATGDOComponent::set_dry_contact_open_sensor(esphome::binary_sensor::BinarySensor* dry_contact_open_sensor) void RATGDOComponent::set_dry_contact_open_sensor(esphome::binary_sensor::BinarySensor* dry_contact_open_sensor)

View File

@ -62,6 +62,11 @@ namespace ratgdo {
observable<float> opening_duration { 0 }; observable<float> opening_duration { 0 };
float start_closing { -1 }; float start_closing { -1 };
observable<float> closing_duration { 0 }; observable<float> closing_duration { 0 };
observable<uint32_t> closing_delay { 0 };
observable<int16_t> target_distance_measurement { -1 };
std::vector<int16_t> distance_measurement{std::vector<int16_t>(10,-1)}; // the length of this vector determines how many in-range readings are required for presence detection to change states
observable<int16_t> last_distance_measurement { 0 };
observable<uint16_t> openings { 0 }; // number of times the door has been opened observable<uint16_t> openings { 0 }; // number of times the door has been opened
observable<uint16_t> paired_total { PAIRED_DEVICES_UNKNOWN }; observable<uint16_t> paired_total { PAIRED_DEVICES_UNKNOWN };
@ -72,6 +77,7 @@ namespace ratgdo {
observable<DoorState> door_state { DoorState::UNKNOWN }; observable<DoorState> door_state { DoorState::UNKNOWN };
observable<float> door_position { DOOR_POSITION_UNKNOWN }; observable<float> door_position { DOOR_POSITION_UNKNOWN };
observable<DoorActionDelayed> door_action_delayed { DoorActionDelayed::NO };
unsigned long door_start_moving { 0 }; unsigned long door_start_moving { 0 };
float door_start_position { DOOR_POSITION_UNKNOWN }; float door_start_position { DOOR_POSITION_UNKNOWN };
@ -84,6 +90,9 @@ namespace ratgdo {
observable<ButtonState> button_state { ButtonState::UNKNOWN }; observable<ButtonState> button_state { ButtonState::UNKNOWN };
observable<MotionState> motion_state { MotionState::UNKNOWN }; observable<MotionState> motion_state { MotionState::UNKNOWN };
observable<LearnState> learn_state { LearnState::UNKNOWN }; observable<LearnState> learn_state { LearnState::UNKNOWN };
observable<VehicleDetectedState> vehicle_detected_state { VehicleDetectedState::NO };
observable<VehicleArrivingState> vehicle_arriving_state { VehicleArrivingState::NO };
observable<VehicleLeavingState> vehicle_leaving_state { VehicleLeavingState::NO };
OnceCallbacks<void(DoorState)> on_door_state_; OnceCallbacks<void(DoorState)> on_door_state_;
@ -127,9 +136,14 @@ namespace ratgdo {
void set_door_position(float door_position) { this->door_position = door_position; } void set_door_position(float door_position) { this->door_position = door_position; }
void set_opening_duration(float duration); void set_opening_duration(float duration);
void set_closing_duration(float duration); void set_closing_duration(float duration);
void set_closing_delay(uint32_t delay) { this->closing_delay = delay; }
void schedule_door_position_sync(float update_period = 500); void schedule_door_position_sync(float update_period = 500);
void door_position_update(); void door_position_update();
void cancel_position_sync_callbacks(); void cancel_position_sync_callbacks();
void set_target_distance_measurement(int16_t distance);
void set_distance_measurement(int16_t distance);
void calculate_presence();
void presence_change(bool sensor_value);
// light // light
void light_toggle(); void light_toggle();
@ -158,6 +172,7 @@ namespace ratgdo {
void subscribe_rolling_code_counter(std::function<void(uint32_t)>&& f); void subscribe_rolling_code_counter(std::function<void(uint32_t)>&& f);
void subscribe_opening_duration(std::function<void(float)>&& f); void subscribe_opening_duration(std::function<void(float)>&& f);
void subscribe_closing_duration(std::function<void(float)>&& f); void subscribe_closing_duration(std::function<void(float)>&& f);
void subscribe_closing_delay(std::function<void(uint32_t)>&& f);
void subscribe_openings(std::function<void(uint16_t)>&& f); void subscribe_openings(std::function<void(uint16_t)>&& f);
void subscribe_paired_devices_total(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_remotes(std::function<void(uint16_t)>&& f);
@ -173,11 +188,17 @@ namespace ratgdo {
void subscribe_motion_state(std::function<void(MotionState)>&& f); void subscribe_motion_state(std::function<void(MotionState)>&& f);
void subscribe_sync_failed(std::function<void(bool)>&& f); void subscribe_sync_failed(std::function<void(bool)>&& f);
void subscribe_learn_state(std::function<void(LearnState)>&& f); void subscribe_learn_state(std::function<void(LearnState)>&& f);
void subscribe_door_action_delayed(std::function<void(DoorActionDelayed)>&& f);
void subscribe_distance_measurement(std::function<void(int16_t)>&& f);
void subscribe_vehicle_detected_state(std::function<void(VehicleDetectedState)>&& f);
void subscribe_vehicle_arriving_state(std::function<void(VehicleArrivingState)>&& f);
void subscribe_vehicle_leaving_state(std::function<void(VehicleLeavingState)>&& f);
protected: protected:
RATGDOStore isr_store_ {}; RATGDOStore isr_store_ {};
protocol::Protocol* protocol_; protocol::Protocol* protocol_;
bool obstruction_sensor_detected_ { false }; bool obstruction_sensor_detected_ { false };
bool presence_detect_window_active_ { false };
InternalGPIOPin* output_gdo_pin_; InternalGPIOPin* output_gdo_pin_;
InternalGPIOPin* input_gdo_pin_; InternalGPIOPin* input_gdo_pin_;

View File

@ -25,6 +25,10 @@ namespace ratgdo {
(STOPPED, 3), (STOPPED, 3),
(OPENING, 4), (OPENING, 4),
(CLOSING, 5)) (CLOSING, 5))
ENUM(DoorActionDelayed, uint8_t,
(NO, 0),
(YES, 1))
/// Enum for all states a the light can be in. /// Enum for all states a the light can be in.
ENUM(LightState, uint8_t, ENUM(LightState, uint8_t,
@ -104,6 +108,18 @@ namespace ratgdo {
(STOP, 3), (STOP, 3),
(UNKNOWN, 4)) (UNKNOWN, 4))
ENUM(VehicleDetectedState, uint8_t,
(NO, 0),
(YES, 1))
ENUM(VehicleArrivingState, uint8_t,
(NO, 0),
(YES, 1))
ENUM(VehicleLeavingState, uint8_t,
(NO, 0),
(YES, 1))
struct Openings { struct Openings {
uint16_t count; uint16_t count;
uint8_t flag; uint8_t flag;

View File

@ -2,6 +2,7 @@ import esphome.codegen as cg
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.components import sensor from esphome.components import sensor
from esphome.const import CONF_ID from esphome.const import CONF_ID
CONF_DISTANCE = "distance"
from .. import RATGDO_CLIENT_SCHMEA, ratgdo_ns, register_ratgdo_child from .. import RATGDO_CLIENT_SCHMEA, ratgdo_ns, register_ratgdo_child
@ -18,6 +19,7 @@ TYPES = {
"paired_devices_keypads": RATGDOSensorType.RATGDO_PAIRED_KEYPADS, "paired_devices_keypads": RATGDOSensorType.RATGDO_PAIRED_KEYPADS,
"paired_devices_wall_controls": RATGDOSensorType.RATGDO_PAIRED_WALL_CONTROLS, "paired_devices_wall_controls": RATGDOSensorType.RATGDO_PAIRED_WALL_CONTROLS,
"paired_devices_accessories": RATGDOSensorType.RATGDO_PAIRED_ACCESSORIES, "paired_devices_accessories": RATGDOSensorType.RATGDO_PAIRED_ACCESSORIES,
"distance": RATGDOSensorType.RATGDO_DISTANCE
} }
@ -38,3 +40,15 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
cg.add(var.set_ratgdo_sensor_type(config[CONF_TYPE])) cg.add(var.set_ratgdo_sensor_type(config[CONF_TYPE]))
await register_ratgdo_child(var, config) await register_ratgdo_child(var, config)
if config['type'] == 'distance':
cg.add_library(
name="Wire",
version=None
)
cg.add_library(
name="vl53l4cx",
repository="https://github.com/stm32duino/VL53L4CX",
version=None,
)
cg.add_define("USE_DISTANCE")

View File

@ -33,6 +33,22 @@ namespace ratgdo {
this->parent_->subscribe_paired_accessories([=](uint16_t value) { this->parent_->subscribe_paired_accessories([=](uint16_t value) {
this->publish_state(value); this->publish_state(value);
}); });
} else if (this->ratgdo_sensor_type_ == RATGDOSensorType::RATGDO_DISTANCE) {
#ifdef USE_DISTANCE
this->distance_sensor_.setI2cDevice(&I2C);
this->distance_sensor_.setXShutPin(32);
// I2C.begin(17,16);
I2C.begin(19,18);
this->distance_sensor_.begin();
this->distance_sensor_.VL53L4CX_Off();
this->distance_sensor_.InitSensor(0x59);
this->distance_sensor_.VL53L4CX_SetDistanceMode(VL53L4CX_DISTANCEMODE_LONG);
this->distance_sensor_.VL53L4CX_StartMeasurement();
this->parent_->subscribe_distance_measurement([=](int16_t value) {
this->publish_state(value);
});
#endif
} }
} }
@ -51,8 +67,46 @@ namespace ratgdo {
ESP_LOGCONFIG(TAG, " Type: Paired Wall Controls"); ESP_LOGCONFIG(TAG, " Type: Paired Wall Controls");
} else if (this->ratgdo_sensor_type_ == RATGDOSensorType::RATGDO_PAIRED_ACCESSORIES) { } else if (this->ratgdo_sensor_type_ == RATGDOSensorType::RATGDO_PAIRED_ACCESSORIES) {
ESP_LOGCONFIG(TAG, " Type: Paired Accessories"); ESP_LOGCONFIG(TAG, " Type: Paired Accessories");
} else if (this->ratgdo_sensor_type_ == RATGDOSensorType::RATGDO_DISTANCE) {
ESP_LOGCONFIG(TAG, " Type: Distance");
} }
} }
void RATGDOSensor::loop()
{
#ifdef USE_DISTANCE
if (this->ratgdo_sensor_type_ == RATGDOSensorType::RATGDO_DISTANCE) {
VL53L4CX_MultiRangingData_t distanceData;
VL53L4CX_MultiRangingData_t *pDistanceData = &distanceData;
uint8_t dataReady = 0;
int objCount = 0;
int16_t maxDistance = 0;
int status;
if (this->distance_sensor_.VL53L4CX_GetMeasurementDataReady(&dataReady) == 0 && dataReady) {
status = this->distance_sensor_.VL53L4CX_GetMultiRangingData(pDistanceData);
objCount = pDistanceData->NumberOfObjectsFound;
maxDistance = objCount == 0 ? -1 : pDistanceData->RangeData[objCount - 1].RangeMilliMeter;
/* if(maxDistance < 0) maxDistance = -1;
* if the sensor is pointed at glass, there are many error readings which will fill the
* vector with out of range data. The sensor should be sensitive enough to detect the floor
* in most situations, unless its mounted really far away.
* If this doesn't work, then the vector size will have to increase substantially
*/
if(maxDistance > 0){
this->parent_->set_distance_measurement(maxDistance);
}
// ESP_LOGD(TAG,"# obj found %d; distance %d",objCount, maxDistance);
if (status == 0) {
status = this->distance_sensor_.VL53L4CX_ClearInterruptAndStartMeasurement();
}
}
}
#endif
}
} // namespace ratgdo } // namespace ratgdo
} // namespace esphome } // namespace esphome

View File

@ -5,6 +5,12 @@
#include "esphome/components/sensor/sensor.h" #include "esphome/components/sensor/sensor.h"
#include "esphome/core/component.h" #include "esphome/core/component.h"
#ifdef USE_DISTANCE
#include "Wire.h"
#include "vl53l4cx_class.h"
#define I2C Wire
#endif
namespace esphome { namespace esphome {
namespace ratgdo { namespace ratgdo {
@ -14,17 +20,23 @@ namespace ratgdo {
RATGDO_PAIRED_REMOTES, RATGDO_PAIRED_REMOTES,
RATGDO_PAIRED_KEYPADS, RATGDO_PAIRED_KEYPADS,
RATGDO_PAIRED_WALL_CONTROLS, RATGDO_PAIRED_WALL_CONTROLS,
RATGDO_PAIRED_ACCESSORIES RATGDO_PAIRED_ACCESSORIES,
RATGDO_DISTANCE
}; };
class RATGDOSensor : public sensor::Sensor, public RATGDOClient, public Component { class RATGDOSensor : public sensor::Sensor, public RATGDOClient, public Component {
public: public:
void dump_config() override; void dump_config() override;
void setup() override; void setup() override;
void loop() override;
void set_ratgdo_sensor_type(RATGDOSensorType ratgdo_sensor_type_) { this->ratgdo_sensor_type_ = ratgdo_sensor_type_; } void set_ratgdo_sensor_type(RATGDOSensorType ratgdo_sensor_type_) { this->ratgdo_sensor_type_ = ratgdo_sensor_type_; }
protected: protected:
RATGDOSensorType ratgdo_sensor_type_; RATGDOSensorType ratgdo_sensor_type_;
#ifdef USE_DISTANCE
VL53L4CX distance_sensor_;
#endif
}; };
} // namespace ratgdo } // namespace ratgdo

View File

@ -1,7 +1,8 @@
import esphome.codegen as cg import esphome.codegen as cg
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.components import switch from esphome.components import switch
from esphome.const import CONF_ID from esphome import pins
from esphome.const import CONF_ID, CONF_PIN
from .. import RATGDO_CLIENT_SCHMEA, ratgdo_ns, register_ratgdo_child from .. import RATGDO_CLIENT_SCHMEA, ratgdo_ns, register_ratgdo_child
@ -13,6 +14,7 @@ SwitchType = ratgdo_ns.enum("SwitchType")
CONF_TYPE = "type" CONF_TYPE = "type"
TYPES = { TYPES = {
"learn": SwitchType.RATGDO_LEARN, "learn": SwitchType.RATGDO_LEARN,
"led": SwitchType.RATGDO_LED
} }
@ -21,6 +23,7 @@ CONFIG_SCHEMA = (
.extend( .extend(
{ {
cv.Required(CONF_TYPE): cv.enum(TYPES, lower=True), cv.Required(CONF_TYPE): cv.enum(TYPES, lower=True),
cv.Optional(CONF_PIN): pins.gpio_output_pin_schema,
} }
) )
.extend(RATGDO_CLIENT_SCHMEA) .extend(RATGDO_CLIENT_SCHMEA)
@ -33,3 +36,7 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
cg.add(var.set_switch_type(config[CONF_TYPE])) cg.add(var.set_switch_type(config[CONF_TYPE]))
await register_ratgdo_child(var, config) await register_ratgdo_child(var, config)
if CONF_PIN in config:
pin = await cg.gpio_pin_expression(config[CONF_PIN])
cg.add(var.set_pin(pin))

View File

@ -21,6 +21,11 @@ namespace ratgdo {
this->parent_->subscribe_learn_state([=](LearnState state) { this->parent_->subscribe_learn_state([=](LearnState state) {
this->publish_state(state == LearnState::ACTIVE); this->publish_state(state == LearnState::ACTIVE);
}); });
}else if(this->switch_type_ == SwitchType::RATGDO_LED) {
this->pin_->setup();
this->parent_->subscribe_vehicle_arriving_state([=](VehicleArrivingState state) {
this->write_state(state == VehicleArrivingState::YES);
});
} }
} }
@ -32,6 +37,9 @@ namespace ratgdo {
} else { } else {
this->parent_->inactivate_learn(); this->parent_->inactivate_learn();
} }
} else if(this->switch_type_ == SwitchType::RATGDO_LED){
this->pin_->digital_write(state);
this->publish_state(state);
} }
} }

View File

@ -9,7 +9,8 @@ namespace esphome {
namespace ratgdo { namespace ratgdo {
enum SwitchType { enum SwitchType {
RATGDO_LEARN RATGDO_LEARN,
RATGDO_LED
}; };
class RATGDOSwitch : public switch_::Switch, public RATGDOClient, public Component { class RATGDOSwitch : public switch_::Switch, public RATGDOClient, public Component {
@ -19,9 +20,11 @@ namespace ratgdo {
void set_switch_type(SwitchType switch_type_) { this->switch_type_ = switch_type_; } void set_switch_type(SwitchType switch_type_) { this->switch_type_ = switch_type_; }
void write_state(bool state) override; void write_state(bool state) override;
void set_pin(GPIOPin *pin) { pin_ = pin; }
protected: protected:
SwitchType switch_type_; SwitchType switch_type_;
GPIOPin *pin_;
}; };
} // namespace ratgdo } // namespace ratgdo

View File

@ -33,6 +33,8 @@ packages:
url: https://github.com/ratgdo/esphome-ratgdo url: https://github.com/ratgdo/esphome-ratgdo
files: [base.yaml] files: [base.yaml]
refresh: 1s refresh: 1s
# remote_package: !include
# file: base.yaml
# Sync time with Home Assistant. # Sync time with Home Assistant.
time: time:

View File

@ -34,6 +34,7 @@ packages:
refresh: 1s refresh: 1s
# remote_package: !include # remote_package: !include
# file: base_drycontact.yaml # file: base_drycontact.yaml
# Sync time with Home Assistant. # Sync time with Home Assistant.
time: time:
- platform: homeassistant - platform: homeassistant

65
static/v32board.yaml Normal file
View File

@ -0,0 +1,65 @@
---
substitutions:
id_prefix: ratgdov32
friendly_name: "ratgdov32"
uart_tx_pin: GPIO17
uart_rx_pin: GPIO21
input_obst_pin: GPIO4
status_door_pin: GPIO26
status_obstruction_pin: GPIO25
dry_contact_open_pin: GPIO13
dry_contact_close_pin: GPIO14
dry_contact_light_pin: GPIO27
web_server:
esphome:
name: ${id_prefix}
friendly_name: ${friendly_name}
name_add_mac_suffix: true
project:
name: ratgdo.esphome
version: "32.0"
esp32:
board: esp32dev
dashboard_import:
package_import_url: github://ratgdo/esphome-ratgdo/v32board.yaml@main
packages:
remote_package:
url: https://github.com/ratgdo/esphome-ratgdo
files: [base.yaml]
refresh: 1s
# remote_package: !include
# file: base.yaml
switch:
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_led
type: led
pin: GPIO4
name: "LED"
entity_category: config
sensor:
- platform: wifi_signal
name: "WiFi Signal"
update_interval: 120s
# Sync time with Home Assistant.
time:
- platform: homeassistant
id: homeassistant_time
api:
id: api_server
improv_serial:
wifi:
ap:
logger:

View File

@ -0,0 +1,64 @@
---
substitutions:
id_prefix: ratgdo32disco
friendly_name: "ratgdo32disco"
uart_tx_pin: GPIO17
uart_rx_pin: GPIO21
input_obst_pin: GPIO4
dry_contact_open_pin: GPIO13
dry_contact_close_pin: GPIO14
discrete_open_pin: GPIO26
discrete_close_pin: GPIO25
web_server:
esphome:
name: ${id_prefix}
friendly_name: ${friendly_name}
name_add_mac_suffix: true
project:
name: ratgdo.esphome
version: "32.0"
esp32:
board: esp32dev
dashboard_import:
package_import_url: github://ratgdo/esphome-ratgdo/v32board_drycontact.yaml@main
packages:
remote_package:
url: https://github.com/ratgdo/esphome-ratgdo
files: [base_drycontact.yaml]
refresh: 1s
# remote_package: !include
# file: base_drycontact.yaml
switch:
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_led
type: led
pin: GPIO4
name: "LED"
entity_category: config
sensor:
- platform: wifi_signal
name: "WiFi Signal"
update_interval: 120s
# Sync time with Home Assistant.
time:
- platform: homeassistant
id: homeassistant_time
api:
id: api_server
improv_serial:
wifi:
ap:
logger:

View File

@ -0,0 +1,65 @@
---
substitutions:
id_prefix: ratgdov32
friendly_name: "ratgdov32"
uart_tx_pin: GPIO17
uart_rx_pin: GPIO21
input_obst_pin: GPIO4
status_door_pin: GPIO26
status_obstruction_pin: GPIO25
dry_contact_open_pin: GPIO13
dry_contact_close_pin: GPIO14
dry_contact_light_pin: GPIO27
web_server:
esphome:
name: ${id_prefix}
friendly_name: ${friendly_name}
name_add_mac_suffix: true
project:
name: ratgdo.esphome
version: "32.0"
esp32:
board: esp32dev
dashboard_import:
package_import_url: github://ratgdo/esphome-ratgdo/v32board_secplusv1.yaml@main
packages:
remote_package:
url: https://github.com/ratgdo/esphome-ratgdo
files: [base_secplusv1.yaml]
refresh: 1s
# remote_package: !include
# file: base_secplusv1.yaml
switch:
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_led
type: led
pin: GPIO4
name: "LED"
entity_category: config
sensor:
- platform: wifi_signal
name: "WiFi Signal"
update_interval: 120s
# Sync time with Home Assistant.
time:
- platform: homeassistant
id: homeassistant_time
api:
id: api_server
improv_serial:
wifi:
ap:
logger:

149
static/v32disco.yaml Normal file
View File

@ -0,0 +1,149 @@
---
substitutions:
id_prefix: ratgdo32disco
friendly_name: "ratgdo32disco"
uart_tx_pin: GPIO17
uart_rx_pin: GPIO21
input_obst_pin: GPIO4
status_door_pin: GPIO26
status_obstruction_pin: GPIO25
dry_contact_open_pin: GPIO13
dry_contact_close_pin: GPIO14
dry_contact_light_pin: GPIO27
web_server:
esphome:
name: ${id_prefix}
friendly_name: ${friendly_name}
name_add_mac_suffix: true
project:
name: ratgdo.esphome
version: "32disco"
esp32:
board: esp32dev
dashboard_import:
package_import_url: github://ratgdo/esphome-ratgdo/v32disco.yaml@main
packages:
remote_package:
url: https://github.com/ratgdo/esphome-ratgdo
files: [base.yaml]
refresh: 1s
# remote_package: !include
# file: base.yaml
# Sync time with Home Assistant.
time:
- platform: homeassistant
id: homeassistant_time
api:
id: api_server
improv_serial:
binary_sensor:
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_vehicle_detected
type: vehicle_detected
name: "Vehicle detected"
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_vehicle_arriving
type: vehicle_arriving
name: "Vehicle arriving"
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_vehicle_leaving
type: vehicle_leaving
name: "Vehicle leaving"
number:
- platform: ratgdo
id: ${id_prefix}_target_distance_measurement
type: target_distance_measurement
entity_category: config
ratgdo_id: ${id_prefix}
name: "Vehicle distance target"
mode: box
unit_of_measurement: "mm"
- platform: ratgdo
id: ${id_prefix}_closing_delay
type: closing_delay
entity_category: config
ratgdo_id: ${id_prefix}
name: "Closing Delay"
unit_of_measurement: "s"
output:
- platform: ledc
pin: GPIO33
id: ${id_prefix}_ledc
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_beeper
type: beeper
rtttl: ${id_prefix}_rtttl
song: "alert:d=8,o=5,b=120:a,p,a,p,a,p,4b,p"
rtttl:
- id: ${id_prefix}_rtttl
output: ${id_prefix}_ledc
switch:
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_led
type: led
pin: GPIO2
name: "LED"
entity_category: config
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_laser
type: led
pin: GPIO23
name: "LASER"
entity_category: config
sensor:
- platform: wifi_signal
name: "WiFi Signal"
update_interval: 120s
- platform: ratgdo
id: ${id_prefix}_vehicle_distance_actual
type: distance
name: "Vehicle distance actual"
ratgdo_id: ${id_prefix}
unit_of_measurement: "mm"
filters:
- throttle: 1s
- filter_out: -1
- median:
window_size: 20
send_every: 5
send_first_at: 5
- platform: adc
pin: GPIO34
name: "Voltage"
attenuation: auto
update_interval: 60s
filters:
- calibrate_linear:
- 1.16 -> 5
- 2.783 -> 12
# uncomment to convert voltage scale to a % for lead acid batteries
# - 2.43 -> 0 # 10.5v = 0%
# - 2.98 -> 100 # 12.85 = 100%
# - clamp:
# min_value: 0
# max_value: 100
# unit_of_measurement: "%"
logger:
ota:

View File

@ -0,0 +1,141 @@
---
substitutions:
id_prefix: ratgdo32disco
friendly_name: "ratgdo32disco"
uart_tx_pin: GPIO17
uart_rx_pin: GPIO21
input_obst_pin: GPIO4
dry_contact_open_pin: GPIO13
dry_contact_close_pin: GPIO14
discrete_open_pin: GPIO26
discrete_close_pin: GPIO25
web_server:
esphome:
name: ${id_prefix}
friendly_name: ${friendly_name}
name_add_mac_suffix: true
project:
name: ratgdo.esphome
version: "32disco"
esp32:
board: esp32dev
dashboard_import:
package_import_url: github://ratgdo/esphome-ratgdo/v32disco_drycontact.yaml@main
packages:
remote_package:
url: https://github.com/ratgdo/esphome-ratgdo
files: [base_drycontact.yaml]
refresh: 1s
# remote_package: !include
# file: base_drycontact.yaml
# Sync time with Home Assistant.
time:
- platform: homeassistant
id: homeassistant_time
api:
id: api_server
improv_serial:
binary_sensor:
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_vehicle_detected
type: vehicle_detected
name: "Vehicle detected"
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_vehicle_arriving
type: vehicle_arriving
name: "Vehicle arriving"
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_vehicle_leaving
type: vehicle_leaving
name: "Vehicle leaving"
number:
- platform: ratgdo
id: ${id_prefix}_target_distance_measurement
type: target_distance_measurement
entity_category: config
ratgdo_id: ${id_prefix}
name: "Vehicle distance target"
mode: box
unit_of_measurement: "mm"
- platform: ratgdo
id: ${id_prefix}_closing_delay
type: closing_delay
entity_category: config
ratgdo_id: ${id_prefix}
name: "Closing Delay"
unit_of_measurement: "s"
output:
- platform: ledc
pin: GPIO33
id: ${id_prefix}_ledc
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_beeper
type: beeper
rtttl: ${id_prefix}_rtttl
song: "alert:d=8,o=5,b=120:a,p,a,p,a,p,4b,p"
rtttl:
- id: ${id_prefix}_rtttl
output: ${id_prefix}_ledc
switch:
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_led
type: led
pin: GPIO2
name: "LED"
entity_category: config
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_laser
type: led
pin: GPIO23
name: "LASER"
entity_category: config
sensor:
- platform: wifi_signal
name: "WiFi Signal"
update_interval: 120s
- platform: ratgdo
id: ${id_prefix}_vehicle_distance_actual
type: distance
name: "Vehicle distance actual"
ratgdo_id: ${id_prefix}
unit_of_measurement: "mm"
filters:
- throttle: 10s
- filter_out: -1
- median:
window_size: 20
send_every: 5
send_first_at: 5
- platform: adc
pin: GPIO34
name: "Voltage"
attenuation: auto
update_interval: 60s
filters:
- calibrate_linear:
- 1.16 -> 5
- 2.783 -> 12
logger:
ota:

View File

@ -0,0 +1,142 @@
---
substitutions:
id_prefix: ratgdo32disco
friendly_name: "ratgdo32disco"
uart_tx_pin: GPIO17
uart_rx_pin: GPIO21
input_obst_pin: GPIO4
status_door_pin: GPIO26
status_obstruction_pin: GPIO25
dry_contact_open_pin: GPIO13
dry_contact_close_pin: GPIO14
dry_contact_light_pin: GPIO27
web_server:
esphome:
name: ${id_prefix}
friendly_name: ${friendly_name}
name_add_mac_suffix: true
project:
name: ratgdo.esphome
version: "32disco"
esp32:
board: esp32dev
dashboard_import:
package_import_url: github://ratgdo/esphome-ratgdo/v32disco_secplusv1.yaml@main
packages:
remote_package:
url: https://github.com/ratgdo/esphome-ratgdo
files: [base_secplusv1.yaml]
refresh: 1s
# remote_package: !include
# file: base_secplusv1.yaml
# Sync time with Home Assistant.
time:
- platform: homeassistant
id: homeassistant_time
api:
id: api_server
improv_serial:
binary_sensor:
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_vehicle_detected
type: vehicle_detected
name: "Vehicle detected"
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_vehicle_arriving
type: vehicle_arriving
name: "Vehicle arriving"
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_vehicle_leaving
type: vehicle_leaving
name: "Vehicle leaving"
number:
- platform: ratgdo
id: ${id_prefix}_target_distance_measurement
type: target_distance_measurement
entity_category: config
ratgdo_id: ${id_prefix}
name: "Vehicle distance target"
mode: box
unit_of_measurement: "mm"
- platform: ratgdo
id: ${id_prefix}_closing_delay
type: closing_delay
entity_category: config
ratgdo_id: ${id_prefix}
name: "Closing Delay"
unit_of_measurement: "s"
output:
- platform: ledc
pin: GPIO33
id: ${id_prefix}_ledc
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_beeper
type: beeper
rtttl: ${id_prefix}_rtttl
song: "alert:d=8,o=5,b=120:a,p,a,p,a,p,4b,p"
rtttl:
- id: ${id_prefix}_rtttl
output: ${id_prefix}_ledc
switch:
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_led
type: led
pin: GPIO2
name: "LED"
entity_category: config
- platform: ratgdo
ratgdo_id: ${id_prefix}
id: ${id_prefix}_laser
type: led
pin: GPIO23
name: "LASER"
entity_category: config
sensor:
- platform: wifi_signal
name: "WiFi Signal"
update_interval: 120s
- platform: ratgdo
id: ${id_prefix}_vehicle_distance_actual
type: distance
name: "Vehicle distance actual"
ratgdo_id: ${id_prefix}
unit_of_measurement: "mm"
filters:
- throttle: 10s
- filter_out: -1
- median:
window_size: 20
send_every: 5
send_first_at: 5
- platform: adc
pin: GPIO34
name: "Voltage"
attenuation: auto
update_interval: 60s
filters:
- calibrate_linear:
- 1.16 -> 5
- 2.783 -> 12
logger:
ota:

1
v32board.yaml Symbolic link
View File

@ -0,0 +1 @@
static/v32board.yaml

1
v32board_drycontact.yaml Symbolic link
View File

@ -0,0 +1 @@
static/v32board_drycontact.yaml

1
v32board_secplusv1.yaml Symbolic link
View File

@ -0,0 +1 @@
static/v32board_secplusv1.yaml

1
v32disco.yaml Symbolic link
View File

@ -0,0 +1 @@
static/v32disco.yaml

1
v32disco_drycontact.yaml Symbolic link
View File

@ -0,0 +1 @@
static/v32disco_drycontact.yaml

1
v32disco_secplusv1.yaml Symbolic link
View File

@ -0,0 +1 @@
static/v32disco_secplusv1.yaml