From f68d126fb8b76af4858b60e2e418e738b17c1e64 Mon Sep 17 00:00:00 2001 From: Paul Wieland Date: Mon, 28 Oct 2024 13:56:16 -0400 Subject: [PATCH 01/12] ratgdo32 --- base.yaml | 4 +- base_drycontact.yaml | 6 +- base_secplusv1.yaml | 3 + components/ratgdo/__init__.py | 2 +- components/ratgdo/binary_sensor/__init__.py | 3 + .../binary_sensor/ratgdo_binary_sensor.cpp | 22 +++ .../binary_sensor/ratgdo_binary_sensor.h | 5 +- components/ratgdo/number/__init__.py | 2 + components/ratgdo/number/ratgdo_number.cpp | 24 +++ components/ratgdo/number/ratgdo_number.h | 2 + components/ratgdo/output/__init__.py | 36 +++++ components/ratgdo/output/ratgdo_output.cpp | 53 +++++++ components/ratgdo/output/ratgdo_output.h | 32 ++++ components/ratgdo/ratgdo.cpp | 141 ++++++++++++++++- components/ratgdo/ratgdo.h | 21 +++ components/ratgdo/ratgdo_state.h | 16 ++ components/ratgdo/sensor/__init__.py | 14 ++ components/ratgdo/sensor/ratgdo_sensor.cpp | 54 +++++++ components/ratgdo/sensor/ratgdo_sensor.h | 14 +- components/ratgdo/switch/__init__.py | 9 +- components/ratgdo/switch/ratgdo_switch.cpp | 8 + components/ratgdo/switch/ratgdo_switch.h | 5 +- static/v25iboard.yaml | 2 + static/v25iboard_drycontact.yaml | 1 + static/v32board.yaml | 65 ++++++++ static/v32board_drycontact.yaml | 64 ++++++++ static/v32board_secplusv1.yaml | 65 ++++++++ static/v32disco.yaml | 149 ++++++++++++++++++ static/v32disco_drycontact.yaml | 141 +++++++++++++++++ static/v32disco_secplusv1.yaml | 142 +++++++++++++++++ v32board.yaml | 1 + v32board_drycontact.yaml | 1 + v32board_secplusv1.yaml | 1 + v32disco.yaml | 1 + v32disco_drycontact.yaml | 1 + v32disco_secplusv1.yaml | 1 + 36 files changed, 1099 insertions(+), 12 deletions(-) create mode 100644 components/ratgdo/output/__init__.py create mode 100644 components/ratgdo/output/ratgdo_output.cpp create mode 100644 components/ratgdo/output/ratgdo_output.h create mode 100644 static/v32board.yaml create mode 100644 static/v32board_drycontact.yaml create mode 100644 static/v32board_secplusv1.yaml create mode 100644 static/v32disco.yaml create mode 100644 static/v32disco_drycontact.yaml create mode 100644 static/v32disco_secplusv1.yaml create mode 120000 v32board.yaml create mode 120000 v32board_drycontact.yaml create mode 120000 v32board_secplusv1.yaml create mode 120000 v32disco.yaml create mode 120000 v32disco_drycontact.yaml create mode 120000 v32disco_secplusv1.yaml diff --git a/base.yaml b/base.yaml index 7511fe3..79c4d64 100644 --- a/base.yaml +++ b/base.yaml @@ -1,10 +1,12 @@ --- - external_components: - source: type: git url: https://github.com/ratgdo/esphome-ratgdo refresh: 1s + # - source: + # type: local + # path: components safe_mode: diff --git a/base_drycontact.yaml b/base_drycontact.yaml index 84b172b..d683a54 100644 --- a/base_drycontact.yaml +++ b/base_drycontact.yaml @@ -2,11 +2,12 @@ external_components: - source: - # type: local - # path: components type: git url: https://github.com/ratgdo/esphome-ratgdo refresh: 1s + # - source: + # type: local + # path: components safe_mode: @@ -20,6 +21,7 @@ text_sensor: ratgdo: id: ${id_prefix} output_gdo_pin: ${uart_tx_pin} + input_gdo_pin: ${uart_rx_pin} input_obst_pin: ${input_obst_pin} dry_contact_open_sensor: ${id_prefix}_dry_contact_open dry_contact_close_sensor: ${id_prefix}_dry_contact_close diff --git a/base_secplusv1.yaml b/base_secplusv1.yaml index 4248cac..a1331f2 100644 --- a/base_secplusv1.yaml +++ b/base_secplusv1.yaml @@ -5,6 +5,9 @@ external_components: type: git url: https://github.com/ratgdo/esphome-ratgdo refresh: 1s + # - source: + # type: local + # path: components safe_mode: diff --git a/components/ratgdo/__init__.py b/components/ratgdo/__init__.py index 5153cad..a6493c7 100644 --- a/components/ratgdo/__init__.py +++ b/components/ratgdo/__init__.py @@ -144,4 +144,4 @@ async def to_code(config): cg.add(var.set_discrete_open_pin(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]) - cg.add(var.set_discrete_close_pin(pin)) + cg.add(var.set_discrete_close_pin(pin)) \ No newline at end of file diff --git a/components/ratgdo/binary_sensor/__init__.py b/components/ratgdo/binary_sensor/__init__.py index 91a215c..7025eb8 100644 --- a/components/ratgdo/binary_sensor/__init__.py +++ b/components/ratgdo/binary_sensor/__init__.py @@ -18,6 +18,9 @@ TYPES = { "obstruction": SensorType.RATGDO_SENSOR_OBSTRUCTION, "motor": SensorType.RATGDO_SENSOR_MOTOR, "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, } diff --git a/components/ratgdo/binary_sensor/ratgdo_binary_sensor.cpp b/components/ratgdo/binary_sensor/ratgdo_binary_sensor.cpp index 456058c..ffd2985 100644 --- a/components/ratgdo/binary_sensor/ratgdo_binary_sensor.cpp +++ b/components/ratgdo/binary_sensor/ratgdo_binary_sensor.cpp @@ -28,6 +28,22 @@ namespace ratgdo { this->parent_->subscribe_button_state([=](ButtonState state) { 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"); } else if (this->binary_sensor_type_ == SensorType::RATGDO_SENSOR_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"); } } diff --git a/components/ratgdo/binary_sensor/ratgdo_binary_sensor.h b/components/ratgdo/binary_sensor/ratgdo_binary_sensor.h index 9e3315a..1d738c3 100644 --- a/components/ratgdo/binary_sensor/ratgdo_binary_sensor.h +++ b/components/ratgdo/binary_sensor/ratgdo_binary_sensor.h @@ -12,7 +12,10 @@ namespace ratgdo { RATGDO_SENSOR_MOTION, RATGDO_SENSOR_OBSTRUCTION, 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 { diff --git a/components/ratgdo/number/__init__.py b/components/ratgdo/number/__init__.py index 59bd7d2..2ffc1dc 100644 --- a/components/ratgdo/number/__init__.py +++ b/components/ratgdo/number/__init__.py @@ -16,6 +16,8 @@ TYPES = { "rolling_code_counter": NumberType.RATGDO_ROLLING_CODE_COUNTER, "opening_duration": NumberType.RATGDO_OPENING_DURATION, "closing_duration": NumberType.RATGDO_CLOSING_DURATION, + "closing_delay": NumberType.RATGDO_CLOSING_DELAY, + "target_distance_measurement": NumberType.RATGDO_TARGET_DISTANCE_MEASUREMENT, } diff --git a/components/ratgdo/number/ratgdo_number.cpp b/components/ratgdo/number/ratgdo_number.cpp index 68df7b5..e3fd1a1 100644 --- a/components/ratgdo/number/ratgdo_number.cpp +++ b/components/ratgdo/number/ratgdo_number.cpp @@ -30,6 +30,10 @@ namespace ratgdo { ESP_LOGCONFIG(TAG, " Type: Opening Duration"); } else if (this->number_type_ == RATGDO_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->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_min_value(0.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) { this->traits.set_max_value(0xfffffff); } else if (this->number_type_ == RATGDO_CLIENT_ID) { this->traits.set_step(0x1000); this->traits.set_min_value(0x539); 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); } else if (this->number_type_ == RATGDO_CLOSING_DURATION) { 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) { value = normalize_client_id(value); this->parent_->call_protocol(SetClientID { static_cast(value) }); + } else if (this->number_type_ == RATGDO_TARGET_DISTANCE_MEASUREMENT) { + this->parent_->set_target_distance_measurement(value); } this->update_state(value); } diff --git a/components/ratgdo/number/ratgdo_number.h b/components/ratgdo/number/ratgdo_number.h index e5f78f6..cd85130 100644 --- a/components/ratgdo/number/ratgdo_number.h +++ b/components/ratgdo/number/ratgdo_number.h @@ -13,6 +13,8 @@ namespace ratgdo { RATGDO_ROLLING_CODE_COUNTER, RATGDO_OPENING_DURATION, RATGDO_CLOSING_DURATION, + RATGDO_CLOSING_DELAY, + RATGDO_TARGET_DISTANCE_MEASUREMENT, }; class RATGDONumber : public number::Number, public RATGDOClient, public Component { diff --git a/components/ratgdo/output/__init__.py b/components/ratgdo/output/__init__.py new file mode 100644 index 0000000..957ac21 --- /dev/null +++ b/components/ratgdo/output/__init__.py @@ -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) diff --git a/components/ratgdo/output/ratgdo_output.cpp b/components/ratgdo/output/ratgdo_output.cpp new file mode 100644 index 0000000..c67a8e1 --- /dev/null +++ b/components/ratgdo/output/ratgdo_output.cpp @@ -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 \ No newline at end of file diff --git a/components/ratgdo/output/ratgdo_output.h b/components/ratgdo/output/ratgdo_output.h new file mode 100644 index 0000000..873bb73 --- /dev/null +++ b/components/ratgdo/output/ratgdo_output.h @@ -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 \ No newline at end of file diff --git a/components/ratgdo/ratgdo.cpp b/components/ratgdo/ratgdo.cpp index 90cb713..9063bf4 100644 --- a/components/ratgdo/ratgdo.cpp +++ b/components/ratgdo/ratgdo.cpp @@ -30,6 +30,9 @@ namespace ratgdo { static const char* const TAG = "ratgdo"; 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() { 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_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); +#endif 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_); @@ -51,6 +58,24 @@ namespace ratgdo { ESP_LOGD(TAG, "| -| | | | | | | | | | |"); ESP_LOGD(TAG, "|__|__|__|__| |_| |_____|____/|_____|"); 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 @@ -335,6 +360,64 @@ namespace ratgdo { 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) { return this->protocol_->call(args); @@ -359,7 +442,7 @@ namespace ratgdo { if (current_millis - last_millis > CHECK_PERIOD) { // 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 // ); @@ -369,7 +452,11 @@ namespace ratgdo { this->obstruction_sensor_detected_ = true; } else if (this->isr_store_.obstruction_low_count == 0) { // 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()) { +#endif // asleep last_asleep = current_millis; } else { @@ -494,7 +581,15 @@ namespace ratgdo { 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) @@ -614,6 +709,10 @@ namespace ratgdo { { this->closing_duration.subscribe([=](float state) { defer("closing_duration", [=] { f(state); }); }); } + void RATGDOComponent::subscribe_closing_delay(std::function&& f) + { + this->closing_delay.subscribe([=](uint32_t state) { defer("closing_delay", [=] { f(state); }); }); + } void RATGDOComponent::subscribe_openings(std::function&& f) { this->openings.subscribe([=](uint16_t state) { defer("openings", [=] { f(state); }); }); @@ -640,11 +739,14 @@ namespace ratgdo { } void RATGDOComponent::subscribe_door_state(std::function&& f) { + static int num = 0; + auto name = "door_state" + std::to_string(num++); + 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) { - defer("door_state", [=] { f(*this->door_state, position); }); + defer(name, [=] { f(*this->door_state, position); }); }); } void RATGDOComponent::subscribe_light_state(std::function&& f) @@ -679,6 +781,37 @@ namespace ratgdo { { this->learn_state.subscribe([=](LearnState state) { defer("learn_state", [=] { f(state); }); }); } + void RATGDOComponent::subscribe_door_action_delayed(std::function&& 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&& 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&& 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&& 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&& 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 void RATGDOComponent::set_dry_contact_open_sensor(esphome::binary_sensor::BinarySensor* dry_contact_open_sensor) diff --git a/components/ratgdo/ratgdo.h b/components/ratgdo/ratgdo.h index 228d5bc..a6524ac 100644 --- a/components/ratgdo/ratgdo.h +++ b/components/ratgdo/ratgdo.h @@ -62,6 +62,11 @@ namespace ratgdo { observable opening_duration { 0 }; float start_closing { -1 }; observable closing_duration { 0 }; + observable closing_delay { 0 }; + + observable target_distance_measurement { -1 }; + std::vector distance_measurement{std::vector(10,-1)}; // the length of this vector determines how many in-range readings are required for presence detection to change states + observable last_distance_measurement { 0 }; observable openings { 0 }; // number of times the door has been opened observable paired_total { PAIRED_DEVICES_UNKNOWN }; @@ -72,6 +77,7 @@ namespace ratgdo { observable door_state { DoorState::UNKNOWN }; observable door_position { DOOR_POSITION_UNKNOWN }; + observable door_action_delayed { DoorActionDelayed::NO }; unsigned long door_start_moving { 0 }; float door_start_position { DOOR_POSITION_UNKNOWN }; @@ -84,6 +90,9 @@ namespace ratgdo { observable button_state { ButtonState::UNKNOWN }; observable motion_state { MotionState::UNKNOWN }; observable learn_state { LearnState::UNKNOWN }; + observable vehicle_detected_state { VehicleDetectedState::NO }; + observable vehicle_arriving_state { VehicleArrivingState::NO }; + observable vehicle_leaving_state { VehicleLeavingState::NO }; OnceCallbacks on_door_state_; @@ -127,9 +136,14 @@ namespace ratgdo { void set_door_position(float door_position) { this->door_position = door_position; } void set_opening_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 door_position_update(); 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 void light_toggle(); @@ -158,6 +172,7 @@ namespace ratgdo { void subscribe_rolling_code_counter(std::function&& f); void subscribe_opening_duration(std::function&& f); void subscribe_closing_duration(std::function&& f); + void subscribe_closing_delay(std::function&& f); void subscribe_openings(std::function&& f); void subscribe_paired_devices_total(std::function&& f); void subscribe_paired_remotes(std::function&& f); @@ -173,11 +188,17 @@ namespace ratgdo { void subscribe_motion_state(std::function&& f); void subscribe_sync_failed(std::function&& f); void subscribe_learn_state(std::function&& f); + void subscribe_door_action_delayed(std::function&& f); + void subscribe_distance_measurement(std::function&& f); + void subscribe_vehicle_detected_state(std::function&& f); + void subscribe_vehicle_arriving_state(std::function&& f); + void subscribe_vehicle_leaving_state(std::function&& f); protected: RATGDOStore isr_store_ {}; protocol::Protocol* protocol_; bool obstruction_sensor_detected_ { false }; + bool presence_detect_window_active_ { false }; InternalGPIOPin* output_gdo_pin_; InternalGPIOPin* input_gdo_pin_; diff --git a/components/ratgdo/ratgdo_state.h b/components/ratgdo/ratgdo_state.h index f71440a..f541e6e 100644 --- a/components/ratgdo/ratgdo_state.h +++ b/components/ratgdo/ratgdo_state.h @@ -25,6 +25,10 @@ namespace ratgdo { (STOPPED, 3), (OPENING, 4), (CLOSING, 5)) + + ENUM(DoorActionDelayed, uint8_t, + (NO, 0), + (YES, 1)) /// Enum for all states a the light can be in. ENUM(LightState, uint8_t, @@ -104,6 +108,18 @@ namespace ratgdo { (STOP, 3), (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 { uint16_t count; uint8_t flag; diff --git a/components/ratgdo/sensor/__init__.py b/components/ratgdo/sensor/__init__.py index 5a593c7..70b44dd 100644 --- a/components/ratgdo/sensor/__init__.py +++ b/components/ratgdo/sensor/__init__.py @@ -2,6 +2,7 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome.components import sensor from esphome.const import CONF_ID +CONF_DISTANCE = "distance" from .. import RATGDO_CLIENT_SCHMEA, ratgdo_ns, register_ratgdo_child @@ -18,6 +19,7 @@ TYPES = { "paired_devices_keypads": RATGDOSensorType.RATGDO_PAIRED_KEYPADS, "paired_devices_wall_controls": RATGDOSensorType.RATGDO_PAIRED_WALL_CONTROLS, "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) cg.add(var.set_ratgdo_sensor_type(config[CONF_TYPE])) 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") diff --git a/components/ratgdo/sensor/ratgdo_sensor.cpp b/components/ratgdo/sensor/ratgdo_sensor.cpp index e28290a..c79cfe6 100644 --- a/components/ratgdo/sensor/ratgdo_sensor.cpp +++ b/components/ratgdo/sensor/ratgdo_sensor.cpp @@ -33,6 +33,22 @@ namespace ratgdo { this->parent_->subscribe_paired_accessories([=](uint16_t 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"); } else if (this->ratgdo_sensor_type_ == RATGDOSensorType::RATGDO_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 esphome diff --git a/components/ratgdo/sensor/ratgdo_sensor.h b/components/ratgdo/sensor/ratgdo_sensor.h index 3a3517c..cf405d4 100644 --- a/components/ratgdo/sensor/ratgdo_sensor.h +++ b/components/ratgdo/sensor/ratgdo_sensor.h @@ -5,6 +5,12 @@ #include "esphome/components/sensor/sensor.h" #include "esphome/core/component.h" +#ifdef USE_DISTANCE + #include "Wire.h" + #include "vl53l4cx_class.h" + #define I2C Wire +#endif + namespace esphome { namespace ratgdo { @@ -14,17 +20,23 @@ namespace ratgdo { RATGDO_PAIRED_REMOTES, RATGDO_PAIRED_KEYPADS, RATGDO_PAIRED_WALL_CONTROLS, - RATGDO_PAIRED_ACCESSORIES + RATGDO_PAIRED_ACCESSORIES, + RATGDO_DISTANCE }; class RATGDOSensor : public sensor::Sensor, public RATGDOClient, public Component { public: void dump_config() override; void setup() override; + void loop() override; void set_ratgdo_sensor_type(RATGDOSensorType ratgdo_sensor_type_) { this->ratgdo_sensor_type_ = ratgdo_sensor_type_; } protected: RATGDOSensorType ratgdo_sensor_type_; + +#ifdef USE_DISTANCE + VL53L4CX distance_sensor_; +#endif }; } // namespace ratgdo diff --git a/components/ratgdo/switch/__init__.py b/components/ratgdo/switch/__init__.py index 9028cca..786d9c8 100644 --- a/components/ratgdo/switch/__init__.py +++ b/components/ratgdo/switch/__init__.py @@ -1,7 +1,8 @@ import esphome.codegen as cg import esphome.config_validation as cv 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 @@ -13,6 +14,7 @@ SwitchType = ratgdo_ns.enum("SwitchType") CONF_TYPE = "type" TYPES = { "learn": SwitchType.RATGDO_LEARN, + "led": SwitchType.RATGDO_LED } @@ -21,6 +23,7 @@ CONFIG_SCHEMA = ( .extend( { cv.Required(CONF_TYPE): cv.enum(TYPES, lower=True), + cv.Optional(CONF_PIN): pins.gpio_output_pin_schema, } ) .extend(RATGDO_CLIENT_SCHMEA) @@ -33,3 +36,7 @@ async def to_code(config): await cg.register_component(var, config) cg.add(var.set_switch_type(config[CONF_TYPE])) 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)) + diff --git a/components/ratgdo/switch/ratgdo_switch.cpp b/components/ratgdo/switch/ratgdo_switch.cpp index b0f911c..18a589a 100644 --- a/components/ratgdo/switch/ratgdo_switch.cpp +++ b/components/ratgdo/switch/ratgdo_switch.cpp @@ -21,6 +21,11 @@ namespace ratgdo { this->parent_->subscribe_learn_state([=](LearnState state) { 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 { this->parent_->inactivate_learn(); } + } else if(this->switch_type_ == SwitchType::RATGDO_LED){ + this->pin_->digital_write(state); + this->publish_state(state); } } diff --git a/components/ratgdo/switch/ratgdo_switch.h b/components/ratgdo/switch/ratgdo_switch.h index 3640bec..8b195df 100644 --- a/components/ratgdo/switch/ratgdo_switch.h +++ b/components/ratgdo/switch/ratgdo_switch.h @@ -9,7 +9,8 @@ namespace esphome { namespace ratgdo { enum SwitchType { - RATGDO_LEARN + RATGDO_LEARN, + RATGDO_LED }; 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 write_state(bool state) override; + void set_pin(GPIOPin *pin) { pin_ = pin; } protected: SwitchType switch_type_; + GPIOPin *pin_; }; } // namespace ratgdo diff --git a/static/v25iboard.yaml b/static/v25iboard.yaml index 98bb6b8..52d2079 100644 --- a/static/v25iboard.yaml +++ b/static/v25iboard.yaml @@ -33,6 +33,8 @@ packages: url: https://github.com/ratgdo/esphome-ratgdo files: [base.yaml] refresh: 1s + # remote_package: !include + # file: base.yaml # Sync time with Home Assistant. time: diff --git a/static/v25iboard_drycontact.yaml b/static/v25iboard_drycontact.yaml index 2d50afc..3f14f46 100644 --- a/static/v25iboard_drycontact.yaml +++ b/static/v25iboard_drycontact.yaml @@ -34,6 +34,7 @@ packages: refresh: 1s # remote_package: !include # file: base_drycontact.yaml + # Sync time with Home Assistant. time: - platform: homeassistant diff --git a/static/v32board.yaml b/static/v32board.yaml new file mode 100644 index 0000000..2f9a0a3 --- /dev/null +++ b/static/v32board.yaml @@ -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: \ No newline at end of file diff --git a/static/v32board_drycontact.yaml b/static/v32board_drycontact.yaml new file mode 100644 index 0000000..7f89fe7 --- /dev/null +++ b/static/v32board_drycontact.yaml @@ -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: \ No newline at end of file diff --git a/static/v32board_secplusv1.yaml b/static/v32board_secplusv1.yaml new file mode 100644 index 0000000..2a0f75a --- /dev/null +++ b/static/v32board_secplusv1.yaml @@ -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: \ No newline at end of file diff --git a/static/v32disco.yaml b/static/v32disco.yaml new file mode 100644 index 0000000..bfb14ac --- /dev/null +++ b/static/v32disco.yaml @@ -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: \ No newline at end of file diff --git a/static/v32disco_drycontact.yaml b/static/v32disco_drycontact.yaml new file mode 100644 index 0000000..99fc1d2 --- /dev/null +++ b/static/v32disco_drycontact.yaml @@ -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: \ No newline at end of file diff --git a/static/v32disco_secplusv1.yaml b/static/v32disco_secplusv1.yaml new file mode 100644 index 0000000..1bbd06a --- /dev/null +++ b/static/v32disco_secplusv1.yaml @@ -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: \ No newline at end of file diff --git a/v32board.yaml b/v32board.yaml new file mode 120000 index 0000000..4f67680 --- /dev/null +++ b/v32board.yaml @@ -0,0 +1 @@ +static/v32board.yaml \ No newline at end of file diff --git a/v32board_drycontact.yaml b/v32board_drycontact.yaml new file mode 120000 index 0000000..892ccfa --- /dev/null +++ b/v32board_drycontact.yaml @@ -0,0 +1 @@ +static/v32board_drycontact.yaml \ No newline at end of file diff --git a/v32board_secplusv1.yaml b/v32board_secplusv1.yaml new file mode 120000 index 0000000..71c7430 --- /dev/null +++ b/v32board_secplusv1.yaml @@ -0,0 +1 @@ +static/v32board_secplusv1.yaml \ No newline at end of file diff --git a/v32disco.yaml b/v32disco.yaml new file mode 120000 index 0000000..8a4d4be --- /dev/null +++ b/v32disco.yaml @@ -0,0 +1 @@ +static/v32disco.yaml \ No newline at end of file diff --git a/v32disco_drycontact.yaml b/v32disco_drycontact.yaml new file mode 120000 index 0000000..278419c --- /dev/null +++ b/v32disco_drycontact.yaml @@ -0,0 +1 @@ +static/v32disco_drycontact.yaml \ No newline at end of file diff --git a/v32disco_secplusv1.yaml b/v32disco_secplusv1.yaml new file mode 120000 index 0000000..8d32965 --- /dev/null +++ b/v32disco_secplusv1.yaml @@ -0,0 +1 @@ +static/v32disco_secplusv1.yaml \ No newline at end of file From 516eb29d967abfb84397e11454f828c05aa45eee Mon Sep 17 00:00:00 2001 From: Paul Wieland Date: Thu, 7 Nov 2024 09:43:47 -0500 Subject: [PATCH 02/12] correct yaml --- static/v32disco.yaml | 13 ++++++++----- static/v32disco_drycontact.yaml | 13 ++++++++----- static/v32disco_secplusv1.yaml | 13 ++++++++----- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/static/v32disco.yaml b/static/v32disco.yaml index bfb14ac..b850723 100644 --- a/static/v32disco.yaml +++ b/static/v32disco.yaml @@ -45,6 +45,13 @@ api: improv_serial: +wifi: + ap: + +logger: + +ota: + binary_sensor: - platform: ratgdo ratgdo_id: ${id_prefix} @@ -142,8 +149,4 @@ sensor: # - clamp: # min_value: 0 # max_value: 100 - # unit_of_measurement: "%" - -logger: - -ota: \ No newline at end of file + # unit_of_measurement: "%" \ No newline at end of file diff --git a/static/v32disco_drycontact.yaml b/static/v32disco_drycontact.yaml index 99fc1d2..ab24738 100644 --- a/static/v32disco_drycontact.yaml +++ b/static/v32disco_drycontact.yaml @@ -44,6 +44,13 @@ api: improv_serial: +wifi: + ap: + +logger: + +ota: + binary_sensor: - platform: ratgdo ratgdo_id: ${id_prefix} @@ -134,8 +141,4 @@ sensor: filters: - calibrate_linear: - 1.16 -> 5 - - 2.783 -> 12 - -logger: - -ota: \ No newline at end of file + - 2.783 -> 12 \ No newline at end of file diff --git a/static/v32disco_secplusv1.yaml b/static/v32disco_secplusv1.yaml index 1bbd06a..58ce207 100644 --- a/static/v32disco_secplusv1.yaml +++ b/static/v32disco_secplusv1.yaml @@ -45,6 +45,13 @@ api: improv_serial: +wifi: + ap: + +logger: + +ota: + binary_sensor: - platform: ratgdo ratgdo_id: ${id_prefix} @@ -135,8 +142,4 @@ sensor: filters: - calibrate_linear: - 1.16 -> 5 - - 2.783 -> 12 - -logger: - -ota: \ No newline at end of file + - 2.783 -> 12 \ No newline at end of file From 8068dbed46f06846f442f162fce1c847e7fea6fe Mon Sep 17 00:00:00 2001 From: Paul Wieland Date: Thu, 7 Nov 2024 11:36:35 -0500 Subject: [PATCH 03/12] ignore bugs --- components/ratgdo/ratgdo.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/ratgdo/ratgdo.cpp b/components/ratgdo/ratgdo.cpp index 9063bf4..154371f 100644 --- a/components/ratgdo/ratgdo.cpp +++ b/components/ratgdo/ratgdo.cpp @@ -32,6 +32,7 @@ namespace ratgdo { 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 + static const int MIN_DISTANCE = 20; // ignore bugs crawling on the distance sensor void RATGDOComponent::setup() { @@ -366,6 +367,8 @@ namespace ratgdo { void RATGDOComponent::set_distance_measurement(int16_t distance) { + if(distance > 0 && distance < MIN_DISTANCE) return; + this->last_distance_measurement = distance; // current value = [0], last value = [1] From 1e15dae5a786561031f107bc2ded16b4ff82e86b Mon Sep 17 00:00:00 2001 From: Paul Wieland Date: Sun, 10 Nov 2024 10:25:43 -0500 Subject: [PATCH 04/12] Add disco to build/webtools --- .github/workflows/build.yml | 18 ++++++++++++++++++ static/index.html | 20 ++++++++++++-------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2996155..4ea2fa0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -55,6 +55,24 @@ jobs: - file: v25iboard_drycontact.yaml name: V2.5i Board Dry Contact manifest_filename: v25iboard_drycontact-manifest.json + - file: v32board.yaml + name: V32 Board Security+ 2.0 + manifest_filename: v32board-manifest.json + - file: v32board_secplusv1.yaml + name: V32 Board Security+ 1.0 + manifest_filename: v32board_secplusv1-manifest.json + - file: v32board_drycontact.yaml + name: V32 Board Board Dry Contact + manifest_filename: v32board_drycontact-manifest.json + - file: v32disco.yaml + name: V32 Disco Board Security+ 2.0 + manifest_filename: v32disco-manifest.json + - file: v32disco_secplusv1.yaml + name: V32 Disco Board Security+ 1.0 + manifest_filename: v32disco_secplusv1-manifest.json + - file: v32disco_drycontact.yaml + name: V32 Disco Board Dry Contact + manifest_filename: v32disco_drycontact-manifest.json fail-fast: false steps: - name: Checkout source code diff --git a/static/index.html b/static/index.html index 77e016c..17168d1 100644 --- a/static/index.html +++ b/static/index.html @@ -177,7 +177,7 @@ />

