Updates
This commit is contained in:
parent
554689e6c0
commit
a93d8e407f
|
@ -19,6 +19,9 @@ struct QueryStatus{};
|
||||||
struct QueryOpenings{};
|
struct QueryOpenings{};
|
||||||
struct ActivateLearn {};
|
struct ActivateLearn {};
|
||||||
struct InactivateLearn {};
|
struct InactivateLearn {};
|
||||||
|
struct QueryPairedDevices { PairedDevice kind; };
|
||||||
|
struct QueryPairedDevicesAll {};
|
||||||
|
struct ClearPairedDevices { PairedDevice kind; };
|
||||||
|
|
||||||
|
|
||||||
// a poor man's sum-type, because C++
|
// a poor man's sum-type, because C++
|
||||||
|
@ -32,6 +35,9 @@ public:
|
||||||
QueryOpenings query_openings;
|
QueryOpenings query_openings;
|
||||||
ActivateLearn activate_learn;
|
ActivateLearn activate_learn;
|
||||||
InactivateLearn inactivate_learn;
|
InactivateLearn inactivate_learn;
|
||||||
|
QueryPairedDevices query_paired_devices;
|
||||||
|
QueryPairedDevicesAll query_paired_devices_all;
|
||||||
|
ClearPairedDevices clear_paired_devices;
|
||||||
} value;
|
} value;
|
||||||
|
|
||||||
enum class Tag {
|
enum class Tag {
|
||||||
|
@ -42,6 +48,9 @@ public:
|
||||||
query_openings,
|
query_openings,
|
||||||
activate_learn,
|
activate_learn,
|
||||||
inactivate_learn,
|
inactivate_learn,
|
||||||
|
query_paired_devices,
|
||||||
|
query_paired_devices_all,
|
||||||
|
clear_paired_devices,
|
||||||
} tag;
|
} tag;
|
||||||
|
|
||||||
Args(GetRollingCodeCounter&& arg): tag(Tag::get_rolling_code_counter) {
|
Args(GetRollingCodeCounter&& arg): tag(Tag::get_rolling_code_counter) {
|
||||||
|
@ -65,6 +74,15 @@ public:
|
||||||
Args(InactivateLearn&& arg): tag(Tag::inactivate_learn) {
|
Args(InactivateLearn&& arg): tag(Tag::inactivate_learn) {
|
||||||
value.inactivate_learn = std::move(arg);
|
value.inactivate_learn = std::move(arg);
|
||||||
}
|
}
|
||||||
|
Args(QueryPairedDevices&& arg): tag(Tag::query_paired_devices) {
|
||||||
|
value.query_paired_devices = std::move(arg);
|
||||||
|
}
|
||||||
|
Args(QueryPairedDevicesAll&& arg): tag(Tag::query_paired_devices_all) {
|
||||||
|
value.query_paired_devices_all = std::move(arg);
|
||||||
|
}
|
||||||
|
Args(ClearPairedDevices&& arg): tag(Tag::clear_paired_devices) {
|
||||||
|
value.clear_paired_devices = std::move(arg);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,19 +7,46 @@ namespace esphome {
|
||||||
namespace ratgdo {
|
namespace ratgdo {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class observable {
|
class distinct_observable;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class observable_base {
|
||||||
public:
|
public:
|
||||||
observable(const T& value)
|
template <typename Observer>
|
||||||
: value_(value)
|
void subscribe(Observer&& observer)
|
||||||
{
|
{
|
||||||
|
this->observers_.push_back(std::forward<Observer>(observer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void notify(T value) const
|
||||||
|
{
|
||||||
|
for (const auto& observer : this->observers_) {
|
||||||
|
observer(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
distinct_observable<T> distinct()
|
||||||
|
{
|
||||||
|
return std::make_shared(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::function<void(T)>> observers_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class observable : public observable_base<T> {
|
||||||
|
public:
|
||||||
|
observable(const T& value) : value_(value) {}
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
observable& operator=(U value)
|
observable& operator=(U value)
|
||||||
{
|
{
|
||||||
if (value != this->value_) {
|
if (value != this->value_) {
|
||||||
this->value_ = value;
|
this->value_ = value;
|
||||||
this->notify();
|
this->notify(value);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -27,22 +54,27 @@ namespace ratgdo {
|
||||||
T const* operator&() const { return &this->value_; }
|
T const* operator&() const { return &this->value_; }
|
||||||
T const& operator*() const { return this->value_; }
|
T const& operator*() const { return this->value_; }
|
||||||
|
|
||||||
template <typename Observer>
|
private:
|
||||||
void subscribe(Observer&& observer)
|
T value_;
|
||||||
{
|
};
|
||||||
this->observers_.push_back(std::forward<Observer>(observer));
|
|
||||||
}
|
|
||||||
|
|
||||||
void notify() const
|
|
||||||
{
|
|
||||||
for (const auto& observer : this->observers_) {
|
template <typename T>
|
||||||
observer(this->value_);
|
class distinct_observable : public observable<T> {
|
||||||
|
public:
|
||||||
|
distinct_observable(std::shared_ptr<observable<T>> inner) : inner_(inner) {
|
||||||
|
inner.subscribe([=] (T value) {
|
||||||
|
if (value != this->value_) {
|
||||||
|
this->value_ = value;
|
||||||
|
this->notify(value);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::shared_ptr<observable<T>> inner_;
|
||||||
T value_;
|
T value_;
|
||||||
std::vector<std::function<void(T)>> observers_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ratgdo
|
} // namespace ratgdo
|
||||||
|
|
|
@ -288,6 +288,11 @@ namespace ratgdo {
|
||||||
ESP_LOGD(TAG, "Time to close (TTC): %ds", ttc.seconds);
|
ESP_LOGD(TAG, "Time to close (TTC): %ds", ttc.seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RATGDOComponent::received(const BatteryState battery_state)
|
||||||
|
{
|
||||||
|
ESP_LOGD(TAG, "Battery state=%s", BatteryState_to_string(battery_state));
|
||||||
|
}
|
||||||
|
|
||||||
void RATGDOComponent::schedule_door_position_sync(float update_period)
|
void RATGDOComponent::schedule_door_position_sync(float update_period)
|
||||||
{
|
{
|
||||||
ESP_LOG1(TAG, "Schedule position sync: delta %f, start position: %f, start moving: %d",
|
ESP_LOG1(TAG, "Schedule position sync: delta %f, start position: %f, start moving: %d",
|
||||||
|
@ -379,10 +384,8 @@ namespace ratgdo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RATGDOComponent::query_status()
|
void RATGDOComponent::query_status()
|
||||||
{
|
{
|
||||||
ESP_LOG2(TAG, "Query status action");
|
|
||||||
this->protocol_->call(QueryStatus{});
|
this->protocol_->call(QueryStatus{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,6 +394,21 @@ namespace ratgdo {
|
||||||
this->protocol_->call(QueryOpenings{});
|
this->protocol_->call(QueryOpenings{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RATGDOComponent::query_paired_devices()
|
||||||
|
{
|
||||||
|
this->protocol_->call(QueryPairedDevicesAll{});
|
||||||
|
}
|
||||||
|
|
||||||
|
void RATGDOComponent::query_paired_devices(PairedDevice kind)
|
||||||
|
{
|
||||||
|
this->protocol_->call(QueryPairedDevices{kind});
|
||||||
|
}
|
||||||
|
|
||||||
|
void RATGDOComponent::clear_paired_devices(PairedDevice kind)
|
||||||
|
{
|
||||||
|
this->protocol_->call(ClearPairedDevices{kind});
|
||||||
|
}
|
||||||
|
|
||||||
void RATGDOComponent::sync()
|
void RATGDOComponent::sync()
|
||||||
{
|
{
|
||||||
this->protocol_->sync();
|
this->protocol_->sync();
|
||||||
|
|
|
@ -106,6 +106,7 @@ namespace ratgdo {
|
||||||
void received(const Openings openings);
|
void received(const Openings openings);
|
||||||
void received(const TimeToClose ttc);
|
void received(const TimeToClose ttc);
|
||||||
void received(const PairedDeviceCount pdc);
|
void received(const PairedDeviceCount pdc);
|
||||||
|
void received(const BatteryState pdc);
|
||||||
|
|
||||||
// door
|
// door
|
||||||
void door_toggle();
|
void door_toggle();
|
||||||
|
|
|
@ -64,6 +64,13 @@ namespace ratgdo {
|
||||||
(RELEASED, 1),
|
(RELEASED, 1),
|
||||||
(UNKNOWN, 2))
|
(UNKNOWN, 2))
|
||||||
|
|
||||||
|
|
||||||
|
ENUM(BatteryState, uint8_t,
|
||||||
|
(UNKNOWN, 0),
|
||||||
|
(CHARGING, 0x6),
|
||||||
|
(FULL, 0x8))
|
||||||
|
|
||||||
|
|
||||||
/// Enum for learn states.
|
/// Enum for learn states.
|
||||||
ENUM(LearnState, uint8_t,
|
ENUM(LearnState, uint8_t,
|
||||||
(INACTIVE, 0),
|
(INACTIVE, 0),
|
||||||
|
|
|
@ -145,22 +145,32 @@ namespace secplus2 {
|
||||||
{
|
{
|
||||||
using Tag = Args::Tag;
|
using Tag = Args::Tag;
|
||||||
if (args.tag == Tag::query_status) {
|
if (args.tag == Tag::query_status) {
|
||||||
this->send_command(Command{CommandType::GET_STATUS});
|
this->send_command(CommandType::GET_STATUS);
|
||||||
} else if (args.tag == Tag::query_openings) {
|
} else if (args.tag == Tag::query_openings) {
|
||||||
this->send_command(Command{CommandType::GET_OPENINGS});
|
this->send_command(CommandType::GET_OPENINGS);
|
||||||
} else if (args.tag == Tag::get_rolling_code_counter) {
|
} else if (args.tag == Tag::get_rolling_code_counter) {
|
||||||
return Result(RollingCodeCounter{std::addressof(this->rolling_code_counter_)});
|
return Result(RollingCodeCounter{std::addressof(this->rolling_code_counter_)});
|
||||||
} else if (args.tag == Tag::set_rolling_code_counter) {
|
} else if (args.tag == Tag::set_rolling_code_counter) {
|
||||||
this->set_rolling_code_counter(args.value.set_rolling_code_counter.counter);
|
this->set_rolling_code_counter(args.value.set_rolling_code_counter.counter);
|
||||||
} else if (args.tag == Tag::set_client_id) {
|
} else if (args.tag == Tag::set_client_id) {
|
||||||
this->set_client_id(args.value.set_client_id.client_id);
|
this->set_client_id(args.value.set_client_id.client_id);
|
||||||
|
} else if (args.tag == Tag::query_paired_devices) {
|
||||||
|
this->query_paired_devices(args.value.query_paired_devices.kind);
|
||||||
|
} else if (args.tag == Tag::query_paired_devices_all) {
|
||||||
|
this->query_paired_devices();
|
||||||
|
} else if (args.tag == Tag::clear_paired_devices) {
|
||||||
|
this->clear_paired_devices(args.value.clear_paired_devices.kind);
|
||||||
|
} else if (args.tag == Tag::activate_learn) {
|
||||||
|
this->activate_learn();
|
||||||
|
} else if (args.tag == Tag::inactivate_learn) {
|
||||||
|
this->inactivate_learn();
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Secplus2::door_command(DoorAction action)
|
void Secplus2::door_command(DoorAction action)
|
||||||
{
|
{
|
||||||
this->send_command(Command(CommandType::DOOR_ACTION, static_cast<uint8_t>(action), 1, 1), false, [=]() {
|
this->send_command(Command(CommandType::DOOR_ACTION, static_cast<uint8_t>(action), 1, 1), IncrementRollingCode::NO, [=]() {
|
||||||
this->scheduler_->set_timeout(this->ratgdo_, "", 150, [=] {
|
this->scheduler_->set_timeout(this->ratgdo_, "", 150, [=] {
|
||||||
this->send_command(Command(CommandType::DOOR_ACTION, static_cast<uint8_t>(action), 0, 1));
|
this->send_command(Command(CommandType::DOOR_ACTION, static_cast<uint8_t>(action), 0, 1));
|
||||||
});
|
});
|
||||||
|
@ -197,7 +207,7 @@ namespace secplus2 {
|
||||||
void Secplus2::query_paired_devices(PairedDevice kind)
|
void Secplus2::query_paired_devices(PairedDevice kind)
|
||||||
{
|
{
|
||||||
ESP_LOGD(TAG, "Query paired devices of type: %s", PairedDevice_to_string(kind));
|
ESP_LOGD(TAG, "Query paired devices of type: %s", PairedDevice_to_string(kind));
|
||||||
this->send_command(CommandType::GET_PAIRED_DEVICES, static_cast<uint8_t>(kind));
|
this->send_command(Command{CommandType::GET_PAIRED_DEVICES, static_cast<uint8_t>(kind)});
|
||||||
}
|
}
|
||||||
|
|
||||||
// wipe devices from memory based on get paired devices nibble values
|
// wipe devices from memory based on get paired devices nibble values
|
||||||
|
@ -208,14 +218,15 @@ namespace secplus2 {
|
||||||
}
|
}
|
||||||
ESP_LOGW(TAG, "Clear paired devices of type: %s", PairedDevice_to_string(kind));
|
ESP_LOGW(TAG, "Clear paired devices of type: %s", PairedDevice_to_string(kind));
|
||||||
if (kind == PairedDevice::ALL) {
|
if (kind == PairedDevice::ALL) {
|
||||||
this->scheduler_->set_timeout(this->ratgdo_, "", 200, [=] { this->send_command(CommandType::CLEAR_PAIRED_DEVICES, static_cast<uint8_t>(PairedDevice::REMOTE)-1); }); // wireless
|
this->scheduler_->set_timeout(this->ratgdo_, "", 200, [=] { this->send_command(Command{CommandType::CLEAR_PAIRED_DEVICES, static_cast<uint8_t>(PairedDevice::REMOTE)-1}); }); // wireless
|
||||||
this->scheduler_->set_timeout(this->ratgdo_, "", 400, [=] { this->send_command(CommandType::CLEAR_PAIRED_DEVICES, static_cast<uint8_t>(PairedDevice::KEYPAD)-1); }); // keypads
|
this->scheduler_->set_timeout(this->ratgdo_, "", 400, [=] { this->send_command(Command{CommandType::CLEAR_PAIRED_DEVICES, static_cast<uint8_t>(PairedDevice::KEYPAD)-1}); }); // keypads
|
||||||
this->scheduler_->set_timeout(this->ratgdo_, "", 600, [=] { this->send_command(CommandType::CLEAR_PAIRED_DEVICES, static_cast<uint8_t>(PairedDevice::WALL_CONTROL)-1); }); // wall controls
|
this->scheduler_->set_timeout(this->ratgdo_, "", 600, [=] { this->send_command(Command{CommandType::CLEAR_PAIRED_DEVICES, static_cast<uint8_t>(PairedDevice::WALL_CONTROL)-1}); }); // wall controls
|
||||||
this->scheduler_->set_timeout(this->ratgdo_, "", 800, [=] { this->send_command(CommandType::CLEAR_PAIRED_DEVICES, static_cast<uint8_t>(PairedDevice::ACCESSORY)-1); }); // accessories
|
this->scheduler_->set_timeout(this->ratgdo_, "", 800, [=] { this->send_command(Command{CommandType::CLEAR_PAIRED_DEVICES, static_cast<uint8_t>(PairedDevice::ACCESSORY)-1}); }); // accessories
|
||||||
this->scheduler_->set_timeout(this->ratgdo_, "", 1000, [=] { this->query_status(); });
|
this->scheduler_->set_timeout(this->ratgdo_, "", 1000, [=] { this->query_status(); });
|
||||||
this->scheduler_->set_timeout(this->ratgdo_, "", 1200, [=] { this->query_paired_devices(); });
|
this->scheduler_->set_timeout(this->ratgdo_, "", 1200, [=] { this->query_paired_devices(); });
|
||||||
} else {
|
} else {
|
||||||
this->send_command(CommandType::CLEAR_PAIRED_DEVICES, static_cast<uint8_t>(kind) - 1); // just requested device
|
uint8_t dev_kind = static_cast<uint8_t>(kind)-1;
|
||||||
|
this->send_command(Command{CommandType::CLEAR_PAIRED_DEVICES, dev_kind}); // just requested device
|
||||||
this->scheduler_->set_timeout(this->ratgdo_, "", 200, [=] { this->query_status(); });
|
this->scheduler_->set_timeout(this->ratgdo_, "", 200, [=] { this->query_status(); });
|
||||||
this->scheduler_->set_timeout(this->ratgdo_, "", 400, [=] { this->query_paired_devices(kind); });
|
this->scheduler_->set_timeout(this->ratgdo_, "", 400, [=] { this->query_paired_devices(kind); });
|
||||||
}
|
}
|
||||||
|
@ -371,20 +382,21 @@ namespace secplus2 {
|
||||||
|
|
||||||
auto learn_state = to_LearnState((cmd.byte2 >> 5) & 1, LearnState::UNKNOWN);
|
auto learn_state = to_LearnState((cmd.byte2 >> 5) & 1, LearnState::UNKNOWN);
|
||||||
if (this->learn_state_ != learn_state) {
|
if (this->learn_state_ != learn_state) {
|
||||||
|
ESP_LOG1(TAG, "Learn state handle: %d", (int)this->learn_poll_status_);
|
||||||
if (learn_state == LearnState::ACTIVE && this->learn_poll_status_) {
|
if (learn_state == LearnState::ACTIVE && this->learn_poll_status_) {
|
||||||
this->scheduler_->set_timeout(this->ratgdo_, "learn_poll", 1000, [=] {
|
this->scheduler_->set_interval(this->ratgdo_, "learn_poll", 1000, [=] {
|
||||||
this->query_status();
|
this->query_status();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this->scheduler_->cancel_timeout(this->ratgdo_, "learn_poll");
|
this->scheduler_->cancel_interval(this->ratgdo_, "learn_poll");
|
||||||
this->learn_poll_status_ = true;
|
this->learn_poll_status_ = true;
|
||||||
}
|
}
|
||||||
if (learn_state == LearnState::INACTIVE) {
|
if (learn_state == LearnState::INACTIVE) {
|
||||||
this->query_paired_devices();
|
this->query_paired_devices();
|
||||||
}
|
}
|
||||||
this->learn_state_ = learn_state;
|
this->learn_state_ = learn_state;
|
||||||
this->ratgdo_->received(learn_state);
|
|
||||||
}
|
}
|
||||||
|
this->ratgdo_->received(learn_state);
|
||||||
}
|
}
|
||||||
else if (cmd.type == CommandType::LIGHT) {
|
else if (cmd.type == CommandType::LIGHT) {
|
||||||
this->ratgdo_->received(to_LightAction(cmd.nibble, LightAction::UNKNOWN));
|
this->ratgdo_->received(to_LightAction(cmd.nibble, LightAction::UNKNOWN));
|
||||||
|
@ -427,16 +439,19 @@ namespace secplus2 {
|
||||||
this->learn_poll_status_ = false;
|
this->learn_poll_status_ = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (cmd.type == CommandType::BATTERY_STATUS) {
|
||||||
|
this->ratgdo_->received(to_BatteryState(cmd.byte1, BatteryState::UNKNOWN));
|
||||||
|
}
|
||||||
|
|
||||||
ESP_LOG1(TAG, "Done handle command: %s", CommandType_to_string(cmd.type));
|
ESP_LOG1(TAG, "Done handle command: %s", CommandType_to_string(cmd.type));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Secplus2::send_command(Command command, bool increment)
|
void Secplus2::send_command(Command command, IncrementRollingCode increment)
|
||||||
{
|
{
|
||||||
ESP_LOG1(TAG, "Send command: %s, data: %02X%02X%02X", CommandType_to_string(command.type), command.byte2, command.byte1, command.nibble);
|
ESP_LOG1(TAG, "Send command: %s, data: %02X%02X%02X", CommandType_to_string(command.type), command.byte2, command.byte1, command.nibble);
|
||||||
if (!this->transmit_pending_) { // have an untransmitted packet
|
if (!this->transmit_pending_) { // have an untransmitted packet
|
||||||
this->encode_packet(command, this->tx_packet_);
|
this->encode_packet(command, this->tx_packet_);
|
||||||
if (increment) {
|
if (increment == IncrementRollingCode::YES) {
|
||||||
this->increment_rolling_code_counter();
|
this->increment_rolling_code_counter();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -452,7 +467,7 @@ namespace secplus2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Secplus2::send_command(Command command, bool increment, std::function<void()>&& on_sent)
|
void Secplus2::send_command(Command command, IncrementRollingCode increment, std::function<void()>&& on_sent)
|
||||||
{
|
{
|
||||||
this->command_sent_.then(on_sent);
|
this->command_sent_.then(on_sent);
|
||||||
this->send_command(command, increment);
|
this->send_command(command, increment);
|
||||||
|
|
|
@ -30,6 +30,7 @@ namespace secplus2 {
|
||||||
(STATUS, 0x081),
|
(STATUS, 0x081),
|
||||||
(OBST_1, 0x084), // sent when an obstruction happens?
|
(OBST_1, 0x084), // sent when an obstruction happens?
|
||||||
(OBST_2, 0x085), // sent when an obstruction happens?
|
(OBST_2, 0x085), // sent when an obstruction happens?
|
||||||
|
(BATTERY_STATUS, 0x9d),
|
||||||
(PAIR_3, 0x0a0),
|
(PAIR_3, 0x0a0),
|
||||||
(PAIR_3_RESP, 0x0a1),
|
(PAIR_3_RESP, 0x0a1),
|
||||||
|
|
||||||
|
@ -61,6 +62,11 @@ namespace secplus2 {
|
||||||
inline bool operator==(const CommandType& cmd_e, const uint16_t cmd_i) { return cmd_i == static_cast<uint16_t>(cmd_e); }
|
inline bool operator==(const CommandType& cmd_e, const uint16_t cmd_i) { return cmd_i == static_cast<uint16_t>(cmd_e); }
|
||||||
|
|
||||||
|
|
||||||
|
enum class IncrementRollingCode {
|
||||||
|
NO,
|
||||||
|
YES,
|
||||||
|
};
|
||||||
|
|
||||||
struct Command {
|
struct Command {
|
||||||
CommandType type;
|
CommandType type;
|
||||||
uint8_t nibble;
|
uint8_t nibble;
|
||||||
|
@ -93,8 +99,8 @@ namespace secplus2 {
|
||||||
optional<Command> read_command();
|
optional<Command> read_command();
|
||||||
void handle_command(const Command& cmd);
|
void handle_command(const Command& cmd);
|
||||||
|
|
||||||
void send_command(Command cmd, bool increment = true);
|
void send_command(Command cmd, IncrementRollingCode increment = IncrementRollingCode::YES);
|
||||||
void send_command(Command cmd, bool increment, std::function<void()>&& on_sent);
|
void send_command(Command cmd, IncrementRollingCode increment, std::function<void()>&& on_sent);
|
||||||
void encode_packet(Command cmd, WirePacket& packet);
|
void encode_packet(Command cmd, WirePacket& packet);
|
||||||
bool transmit_packet();
|
bool transmit_packet();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue