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-17 14:50:38 +00:00
|
|
|
#include "SoftwareSerial.h" // Using espsoftwareserial https://github.com/plerup/espsoftwareserial
|
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-07 14:51:22 +00:00
|
|
|
#include "ratgdo_child.h"
|
2023-06-07 15:44:31 +00:00
|
|
|
#include "ratgdo_state.h"
|
|
|
|
|
2023-06-05 17:59:55 +00:00
|
|
|
namespace esphome {
|
|
|
|
namespace ratgdo {
|
|
|
|
|
2023-06-07 14:47:27 +00:00
|
|
|
// Forward declare RATGDOClient
|
|
|
|
class RATGDOClient;
|
|
|
|
|
2023-06-10 00:11:27 +00:00
|
|
|
static const uint8_t CODE_LENGTH = 19;
|
|
|
|
|
2023-06-24 20:38:44 +00:00
|
|
|
/*
|
|
|
|
from: https://github.com/argilo/secplus/blob/f98c3220356c27717a25102c0b35815ebbd26ccc/secplus.py#L540
|
|
|
|
_WIRELINE_COMMANDS = {
|
|
|
|
# sent by opener
|
|
|
|
0x081: "status",
|
|
|
|
0x084: "unknown_1",
|
|
|
|
0x085: "unknown_2",
|
|
|
|
0x0a1: "pair_3_resp",
|
|
|
|
0x284: "motor_on",
|
|
|
|
0x393: "learn_3_resp",
|
|
|
|
0x401: "pair_2_resp",
|
|
|
|
0x48c: "openings",
|
|
|
|
|
|
|
|
# sent by switch
|
|
|
|
0x080: "get_status",
|
|
|
|
0x0a0: "pair_3",
|
|
|
|
0x181: "learn_2",
|
|
|
|
0x18c: "lock",
|
|
|
|
0x280: "open",
|
|
|
|
0x281: "light",
|
|
|
|
0x285: "motion",
|
|
|
|
0x391: "learn_1",
|
|
|
|
0x392: "learn_3",
|
|
|
|
0x400: "pair_2",
|
|
|
|
0x48b: "get_openings",
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace data {
|
|
|
|
const uint32_t OFF = 0;
|
|
|
|
const uint32_t CLOSE = 0;
|
|
|
|
const uint32_t ON = 1;
|
|
|
|
const uint32_t OPEN = 1;
|
|
|
|
const uint32_t TOGGLE = 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace command {
|
|
|
|
|
|
|
|
enum cmd : uint64_t {
|
|
|
|
GET_STATUS = 0x080,
|
|
|
|
STATUS = 0x081,
|
|
|
|
OBST_1 = 0x084, // sent when an obstruction happens?
|
|
|
|
OBST_2 = 0x085, // sent when an obstruction happens?
|
|
|
|
PAIR_3 = 0x0a0,
|
|
|
|
PAIR_3_RESP = 0x0a1,
|
|
|
|
|
|
|
|
LEARN_2 = 0x181,
|
|
|
|
LOCK = 0x18c,
|
|
|
|
|
|
|
|
OPEN = 0x280,
|
|
|
|
LIGHT = 0x281,
|
|
|
|
MOTOR_ON = 0x284,
|
|
|
|
MOTION = 0x285,
|
|
|
|
|
|
|
|
LEARN_1 = 0x391,
|
|
|
|
LEARN_3 = 0x392,
|
|
|
|
LEARN_3_RESP = 0x393,
|
|
|
|
|
|
|
|
PAIR_2 = 0x400,
|
|
|
|
PAIR_2_RESP = 0x401,
|
|
|
|
GET_OPENINGS = 0x48b,
|
|
|
|
OPENINGS = 0x48c,
|
|
|
|
};
|
|
|
|
}
|
2023-06-09 20:06:51 +00:00
|
|
|
|
2023-06-05 21:26:28 +00:00
|
|
|
struct RATGDOStore {
|
2023-06-05 23:07:10 +00:00
|
|
|
ISRInternalGPIOPin input_obst;
|
|
|
|
|
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-09 23:37:43 +00:00
|
|
|
static void IRAM_ATTR HOT isrObstruction(RATGDOStore* arg);
|
2023-06-05 21:26:28 +00:00
|
|
|
};
|
|
|
|
|
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
|
|
|
|
2023-06-17 14:50:38 +00:00
|
|
|
EspSoftwareSerial::UART swSerial;
|
|
|
|
|
2023-06-09 23:43:50 +00:00
|
|
|
uint32_t rollingCodeCounter { 0 };
|
|
|
|
uint32_t lastSyncedRollingCodeCounter { 0 };
|
2023-06-09 23:43:43 +00:00
|
|
|
|
2023-06-24 20:38:44 +00:00
|
|
|
uint8_t txRollingCode[CODE_LENGTH];
|
|
|
|
uint8_t rxRollingCode[CODE_LENGTH];
|
|
|
|
|
2023-06-09 22:36:56 +00:00
|
|
|
uint16_t previousOpenings { 0 }; // number of times the door has been opened
|
2023-06-09 23:43:50 +00:00
|
|
|
uint16_t openings { 0 }; // number of times the door has been opened
|
2023-06-09 22:36:56 +00:00
|
|
|
|
2023-06-24 20:38:44 +00:00
|
|
|
DoorState previousDoorState { DoorState::DOOR_STATE_UNKNOWN };
|
|
|
|
DoorState doorState { DoorState::DOOR_STATE_UNKNOWN };
|
|
|
|
|
|
|
|
LightState previousLightState { LightState::LIGHT_STATE_UNKNOWN };
|
|
|
|
LightState lightState { LightState::LIGHT_STATE_UNKNOWN };
|
2023-06-05 18:56:03 +00:00
|
|
|
|
2023-06-24 20:38:44 +00:00
|
|
|
LockState previousLockState { LockState::LOCK_STATE_UNKNOWN };
|
|
|
|
LockState lockState { LockState::LOCK_STATE_UNKNOWN };
|
|
|
|
|
|
|
|
ObstructionState previousObstructionState { ObstructionState::OBSTRUCTION_STATE_UNKNOWN };
|
|
|
|
ObstructionState obstructionState { ObstructionState::OBSTRUCTION_STATE_UNKNOWN };
|
|
|
|
|
|
|
|
MotorState previousMotorState { MotorState::MOTOR_STATE_UNKNOWN };
|
|
|
|
MotorState motorState { MotorState::MOTOR_STATE_UNKNOWN };
|
|
|
|
|
|
|
|
ButtonState previousButtonState { ButtonState::BUTTON_STATE_UNKNOWN };
|
|
|
|
ButtonState buttonState { ButtonState::BUTTON_STATE_UNKNOWN };
|
|
|
|
|
|
|
|
MotionState previousMotionState { MotionState::MOTION_STATE_UNKNOWN };
|
|
|
|
MotionState motionState { MotionState::MOTION_STATE_UNKNOWN };
|
2023-06-08 00:20:32 +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-24 21:01:20 +00:00
|
|
|
void set_remote_id(uint64_t remote_id) { this->remote_id = remote_id & 0xffffff; }; // not sure how large remote_id can be, assuming not more than 24 bits
|
2023-06-05 23:19:52 +00:00
|
|
|
|
2023-06-05 18:56:03 +00:00
|
|
|
/********************************** FUNCTION DECLARATION
|
|
|
|
* *****************************************/
|
2023-06-24 20:38:44 +00:00
|
|
|
void transmit(command::cmd command, uint32_t data = 0, bool increment = true);
|
|
|
|
|
2023-06-05 18:56:03 +00:00
|
|
|
void sync();
|
|
|
|
|
2023-06-09 23:14:13 +00:00
|
|
|
void gdoStateLoop();
|
2023-06-05 18:56:03 +00:00
|
|
|
void obstructionLoop();
|
2023-06-09 23:14:13 +00:00
|
|
|
void statusUpdateLoop();
|
2023-06-09 22:36:56 +00:00
|
|
|
|
2023-06-24 20:38:44 +00:00
|
|
|
void sendCommandAndSaveCounter(command::cmd command, uint32_t data = 0, bool increment = true);
|
|
|
|
|
|
|
|
void doorCommand(uint32_t data);
|
2023-06-05 23:28:47 +00:00
|
|
|
void toggleDoor();
|
|
|
|
void openDoor();
|
|
|
|
void closeDoor();
|
|
|
|
void stopDoor();
|
2023-06-24 20:38:44 +00:00
|
|
|
|
2023-06-05 23:28:47 +00:00
|
|
|
void toggleLight();
|
|
|
|
void lightOn();
|
|
|
|
void lightOff();
|
2023-06-24 20:38:44 +00:00
|
|
|
|
2023-06-05 23:28:47 +00:00
|
|
|
void toggleLock();
|
|
|
|
void lock();
|
|
|
|
void unlock();
|
2023-06-07 23:59:49 +00:00
|
|
|
void query();
|
2023-06-09 23:14:13 +00:00
|
|
|
|
2023-06-05 19:00:45 +00:00
|
|
|
void printRollingCode();
|
2023-06-24 20:38:44 +00:00
|
|
|
void getRollingCode(command::cmd command, uint32_t data, bool increment);
|
2023-06-09 23:30:52 +00:00
|
|
|
uint16_t readRollingCode();
|
2023-06-07 22:59:56 +00:00
|
|
|
void incrementRollingCodeCounter();
|
2023-06-07 23:10:02 +00:00
|
|
|
void sendRollingCodeChanged();
|
|
|
|
void setRollingCodeCounter(uint32_t counter);
|
2023-06-09 21:39:49 +00:00
|
|
|
LightState getLightState();
|
2023-06-07 14:45:49 +00:00
|
|
|
/** Register a child component. */
|
2023-06-07 14:47:27 +00:00
|
|
|
void register_child(RATGDOClient* obj);
|
2023-06-05 18:56:03 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
ESPPreferenceObject pref_;
|
2023-06-07 14:51:53 +00:00
|
|
|
std::vector<RATGDOClient*> children_;
|
2023-06-09 23:53:09 +00:00
|
|
|
bool rollingCodeUpdatesEnabled_ { true };
|
2023-06-08 01:40:38 +00:00
|
|
|
bool forceUpdate_ { false };
|
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-24 21:01:20 +00:00
|
|
|
uint64_t remote_id;
|
2023-06-05 23:07:10 +00:00
|
|
|
|
2023-06-05 18:56:03 +00:00
|
|
|
}; // RATGDOComponent
|
2023-06-05 18:07:10 +00:00
|
|
|
|
|
|
|
} // namespace ratgdo
|
2023-06-17 14:50:38 +00:00
|
|
|
} // namespace esphome
|