Rework of door position sync (#61)
Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
parent
fe593a9a76
commit
575471bda1
|
@ -16,6 +16,9 @@
|
||||||
|
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
#define ESP_LOG1 ESP_LOGV
|
||||||
|
#define ESP_LOG2 ESP_LOGV
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace ratgdo {
|
namespace ratgdo {
|
||||||
|
|
||||||
|
@ -97,20 +100,19 @@ namespace ratgdo {
|
||||||
uint16_t cmd = ((fixed >> 24) & 0xf00) | (data & 0xff);
|
uint16_t cmd = ((fixed >> 24) & 0xf00) | (data & 0xff);
|
||||||
data &= ~0xf000; // clear parity nibble
|
data &= ~0xf000; // clear parity nibble
|
||||||
|
|
||||||
Command cmd_enum = to_Command(cmd, Command::UNKNOWN);
|
|
||||||
|
|
||||||
if ((fixed & 0xfffffff) == this->remote_id_) { // my commands
|
if ((fixed & 0xfffffff) == this->remote_id_) { // my commands
|
||||||
ESP_LOGV(TAG, "[%ld] received mine: rolling=%07" PRIx32 " fixed=%010" PRIx64 " data=%08" PRIx32, millis(), rolling, fixed, data);
|
ESP_LOG1(TAG, "[%ld] received mine: rolling=%07" PRIx32 " fixed=%010" PRIx64 " data=%08" PRIx32, millis(), rolling, fixed, data);
|
||||||
return static_cast<uint16_t>(Command::UNKNOWN);
|
return static_cast<uint16_t>(Command::UNKNOWN);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGV(TAG, "[%ld] received rolling=%07" PRIx32 " fixed=%010" PRIx64 " data=%08" PRIx32, millis(), rolling, fixed, data);
|
ESP_LOG1(TAG, "[%ld] received rolling=%07" PRIx32 " fixed=%010" PRIx64 " data=%08" PRIx32, millis(), rolling, fixed, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Command cmd_enum = to_Command(cmd, Command::UNKNOWN);
|
||||||
uint8_t nibble = (data >> 8) & 0xff;
|
uint8_t nibble = (data >> 8) & 0xff;
|
||||||
uint8_t byte1 = (data >> 16) & 0xff;
|
uint8_t byte1 = (data >> 16) & 0xff;
|
||||||
uint8_t byte2 = (data >> 24) & 0xff;
|
uint8_t byte2 = (data >> 24) & 0xff;
|
||||||
|
|
||||||
ESP_LOGV(TAG, "cmd=%03x (%s) byte2=%02x byte1=%02x nibble=%01x", cmd, Command_to_string(cmd_enum), byte2, byte1, nibble);
|
ESP_LOG1(TAG, "cmd=%03x (%s) byte2=%02x byte1=%02x nibble=%01x", cmd, Command_to_string(cmd_enum), byte2, byte1, nibble);
|
||||||
|
|
||||||
if (cmd == Command::STATUS) {
|
if (cmd == Command::STATUS) {
|
||||||
|
|
||||||
|
@ -144,26 +146,55 @@ namespace ratgdo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (door_state == DoorState::OPEN) {
|
if (door_state == DoorState::OPENING) {
|
||||||
this->door_position = 1.0;
|
// door started opening
|
||||||
} else if (door_state == DoorState::CLOSED) {
|
if (prev_door_state == DoorState::CLOSING) {
|
||||||
this->door_position = 0.0;
|
this->door_position_update();
|
||||||
} else {
|
this->cancel_position_sync_callbacks();
|
||||||
if (*this->closing_duration == 0 || *this->opening_duration == 0 || *this->door_position == DOOR_POSITION_UNKNOWN) {
|
this->door_move_delta = DOOR_DELTA_UNKNOWN;
|
||||||
|
}
|
||||||
|
this->door_start_moving = millis();
|
||||||
|
this->door_start_position = *this->door_position;
|
||||||
|
if (this->door_move_delta == DOOR_DELTA_UNKNOWN) {
|
||||||
|
this->door_move_delta = 1.0 - this->door_start_position;
|
||||||
|
}
|
||||||
|
this->schedule_door_position_sync();
|
||||||
|
|
||||||
|
// this would only get called if no status message is received after door stops moving
|
||||||
|
// request a status message in that case
|
||||||
|
set_timeout("door_status_update", (*this->opening_duration + 1) * 1000, [=]() {
|
||||||
|
this->send_command(Command::GET_STATUS);
|
||||||
|
});
|
||||||
|
} else if (door_state == DoorState::CLOSING) {
|
||||||
|
// door started closing
|
||||||
|
if (prev_door_state == DoorState::OPENING) {
|
||||||
|
this->door_position_update();
|
||||||
|
this->cancel_position_sync_callbacks();
|
||||||
|
this->door_move_delta = DOOR_DELTA_UNKNOWN;
|
||||||
|
}
|
||||||
|
this->door_start_moving = millis();
|
||||||
|
this->door_start_position = *this->door_position;
|
||||||
|
if (this->door_move_delta == DOOR_DELTA_UNKNOWN) {
|
||||||
|
this->door_move_delta = 0.0 - this->door_start_position;
|
||||||
|
}
|
||||||
|
this->schedule_door_position_sync();
|
||||||
|
|
||||||
|
// this would only get called if no status message is received after door stops moving
|
||||||
|
// request a status message in that case
|
||||||
|
set_timeout("door_status_update", (*this->closing_duration + 1) * 1000, [=]() {
|
||||||
|
this->send_command(Command::GET_STATUS);
|
||||||
|
});
|
||||||
|
} else if (door_state == DoorState::STOPPED) {
|
||||||
|
this->door_position_update();
|
||||||
|
if (*this->door_position == DOOR_POSITION_UNKNOWN) {
|
||||||
this->door_position = 0.5; // best guess
|
this->door_position = 0.5; // best guess
|
||||||
}
|
}
|
||||||
}
|
this->cancel_position_sync_callbacks();
|
||||||
|
} else if (door_state == DoorState::OPEN) {
|
||||||
if (door_state == DoorState::OPENING && !this->moving_to_position) {
|
this->door_position = 1.0;
|
||||||
this->position_sync_while_opening(1.0 - *this->door_position);
|
this->cancel_position_sync_callbacks();
|
||||||
this->moving_to_position = true;
|
} else if (door_state == DoorState::CLOSED) {
|
||||||
}
|
this->door_position = 0.0;
|
||||||
if (door_state == DoorState::CLOSING && !this->moving_to_position) {
|
|
||||||
this->position_sync_while_closing(*this->door_position);
|
|
||||||
this->moving_to_position = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (door_state == DoorState::OPEN || door_state == DoorState::CLOSED || door_state == DoorState::STOPPED) {
|
|
||||||
this->cancel_position_sync_callbacks();
|
this->cancel_position_sync_callbacks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +236,7 @@ namespace ratgdo {
|
||||||
} else if (cmd == Command::MOTOR_ON) {
|
} else if (cmd == Command::MOTOR_ON) {
|
||||||
this->motor_state = MotorState::ON;
|
this->motor_state = MotorState::ON;
|
||||||
ESP_LOGD(TAG, "Motor: state=%s", MotorState_to_string(*this->motor_state));
|
ESP_LOGD(TAG, "Motor: state=%s", MotorState_to_string(*this->motor_state));
|
||||||
} else if (cmd == Command::OPEN) {
|
} else if (cmd == Command::DOOR_ACTION) {
|
||||||
this->button_state = (byte1 & 1) == 1 ? ButtonState::PRESSED : ButtonState::RELEASED;
|
this->button_state = (byte1 & 1) == 1 ? ButtonState::PRESSED : ButtonState::RELEASED;
|
||||||
ESP_LOGD(TAG, "Open: button=%s", ButtonState_to_string(*this->button_state));
|
ESP_LOGD(TAG, "Open: button=%s", ButtonState_to_string(*this->button_state));
|
||||||
} else if (cmd == Command::OPENINGS) {
|
} else if (cmd == Command::OPENINGS) {
|
||||||
|
@ -231,16 +262,39 @@ namespace ratgdo {
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RATGDOComponent::schedule_door_position_sync(float update_period)
|
||||||
|
{
|
||||||
|
ESP_LOG1(TAG, "Schedule position sync: delta %f, start position: %f, start moving: %d",
|
||||||
|
this->door_move_delta, this->door_start_position, this->door_start_moving);
|
||||||
|
auto duration = this->door_move_delta > 0 ? *this->opening_duration : *this->closing_duration;
|
||||||
|
auto count = int(1000 * duration / update_period);
|
||||||
|
set_retry("position_sync_while_moving", update_period, count, [=](uint8_t r) {
|
||||||
|
this->door_position_update();
|
||||||
|
return RetryResult::RETRY;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void RATGDOComponent::door_position_update()
|
||||||
|
{
|
||||||
|
if (this->door_start_moving == 0 || this->door_start_position == DOOR_POSITION_UNKNOWN || this->door_move_delta == DOOR_DELTA_UNKNOWN) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto now = millis();
|
||||||
|
auto duration = this->door_move_delta > 0 ? *this->opening_duration : -*this->closing_duration;
|
||||||
|
auto position = this->door_start_position + (now - this->door_start_moving) / (1000 * duration);
|
||||||
|
ESP_LOG2(TAG, "[%d] Position update: %f", now, position);
|
||||||
|
this->door_position = clamp(position, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
void RATGDOComponent::encode_packet(Command command, uint32_t data, bool increment, WirePacket& packet)
|
void RATGDOComponent::encode_packet(Command command, uint32_t data, bool increment, WirePacket& packet)
|
||||||
{
|
{
|
||||||
auto cmd = static_cast<uint64_t>(command);
|
auto cmd = static_cast<uint64_t>(command);
|
||||||
uint64_t fixed = ((cmd & ~0xff) << 24) | this->remote_id_;
|
uint64_t fixed = ((cmd & ~0xff) << 24) | this->remote_id_;
|
||||||
uint32_t send_data = (data << 8) | (cmd & 0xff);
|
uint32_t send_data = (data << 8) | (cmd & 0xff);
|
||||||
|
|
||||||
ESP_LOGV(TAG, "[%ld] Encode for transmit rolling=%07" PRIx32 " fixed=%010" PRIx64 " data=%08" PRIx32, millis(), *this->rolling_code_counter, fixed, send_data);
|
ESP_LOG2(TAG, "[%ld] Encode for transmit rolling=%07" PRIx32 " fixed=%010" PRIx64 " data=%08" PRIx32, millis(), *this->rolling_code_counter, fixed, send_data);
|
||||||
encode_wireline(*this->rolling_code_counter, fixed, send_data, packet);
|
encode_wireline(*this->rolling_code_counter, fixed, send_data, packet);
|
||||||
|
|
||||||
this->print_packet(packet);
|
|
||||||
if (increment) {
|
if (increment) {
|
||||||
this->increment_rolling_code_counter();
|
this->increment_rolling_code_counter();
|
||||||
}
|
}
|
||||||
|
@ -271,7 +325,7 @@ namespace ratgdo {
|
||||||
|
|
||||||
void RATGDOComponent::print_packet(const WirePacket& packet) const
|
void RATGDOComponent::print_packet(const WirePacket& packet) const
|
||||||
{
|
{
|
||||||
ESP_LOGV(TAG, "Counter: %d Send code: [%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X]",
|
ESP_LOG2(TAG, "Counter: %d Send code: [%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X]",
|
||||||
*this->rolling_code_counter,
|
*this->rolling_code_counter,
|
||||||
packet[0],
|
packet[0],
|
||||||
packet[1],
|
packet[1],
|
||||||
|
@ -312,7 +366,7 @@ namespace ratgdo {
|
||||||
const long PULSES_LOWER_LIMIT = 3;
|
const long PULSES_LOWER_LIMIT = 3;
|
||||||
|
|
||||||
if (current_millis - last_millis > CHECK_PERIOD) {
|
if (current_millis - last_millis > CHECK_PERIOD) {
|
||||||
// ESP_LOGD(TAG, "%ld: Obstruction count: %d, expected: %d, since asleep: %ld",
|
// ESP_LOGD(TAG, "%ld: Obstruction count: %d, expected: %d, since asleep: %ld",
|
||||||
// current_millis, this->isr_store_.obstruction_low_count, PULSES_EXPECTED,
|
// current_millis, this->isr_store_.obstruction_low_count, PULSES_EXPECTED,
|
||||||
// current_millis - last_asleep
|
// current_millis - last_asleep
|
||||||
// );
|
// );
|
||||||
|
@ -348,6 +402,7 @@ namespace ratgdo {
|
||||||
while (this->sw_serial_.available()) {
|
while (this->sw_serial_.available()) {
|
||||||
uint8_t ser_byte = this->sw_serial_.read();
|
uint8_t ser_byte = this->sw_serial_.read();
|
||||||
if (ser_byte != 0x55 && ser_byte != 0x01 && ser_byte != 0x00) {
|
if (ser_byte != 0x55 && ser_byte != 0x01 && ser_byte != 0x00) {
|
||||||
|
ESP_LOG2(TAG, "Ignoring byte: %02X, baud: %d", ser_byte, this->sw_serial_.baudRate());
|
||||||
byte_count = 0;
|
byte_count = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -415,6 +470,9 @@ namespace ratgdo {
|
||||||
delayMicroseconds(100);
|
delayMicroseconds(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ESP_LOG2(TAG, "Sending packet");
|
||||||
|
this->print_packet(this->tx_packet_);
|
||||||
|
|
||||||
// indicate the start of a frame by pulling the 12V line low for at leat 1 byte followed by
|
// indicate the start of a frame by pulling the 12V line low for at leat 1 byte followed by
|
||||||
// one STOP bit, which indicates to the receiving end that the start of the message follows
|
// one STOP bit, which indicates to the receiving end that the start of the message follows
|
||||||
// The output pin is controlling a transistor, so the logic is inverted
|
// The output pin is controlling a transistor, so the logic is inverted
|
||||||
|
@ -447,7 +505,7 @@ namespace ratgdo {
|
||||||
500, MAX_ATTEMPTS, [=](uint8_t r) {
|
500, MAX_ATTEMPTS, [=](uint8_t r) {
|
||||||
auto result = sync_step();
|
auto result = sync_step();
|
||||||
if (result == RetryResult::RETRY) {
|
if (result == RetryResult::RETRY) {
|
||||||
if (r == MAX_ATTEMPTS-2 && *this->door_state == DoorState::UNKNOWN) { // made a few attempts and no progress (door state is the first sync request)
|
if (r == MAX_ATTEMPTS - 2 && *this->door_state == DoorState::UNKNOWN) { // made a few attempts and no progress (door state is the first sync request)
|
||||||
// increment rolling code counter by some amount in case we crashed without writing to flash the latest value
|
// increment rolling code counter by some amount in case we crashed without writing to flash the latest value
|
||||||
this->increment_rolling_code_counter(MAX_CODES_WITHOUT_FLASH_WRITE);
|
this->increment_rolling_code_counter(MAX_CODES_WITHOUT_FLASH_WRITE);
|
||||||
}
|
}
|
||||||
|
@ -467,7 +525,6 @@ namespace ratgdo {
|
||||||
if (*this->door_state == DoorState::OPENING) {
|
if (*this->door_state == DoorState::OPENING) {
|
||||||
return; // gets ignored by opener
|
return; // gets ignored by opener
|
||||||
}
|
}
|
||||||
this->cancel_position_sync_callbacks();
|
|
||||||
|
|
||||||
this->door_command(data::DOOR_OPEN);
|
this->door_command(data::DOOR_OPEN);
|
||||||
}
|
}
|
||||||
|
@ -477,7 +534,6 @@ namespace ratgdo {
|
||||||
if (*this->door_state == DoorState::CLOSING || *this->door_state == DoorState::OPENING) {
|
if (*this->door_state == DoorState::CLOSING || *this->door_state == DoorState::OPENING) {
|
||||||
return; // gets ignored by opener
|
return; // gets ignored by opener
|
||||||
}
|
}
|
||||||
this->cancel_position_sync_callbacks();
|
|
||||||
|
|
||||||
this->door_command(data::DOOR_CLOSE);
|
this->door_command(data::DOOR_CLOSE);
|
||||||
}
|
}
|
||||||
|
@ -496,59 +552,10 @@ namespace ratgdo {
|
||||||
if (*this->door_state == DoorState::OPENING) {
|
if (*this->door_state == DoorState::OPENING) {
|
||||||
return; // gets ignored by opener
|
return; // gets ignored by opener
|
||||||
}
|
}
|
||||||
this->cancel_position_sync_callbacks();
|
|
||||||
|
|
||||||
this->door_command(data::DOOR_TOGGLE);
|
this->door_command(data::DOOR_TOGGLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RATGDOComponent::position_sync_while_opening(float delta, float update_period)
|
|
||||||
{
|
|
||||||
if (*this->opening_duration == 0) {
|
|
||||||
ESP_LOGW(TAG, "I don't know opening duration, ignoring position sync");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto updates = *this->opening_duration * 1000 * delta / update_period;
|
|
||||||
auto position_update = delta / updates;
|
|
||||||
auto count = int(updates);
|
|
||||||
ESP_LOGV(TAG, "[Opening] Position sync %d times: ", count);
|
|
||||||
// try to keep position in sync while door is moving
|
|
||||||
set_retry("position_sync_while_moving", update_period, count, [=](uint8_t r) {
|
|
||||||
ESP_LOGV(TAG, "[Opening] Position sync: %d: ", r);
|
|
||||||
this->door_position = *this->door_position + position_update;
|
|
||||||
return RetryResult::RETRY;
|
|
||||||
});
|
|
||||||
|
|
||||||
// this would only get called if no status message is received after door stops moving
|
|
||||||
// request a status message in that case, will get cancelled if a status message is received before
|
|
||||||
set_timeout("door_status_update", (*this->opening_duration + 1) * 1000, [=]() {
|
|
||||||
this->send_command(Command::GET_STATUS);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void RATGDOComponent::position_sync_while_closing(float delta, float update_period)
|
|
||||||
{
|
|
||||||
if (*this->closing_duration == 0) {
|
|
||||||
ESP_LOGW(TAG, "I don't know closing duration, ignoring position sync");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto updates = *this->closing_duration * 1000 * delta / update_period;
|
|
||||||
auto position_update = delta / updates;
|
|
||||||
auto count = int(updates);
|
|
||||||
ESP_LOGV(TAG, "[Closing] Position sync %d times: ", count);
|
|
||||||
// try to keep position in sync while door is moving
|
|
||||||
set_retry("position_sync_while_moving", update_period, count, [=](uint8_t r) {
|
|
||||||
ESP_LOGV(TAG, "[Closing] Position sync: %d: ", r);
|
|
||||||
this->door_position = *this->door_position - position_update;
|
|
||||||
return RetryResult::RETRY;
|
|
||||||
});
|
|
||||||
|
|
||||||
// this would only get called if no status message is received after door stops moving
|
|
||||||
// request a status message in that case
|
|
||||||
set_timeout("door_status_update", (*this->closing_duration + 1) * 1000, [=]() {
|
|
||||||
this->send_command(Command::GET_STATUS);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void RATGDOComponent::door_move_to_position(float position)
|
void RATGDOComponent::door_move_to_position(float position)
|
||||||
{
|
{
|
||||||
if (*this->door_state == DoorState::OPENING || *this->door_state == DoorState::CLOSING) {
|
if (*this->door_state == DoorState::OPENING || *this->door_state == DoorState::CLOSING) {
|
||||||
|
@ -562,50 +569,44 @@ namespace ratgdo {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto duration = delta > 0 ? *this->opening_duration : *this->closing_duration;
|
auto duration = delta > 0 ? *this->opening_duration : -*this->closing_duration;
|
||||||
if (duration == 0) {
|
if (duration == 0) {
|
||||||
ESP_LOGW(TAG, "I don't know duration, ignoring move to position");
|
ESP_LOGW(TAG, "I don't know duration, ignoring move to position");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (delta > 0) { // open
|
auto operation_time = 1000 * duration * delta;
|
||||||
this->door_command(data::DOOR_OPEN);
|
this->door_move_delta = delta;
|
||||||
this->position_sync_while_opening(delta);
|
|
||||||
} else { // close
|
|
||||||
delta = -delta;
|
|
||||||
this->door_command(data::DOOR_CLOSE);
|
|
||||||
this->position_sync_while_closing(delta);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto operation_time = duration * 1000 * delta;
|
|
||||||
ESP_LOGD(TAG, "Moving to position %.2f in %.1fs", position, operation_time / 1000.0);
|
ESP_LOGD(TAG, "Moving to position %.2f in %.1fs", position, operation_time / 1000.0);
|
||||||
this->moving_to_position = true;
|
|
||||||
|
this->door_command(delta > 0 ? data::DOOR_OPEN : data::DOOR_CLOSE);
|
||||||
set_timeout("move_to_position", operation_time, [=] {
|
set_timeout("move_to_position", operation_time, [=] {
|
||||||
this->door_command(data::DOOR_STOP);
|
this->door_command(data::DOOR_STOP);
|
||||||
this->moving_to_position = false;
|
|
||||||
this->door_position = position;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void RATGDOComponent::cancel_position_sync_callbacks()
|
void RATGDOComponent::cancel_position_sync_callbacks()
|
||||||
{
|
{
|
||||||
if (this->moving_to_position) {
|
if (this->door_start_moving != 0) {
|
||||||
ESP_LOGD(TAG, "Cancelling position callbacks");
|
ESP_LOGD(TAG, "Cancelling position callbacks");
|
||||||
cancel_timeout("move_to_position");
|
cancel_timeout("move_to_position");
|
||||||
cancel_retry("position_sync_while_moving");
|
cancel_retry("position_sync_while_moving");
|
||||||
cancel_timeout("door_status_update");
|
cancel_timeout("door_status_update");
|
||||||
|
|
||||||
|
this->door_start_moving = 0;
|
||||||
|
this->door_start_position = DOOR_POSITION_UNKNOWN;
|
||||||
|
this->door_move_delta = DOOR_DELTA_UNKNOWN;
|
||||||
}
|
}
|
||||||
moving_to_position = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RATGDOComponent::door_command(uint32_t data)
|
void RATGDOComponent::door_command(uint32_t data)
|
||||||
{
|
{
|
||||||
data |= (1 << 16); // button 1 ?
|
data |= (1 << 16); // button 1 ?
|
||||||
data |= (1 << 8); // button press
|
data |= (1 << 8); // button press
|
||||||
this->send_command(Command::OPEN, data, false);
|
this->send_command(Command::DOOR_ACTION, data, false);
|
||||||
set_timeout(100, [=] {
|
set_timeout(200, [=] {
|
||||||
auto data2 = data & ~(1 << 8); // button release
|
auto data2 = data & ~(1 << 8); // button release
|
||||||
this->send_command(Command::OPEN, data2);
|
this->send_command(Command::DOOR_ACTION, data2);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ namespace ratgdo {
|
||||||
typedef uint8_t WirePacket[PACKET_LENGTH];
|
typedef uint8_t WirePacket[PACKET_LENGTH];
|
||||||
|
|
||||||
const float DOOR_POSITION_UNKNOWN = -1.0;
|
const float DOOR_POSITION_UNKNOWN = -1.0;
|
||||||
|
const float DOOR_DELTA_UNKNOWN = -2.0;
|
||||||
|
|
||||||
namespace data {
|
namespace data {
|
||||||
const uint32_t LIGHT_OFF = 0;
|
const uint32_t LIGHT_OFF = 0;
|
||||||
|
@ -64,7 +65,7 @@ namespace ratgdo {
|
||||||
|
|
||||||
(LEARN_2, 0x181),
|
(LEARN_2, 0x181),
|
||||||
(LOCK, 0x18c),
|
(LOCK, 0x18c),
|
||||||
(OPEN, 0x280),
|
(DOOR_ACTION, 0x280),
|
||||||
(LIGHT, 0x281),
|
(LIGHT, 0x281),
|
||||||
(MOTOR_ON, 0x284),
|
(MOTOR_ON, 0x284),
|
||||||
(MOTION, 0x285),
|
(MOTION, 0x285),
|
||||||
|
@ -88,7 +89,7 @@ namespace ratgdo {
|
||||||
struct RATGDOStore {
|
struct RATGDOStore {
|
||||||
int obstruction_low_count = 0; // count obstruction low pulses
|
int obstruction_low_count = 0; // count obstruction low pulses
|
||||||
|
|
||||||
static void IRAM_ATTR HOT isr_obstruction(RATGDOStore* arg)
|
static void IRAM_ATTR HOT isr_obstruction(RATGDOStore* arg)
|
||||||
{
|
{
|
||||||
arg->obstruction_low_count++;
|
arg->obstruction_low_count++;
|
||||||
}
|
}
|
||||||
|
@ -111,7 +112,10 @@ namespace ratgdo {
|
||||||
|
|
||||||
observable<DoorState> door_state { DoorState::UNKNOWN };
|
observable<DoorState> door_state { DoorState::UNKNOWN };
|
||||||
observable<float> door_position { DOOR_POSITION_UNKNOWN };
|
observable<float> door_position { DOOR_POSITION_UNKNOWN };
|
||||||
bool moving_to_position { false };
|
|
||||||
|
unsigned long door_start_moving { 0 };
|
||||||
|
float door_start_position { DOOR_POSITION_UNKNOWN };
|
||||||
|
float door_move_delta { DOOR_DELTA_UNKNOWN };
|
||||||
|
|
||||||
observable<LightState> light_state { LightState::UNKNOWN };
|
observable<LightState> light_state { LightState::UNKNOWN };
|
||||||
observable<LockState> lock_state { LockState::UNKNOWN };
|
observable<LockState> lock_state { LockState::UNKNOWN };
|
||||||
|
@ -146,12 +150,12 @@ namespace ratgdo {
|
||||||
void close_door();
|
void close_door();
|
||||||
void stop_door();
|
void stop_door();
|
||||||
void door_move_to_position(float position);
|
void door_move_to_position(float position);
|
||||||
void position_sync_while_opening(float delta, float update_period = 500);
|
|
||||||
void position_sync_while_closing(float delta, float update_period = 500);
|
|
||||||
void cancel_position_sync_callbacks();
|
|
||||||
void set_door_position(float door_position) { this->door_position = door_position; }
|
void set_door_position(float door_position) { this->door_position = door_position; }
|
||||||
void set_opening_duration(float duration);
|
void set_opening_duration(float duration);
|
||||||
void set_closing_duration(float duration);
|
void set_closing_duration(float duration);
|
||||||
|
void schedule_door_position_sync(float update_period = 500);
|
||||||
|
void door_position_update();
|
||||||
|
void cancel_position_sync_callbacks();
|
||||||
|
|
||||||
// light
|
// light
|
||||||
void toggle_light();
|
void toggle_light();
|
||||||
|
|
Loading…
Reference in New Issue