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
|
2023-06-07 16:06:11 -05:00
|
|
|
#include "esphome/components/uart/uart.h"
|
2023-06-05 13:34:06 -05:00
|
|
|
#include "esphome/core/component.h"
|
2023-06-05 14:46:23 -05:00
|
|
|
#include "esphome/core/gpio.h"
|
2023-06-05 20:05:37 -05:00
|
|
|
#include "esphome/core/log.h"
|
2023-06-05 20:06:12 -05:00
|
|
|
#include "esphome/core/preferences.h"
|
2023-06-05 13:07:10 -05:00
|
|
|
|
2023-06-05 13:26:26 -05:00
|
|
|
extern "C" {
|
|
|
|
#include "secplus.h"
|
|
|
|
}
|
|
|
|
|
2023-06-07 09:51:22 -05:00
|
|
|
#include "ratgdo_child.h"
|
2023-06-07 10:44:31 -05:00
|
|
|
#include "ratgdo_state.h"
|
|
|
|
|
2023-06-05 18:24:05 -05:00
|
|
|
#define CODE_LENGTH 19
|
|
|
|
|
2023-06-05 12:59:55 -05:00
|
|
|
namespace esphome {
|
|
|
|
namespace ratgdo {
|
|
|
|
|
2023-06-07 09:47:27 -05:00
|
|
|
// Forward declare RATGDOClient
|
|
|
|
class RATGDOClient;
|
|
|
|
|
2023-06-09 15:06:51 -05:00
|
|
|
typedef struct {
|
|
|
|
uint64_t fixed;
|
|
|
|
uint32_t data;
|
2023-06-09 15:15:53 -05:00
|
|
|
bool operator==(const command a) const
|
2023-06-09 15:15:27 -05:00
|
|
|
{
|
|
|
|
return (fixed == a.fixed && data == a.data);
|
|
|
|
}
|
2023-06-09 15:06:51 -05:00
|
|
|
} command;
|
|
|
|
|
2023-06-09 15:11:16 -05:00
|
|
|
typedef struct {
|
|
|
|
command REBOOT1;
|
|
|
|
command REBOOT2;
|
|
|
|
command REBOOT3;
|
|
|
|
command REBOOT4;
|
|
|
|
command REBOOT5;
|
|
|
|
command REBOOT6;
|
|
|
|
command DOOR1;
|
|
|
|
command DOOR2;
|
|
|
|
command LIGHT;
|
|
|
|
command LOCK;
|
|
|
|
} commands;
|
|
|
|
|
|
|
|
const commands Command = {
|
2023-06-09 15:06:51 -05:00
|
|
|
.REBOOT1 = (command) { 0x400000000, 0x0000618b },
|
|
|
|
.REBOOT2 = (command) { 0, 0x01009080 },
|
|
|
|
.REBOOT3 = (command) { 0, 0x0000b1a0 },
|
|
|
|
.REBOOT4 = (command) { 0, 0x01009080 },
|
|
|
|
.REBOOT5 = (command) { 0x300000000, 0x00008092 },
|
|
|
|
.REBOOT6 = (command) { 0x300000000, 0x00008092 },
|
|
|
|
.DOOR1 = (command) { 0x200000000, 0x01018280 },
|
|
|
|
.DOOR2 = (command) { 0x200000000, 0x01009280 },
|
|
|
|
.LIGHT = (command) { 0x200000000, 0x00009281 },
|
|
|
|
.LOCK = (command) { 0x0100000000, 0x0000728c },
|
2023-06-07 09:40:45 -05:00
|
|
|
};
|
2023-06-05 16:26:28 -05:00
|
|
|
struct RATGDOStore {
|
2023-06-05 18:07:10 -05:00
|
|
|
ISRInternalGPIOPin input_obst;
|
|
|
|
|
2023-06-05 17:44:24 -05:00
|
|
|
int obstructionLowCount = 0; // count obstruction low pulses
|
|
|
|
long lastObstructionHigh = 0; // count time between high pulses from the obst ISR
|
2023-06-05 16:26:28 -05:00
|
|
|
|
2023-06-05 16:26:33 -05: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 16:26:28 -05:00
|
|
|
};
|
|
|
|
|
2023-06-07 16:05:46 -05:00
|
|
|
class RATGDOComponent : public uart::UARTDevice, 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-05 13:56:03 -05:00
|
|
|
/********************************** GLOBAL VARS
|
|
|
|
* *****************************************/
|
2023-06-05 20:57:12 -05:00
|
|
|
uint32_t rollingCodeCounter;
|
2023-06-05 18:07:10 -05:00
|
|
|
uint8_t txRollingCode[CODE_LENGTH];
|
|
|
|
uint8_t rxRollingCode[CODE_LENGTH];
|
2023-06-05 13:56:03 -05:00
|
|
|
|
2023-06-07 18:59:49 -05:00
|
|
|
uint8_t previousDoorState { DoorState::DOOR_STATE_UNKNOWN };
|
|
|
|
uint8_t previousLightState { LightState::LIGHT_STATE_UNKNOWN };
|
|
|
|
uint8_t previousLockState { LockState::LOCK_STATE_UNKNOWN };
|
|
|
|
uint8_t previousObstructionState { ObstructionState::OBSTRUCTION_STATE_UNKNOWN };
|
2023-06-07 21:48:15 -05:00
|
|
|
uint8_t previousMotorState { MotorState::MOTOR_STATE_UNKNOWN };
|
2023-06-07 18:59:49 -05:00
|
|
|
|
2023-06-07 19:20:32 -05:00
|
|
|
uint8_t obstructionState { ObstructionState::OBSTRUCTION_STATE_UNKNOWN };
|
|
|
|
uint8_t motionState { MotionState::MOTION_STATE_CLEAR };
|
2023-06-07 21:48:15 -05:00
|
|
|
uint8_t motorState { MotorState::MOTOR_STATE_UNKNOWN };
|
2023-06-07 19:20:32 -05:00
|
|
|
uint8_t lockState { LockState::LOCK_STATE_UNKNOWN };
|
|
|
|
uint8_t lightState { LightState::LIGHT_STATE_UNKNOWN };
|
|
|
|
uint8_t doorState { DoorState::DOOR_STATE_UNKNOWN };
|
|
|
|
|
2023-06-05 14:40:53 -05:00
|
|
|
void set_output_gdo_pin(InternalGPIOPin* pin) { this->output_gdo_pin_ = pin; };
|
2023-06-05 18:19:52 -05: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 14:40:53 -05: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 14:39:46 -05:00
|
|
|
|
2023-06-05 13:56:03 -05:00
|
|
|
/********************************** FUNCTION DECLARATION
|
|
|
|
* *****************************************/
|
2023-06-09 15:12:20 -05:00
|
|
|
void transmit(command command);
|
2023-06-05 13:56:03 -05:00
|
|
|
void sync();
|
|
|
|
|
|
|
|
void obstructionLoop();
|
2023-06-05 18:29:16 -05:00
|
|
|
void sendObstructionStatus();
|
2023-06-05 13:56:03 -05:00
|
|
|
|
2023-06-05 18:28:47 -05:00
|
|
|
void toggleDoor();
|
|
|
|
void openDoor();
|
|
|
|
void closeDoor();
|
|
|
|
void stopDoor();
|
2023-06-05 13:56:03 -05:00
|
|
|
void sendDoorStatus();
|
2023-06-05 18:28:47 -05:00
|
|
|
|
|
|
|
void toggleLight();
|
|
|
|
void lightOn();
|
|
|
|
void lightOff();
|
2023-06-07 20:46:44 -05:00
|
|
|
bool isLightOn();
|
2023-06-05 18:28:47 -05:00
|
|
|
void sendLightStatus();
|
|
|
|
|
|
|
|
void toggleLock();
|
|
|
|
void lock();
|
|
|
|
void unlock();
|
|
|
|
void sendLockStatus();
|
|
|
|
|
|
|
|
void sendMotionStatus();
|
2023-06-07 21:40:07 -05:00
|
|
|
void sendMotorStatus();
|
2023-06-07 18:59:49 -05:00
|
|
|
void query();
|
2023-06-05 13:56:03 -05:00
|
|
|
void doorStateLoop();
|
2023-06-05 14:00:45 -05:00
|
|
|
void printRollingCode();
|
2023-06-09 15:12:20 -05:00
|
|
|
void getRollingCode(command command);
|
2023-06-05 18:25:36 -05:00
|
|
|
void gdoStateLoop();
|
2023-06-05 18:25:55 -05:00
|
|
|
void statusUpdateLoop();
|
2023-06-09 15:06:51 -05:00
|
|
|
void readRollingCode(bool& isStatus, uint8_t& door, uint8_t& light, uint8_t& lock, uint8_t& motion, uint8_t& obstruction, uint8_t& motor);
|
2023-06-07 17:59:56 -05:00
|
|
|
void incrementRollingCodeCounter();
|
2023-06-07 18:10:02 -05:00
|
|
|
void sendRollingCodeChanged();
|
|
|
|
void setRollingCodeCounter(uint32_t counter);
|
2023-06-09 15:12:20 -05:00
|
|
|
void sendCommandAndSaveCounter(command command);
|
2023-06-07 09:45:49 -05:00
|
|
|
/** Register a child component. */
|
2023-06-07 09:47:27 -05:00
|
|
|
void register_child(RATGDOClient* obj);
|
2023-06-05 13:56:03 -05:00
|
|
|
|
|
|
|
protected:
|
|
|
|
ESPPreferenceObject pref_;
|
2023-06-07 09:51:53 -05:00
|
|
|
std::vector<RATGDOClient*> children_;
|
2023-06-07 20:40:38 -05:00
|
|
|
bool forceUpdate_ { false };
|
2023-06-05 16:26:33 -05:00
|
|
|
RATGDOStore store_ {};
|
2023-06-05 16:26:28 -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_;
|
|
|
|
|
2023-06-05 14:40:53 -05:00
|
|
|
InternalGPIOPin* status_door_pin_;
|
|
|
|
InternalGPIOPin* status_obst_pin_;
|
2023-06-05 13:56:03 -05:00
|
|
|
|
|
|
|
}; // RATGDOComponent
|
2023-06-05 13:07:10 -05:00
|
|
|
|
|
|
|
} // namespace ratgdo
|
2023-06-07 16:06:11 -05:00
|
|
|
} // namespace esphome
|