ESPHome ratgdo

- In order to install the firmware, first pick your door opener control protocol, then pick your ratgdo control board version. + In order to install the firmware, first pick your door opener control protocol, then pick your ratgdo control board version. No programming or other software required.

@@ -209,6 +209,12 @@

Choose your ratgdo control board:

+ +
@@ -255,12 +261,10 @@

Drivers

If you can't connect to your ratgdo board make sure you have the right driver installed for the type of board you have.

-

Watch the driver and firmware installation [video on YouTube].

- - +

Watch the v2.5i driver and firmware installation [video on YouTube].

Advanced Users

    From fd43050842ecf063f3700243478c009d43fccacc Mon Sep 17 00:00:00 2001 From: Paul Wieland Date: Sun, 10 Nov 2024 11:41:55 -0500 Subject: [PATCH 05/12] closing delay max reduce to increase slider resolution --- components/ratgdo/number/ratgdo_number.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/ratgdo/number/ratgdo_number.cpp b/components/ratgdo/number/ratgdo_number.cpp index e3fd1a1..da99b5d 100644 --- a/components/ratgdo/number/ratgdo_number.cpp +++ b/components/ratgdo/number/ratgdo_number.cpp @@ -91,7 +91,7 @@ namespace ratgdo { } 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); + this->traits.set_max_value(60.0); } else if (this->number_type_ == RATGDO_ROLLING_CODE_COUNTER) { this->traits.set_max_value(0xfffffff); } else if (this->number_type_ == RATGDO_CLIENT_ID) { From eee6f5e4d504b08b9522d30740e8207210058ddd Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 10 Nov 2024 18:05:29 +0000 Subject: [PATCH 06/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- components/ratgdo/__init__.py | 2 +- .../binary_sensor/ratgdo_binary_sensor.cpp | 6 +- components/ratgdo/number/ratgdo_number.cpp | 4 +- components/ratgdo/output/ratgdo_output.cpp | 79 ++++++++++--------- components/ratgdo/output/ratgdo_output.h | 42 +++++----- components/ratgdo/ratgdo.cpp | 28 ++++--- components/ratgdo/ratgdo.h | 2 +- components/ratgdo/ratgdo_state.h | 2 +- components/ratgdo/sensor/__init__.py | 2 +- components/ratgdo/sensor/ratgdo_sensor.cpp | 12 +-- components/ratgdo/sensor/ratgdo_sensor.h | 6 +- components/ratgdo/switch/__init__.py | 1 - components/ratgdo/switch/ratgdo_switch.cpp | 4 +- components/ratgdo/switch/ratgdo_switch.h | 4 +- static/v32board.yaml | 2 +- static/v32board_drycontact.yaml | 2 +- static/v32board_secplusv1.yaml | 2 +- static/v32disco.yaml | 2 +- static/v32disco_drycontact.yaml | 2 +- static/v32disco_secplusv1.yaml | 2 +- 20 files changed, 107 insertions(+), 99 deletions(-) diff --git a/components/ratgdo/__init__.py b/components/ratgdo/__init__.py index a6493c7..5153cad 100644 --- a/components/ratgdo/__init__.py +++ b/components/ratgdo/__init__.py @@ -144,4 +144,4 @@ async def to_code(config): cg.add(var.set_discrete_open_pin(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]) - cg.add(var.set_discrete_close_pin(pin)) \ No newline at end of file + cg.add(var.set_discrete_close_pin(pin)) diff --git a/components/ratgdo/binary_sensor/ratgdo_binary_sensor.cpp b/components/ratgdo/binary_sensor/ratgdo_binary_sensor.cpp index ffd2985..2c50669 100644 --- a/components/ratgdo/binary_sensor/ratgdo_binary_sensor.cpp +++ b/components/ratgdo/binary_sensor/ratgdo_binary_sensor.cpp @@ -28,18 +28,18 @@ namespace ratgdo { this->parent_->subscribe_button_state([=](ButtonState state) { this->publish_state(state == ButtonState::PRESSED); }); - } else if(this->binary_sensor_type_ == SensorType::RATGDO_SENSOR_VEHICLE_DETECTED) { + } 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) { + } 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) { + } 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); diff --git a/components/ratgdo/number/ratgdo_number.cpp b/components/ratgdo/number/ratgdo_number.cpp index da99b5d..40ab378 100644 --- a/components/ratgdo/number/ratgdo_number.cpp +++ b/components/ratgdo/number/ratgdo_number.cpp @@ -74,7 +74,7 @@ namespace ratgdo { this->parent_->subscribe_closing_delay([=](uint32_t value) { this->update_state(value); }); - } else if (this->number_type_ == RATGDO_TARGET_DISTANCE_MEASUREMENT){ + } else if (this->number_type_ == RATGDO_TARGET_DISTANCE_MEASUREMENT) { // this->parent_->subscribe_target_distance_measurement([=](float value) { // this->update_state(value); // }); @@ -98,7 +98,7 @@ namespace ratgdo { this->traits.set_step(0x1000); this->traits.set_min_value(0x539); this->traits.set_max_value(0x7ff539); - } else if(this->number_type_ == RATGDO_TARGET_DISTANCE_MEASUREMENT) { + } 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); diff --git a/components/ratgdo/output/ratgdo_output.cpp b/components/ratgdo/output/ratgdo_output.cpp index c67a8e1..ba389ba 100644 --- a/components/ratgdo/output/ratgdo_output.cpp +++ b/components/ratgdo/output/ratgdo_output.cpp @@ -5,49 +5,54 @@ namespace esphome { namespace ratgdo { -static const char *TAG = "ratgdo.output"; + static const char* TAG = "ratgdo.output"; -void RATGDOOutput::setup(){ - ESP_LOGD(TAG,"Output was setup"); + 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(); }); + 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; - } - }); + 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::play() + { + this->beeper_->play(this->rtttlSong_); } -} -void RATGDOOutput::set_output_type(OutputType output_type_) { - this->output_type_ = output_type_; -} + void RATGDOOutput::finished_playback() + { + if (this->repeat_) + this->play(); + } -} //namespace ratgdo -} //namespace esphome \ No newline at end of file + 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 diff --git a/components/ratgdo/output/ratgdo_output.h b/components/ratgdo/output/ratgdo_output.h index 873bb73..f15a5d6 100644 --- a/components/ratgdo/output/ratgdo_output.h +++ b/components/ratgdo/output/ratgdo_output.h @@ -1,32 +1,32 @@ #pragma once #include "../ratgdo.h" -#include "esphome/core/component.h" #include "esphome/components/rtttl/rtttl.h" +#include "esphome/core/component.h" namespace esphome { namespace ratgdo { - enum OutputType { - RATGDO_BEEPER - }; + 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; } + 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_; - }; + protected: + OutputType output_type_; + rtttl::Rtttl* beeper_; + std::string rtttlSong_; + bool repeat_; + }; -} //namespace ratgdo -} //namespace esphome \ No newline at end of file +} // namespace ratgdo +} // namespace esphome diff --git a/components/ratgdo/ratgdo.cpp b/components/ratgdo/ratgdo.cpp index 154371f..309ff85 100644 --- a/components/ratgdo/ratgdo.cpp +++ b/components/ratgdo/ratgdo.cpp @@ -63,14 +63,14 @@ namespace 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_){ + 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){ + if (state == DoorState::CLOSED) { this->presence_detect_window_active_ = false; cancel_timeout("presence_detect_window"); } @@ -361,13 +361,15 @@ namespace ratgdo { this->closing_duration = duration; } - void RATGDOComponent::set_target_distance_measurement(int16_t distance){ + void RATGDOComponent::set_target_distance_measurement(int16_t distance) + { this->target_distance_measurement = distance; } void RATGDOComponent::set_distance_measurement(int16_t distance) { - if(distance > 0 && distance < MIN_DISTANCE) return; + if (distance > 0 && distance < MIN_DISTANCE) + return; this->last_distance_measurement = distance; @@ -394,9 +396,11 @@ namespace ratgdo { 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; + + 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"); @@ -404,14 +408,14 @@ namespace ratgdo { void RATGDOComponent::presence_change(bool sensor_value) { - if(this->presence_detect_window_active_){ - if(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{ + } else { this->vehicle_arriving_state = VehicleArrivingState::NO; this->vehicle_leaving_state = VehicleLeavingState::YES; set_timeout(CLEAR_PRESENCE, [=] { @@ -584,13 +588,13 @@ namespace ratgdo { void RATGDOComponent::door_action(DoorAction action) { - if(*this->closing_delay > 0 && action == DoorAction::CLOSE){ + 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{ + } else { this->protocol_->door_action(action); } } diff --git a/components/ratgdo/ratgdo.h b/components/ratgdo/ratgdo.h index a6524ac..35a9b46 100644 --- a/components/ratgdo/ratgdo.h +++ b/components/ratgdo/ratgdo.h @@ -65,7 +65,7 @@ namespace ratgdo { observable closing_delay { 0 }; observable target_distance_measurement { -1 }; - std::vector distance_measurement{std::vector(10,-1)}; // the length of this vector determines how many in-range readings are required for presence detection to change states + std::vector distance_measurement { std::vector(10, -1) }; // the length of this vector determines how many in-range readings are required for presence detection to change states observable last_distance_measurement { 0 }; observable openings { 0 }; // number of times the door has been opened diff --git a/components/ratgdo/ratgdo_state.h b/components/ratgdo/ratgdo_state.h index f541e6e..679cc8b 100644 --- a/components/ratgdo/ratgdo_state.h +++ b/components/ratgdo/ratgdo_state.h @@ -25,7 +25,7 @@ namespace ratgdo { (STOPPED, 3), (OPENING, 4), (CLOSING, 5)) - + ENUM(DoorActionDelayed, uint8_t, (NO, 0), (YES, 1)) diff --git a/components/ratgdo/sensor/__init__.py b/components/ratgdo/sensor/__init__.py index 70b44dd..d87d320 100644 --- a/components/ratgdo/sensor/__init__.py +++ b/components/ratgdo/sensor/__init__.py @@ -40,7 +40,7 @@ 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) - + if config['type'] == 'distance': cg.add_library( name="Wire", diff --git a/components/ratgdo/sensor/ratgdo_sensor.cpp b/components/ratgdo/sensor/ratgdo_sensor.cpp index c79cfe6..e90017f 100644 --- a/components/ratgdo/sensor/ratgdo_sensor.cpp +++ b/components/ratgdo/sensor/ratgdo_sensor.cpp @@ -38,7 +38,7 @@ namespace ratgdo { this->distance_sensor_.setI2cDevice(&I2C); this->distance_sensor_.setXShutPin(32); // I2C.begin(17,16); - I2C.begin(19,18); + I2C.begin(19, 18); this->distance_sensor_.begin(); this->distance_sensor_.VL53L4CX_Off(); this->distance_sensor_.InitSensor(0x59); @@ -77,7 +77,7 @@ namespace ratgdo { #ifdef USE_DISTANCE if (this->ratgdo_sensor_type_ == RATGDOSensorType::RATGDO_DISTANCE) { VL53L4CX_MultiRangingData_t distanceData; - VL53L4CX_MultiRangingData_t *pDistanceData = &distanceData; + VL53L4CX_MultiRangingData_t* pDistanceData = &distanceData; uint8_t dataReady = 0; int objCount = 0; int16_t maxDistance = 0; @@ -86,15 +86,15 @@ namespace ratgdo { 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 + /* 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){ + if (maxDistance > 0) { this->parent_->set_distance_measurement(maxDistance); } diff --git a/components/ratgdo/sensor/ratgdo_sensor.h b/components/ratgdo/sensor/ratgdo_sensor.h index cf405d4..d7cfdaf 100644 --- a/components/ratgdo/sensor/ratgdo_sensor.h +++ b/components/ratgdo/sensor/ratgdo_sensor.h @@ -6,9 +6,9 @@ #include "esphome/core/component.h" #ifdef USE_DISTANCE - #include "Wire.h" - #include "vl53l4cx_class.h" - #define I2C Wire +#include "Wire.h" +#include "vl53l4cx_class.h" +#define I2C Wire #endif namespace esphome { diff --git a/components/ratgdo/switch/__init__.py b/components/ratgdo/switch/__init__.py index 786d9c8..c13265b 100644 --- a/components/ratgdo/switch/__init__.py +++ b/components/ratgdo/switch/__init__.py @@ -39,4 +39,3 @@ async def to_code(config): if CONF_PIN in config: pin = await cg.gpio_pin_expression(config[CONF_PIN]) cg.add(var.set_pin(pin)) - diff --git a/components/ratgdo/switch/ratgdo_switch.cpp b/components/ratgdo/switch/ratgdo_switch.cpp index 18a589a..11b85dd 100644 --- a/components/ratgdo/switch/ratgdo_switch.cpp +++ b/components/ratgdo/switch/ratgdo_switch.cpp @@ -21,7 +21,7 @@ namespace ratgdo { this->parent_->subscribe_learn_state([=](LearnState state) { this->publish_state(state == LearnState::ACTIVE); }); - }else if(this->switch_type_ == SwitchType::RATGDO_LED) { + } 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); @@ -37,7 +37,7 @@ namespace ratgdo { } else { this->parent_->inactivate_learn(); } - } else if(this->switch_type_ == SwitchType::RATGDO_LED){ + } else if (this->switch_type_ == SwitchType::RATGDO_LED) { this->pin_->digital_write(state); this->publish_state(state); } diff --git a/components/ratgdo/switch/ratgdo_switch.h b/components/ratgdo/switch/ratgdo_switch.h index 8b195df..f4631c4 100644 --- a/components/ratgdo/switch/ratgdo_switch.h +++ b/components/ratgdo/switch/ratgdo_switch.h @@ -20,11 +20,11 @@ namespace ratgdo { void set_switch_type(SwitchType switch_type_) { this->switch_type_ = switch_type_; } void write_state(bool state) override; - void set_pin(GPIOPin *pin) { pin_ = pin; } + void set_pin(GPIOPin* pin) { pin_ = pin; } protected: SwitchType switch_type_; - GPIOPin *pin_; + GPIOPin* pin_; }; } // namespace ratgdo diff --git a/static/v32board.yaml b/static/v32board.yaml index 2f9a0a3..743973f 100644 --- a/static/v32board.yaml +++ b/static/v32board.yaml @@ -62,4 +62,4 @@ improv_serial: wifi: ap: -logger: \ No newline at end of file +logger: diff --git a/static/v32board_drycontact.yaml b/static/v32board_drycontact.yaml index 7f89fe7..e9df584 100644 --- a/static/v32board_drycontact.yaml +++ b/static/v32board_drycontact.yaml @@ -61,4 +61,4 @@ improv_serial: wifi: ap: -logger: \ No newline at end of file +logger: diff --git a/static/v32board_secplusv1.yaml b/static/v32board_secplusv1.yaml index 2a0f75a..e433ae1 100644 --- a/static/v32board_secplusv1.yaml +++ b/static/v32board_secplusv1.yaml @@ -62,4 +62,4 @@ improv_serial: wifi: ap: -logger: \ No newline at end of file +logger: diff --git a/static/v32disco.yaml b/static/v32disco.yaml index b850723..01b3307 100644 --- a/static/v32disco.yaml +++ b/static/v32disco.yaml @@ -149,4 +149,4 @@ sensor: # - clamp: # min_value: 0 # max_value: 100 - # unit_of_measurement: "%" \ No newline at end of file + # unit_of_measurement: "%" diff --git a/static/v32disco_drycontact.yaml b/static/v32disco_drycontact.yaml index ab24738..a87f691 100644 --- a/static/v32disco_drycontact.yaml +++ b/static/v32disco_drycontact.yaml @@ -141,4 +141,4 @@ sensor: filters: - calibrate_linear: - 1.16 -> 5 - - 2.783 -> 12 \ No newline at end of file + - 2.783 -> 12 diff --git a/static/v32disco_secplusv1.yaml b/static/v32disco_secplusv1.yaml index 58ce207..bb80b95 100644 --- a/static/v32disco_secplusv1.yaml +++ b/static/v32disco_secplusv1.yaml @@ -142,4 +142,4 @@ sensor: filters: - calibrate_linear: - 1.16 -> 5 - - 2.783 -> 12 \ No newline at end of file + - 2.783 -> 12 From be6ec93b3e9b1186db7e66de13c192186b2929f5 Mon Sep 17 00:00:00 2001 From: Paul Wieland Date: Sun, 10 Nov 2024 13:21:39 -0500 Subject: [PATCH 07/12] add branch to be removed after merge --- static/v32board.yaml | 1 + static/v32board_drycontact.yaml | 1 + static/v32board_secplusv1.yaml | 1 + static/v32disco.yaml | 1 + static/v32disco_drycontact.yaml | 1 + static/v32disco_secplusv1.yaml | 1 + 6 files changed, 6 insertions(+) diff --git a/static/v32board.yaml b/static/v32board.yaml index 2f9a0a3..a0455d7 100644 --- a/static/v32board.yaml +++ b/static/v32board.yaml @@ -30,6 +30,7 @@ dashboard_import: packages: remote_package: url: https://github.com/ratgdo/esphome-ratgdo + ref: ratgdo32 files: [base.yaml] refresh: 1s # remote_package: !include diff --git a/static/v32board_drycontact.yaml b/static/v32board_drycontact.yaml index 7f89fe7..daa3db1 100644 --- a/static/v32board_drycontact.yaml +++ b/static/v32board_drycontact.yaml @@ -29,6 +29,7 @@ dashboard_import: packages: remote_package: url: https://github.com/ratgdo/esphome-ratgdo + ref: ratgdo32 files: [base_drycontact.yaml] refresh: 1s # remote_package: !include diff --git a/static/v32board_secplusv1.yaml b/static/v32board_secplusv1.yaml index 2a0f75a..e14b493 100644 --- a/static/v32board_secplusv1.yaml +++ b/static/v32board_secplusv1.yaml @@ -30,6 +30,7 @@ dashboard_import: packages: remote_package: url: https://github.com/ratgdo/esphome-ratgdo + ref: ratgdo32 files: [base_secplusv1.yaml] refresh: 1s # remote_package: !include diff --git a/static/v32disco.yaml b/static/v32disco.yaml index b850723..138e093 100644 --- a/static/v32disco.yaml +++ b/static/v32disco.yaml @@ -30,6 +30,7 @@ dashboard_import: packages: remote_package: url: https://github.com/ratgdo/esphome-ratgdo + ref: ratgdo32 files: [base.yaml] refresh: 1s # remote_package: !include diff --git a/static/v32disco_drycontact.yaml b/static/v32disco_drycontact.yaml index ab24738..b5b32ed 100644 --- a/static/v32disco_drycontact.yaml +++ b/static/v32disco_drycontact.yaml @@ -29,6 +29,7 @@ dashboard_import: packages: remote_package: url: https://github.com/ratgdo/esphome-ratgdo + ref: ratgdo32 files: [base_drycontact.yaml] refresh: 1s # remote_package: !include diff --git a/static/v32disco_secplusv1.yaml b/static/v32disco_secplusv1.yaml index 58ce207..af533a3 100644 --- a/static/v32disco_secplusv1.yaml +++ b/static/v32disco_secplusv1.yaml @@ -30,6 +30,7 @@ dashboard_import: packages: remote_package: url: https://github.com/ratgdo/esphome-ratgdo + ref: ratgdo32 files: [base_secplusv1.yaml] refresh: 1s # remote_package: !include From ae8d1a3c2a4bb69a5ae56c72e5d04443bf44b98c Mon Sep 17 00:00:00 2001 From: Paul Wieland Date: Sun, 10 Nov 2024 13:47:47 -0500 Subject: [PATCH 08/12] add branch roll back after merge --- base.yaml | 1 + base_drycontact.yaml | 1 + base_secplusv1.yaml | 1 + 3 files changed, 3 insertions(+) diff --git a/base.yaml b/base.yaml index 79c4d64..895610d 100644 --- a/base.yaml +++ b/base.yaml @@ -3,6 +3,7 @@ external_components: - source: type: git url: https://github.com/ratgdo/esphome-ratgdo + ref: ratgdo32 refresh: 1s # - source: # type: local diff --git a/base_drycontact.yaml b/base_drycontact.yaml index d683a54..8265070 100644 --- a/base_drycontact.yaml +++ b/base_drycontact.yaml @@ -4,6 +4,7 @@ external_components: - source: type: git url: https://github.com/ratgdo/esphome-ratgdo + ref: ratgdo32 refresh: 1s # - source: # type: local diff --git a/base_secplusv1.yaml b/base_secplusv1.yaml index a1331f2..5266d0f 100644 --- a/base_secplusv1.yaml +++ b/base_secplusv1.yaml @@ -4,6 +4,7 @@ external_components: - source: type: git url: https://github.com/ratgdo/esphome-ratgdo + ref: ratgdo32 refresh: 1s # - source: # type: local From ee0f0bcabd7f6f0eb9aa018764dae4e77a3fc630 Mon Sep 17 00:00:00 2001 From: Paul Wieland Date: Sun, 10 Nov 2024 13:53:47 -0500 Subject: [PATCH 09/12] LED GPIO --- static/v32board.yaml | 2 +- static/v32board_drycontact.yaml | 2 +- static/v32board_secplusv1.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/static/v32board.yaml b/static/v32board.yaml index c56d33c..b606582 100644 --- a/static/v32board.yaml +++ b/static/v32board.yaml @@ -41,7 +41,7 @@ switch: ratgdo_id: ${id_prefix} id: ${id_prefix}_led type: led - pin: GPIO4 + pin: GPIO2 name: "LED" entity_category: config diff --git a/static/v32board_drycontact.yaml b/static/v32board_drycontact.yaml index 5a7a365..746e1ed 100644 --- a/static/v32board_drycontact.yaml +++ b/static/v32board_drycontact.yaml @@ -40,7 +40,7 @@ switch: ratgdo_id: ${id_prefix} id: ${id_prefix}_led type: led - pin: GPIO4 + pin: GPIO2 name: "LED" entity_category: config diff --git a/static/v32board_secplusv1.yaml b/static/v32board_secplusv1.yaml index a47a8e3..87da7a2 100644 --- a/static/v32board_secplusv1.yaml +++ b/static/v32board_secplusv1.yaml @@ -41,7 +41,7 @@ switch: ratgdo_id: ${id_prefix} id: ${id_prefix}_led type: led - pin: GPIO4 + pin: GPIO2 name: "LED" entity_category: config From 1f9b4a4682642ed2208a38628c7d8f4d4d5781eb Mon Sep 17 00:00:00 2001 From: Paul Wieland Date: Tue, 12 Nov 2024 12:18:40 -0500 Subject: [PATCH 10/12] temp switch gh pages to ratgdo32 branch --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4ea2fa0..f9c30c9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -97,7 +97,7 @@ jobs: consolidate: - if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' + if: github.event_name != 'pull_request' && github.ref == 'refs/heads/ratgdo32' name: Consolidate firmwares runs-on: ubuntu-latest needs: build @@ -119,7 +119,7 @@ jobs: path: output deploy: - if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' + if: github.event_name != 'pull_request' && github.ref == 'refs/heads/ratgdo32' name: Deploy to GitHub Pages runs-on: ubuntu-latest needs: consolidate From 53a2589ba313277399ddbe44f3146e877a407b82 Mon Sep 17 00:00:00 2001 From: Paul Wieland Date: Tue, 12 Nov 2024 12:35:05 -0500 Subject: [PATCH 11/12] ratgdo32 branch --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f9c30c9..19c19d1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: push: branches: - - main + - ratgdo32 pull_request: schedule: - cron: '0 4 * * 1' @@ -78,7 +78,7 @@ jobs: - name: Checkout source code uses: actions/checkout@v3.3.0 - name: Build firmware - uses: ratgdo/esphome-build-action@main + uses: ratgdo/esphome-build-action@ratgdo32 id: esphome-build with: yaml_file: ${{ matrix.firmware.file }} From f0cf81b5dde71ad9bff7e0fdf42770b3b1dcf53a Mon Sep 17 00:00:00 2001 From: Paul Wieland Date: Tue, 12 Nov 2024 12:52:59 -0500 Subject: [PATCH 12/12] Update build.yml --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 19c19d1..fffa5a9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -78,7 +78,7 @@ jobs: - name: Checkout source code uses: actions/checkout@v3.3.0 - name: Build firmware - uses: ratgdo/esphome-build-action@ratgdo32 + uses: ratgdo/esphome-build-action@main id: esphome-build with: yaml_file: ${{ matrix.firmware.file }}