Format all files
This commit is contained in:
+224
-222
@@ -7,22 +7,22 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/defines.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/preferences.h"
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "callbacks.h"
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/defines.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/preferences.h"
|
||||
#include "observable.h"
|
||||
#include "ratgdo_state.h"
|
||||
|
||||
namespace esphome::ratgdo {
|
||||
|
||||
namespace secplus2 { class Secplus2; }
|
||||
namespace secplus2 {
|
||||
class Secplus2;
|
||||
}
|
||||
|
||||
class RATGDOComponent;
|
||||
typedef Parented<RATGDOComponent> RATGDOClient;
|
||||
@@ -30,214 +30,222 @@ typedef Parented<RATGDOComponent> RATGDOClient;
|
||||
const float DOOR_POSITION_UNKNOWN = -1.0;
|
||||
const float DOOR_DELTA_UNKNOWN = -2.0;
|
||||
|
||||
|
||||
|
||||
class RATGDOComponent : public Component {
|
||||
public:
|
||||
RATGDOComponent()
|
||||
{
|
||||
}
|
||||
public:
|
||||
RATGDOComponent() {}
|
||||
|
||||
void setup() override;
|
||||
void loop() override;
|
||||
void dump_config() override;
|
||||
void on_shutdown() override;
|
||||
void setup() override;
|
||||
void loop() override;
|
||||
void dump_config() override;
|
||||
void on_shutdown() override;
|
||||
|
||||
float get_setup_priority() const override { return setup_priority::AFTER_WIFI; }
|
||||
float get_setup_priority() const override {
|
||||
return setup_priority::AFTER_WIFI;
|
||||
}
|
||||
|
||||
void init_protocol();
|
||||
void init_protocol();
|
||||
|
||||
float start_opening { -1 };
|
||||
single_observable<float> opening_duration { 0 };
|
||||
float start_closing { -1 };
|
||||
single_observable<float> closing_duration { 0 };
|
||||
float start_opening{-1};
|
||||
single_observable<float> opening_duration{0};
|
||||
float start_closing{-1};
|
||||
single_observable<float> closing_duration{0};
|
||||
|
||||
observable<int16_t, RATGDO_MAX_DISTANCE_SUBSCRIBERS> last_distance_measurement { 0 };
|
||||
observable<int16_t, RATGDO_MAX_DISTANCE_SUBSCRIBERS>
|
||||
last_distance_measurement{0};
|
||||
|
||||
single_observable<uint16_t> openings { 0 }; // number of times the door has been opened
|
||||
single_observable<uint16_t> openings{
|
||||
0}; // number of times the door has been opened
|
||||
|
||||
observable<DoorState, RATGDO_MAX_DOOR_STATE_SUBSCRIBERS> door_state { DoorState::UNKNOWN };
|
||||
observable<float, RATGDO_MAX_DOOR_STATE_SUBSCRIBERS> door_position { DOOR_POSITION_UNKNOWN };
|
||||
observable<DoorState, RATGDO_MAX_DOOR_STATE_SUBSCRIBERS> door_state{
|
||||
DoorState::UNKNOWN};
|
||||
observable<float, RATGDO_MAX_DOOR_STATE_SUBSCRIBERS> door_position{
|
||||
DOOR_POSITION_UNKNOWN};
|
||||
|
||||
unsigned long door_start_moving { 0 };
|
||||
float door_start_position { DOOR_POSITION_UNKNOWN };
|
||||
float door_move_delta { DOOR_DELTA_UNKNOWN };
|
||||
uint16_t position_sync_remaining_ { 0 };
|
||||
float target_position_ { DOOR_POSITION_UNKNOWN };
|
||||
DoorAction target_direction_ { DoorAction::UNKNOWN };
|
||||
unsigned long door_start_moving{0};
|
||||
float door_start_position{DOOR_POSITION_UNKNOWN};
|
||||
float door_move_delta{DOOR_DELTA_UNKNOWN};
|
||||
uint16_t position_sync_remaining_{0};
|
||||
float target_position_{DOOR_POSITION_UNKNOWN};
|
||||
DoorAction target_direction_{DoorAction::UNKNOWN};
|
||||
|
||||
single_observable<LightState> light_state { LightState::UNKNOWN };
|
||||
single_observable<LockState> lock_state { LockState::UNKNOWN };
|
||||
single_observable<LightState> light_state{LightState::UNKNOWN};
|
||||
single_observable<LockState> lock_state{LockState::UNKNOWN};
|
||||
|
||||
OnceCallbacks<void(DoorState)> on_door_state_;
|
||||
OnceCallbacks<void(DoorState)> on_door_state_;
|
||||
|
||||
single_observable<bool> synced { false };
|
||||
single_observable<optional<bool>> sync_failed { nullopt };
|
||||
single_observable<bool> synced{false};
|
||||
single_observable<optional<bool>> sync_failed{nullopt};
|
||||
|
||||
void set_output_gdo_pin(InternalGPIOPin* pin) { this->output_gdo_pin_ = pin; }
|
||||
void set_input_gdo_pin(InternalGPIOPin* pin) { this->input_gdo_pin_ = pin; }
|
||||
void set_output_gdo_pin(InternalGPIOPin* pin) { this->output_gdo_pin_ = pin; }
|
||||
void set_input_gdo_pin(InternalGPIOPin* pin) { this->input_gdo_pin_ = pin; }
|
||||
|
||||
void received(const DoorState door_state);
|
||||
void received(const LightState light_state);
|
||||
void received(const LockState lock_state);
|
||||
void received(const LightAction light_action);
|
||||
void received(const Openings openings);
|
||||
|
||||
// door
|
||||
void door_toggle();
|
||||
void door_open();
|
||||
void door_close();
|
||||
void door_stop();
|
||||
|
||||
void received(const DoorState door_state);
|
||||
void received(const LightState light_state);
|
||||
void received(const LockState lock_state);
|
||||
void received(const LightAction light_action);
|
||||
void received(const Openings openings);
|
||||
void door_action(DoorAction action);
|
||||
void smart_door_action(DoorAction target_direction);
|
||||
void door_move_to_position(float position);
|
||||
void set_door_position(float door_position) {
|
||||
this->door_position = door_position;
|
||||
}
|
||||
void set_opening_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();
|
||||
void set_distance_measurement(int16_t distance);
|
||||
|
||||
// door
|
||||
void door_toggle();
|
||||
void door_open();
|
||||
void door_close();
|
||||
void door_stop();
|
||||
// light
|
||||
void light_on();
|
||||
void light_off();
|
||||
LightState get_light_state() const;
|
||||
|
||||
void door_action(DoorAction action);
|
||||
void smart_door_action(DoorAction target_direction);
|
||||
void door_move_to_position(float position);
|
||||
void set_door_position(float door_position) { this->door_position = door_position; }
|
||||
void set_opening_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();
|
||||
void set_distance_measurement(int16_t distance);
|
||||
// lock
|
||||
void lock();
|
||||
void unlock();
|
||||
|
||||
// light
|
||||
void light_on();
|
||||
void light_off();
|
||||
LightState get_light_state() const;
|
||||
// button functionality
|
||||
void query_status();
|
||||
void query_openings();
|
||||
void sync();
|
||||
|
||||
// lock
|
||||
void lock();
|
||||
void unlock();
|
||||
using Component::set_timeout;
|
||||
|
||||
// button functionality
|
||||
void query_status();
|
||||
void query_openings();
|
||||
void sync();
|
||||
void set_door_state_expiry();
|
||||
void cancel_door_state_expiry();
|
||||
|
||||
using Component::set_timeout;
|
||||
|
||||
void set_door_state_expiry();
|
||||
void cancel_door_state_expiry();
|
||||
|
||||
// Register a one-shot door state callback with automatic expiry.
|
||||
//
|
||||
// Handles secplus1's nested callback chains where opening from
|
||||
// STOPPED requires multiple state transitions:
|
||||
//
|
||||
// on_door_state(outer_cb) // wait for CLOSING
|
||||
// → set_door_state_expiry() // expiry A
|
||||
// → [door reports CLOSING]
|
||||
// → outer_cb fires, calls:
|
||||
// toggle_door()
|
||||
// on_door_state(inner_cb) // wait for STOPPED
|
||||
// → set_door_state_expiry() // expiry B (replaces A)
|
||||
// → [door reports STOPPED]
|
||||
// → inner_cb fires
|
||||
// toggle_door() // door now opening
|
||||
// count()==0 → cancel expiry B
|
||||
//
|
||||
// The user callback runs BEFORE the expiry check because it may
|
||||
// re-arm the chain by calling on_door_state() again. If it does,
|
||||
// the new call sets expiry B which replaces expiry A (same timeout
|
||||
// ID = replace, not add). We only cancel expiry when count()==0,
|
||||
// meaning no new callback was queued — otherwise we'd cancel
|
||||
// expiry B here and leave the inner callback without protection.
|
||||
template <typename F>
|
||||
void on_door_state(F&& callback)
|
||||
{
|
||||
using Cb = std::decay_t<F>;
|
||||
this->on_door_state_([this, cb = Cb(std::forward<F>(callback))](DoorState s) {
|
||||
cb(s);
|
||||
if (!this->on_door_state_.count()) {
|
||||
this->cancel_door_state_expiry();
|
||||
}
|
||||
// Register a one-shot door state callback with automatic expiry.
|
||||
//
|
||||
// Handles secplus1's nested callback chains where opening from
|
||||
// STOPPED requires multiple state transitions:
|
||||
//
|
||||
// on_door_state(outer_cb) // wait for CLOSING
|
||||
// → set_door_state_expiry() // expiry A
|
||||
// → [door reports CLOSING]
|
||||
// → outer_cb fires, calls:
|
||||
// toggle_door()
|
||||
// on_door_state(inner_cb) // wait for STOPPED
|
||||
// → set_door_state_expiry() // expiry B (replaces A)
|
||||
// → [door reports STOPPED]
|
||||
// → inner_cb fires
|
||||
// toggle_door() // door now opening
|
||||
// count()==0 → cancel expiry B
|
||||
//
|
||||
// The user callback runs BEFORE the expiry check because it may
|
||||
// re-arm the chain by calling on_door_state() again. If it does,
|
||||
// the new call sets expiry B which replaces expiry A (same timeout
|
||||
// ID = replace, not add). We only cancel expiry when count()==0,
|
||||
// meaning no new callback was queued — otherwise we'd cancel
|
||||
// expiry B here and leave the inner callback without protection.
|
||||
template <typename F>
|
||||
void on_door_state(F&& callback) {
|
||||
using Cb = std::decay_t<F>;
|
||||
this->on_door_state_(
|
||||
[this, cb = Cb(std::forward<F>(callback))](DoorState s) {
|
||||
cb(s);
|
||||
if (!this->on_door_state_.count()) {
|
||||
this->cancel_door_state_expiry();
|
||||
}
|
||||
});
|
||||
this->set_door_state_expiry();
|
||||
}
|
||||
this->set_door_state_expiry();
|
||||
}
|
||||
|
||||
// children subscriptions — type-safe templates (no std::function)
|
||||
// Callbacks must be trivially copyable and fit in Callback storage
|
||||
// (3 * sizeof(void*)), e.g. [this] or [this, f] lambdas.
|
||||
// Enforced at compile time by Callback::create().
|
||||
template <typename F>
|
||||
void subscribe_opening_duration(F&& f);
|
||||
template <typename F>
|
||||
void subscribe_closing_duration(F&& f);
|
||||
template <typename F>
|
||||
void subscribe_openings(F&& f);
|
||||
template <typename F>
|
||||
void subscribe_door_state(F&& f);
|
||||
template <typename F>
|
||||
void subscribe_light_state(F&& f);
|
||||
template <typename F>
|
||||
void subscribe_lock_state(F&& f);
|
||||
template <typename F>
|
||||
void subscribe_sync_failed(F&& f);
|
||||
template <typename F>
|
||||
void subscribe_distance_measurement(F&& f);
|
||||
// children subscriptions — type-safe templates (no std::function)
|
||||
// Callbacks must be trivially copyable and fit in Callback storage
|
||||
// (3 * sizeof(void*)), e.g. [this] or [this, f] lambdas.
|
||||
// Enforced at compile time by Callback::create().
|
||||
template <typename F>
|
||||
void subscribe_opening_duration(F&& f);
|
||||
template <typename F>
|
||||
void subscribe_closing_duration(F&& f);
|
||||
template <typename F>
|
||||
void subscribe_openings(F&& f);
|
||||
template <typename F>
|
||||
void subscribe_door_state(F&& f);
|
||||
template <typename F>
|
||||
void subscribe_light_state(F&& f);
|
||||
template <typename F>
|
||||
void subscribe_lock_state(F&& f);
|
||||
template <typename F>
|
||||
void subscribe_sync_failed(F&& f);
|
||||
template <typename F>
|
||||
void subscribe_distance_measurement(F&& f);
|
||||
|
||||
protected:
|
||||
// Pointers first (4-byte aligned)
|
||||
secplus2::Secplus2* protocol_;
|
||||
InternalGPIOPin* output_gdo_pin_;
|
||||
InternalGPIOPin* input_gdo_pin_;
|
||||
protected:
|
||||
// Pointers first (4-byte aligned)
|
||||
secplus2::Secplus2* protocol_;
|
||||
InternalGPIOPin* output_gdo_pin_;
|
||||
InternalGPIOPin* input_gdo_pin_;
|
||||
|
||||
// Bool members packed into bitfield
|
||||
struct {
|
||||
uint8_t reserved : 8; // Reserved for future use
|
||||
} flags_ { 0 };
|
||||
// Bool members packed into bitfield
|
||||
struct {
|
||||
uint8_t reserved : 8; // Reserved for future use
|
||||
} flags_{0};
|
||||
|
||||
// Subscriber counters for defer name allocation
|
||||
uint8_t door_state_sub_num_ { 0 };
|
||||
uint8_t distance_sub_num_ { 0 };
|
||||
}; // RATGDOComponent
|
||||
// Subscriber counters for defer name allocation
|
||||
uint8_t door_state_sub_num_{0};
|
||||
uint8_t distance_sub_num_{0};
|
||||
}; // RATGDOComponent
|
||||
|
||||
void log_subscriber_overflow(const LogString* observable_name, uint32_t max);
|
||||
|
||||
inline uint32_t get_scheduler_id(uint32_t base, uint32_t count, uint8_t& counter, const LogString* observable_name)
|
||||
{
|
||||
if (count == 0) {
|
||||
log_subscriber_overflow(observable_name, count);
|
||||
return base;
|
||||
}
|
||||
if (counter >= count) {
|
||||
log_subscriber_overflow(observable_name, count);
|
||||
return base + count - 1; // reuse last ID to avoid collision with first subscriber
|
||||
}
|
||||
return base + counter++;
|
||||
inline uint32_t get_scheduler_id(uint32_t base, uint32_t count,
|
||||
uint8_t& counter,
|
||||
const LogString* observable_name) {
|
||||
if (count == 0) {
|
||||
log_subscriber_overflow(observable_name, count);
|
||||
return base;
|
||||
}
|
||||
if (counter >= count) {
|
||||
log_subscriber_overflow(observable_name, count);
|
||||
return base + count -
|
||||
1; // reuse last ID to avoid collision with first subscriber
|
||||
}
|
||||
return base + counter++;
|
||||
}
|
||||
|
||||
// Scheduler IDs using uint32_t ranges to avoid heap allocations
|
||||
// Bases are auto-generated from counts to prevent ID conflicts
|
||||
namespace scheduler_ids {
|
||||
inline constexpr uint32_t INTERVAL_POSITION_SYNC = 0;
|
||||
inline constexpr uint32_t INTERVAL_POSITION_SYNC = 0;
|
||||
|
||||
// Multi-subscriber ranges — counts derived from codegen defines
|
||||
inline constexpr uint32_t DEFER_DOOR_STATE_COUNT = RATGDO_MAX_DOOR_STATE_SUBSCRIBERS;
|
||||
inline constexpr uint32_t DEFER_DOOR_STATE_BASE = INTERVAL_POSITION_SYNC + 1;
|
||||
// Multi-subscriber ranges — counts derived from codegen defines
|
||||
inline constexpr uint32_t DEFER_DOOR_STATE_COUNT =
|
||||
RATGDO_MAX_DOOR_STATE_SUBSCRIBERS;
|
||||
inline constexpr uint32_t DEFER_DOOR_STATE_BASE = INTERVAL_POSITION_SYNC + 1;
|
||||
|
||||
inline constexpr uint32_t DEFER_DISTANCE_COUNT = RATGDO_MAX_DISTANCE_SUBSCRIBERS;
|
||||
inline constexpr uint32_t DEFER_DISTANCE_BASE = DEFER_DOOR_STATE_BASE + DEFER_DOOR_STATE_COUNT;
|
||||
inline constexpr uint32_t DEFER_DISTANCE_END = DEFER_DISTANCE_BASE + DEFER_DISTANCE_COUNT;
|
||||
inline constexpr uint32_t DEFER_DISTANCE_COUNT =
|
||||
RATGDO_MAX_DISTANCE_SUBSCRIBERS;
|
||||
inline constexpr uint32_t DEFER_DISTANCE_BASE =
|
||||
DEFER_DOOR_STATE_BASE + DEFER_DOOR_STATE_COUNT;
|
||||
inline constexpr uint32_t DEFER_DISTANCE_END =
|
||||
DEFER_DISTANCE_BASE + DEFER_DISTANCE_COUNT;
|
||||
|
||||
// Single-subscriber IDs
|
||||
enum : uint32_t {
|
||||
DEFER_OPENING_DURATION = DEFER_DISTANCE_END,
|
||||
DEFER_CLOSING_DURATION,
|
||||
DEFER_OPENINGS,
|
||||
DEFER_LIGHT_STATE,
|
||||
DEFER_LOCK_STATE,
|
||||
// Single-subscriber IDs
|
||||
enum : uint32_t {
|
||||
DEFER_OPENING_DURATION = DEFER_DISTANCE_END,
|
||||
DEFER_CLOSING_DURATION,
|
||||
DEFER_OPENINGS,
|
||||
DEFER_LIGHT_STATE,
|
||||
DEFER_LOCK_STATE,
|
||||
|
||||
// Named timeout IDs (replacing string-based names)
|
||||
TIMEOUT_DOOR_QUERY_STATE,
|
||||
TIMEOUT_DOOR_ACTION,
|
||||
TIMEOUT_MOVE_TO_POSITION,
|
||||
TIMEOUT_DOOR_STATE_EXPIRY,
|
||||
TIMEOUT_SYNC,
|
||||
};
|
||||
} // namespace scheduler_ids
|
||||
// Named timeout IDs (replacing string-based names)
|
||||
TIMEOUT_DOOR_QUERY_STATE,
|
||||
TIMEOUT_DOOR_ACTION,
|
||||
TIMEOUT_MOVE_TO_POSITION,
|
||||
TIMEOUT_DOOR_STATE_EXPIRY,
|
||||
TIMEOUT_SYNC,
|
||||
};
|
||||
} // namespace scheduler_ids
|
||||
|
||||
// Template implementations for subscribe methods.
|
||||
// Each wraps the callback in a deferred call so that if the observable
|
||||
@@ -245,72 +253,66 @@ namespace scheduler_ids {
|
||||
// is dispatched to the child component.
|
||||
|
||||
template <typename F>
|
||||
void RATGDOComponent::subscribe_opening_duration(F&& f)
|
||||
{
|
||||
this->opening_duration.subscribe([this, f](float state) {
|
||||
defer(scheduler_ids::DEFER_OPENING_DURATION, [f, state] { f(state); });
|
||||
});
|
||||
void RATGDOComponent::subscribe_opening_duration(F&& f) {
|
||||
this->opening_duration.subscribe([this, f](float state) {
|
||||
defer(scheduler_ids::DEFER_OPENING_DURATION, [f, state] { f(state); });
|
||||
});
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void RATGDOComponent::subscribe_closing_duration(F&& f)
|
||||
{
|
||||
this->closing_duration.subscribe([this, f](float state) {
|
||||
defer(scheduler_ids::DEFER_CLOSING_DURATION, [f, state] { f(state); });
|
||||
});
|
||||
void RATGDOComponent::subscribe_closing_duration(F&& f) {
|
||||
this->closing_duration.subscribe([this, f](float state) {
|
||||
defer(scheduler_ids::DEFER_CLOSING_DURATION, [f, state] { f(state); });
|
||||
});
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void RATGDOComponent::subscribe_openings(F&& f)
|
||||
{
|
||||
this->openings.subscribe([this, f](uint16_t state) {
|
||||
defer(scheduler_ids::DEFER_OPENINGS, [f, state] { f(state); });
|
||||
});
|
||||
void RATGDOComponent::subscribe_openings(F&& f) {
|
||||
this->openings.subscribe([this, f](uint16_t state) {
|
||||
defer(scheduler_ids::DEFER_OPENINGS, [f, state] { f(state); });
|
||||
});
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void RATGDOComponent::subscribe_door_state(F&& f)
|
||||
{
|
||||
uint32_t id = get_scheduler_id(scheduler_ids::DEFER_DOOR_STATE_BASE, scheduler_ids::DEFER_DOOR_STATE_COUNT,
|
||||
this->door_state_sub_num_, LOG_STR("door_state"));
|
||||
this->door_state.subscribe([this, f, id](DoorState state) {
|
||||
defer(id, [this, f, state] { f(state, *this->door_position); });
|
||||
});
|
||||
this->door_position.subscribe([this, f, id](float position) {
|
||||
defer(id, [this, f, position] { f(*this->door_state, position); });
|
||||
});
|
||||
void RATGDOComponent::subscribe_door_state(F&& f) {
|
||||
uint32_t id =
|
||||
get_scheduler_id(scheduler_ids::DEFER_DOOR_STATE_BASE,
|
||||
scheduler_ids::DEFER_DOOR_STATE_COUNT,
|
||||
this->door_state_sub_num_, LOG_STR("door_state"));
|
||||
this->door_state.subscribe([this, f, id](DoorState state) {
|
||||
defer(id, [this, f, state] { f(state, *this->door_position); });
|
||||
});
|
||||
this->door_position.subscribe([this, f, id](float position) {
|
||||
defer(id, [this, f, position] { f(*this->door_state, position); });
|
||||
});
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void RATGDOComponent::subscribe_light_state(F&& f)
|
||||
{
|
||||
this->light_state.subscribe([this, f](LightState state) {
|
||||
defer(scheduler_ids::DEFER_LIGHT_STATE, [f, state] { f(state); });
|
||||
});
|
||||
void RATGDOComponent::subscribe_light_state(F&& f) {
|
||||
this->light_state.subscribe([this, f](LightState state) {
|
||||
defer(scheduler_ids::DEFER_LIGHT_STATE, [f, state] { f(state); });
|
||||
});
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void RATGDOComponent::subscribe_lock_state(F&& f)
|
||||
{
|
||||
this->lock_state.subscribe([this, f](LockState state) {
|
||||
defer(scheduler_ids::DEFER_LOCK_STATE, [f, state] { f(state); });
|
||||
});
|
||||
void RATGDOComponent::subscribe_lock_state(F&& f) {
|
||||
this->lock_state.subscribe([this, f](LockState state) {
|
||||
defer(scheduler_ids::DEFER_LOCK_STATE, [f, state] { f(state); });
|
||||
});
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void RATGDOComponent::subscribe_sync_failed(F&& f)
|
||||
{
|
||||
this->sync_failed.subscribe(std::forward<F>(f));
|
||||
void RATGDOComponent::subscribe_sync_failed(F&& f) {
|
||||
this->sync_failed.subscribe(std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void RATGDOComponent::subscribe_distance_measurement(F&& f)
|
||||
{
|
||||
uint32_t id = get_scheduler_id(scheduler_ids::DEFER_DISTANCE_BASE, scheduler_ids::DEFER_DISTANCE_COUNT,
|
||||
this->distance_sub_num_, LOG_STR("distance_measurement"));
|
||||
this->last_distance_measurement.subscribe([this, f, id](int16_t state) {
|
||||
defer(id, [f, state] { f(state); });
|
||||
});
|
||||
void RATGDOComponent::subscribe_distance_measurement(F&& f) {
|
||||
uint32_t id = get_scheduler_id(
|
||||
scheduler_ids::DEFER_DISTANCE_BASE, scheduler_ids::DEFER_DISTANCE_COUNT,
|
||||
this->distance_sub_num_, LOG_STR("distance_measurement"));
|
||||
this->last_distance_measurement.subscribe(
|
||||
[this, f, id](int16_t state) { defer(id, [f, state] { f(state); }); });
|
||||
}
|
||||
|
||||
} // namespace esphome::ratgdo
|
||||
} // namespace esphome::ratgdo
|
||||
|
||||
Reference in New Issue
Block a user