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
|
2023-06-06 01:06:12 +00:00
|
|
|
#include "esphome/components/uart/uart.h"
|
2023-06-05 18:34:06 +00:00
|
|
|
#include "esphome/core/component.h"
|
2023-06-05 19:46:23 +00:00
|
|
|
#include "esphome/core/gpio.h"
|
2023-06-06 01:05:37 +00:00
|
|
|
#include "esphome/core/log.h"
|
2023-06-06 01:06:12 +00:00
|
|
|
#include "esphome/core/preferences.h"
|
2023-06-05 18:07:10 +00:00
|
|
|
|
2023-06-05 18:26:26 +00:00
|
|
|
extern "C" {
|
|
|
|
#include "secplus.h"
|
|
|
|
}
|
|
|
|
|
2023-06-05 23:24:05 +00:00
|
|
|
#define CODE_LENGTH 19
|
|
|
|
|
2023-06-05 17:59:55 +00:00
|
|
|
namespace esphome {
|
|
|
|
namespace ratgdo {
|
|
|
|
|
2023-06-07 14:20:30 +00:00
|
|
|
/// Enum for all states a the door can be in.
|
|
|
|
enum DoorState : uint8_t {
|
|
|
|
DOOR_STATE_UNKNOWN = 0,
|
|
|
|
DOOR_STATE_OPEN = 1,
|
|
|
|
DOOR_STATE_CLOSED = 2,
|
|
|
|
DOOR_STATE_STOPPED = 3,
|
|
|
|
DOOR_STATE_OPENING = 4,
|
|
|
|
DOOR_STATE_CLOSING = 5
|
|
|
|
};
|
|
|
|
const char* door_state_to_string(DoorState state);
|
|
|
|
|
|
|
|
/// Enum for all states a the light can be in.
|
|
|
|
enum LightState : uint8_t {
|
|
|
|
LIGHT_STATE_OFF = 0,
|
|
|
|
LIGHT_STATE_ON = 1,
|
|
|
|
LIGHT_STATE_UNKNOWN = 2,
|
|
|
|
};
|
|
|
|
const char* light_state_to_string(LightState state);
|
|
|
|
|
|
|
|
/// Enum for all states a the lock can be in.
|
|
|
|
enum LockState : uint8_t {
|
|
|
|
LOCK_STATE_UNLOCKED = 0,
|
|
|
|
LOCK_STATE_LOCKED = 1,
|
|
|
|
LOCK_STATE_UNKNOWN = 2,
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Enum for all states a the motion can be in.
|
|
|
|
enum MotionState : uint8_t {
|
|
|
|
MOTION_STATE_CLEAR = 0,
|
|
|
|
MOTION_STATE_DETECTED = 1,
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Enum for all states a the obstruction can be in.
|
|
|
|
enum ObstructionState : uint8_t {
|
|
|
|
OBSTRUCTION_STATE_OBSTRUCTED = 0,
|
|
|
|
OBSTRUCTION_STATE_CLEAR = 1,
|
|
|
|
OBSTRUCTION_STATE_UNKNOWN = 2,
|
|
|
|
};
|
2023-06-05 21:26:28 +00:00
|
|
|
struct RATGDOStore {
|
2023-06-05 23:07:10 +00:00
|
|
|
ISRInternalGPIOPin input_obst;
|
|
|
|
|
2023-06-05 21:26:28 +00:00
|
|
|
ISRInternalGPIOPin trigger_open;
|
|
|
|
ISRInternalGPIOPin trigger_close;
|
|
|
|
ISRInternalGPIOPin trigger_light;
|
2023-06-05 23:07:10 +00:00
|
|
|
|
2023-06-05 23:59:09 +00:00
|
|
|
bool dryContactDoorOpen { false };
|
|
|
|
bool dryContactDoorClose { false };
|
2023-06-05 23:59:11 +00:00
|
|
|
bool dryContactToggleLight { false };
|
2023-06-05 21:26:28 +00:00
|
|
|
|
2023-06-05 22:44:24 +00:00
|
|
|
int obstructionLowCount = 0; // count obstruction low pulses
|
|
|
|
long lastObstructionHigh = 0; // count time between high pulses from the obst ISR
|
2023-06-05 21:26:28 +00:00
|
|
|
|
2023-06-07 14:20:30 +00:00
|
|
|
uint8_t obstructionState = ObstructionState.OBSTRUCTION_STATE_UNKNOWN;
|
|
|
|
uint8_t motionState = MotionState.MOTION_STATE_CLEAR;
|
|
|
|
uint8_t lockState = LockState.LOCK_STATE_UNKNOWN;
|
|
|
|
uint8_t lightState = LightState.LIGHT_STATE_UNKNOWN;
|
|
|
|
uint8_t doorState = DoorState.DOOR_STATE_UNKNOWN;
|
2023-06-05 23:22:59 +00:00
|
|
|
|
2023-06-05 21:26:33 +00:00
|
|
|
static void IRAM_ATTR isrDoorOpen(RATGDOStore* arg);
|
|
|
|
static void IRAM_ATTR isrDoorClose(RATGDOStore* arg);
|
|
|
|
static void IRAM_ATTR isrLight(RATGDOStore* arg);
|
|
|
|
static void IRAM_ATTR isrObstruction(RATGDOStore* arg);
|
2023-06-05 21:26:28 +00:00
|
|
|
};
|
|
|
|
|
2023-06-06 01:04:30 +00:00
|
|
|
class RATGDOComponent : public uart::UARTDevice, 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-05 18:56:03 +00:00
|
|
|
/********************************** GLOBAL VARS
|
|
|
|
* *****************************************/
|
2023-06-06 01:57:12 +00:00
|
|
|
uint32_t rollingCodeCounter;
|
2023-06-05 23:07:10 +00:00
|
|
|
uint8_t txRollingCode[CODE_LENGTH];
|
|
|
|
uint8_t rxRollingCode[CODE_LENGTH];
|
2023-06-05 18:56:03 +00:00
|
|
|
|
2023-06-05 19:40:53 +00:00
|
|
|
void set_output_gdo_pin(InternalGPIOPin* pin) { this->output_gdo_pin_ = pin; };
|
2023-06-05 23:19:52 +00:00
|
|
|
void set_input_gdo_pin(InternalGPIOPin* pin) { this->input_gdo_pin_ = pin; };
|
|
|
|
void set_input_obst_pin(InternalGPIOPin* pin) { this->input_obst_pin_ = pin; };
|
|
|
|
|
2023-06-05 19:40:53 +00:00
|
|
|
void set_trigger_open_pin(InternalGPIOPin* pin) { this->trigger_open_pin_ = pin; };
|
|
|
|
void set_trigger_close_pin(InternalGPIOPin* pin) { this->trigger_close_pin_ = pin; };
|
|
|
|
void set_trigger_light_pin(InternalGPIOPin* pin) { this->trigger_light_pin_ = pin; };
|
2023-06-05 23:19:52 +00:00
|
|
|
|
2023-06-05 19:40:53 +00:00
|
|
|
void set_status_door_pin(InternalGPIOPin* pin) { this->status_door_pin_ = pin; };
|
|
|
|
void set_status_obst_pin(InternalGPIOPin* pin) { this->status_obst_pin_ = pin; };
|
2023-06-05 19:39:46 +00:00
|
|
|
|
2023-06-05 18:56:03 +00:00
|
|
|
/********************************** FUNCTION DECLARATION
|
|
|
|
* *****************************************/
|
2023-06-06 02:27:14 +00:00
|
|
|
void transmit(const char* command);
|
2023-06-05 18:56:03 +00:00
|
|
|
void sync();
|
|
|
|
|
|
|
|
void obstructionLoop();
|
2023-06-05 23:29:16 +00:00
|
|
|
void sendObstructionStatus();
|
2023-06-05 18:56:03 +00:00
|
|
|
|
2023-06-05 23:28:47 +00:00
|
|
|
void toggleDoor();
|
|
|
|
void openDoor();
|
|
|
|
void closeDoor();
|
|
|
|
void stopDoor();
|
2023-06-05 18:56:03 +00:00
|
|
|
void sendDoorStatus();
|
2023-06-05 23:28:47 +00:00
|
|
|
|
|
|
|
void toggleLight();
|
|
|
|
void lightOn();
|
|
|
|
void lightOff();
|
|
|
|
void sendLightStatus();
|
|
|
|
|
|
|
|
void toggleLock();
|
|
|
|
void lock();
|
|
|
|
void unlock();
|
|
|
|
void sendLockStatus();
|
|
|
|
|
|
|
|
void sendMotionStatus();
|
|
|
|
|
2023-06-05 18:56:03 +00:00
|
|
|
void doorStateLoop();
|
|
|
|
void dryContactLoop();
|
2023-06-05 19:00:45 +00:00
|
|
|
void printRollingCode();
|
|
|
|
void getRollingCode(const char* command);
|
2023-06-05 23:25:36 +00:00
|
|
|
void gdoStateLoop();
|
2023-06-05 23:25:55 +00:00
|
|
|
void statusUpdateLoop();
|
2023-06-05 23:26:28 +00:00
|
|
|
void readRollingCode(uint8_t& door, uint8_t& light, uint8_t& lock, uint8_t& motion, uint8_t& obstruction);
|
2023-06-06 00:22:23 +00:00
|
|
|
void sendCommand(const char* command);
|
2023-06-05 18:56:03 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
ESPPreferenceObject pref_;
|
2023-06-05 21:26:33 +00:00
|
|
|
RATGDOStore store_ {};
|
2023-06-05 21:26:28 +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_;
|
|
|
|
|
2023-06-05 19:40:53 +00:00
|
|
|
InternalGPIOPin* trigger_open_pin_;
|
|
|
|
InternalGPIOPin* trigger_close_pin_;
|
|
|
|
InternalGPIOPin* trigger_light_pin_;
|
2023-06-05 23:07:10 +00:00
|
|
|
|
2023-06-05 19:40:53 +00:00
|
|
|
InternalGPIOPin* status_door_pin_;
|
|
|
|
InternalGPIOPin* status_obst_pin_;
|
2023-06-05 18:56:03 +00:00
|
|
|
|
|
|
|
}; // RATGDOComponent
|
2023-06-05 18:07:10 +00:00
|
|
|
|
|
|
|
} // namespace ratgdo
|
|
|
|
} // namespace esphome
|