2023-06-05 17:12:51 +00:00
/************************************
* Rage
* Against
* The
* Garage
* Door
* Opener
*
* Copyright ( C ) 2022 Paul Wieland
*
* GNU GENERAL PUBLIC LICENSE
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2023-06-05 18:07:10 +00:00
# pragma once
2024-01-19 23:24:16 +00:00
2024-07-03 15:41:59 +00:00
# include "esphome/components/binary_sensor/binary_sensor.h"
2023-06-05 18:34:06 +00:00
# include "esphome/core/component.h"
2024-07-03 13:34:57 +00:00
# include "esphome/core/defines.h"
2024-01-19 23:24:16 +00:00
# include "esphome/core/hal.h"
2023-06-06 01:06:12 +00:00
# include "esphome/core/preferences.h"
2023-06-05 18:26:26 +00:00
2024-01-19 23:24:16 +00:00
# include "callbacks.h"
# include "macros.h"
# include "observable.h"
# include "protocol.h"
2023-06-07 15:44:31 +00:00
# include "ratgdo_state.h"
2023-06-05 17:59:55 +00:00
namespace esphome {
2024-01-19 23:24:16 +00:00
class InternalGPIOPin ;
2023-06-05 17:59:55 +00:00
namespace ratgdo {
2023-07-01 14:13:38 +00:00
class RATGDOComponent ;
typedef Parented < RATGDOComponent > RATGDOClient ;
2023-06-07 14:47:27 +00:00
2023-06-25 23:03:39 +00:00
const float DOOR_POSITION_UNKNOWN = - 1.0 ;
2023-10-08 22:36:09 +00:00
const float DOOR_DELTA_UNKNOWN = - 2.0 ;
2024-01-18 22:25:08 +00:00
const uint16_t PAIRED_DEVICES_UNKNOWN = 0xFF ;
2023-06-25 23:03:39 +00:00
2023-06-05 21:26:28 +00:00
struct RATGDOStore {
2023-07-03 02:44:34 +00:00
int obstruction_low_count = 0 ; // count obstruction low pulses
2023-06-05 21:26:28 +00:00
2023-10-08 22:36:09 +00:00
static void IRAM_ATTR HOT isr_obstruction ( RATGDOStore * arg )
2023-08-26 21:45:51 +00:00
{
arg - > obstruction_low_count + + ;
}
2023-06-05 21:26:28 +00:00
} ;
2024-01-19 23:24:16 +00:00
using protocol : : Args ;
using protocol : : Result ;
2023-06-17 14:50:38 +00:00
class RATGDOComponent : public Component {
2023-06-05 18:56:03 +00:00
public :
void setup ( ) override ;
void loop ( ) override ;
2023-06-06 01:37:27 +00:00
void dump_config ( ) override ;
2023-06-09 22:36:56 +00:00
2024-01-19 23:24:16 +00:00
void init_protocol ( ) ;
void obstruction_loop ( ) ;
2023-06-25 23:03:39 +00:00
2023-07-03 02:44:34 +00:00
float start_opening { - 1 } ;
observable < float > opening_duration { 0 } ;
float start_closing { - 1 } ;
observable < float > closing_duration { 0 } ;
2024-10-28 17:56:16 +00:00
observable < uint32_t > closing_delay { 0 } ;
observable < int16_t > target_distance_measurement { - 1 } ;
2024-11-10 18:05:29 +00:00
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
2024-10-28 17:56:16 +00:00
observable < int16_t > last_distance_measurement { 0 } ;
2023-06-24 20:38:44 +00:00
2023-07-01 14:13:38 +00:00
observable < uint16_t > openings { 0 } ; // number of times the door has been opened
2024-01-18 22:25:08 +00:00
observable < uint16_t > paired_total { PAIRED_DEVICES_UNKNOWN } ;
observable < uint16_t > paired_remotes { PAIRED_DEVICES_UNKNOWN } ;
observable < uint16_t > paired_keypads { PAIRED_DEVICES_UNKNOWN } ;
observable < uint16_t > paired_wall_controls { PAIRED_DEVICES_UNKNOWN } ;
observable < uint16_t > paired_accessories { PAIRED_DEVICES_UNKNOWN } ;
2023-06-09 22:36:56 +00:00
2023-07-03 16:47:00 +00:00
observable < DoorState > door_state { DoorState : : UNKNOWN } ;
2023-07-03 02:44:34 +00:00
observable < float > door_position { DOOR_POSITION_UNKNOWN } ;
2024-10-28 17:56:16 +00:00
observable < DoorActionDelayed > door_action_delayed { DoorActionDelayed : : NO } ;
2023-10-08 22:36:09 +00:00
unsigned long door_start_moving { 0 } ;
float door_start_position { DOOR_POSITION_UNKNOWN } ;
float door_move_delta { DOOR_DELTA_UNKNOWN } ;
2023-07-03 02:44:34 +00:00
2023-07-03 16:47:00 +00:00
observable < LightState > light_state { LightState : : UNKNOWN } ;
observable < LockState > lock_state { LockState : : UNKNOWN } ;
observable < ObstructionState > obstruction_state { ObstructionState : : UNKNOWN } ;
observable < MotorState > motor_state { MotorState : : UNKNOWN } ;
observable < ButtonState > button_state { ButtonState : : UNKNOWN } ;
observable < MotionState > motion_state { MotionState : : UNKNOWN } ;
2024-01-18 22:25:08 +00:00
observable < LearnState > learn_state { LearnState : : UNKNOWN } ;
2024-10-28 17:56:16 +00:00
observable < VehicleDetectedState > vehicle_detected_state { VehicleDetectedState : : NO } ;
observable < VehicleArrivingState > vehicle_arriving_state { VehicleArrivingState : : NO } ;
observable < VehicleLeavingState > vehicle_leaving_state { VehicleLeavingState : : NO } ;
2023-07-03 02:44:34 +00:00
2024-01-19 23:24:16 +00:00
OnceCallbacks < void ( DoorState ) > on_door_state_ ;
2023-10-19 00:18:42 +00:00
2023-07-07 22:56:12 +00:00
observable < bool > sync_failed { false } ;
2023-07-03 02:44:34 +00:00
void set_output_gdo_pin ( InternalGPIOPin * pin ) { this - > output_gdo_pin_ = pin ; }
void set_input_gdo_pin ( InternalGPIOPin * pin ) { this - > input_gdo_pin_ = pin ; }
void set_input_obst_pin ( InternalGPIOPin * pin ) { this - > input_obst_pin_ = pin ; }
2024-04-17 20:17:29 +00:00
// dry contact methods
2024-07-03 13:34:57 +00:00
void set_dry_contact_open_sensor ( esphome : : binary_sensor : : BinarySensor * dry_contact_open_sensor_ ) ;
void set_dry_contact_close_sensor ( esphome : : binary_sensor : : BinarySensor * dry_contact_close_sensor_ ) ;
2024-07-03 00:59:37 +00:00
void set_discrete_open_pin ( InternalGPIOPin * pin ) { this - > protocol_ - > set_discrete_open_pin ( pin ) ; }
void set_discrete_close_pin ( InternalGPIOPin * pin ) { this - > protocol_ - > set_discrete_close_pin ( pin ) ; }
2024-04-17 20:17:29 +00:00
2024-01-19 23:24:16 +00:00
Result call_protocol ( Args args ) ;
void received ( const DoorState door_state ) ;
void received ( const LightState light_state ) ;
void received ( const LockState lock_state ) ;
void received ( const ObstructionState obstruction_state ) ;
void received ( const LightAction light_action ) ;
void received ( const MotorState motor_state ) ;
void received ( const ButtonState button_state ) ;
void received ( const MotionState motion_state ) ;
void received ( const LearnState light_state ) ;
void received ( const Openings openings ) ;
void received ( const TimeToClose ttc ) ;
void received ( const PairedDeviceCount pdc ) ;
void received ( const BatteryState pdc ) ;
2023-07-03 02:44:34 +00:00
2023-07-03 02:45:00 +00:00
// door
2024-01-19 23:24:16 +00:00
void door_toggle ( ) ;
void door_open ( ) ;
void door_close ( ) ;
void door_stop ( ) ;
void door_action ( DoorAction action ) ;
void ensure_door_action ( DoorAction action , uint32_t delay = 1500 ) ;
2023-07-03 02:44:34 +00:00
void door_move_to_position ( float position ) ;
2023-07-07 22:56:12 +00:00
void set_door_position ( float door_position ) { this - > door_position = door_position ; }
2023-07-03 02:44:34 +00:00
void set_opening_duration ( float duration ) ;
void set_closing_duration ( float duration ) ;
2024-10-28 17:56:16 +00:00
void set_closing_delay ( uint32_t delay ) { this - > closing_delay = delay ; }
2023-10-08 22:36:09 +00:00
void schedule_door_position_sync ( float update_period = 500 ) ;
void door_position_update ( ) ;
void cancel_position_sync_callbacks ( ) ;
2024-10-28 17:56:16 +00:00
void set_target_distance_measurement ( int16_t distance ) ;
void set_distance_measurement ( int16_t distance ) ;
void calculate_presence ( ) ;
void presence_change ( bool sensor_value ) ;
2023-07-03 02:44:34 +00:00
// light
2024-01-19 23:24:16 +00:00
void light_toggle ( ) ;
2023-07-03 02:44:34 +00:00
void light_on ( ) ;
void light_off ( ) ;
LightState get_light_state ( ) const ;
// lock
2024-01-19 23:24:16 +00:00
void lock_toggle ( ) ;
2023-06-05 23:28:47 +00:00
void lock ( ) ;
void unlock ( ) ;
2023-06-25 15:45:37 +00:00
2024-01-18 22:25:08 +00:00
// Learn & Paired
void activate_learn ( ) ;
void inactivate_learn ( ) ;
void query_paired_devices ( ) ;
void query_paired_devices ( PairedDevice kind ) ;
void clear_paired_devices ( PairedDevice kind ) ;
2023-07-03 02:44:34 +00:00
// button functionality
2023-06-24 23:51:19 +00:00
void query_status ( ) ;
void query_openings ( ) ;
2023-07-03 02:44:34 +00:00
void sync ( ) ;
2023-06-09 23:14:13 +00:00
2023-07-03 02:44:34 +00:00
// children subscriptions
2023-07-01 14:13:38 +00:00
void subscribe_rolling_code_counter ( std : : function < void ( uint32_t ) > & & f ) ;
void subscribe_opening_duration ( std : : function < void ( float ) > & & f ) ;
void subscribe_closing_duration ( std : : function < void ( float ) > & & f ) ;
2024-10-28 17:56:16 +00:00
void subscribe_closing_delay ( std : : function < void ( uint32_t ) > & & f ) ;
2023-07-01 14:13:38 +00:00
void subscribe_openings ( std : : function < void ( uint16_t ) > & & f ) ;
2024-01-18 22:25:08 +00:00
void subscribe_paired_devices_total ( std : : function < void ( uint16_t ) > & & f ) ;
void subscribe_paired_remotes ( std : : function < void ( uint16_t ) > & & f ) ;
void subscribe_paired_keypads ( std : : function < void ( uint16_t ) > & & f ) ;
void subscribe_paired_wall_controls ( std : : function < void ( uint16_t ) > & & f ) ;
void subscribe_paired_accessories ( std : : function < void ( uint16_t ) > & & f ) ;
2023-07-01 14:13:38 +00:00
void subscribe_door_state ( std : : function < void ( DoorState , float ) > & & f ) ;
void subscribe_light_state ( std : : function < void ( LightState ) > & & f ) ;
void subscribe_lock_state ( std : : function < void ( LockState ) > & & f ) ;
void subscribe_obstruction_state ( std : : function < void ( ObstructionState ) > & & f ) ;
void subscribe_motor_state ( std : : function < void ( MotorState ) > & & f ) ;
void subscribe_button_state ( std : : function < void ( ButtonState ) > & & f ) ;
void subscribe_motion_state ( std : : function < void ( MotionState ) > & & f ) ;
2023-07-07 22:56:12 +00:00
void subscribe_sync_failed ( std : : function < void ( bool ) > & & f ) ;
2024-01-18 22:25:08 +00:00
void subscribe_learn_state ( std : : function < void ( LearnState ) > & & f ) ;
2024-10-28 17:56:16 +00:00
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 ) ;
2023-07-07 22:56:12 +00:00
2023-06-05 18:56:03 +00:00
protected :
2023-07-03 02:44:34 +00:00
RATGDOStore isr_store_ { } ;
2024-01-19 23:24:16 +00:00
protocol : : Protocol * protocol_ ;
2024-07-03 11:44:33 +00:00
bool obstruction_sensor_detected_ { false } ;
2024-10-28 17:56:16 +00:00
bool presence_detect_window_active_ { false } ;
2023-08-26 13:11:02 +00:00
2023-06-05 19:40:53 +00:00
InternalGPIOPin * output_gdo_pin_ ;
2023-06-05 23:07:10 +00:00
InternalGPIOPin * input_gdo_pin_ ;
InternalGPIOPin * input_obst_pin_ ;
2024-07-03 13:34:57 +00:00
esphome : : binary_sensor : : BinarySensor * dry_contact_open_sensor_ ;
esphome : : binary_sensor : : BinarySensor * dry_contact_close_sensor_ ;
2023-06-05 18:56:03 +00:00
} ; // RATGDOComponent
2023-06-05 18:07:10 +00:00
} // namespace ratgdo
2023-10-19 00:23:30 +00:00
} // namespace esphome