2023-06-05 12:12:51 -05:00
/************************************
* Rage
* Against
* The
* Garage
* Door
* Opener
*
* Copyright ( C ) 2022 Paul Wieland
*
* GNU GENERAL PUBLIC LICENSE
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2023-06-05 13:07:10 -05:00
# pragma once
2024-01-19 13:24:16 -10:00
2024-07-03 08:41:59 -07:00
# include "esphome/components/binary_sensor/binary_sensor.h"
2023-06-05 13:34:06 -05:00
# include "esphome/core/component.h"
2024-07-03 09:34:57 -04:00
# include "esphome/core/defines.h"
2024-01-19 13:24:16 -10:00
# include "esphome/core/hal.h"
2023-06-05 20:06:12 -05:00
# include "esphome/core/preferences.h"
2023-06-05 13:26:26 -05:00
2024-01-19 13:24:16 -10:00
# include "callbacks.h"
# include "macros.h"
# include "observable.h"
# include "protocol.h"
2023-06-07 10:44:31 -05:00
# include "ratgdo_state.h"
2023-06-05 12:59:55 -05:00
namespace esphome {
2024-01-19 13:24:16 -10:00
class InternalGPIOPin ;
2023-06-05 12:59:55 -05:00
namespace ratgdo {
2023-07-01 07:13:38 -07:00
class RATGDOComponent ;
typedef Parented < RATGDOComponent > RATGDOClient ;
2023-06-07 09:47:27 -05:00
2023-06-25 16:03:39 -07:00
const float DOOR_POSITION_UNKNOWN = - 1.0 ;
2023-10-08 15:36:09 -07:00
const float DOOR_DELTA_UNKNOWN = - 2.0 ;
2024-01-18 17:25:08 -05:00
const uint16_t PAIRED_DEVICES_UNKNOWN = 0xFF ;
2023-06-25 16:03:39 -07:00
2023-06-05 16:26:28 -05:00
struct RATGDOStore {
2023-07-02 19:44:34 -07:00
int obstruction_low_count = 0 ; // count obstruction low pulses
2023-06-05 16:26:28 -05:00
2023-10-08 15:36:09 -07:00
static void IRAM_ATTR HOT isr_obstruction ( RATGDOStore * arg )
2023-08-26 14:45:51 -07:00
{
arg - > obstruction_low_count + + ;
}
2023-06-05 16:26:28 -05:00
} ;
2024-01-19 13:24:16 -10:00
using protocol : : Args ;
using protocol : : Result ;
2023-06-17 09:50:38 -05:00
class RATGDOComponent : public Component {
2023-06-05 13:56:03 -05:00
public :
void setup ( ) override ;
void loop ( ) override ;
2023-06-05 20:37:27 -05:00
void dump_config ( ) override ;
2023-06-09 17:36:56 -05:00
2024-01-19 13:24:16 -10:00
void init_protocol ( ) ;
void obstruction_loop ( ) ;
2023-06-25 16:03:39 -07:00
2023-07-02 19:44:34 -07:00
float start_opening { - 1 } ;
observable < float > opening_duration { 0 } ;
float start_closing { - 1 } ;
observable < float > closing_duration { 0 } ;
2024-10-28 13:56:16 -04:00
observable < uint32_t > closing_delay { 0 } ;
observable < int16_t > target_distance_measurement { - 1 } ;
2024-12-06 14:40:34 -05:00
std : : vector < int16_t > distance_measurement { std : : vector < int16_t > ( 30 , - 1 ) } ; // the length of this vector determines how many in-range readings are required for presence detection to change states
2024-10-28 13:56:16 -04:00
observable < int16_t > last_distance_measurement { 0 } ;
2023-06-24 13:38:44 -07:00
2023-07-01 07:13:38 -07:00
observable < uint16_t > openings { 0 } ; // number of times the door has been opened
2024-01-18 17:25:08 -05: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 17:36:56 -05:00
2023-07-03 09:47:00 -07:00
observable < DoorState > door_state { DoorState : : UNKNOWN } ;
2023-07-02 19:44:34 -07:00
observable < float > door_position { DOOR_POSITION_UNKNOWN } ;
2024-10-28 13:56:16 -04:00
observable < DoorActionDelayed > door_action_delayed { DoorActionDelayed : : NO } ;
2023-10-08 15:36:09 -07:00
unsigned long door_start_moving { 0 } ;
float door_start_position { DOOR_POSITION_UNKNOWN } ;
float door_move_delta { DOOR_DELTA_UNKNOWN } ;
2023-07-02 19:44:34 -07:00
2023-07-03 09:47:00 -07: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 17:25:08 -05:00
observable < LearnState > learn_state { LearnState : : UNKNOWN } ;
2024-10-28 13:56:16 -04:00
observable < VehicleDetectedState > vehicle_detected_state { VehicleDetectedState : : NO } ;
observable < VehicleArrivingState > vehicle_arriving_state { VehicleArrivingState : : NO } ;
observable < VehicleLeavingState > vehicle_leaving_state { VehicleLeavingState : : NO } ;
2023-07-02 19:44:34 -07:00
2024-01-19 13:24:16 -10:00
OnceCallbacks < void ( DoorState ) > on_door_state_ ;
2023-10-18 17:18:42 -07:00
2023-07-07 15:56:12 -07:00
observable < bool > sync_failed { false } ;
2023-07-02 19:44:34 -07: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 16:17:29 -04:00
// dry contact methods
2024-07-03 09:34:57 -04: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-02 17:59:37 -07: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 16:17:29 -04:00
2024-01-19 13:24:16 -10: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-02 19:44:34 -07:00
2023-07-02 21:45:00 -05:00
// door
2024-01-19 13:24:16 -10: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-02 19:44:34 -07:00
void door_move_to_position ( float position ) ;
2023-07-07 15:56:12 -07:00
void set_door_position ( float door_position ) { this - > door_position = door_position ; }
2023-07-02 19:44:34 -07:00
void set_opening_duration ( float duration ) ;
void set_closing_duration ( float duration ) ;
2024-10-28 13:56:16 -04:00
void set_closing_delay ( uint32_t delay ) { this - > closing_delay = delay ; }
2023-10-08 15:36:09 -07:00
void schedule_door_position_sync ( float update_period = 500 ) ;
void door_position_update ( ) ;
void cancel_position_sync_callbacks ( ) ;
2024-10-28 13:56:16 -04: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-02 19:44:34 -07:00
// light
2024-01-19 13:24:16 -10:00
void light_toggle ( ) ;
2023-07-02 19:44:34 -07:00
void light_on ( ) ;
void light_off ( ) ;
LightState get_light_state ( ) const ;
// lock
2024-01-19 13:24:16 -10:00
void lock_toggle ( ) ;
2023-06-05 18:28:47 -05:00
void lock ( ) ;
void unlock ( ) ;
2023-06-25 10:45:37 -05:00
2024-01-18 17:25:08 -05: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-02 19:44:34 -07:00
// button functionality
2023-06-24 16:51:19 -07:00
void query_status ( ) ;
void query_openings ( ) ;
2023-07-02 19:44:34 -07:00
void sync ( ) ;
2023-06-09 18:14:13 -05:00
2023-07-02 19:44:34 -07:00
// children subscriptions
2023-07-01 07:13:38 -07: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 13:56:16 -04:00
void subscribe_closing_delay ( std : : function < void ( uint32_t ) > & & f ) ;
2023-07-01 07:13:38 -07:00
void subscribe_openings ( std : : function < void ( uint16_t ) > & & f ) ;
2024-01-18 17:25:08 -05: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 07:13:38 -07: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 15:56:12 -07:00
void subscribe_sync_failed ( std : : function < void ( bool ) > & & f ) ;
2024-01-18 17:25:08 -05:00
void subscribe_learn_state ( std : : function < void ( LearnState ) > & & f ) ;
2024-10-28 13:56:16 -04: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 15:56:12 -07:00
2023-06-05 13:56:03 -05:00
protected :
2023-07-02 19:44:34 -07:00
RATGDOStore isr_store_ { } ;
2024-01-19 13:24:16 -10:00
protocol : : Protocol * protocol_ ;
2024-07-03 07:44:33 -04:00
bool obstruction_sensor_detected_ { false } ;
2024-10-28 13:56:16 -04:00
bool presence_detect_window_active_ { false } ;
2023-08-26 08:11:02 -05:00
2023-06-05 14:40:53 -05:00
InternalGPIOPin * output_gdo_pin_ ;
2023-06-05 18:07:10 -05:00
InternalGPIOPin * input_gdo_pin_ ;
InternalGPIOPin * input_obst_pin_ ;
2024-07-03 09:34:57 -04:00
esphome : : binary_sensor : : BinarySensor * dry_contact_open_sensor_ ;
esphome : : binary_sensor : : BinarySensor * dry_contact_close_sensor_ ;
2023-06-05 13:56:03 -05:00
} ; // RATGDOComponent
2023-06-05 13:07:10 -05:00
} // namespace ratgdo
2023-10-18 14:23:30 -10:00
} // namespace esphome