This commit is contained in:
Marius Muja 2024-01-14 00:00:21 -08:00
parent 2a86b6fae1
commit 11a98edd79
3 changed files with 51 additions and 20 deletions

View File

@ -97,6 +97,10 @@ namespace ratgdo {
{
auto prev_door_state = *this->door_state;
if (prev_door_state == door_state) {
return;
}
// opening duration calibration
if (*this->opening_duration == 0) {
if (door_state == DoorState::OPENING && prev_door_state == DoorState::CLOSED) {

View File

@ -25,14 +25,17 @@ namespace secplus1 {
void Secplus1::loop()
{
auto cmd = this->read_command();
if (cmd) {
this->handle_command(cmd.value());
auto rx_cmd = this->read_command();
if (rx_cmd) {
this->handle_command(rx_cmd.value());
}
auto tx_cmd = this->pending_tx();
if (
!this->is_0x37_panel_ &&
this->wall_panel_emulation_state_ != WallPanelEmulationState::RUNNING &&
(millis() - this->last_rx_) > 50
(millis() - this->last_tx_) > 200 && // don't send twice in a period
(millis() - this->last_rx_) > 50 && // time to send it
tx_cmd && // have pending command
!(this->is_0x37_panel_ && tx_cmd.value() == CommandType::TOGGLE_LOCK_PRESS) &&
this->wall_panel_emulation_state_ != WallPanelEmulationState::RUNNING
) {
this->do_transmit_if_pending();
}
@ -190,6 +193,10 @@ namespace secplus1 {
void Secplus1::toggle_door()
{
this->enqueue_transmit(CommandType::TOGGLE_DOOR_PRESS);
this->enqueue_transmit(CommandType::QUERY_DOOR_STATUS);
if (this->door_state == DoorState::STOPPED || this->door_state == DoorState::OPEN || this->door_state == DoorState::CLOSED) {
this->door_moving_ = true;
}
}
Result Secplus1::call(Args args)
@ -284,7 +291,7 @@ namespace secplus1 {
void Secplus1::handle_command(const RxCommand& cmd)
{
if (cmd.req == CommandType::DOOR_STATUS) {
if (cmd.req == CommandType::QUERY_DOOR_STATUS) {
DoorState door_state;
auto val = cmd.resp & 0x7;
@ -313,19 +320,25 @@ namespace secplus1 {
this->maybe_door_state = door_state;
} else {
this->door_state = door_state;
if (this->door_state == DoorState::STOPPED || this->door_state == DoorState::OPEN || this->door_state == DoorState::CLOSED) {
this->door_moving_ = false;
}
this->ratgdo_->received(door_state);
}
}
else if (cmd.req == CommandType::DOOR_STATUS_0x37) {
else if (cmd.req == CommandType::QUERY_DOOR_STATUS_0x37) {
this->is_0x37_panel_ = true;
if (!this->do_transmit_if_pending()) {
auto cmd = this->pending_tx();
if (cmd && cmd.value() == CommandType::TOGGLE_LOCK_PRESS) {
this->do_transmit_if_pending();
} else {
// inject door status request
if (millis() - this->last_status_query_ > 10000) {
this->transmit_byte(static_cast<uint8_t>(CommandType::DOOR_STATUS), true);
if (door_moving_ || (millis() - this->last_status_query_ > 10000)) {
this->transmit_byte(static_cast<uint8_t>(CommandType::QUERY_DOOR_STATUS), true);
this->last_status_query_ = millis();
}
}
} else if (cmd.req == CommandType::OTHER_STATUS) {
} else if (cmd.req == CommandType::QUERY_OTHER_STATUS) {
LightState light_state = to_LightState((cmd.resp >> 2) & 1, LightState::UNKNOWN);
if (!this->is_0x37_panel_ && light_state != this->maybe_light_state) {
@ -367,7 +380,7 @@ namespace secplus1 {
bool Secplus1::do_transmit_if_pending()
{
auto cmd = this->pending_tx();
auto cmd = this->pop_pending_tx();
if (cmd) {
this->enqueue_command_pair(cmd.value());
this->transmit_byte(static_cast<uint32_t>(cmd.value()));
@ -401,11 +414,20 @@ namespace secplus1 {
return {};
}
auto cmd = this->pending_tx_.top();
if (cmd.time < millis()) {
this->pending_tx_.pop();
return cmd.request;
if (cmd.time > millis()) {
return {};
}
return {};
return cmd.request;
}
optional<CommandType> Secplus1::pop_pending_tx()
{
auto cmd = this->pending_tx();
if (cmd) {
this->pending_tx_.pop();
}
return cmd;
}
void Secplus1::transmit_byte(uint32_t value, bool enable_rx)
@ -414,6 +436,7 @@ namespace secplus1 {
this->sw_serial_.enableIntTx(false);
}
this->sw_serial_.write(value);
this->last_tx_ = millis();
if (!enable_rx) {
this->sw_serial_.enableIntTx(true);
}

View File

@ -39,10 +39,10 @@ namespace secplus1 {
(TOGGLE_LIGHT_RELEASE, 0x33),
(TOGGLE_LOCK_PRESS, 0x34),
(TOGGLE_LOCK_RELEASE, 0x35),
(DOOR_STATUS_0x37, 0x37),
(DOOR_STATUS, 0x38),
(QUERY_DOOR_STATUS_0x37, 0x37),
(QUERY_DOOR_STATUS, 0x38),
(OBSTRUCTION, 0x39),
(OTHER_STATUS, 0x3A),
(QUERY_OTHER_STATUS, 0x3A),
(UNKNOWN, 0xFF),
)
@ -95,6 +95,7 @@ namespace secplus1 {
void enqueue_transmit(CommandType cmd, uint32_t time = 0);
optional<CommandType> pending_tx();
optional<CommandType> pop_pending_tx();
bool do_transmit_if_pending();
void enqueue_command_pair(CommandType cmd);
void transmit_byte(uint32_t value, bool enable_rx = false);
@ -112,6 +113,8 @@ namespace secplus1 {
LockState maybe_lock_state { LockState::UNKNOWN };
DoorState maybe_door_state { DoorState::UNKNOWN };
bool door_moving_ { false };
bool wall_panel_starting_ { false };
uint32_t wall_panel_emulation_start_ { 0 };
WallPanelEmulationState wall_panel_emulation_state_ { WallPanelEmulationState::WAITING };
@ -119,6 +122,7 @@ namespace secplus1 {
bool is_0x37_panel_ { false };
std::priority_queue<TxCommand, std::vector<TxCommand>, FirstToSend> pending_tx_;
uint32_t last_rx_ { 0 };
uint32_t last_tx_ { 0 };
uint32_t last_status_query_ { 0 };
SoftwareSerial sw_serial_;