Home IO Control
ESPHome add-on for IO-Homecontrol devices
Loading...
Searching...
No Matches
esphome::home_io_control::StatusPollPolicy Class Reference

Per-hub poll scheduling and failure-backoff policy. More...

#include <status_poll_policy.h>

Collaboration diagram for esphome::home_io_control::StatusPollPolicy:

Public Member Functions

void set_interval (const std::string &device_id, uint32_t interval_ms)
 Set the configured follow-up poll interval (ms; 0 = legacy one-shot settle only).
uint32_t get_interval (const std::string &device_id) const
 Return the configured interval (0 when not set or unconfigured).
void begin_tracking (const std::string &device_id, uint32_t initial_delay_ms, uint32_t now)
 Begin bounded follow-up polling after a command or remote activity.
void clear (const std::string &device_id)
 Stop all polling for a device and reset failure counts. Preserves interval_ms.
MovingReportAction on_moving_report (const std::string &device_id, uint32_t now, bool may_open)
 Decide what a status report that reads as moving means for the follow-up window.
void on_trusted_report (const std::string &device_id, std::optional< uint16_t > remaining_s, uint32_t now)
 Aim or re-aim the predicted-end read from a trusted status report of a moving device.
uint32_t frozen_count_delay_ms (const std::string &device_id) const
 How long the next progress read waits when the device's remaining time has stopped falling.
uint32_t get_settle_update (const std::string &device_id) const
 The planned predicted-end read's timestamp (0 = none).
void set_next_update (const std::string &device_id, uint32_t abs_time)
 Schedule the next poll at an absolute millis() timestamp.
uint32_t get_next_update (const std::string &device_id) const
uint32_t on_exchange_failed (const std::string &device_id, bool auth_like, uint32_t now, bool device_moving=false)
 Record a failed background poll; apply backoff or clear tracking if the window expired.
void clear_failure_streaks (const std::string &device_id)
 Reset failure streaks (and skipped moving misses) after a successful exchange response.
uint8_t get_status_poll_failures (const std::string &device_id) const
uint8_t get_auth_poll_failures (const std::string &device_id) const
uint8_t get_moving_poll_misses (const std::string &device_id) const
 Consecutive failed polls of a moving device skipped so far.
uint32_t get_poll_deadline (const std::string &device_id) const
void mark_stop_settle (const std::string &device_id)
 Mark the device's next poll as the one reading where an accepted STOP left it, so it is a settling read (decisions::ReadKind::SETTLING).
bool take_stop_settle (const std::string &device_id)
 Consume the mark set by mark_stop_settle(): true once, for the first poll dispatched after it.
void set_confirm_stopped (const std::string &device_id, bool needed)
 Mark (or unmark) the device's next poll as the one confirming a stop off target, so it is a settling read too.
bool take_confirm_stopped (const std::string &device_id)
 Consume the mark set by set_confirm_stopped(): true once, for the first poll dispatched after it.
bool is_predicted_end_read (const std::string &device_id) const
 True when the next poll is the predicted-end read (the mark take_settling_read() consumes).
bool take_settling_read (const std::string &device_id)
 Consume the marks (none short-circuits another) for the poll being dispatched.
bool is_tracking_active (const std::string &device_id, uint32_t now) const
 True when the device has an active bounded polling window (deadline set and not expired).
std::optional< std::string > pop_due_device (uint32_t now)
 Return and consume the first device with a poll overdue.
ForeignAction on_foreign_frame (const std::string &device_id, ForeignFrameKind kind, const std::string &controller, uint8_t cmd, uint32_t now, uint32_t last_status_ms)
 Decide what an overheard frame of another controller means for this device.
void on_remote_poll_ran (const std::string &device_id)
 The poll armed by foreign traffic ran (or was dropped): nothing is pending any more.
bool is_remote_poll_pending (const std::string &device_id, uint32_t now) const
 True while a poll armed by foreign traffic is pending.
std::optional< std::string > pop_ended_device ()
 Return and consume a device whose polling window ended without the device being reported at rest: the window expired with a poll still pending (pop_due_device()), or the failure ladder no longer fits in it (on_exchange_failed()).
void on_linked_remote_activity ()
 A linked remote was heard: open a burst, or keep the open one.
void on_exchange_ended (uint32_t now, uint32_t delay_ms)
 An exchange ended at now.
bool take_due_catchup (uint32_t now)
 True once when the open burst's catch-up is due at now.
void mark_state_unknown (const std::string &device_id)
 Mark the device's next status read as a catch-up read: a press the hub missed may have set it moving since its last report, so the read treats its state as unknown (decisions::AttemptRequest::with_state_unknown()).
bool take_state_unknown (const std::string &device_id)
 Consume the mark set by mark_state_unknown(): true once, for the status read dispatched after it.

Detailed Description

Per-hub poll scheduling and failure-backoff policy.

Maintains a PollTracking entry per device; all hub poll bookkeeping lives here and nowhere else. Callers inject 'now' timestamps so the class is fully testable without a hardware clock.

Definition at line 238 of file status_poll_policy.h.

Member Function Documentation

◆ begin_tracking()

void esphome::home_io_control::StatusPollPolicy::begin_tracking ( const std::string & device_id,
uint32_t initial_delay_ms,
uint32_t now )

Begin bounded follow-up polling after a command or remote activity.

Sets a deadline regardless of whether a configured interval exists; interval-0 devices use remaining-time or default settle delays computed at response time.

Definition at line 39 of file status_poll_policy.cpp.

◆ clear()

void esphome::home_io_control::StatusPollPolicy::clear ( const std::string & device_id)

Stop all polling for a device and reset failure counts. Preserves interval_ms.

Definition at line 52 of file status_poll_policy.cpp.

◆ clear_failure_streaks()

void esphome::home_io_control::StatusPollPolicy::clear_failure_streaks ( const std::string & device_id)

Reset failure streaks (and skipped moving misses) after a successful exchange response.

Definition at line 201 of file status_poll_policy.cpp.

◆ frozen_count_delay_ms()

uint32_t esphome::home_io_control::StatusPollPolicy::frozen_count_delay_ms ( const std::string & device_id) const
nodiscard

How long the next progress read waits when the device's remaining time has stopped falling.

Zero while the count falls or none is known. From the PREDICTED_END_STALE_REPORTS-th report in a row whose count did not fall: FROZEN_COUNT_BACKOFF_FIRST_MS, then FROZEN_COUNT_BACKOFF_SECOND_MS, then FROZEN_COUNT_BACKOFF_MAX_MS for every further one. A caller whose own cadence is longer keeps it.

Parameters
device_idDevice whose last trusted report was passed to on_trusted_report().

Definition at line 113 of file status_poll_policy.cpp.

◆ get_auth_poll_failures()

uint8_t esphome::home_io_control::StatusPollPolicy::get_auth_poll_failures ( const std::string & device_id) const
nodiscard

Definition at line 262 of file status_poll_policy.cpp.

◆ get_interval()

uint32_t esphome::home_io_control::StatusPollPolicy::get_interval ( const std::string & device_id) const
nodiscard

Return the configured interval (0 when not set or unconfigured).

Definition at line 34 of file status_poll_policy.cpp.

◆ get_moving_poll_misses()

uint8_t esphome::home_io_control::StatusPollPolicy::get_moving_poll_misses ( const std::string & device_id) const
nodiscard

Consecutive failed polls of a moving device skipped so far.

Definition at line 267 of file status_poll_policy.cpp.

◆ get_next_update()

uint32_t esphome::home_io_control::StatusPollPolicy::get_next_update ( const std::string & device_id) const
nodiscard

Definition at line 136 of file status_poll_policy.cpp.

◆ get_poll_deadline()

uint32_t esphome::home_io_control::StatusPollPolicy::get_poll_deadline ( const std::string & device_id) const
nodiscard

Definition at line 141 of file status_poll_policy.cpp.

◆ get_settle_update()

uint32_t esphome::home_io_control::StatusPollPolicy::get_settle_update ( const std::string & device_id) const
nodiscard

The planned predicted-end read's timestamp (0 = none).

Definition at line 127 of file status_poll_policy.cpp.

◆ get_status_poll_failures()

uint8_t esphome::home_io_control::StatusPollPolicy::get_status_poll_failures ( const std::string & device_id) const
nodiscard

Definition at line 257 of file status_poll_policy.cpp.

◆ is_predicted_end_read()

bool esphome::home_io_control::StatusPollPolicy::is_predicted_end_read ( const std::string & device_id) const
nodiscard

True when the next poll is the predicted-end read (the mark take_settling_read() consumes).

Definition at line 240 of file status_poll_policy.cpp.

◆ is_remote_poll_pending()

bool esphome::home_io_control::StatusPollPolicy::is_remote_poll_pending ( const std::string & device_id,
uint32_t now ) const
nodiscard

True while a poll armed by foreign traffic is pending.

A pending poll whose signal was lost expires by itself once now is more than REMOTE_ACTIVITY_STATUS_POLL_DELAY_MS past its due time.

Definition at line 277 of file status_poll_policy.cpp.

◆ is_tracking_active()

bool esphome::home_io_control::StatusPollPolicy::is_tracking_active ( const std::string & device_id,
uint32_t now ) const
nodiscard

True when the device has an active bounded polling window (deadline set and not expired).

Definition at line 146 of file status_poll_policy.cpp.

◆ mark_state_unknown()

void esphome::home_io_control::StatusPollPolicy::mark_state_unknown ( const std::string & device_id)

Mark the device's next status read as a catch-up read: a press the hub missed may have set it moving since its last report, so the read treats its state as unknown (decisions::AttemptRequest::with_state_unknown()).

Needs no tracked device; begin_tracking() and clear() drop the mark, since heard activity or a report is news again.

Definition at line 388 of file status_poll_policy.cpp.

◆ mark_stop_settle()

void esphome::home_io_control::StatusPollPolicy::mark_stop_settle ( const std::string & device_id)

Mark the device's next poll as the one reading where an accepted STOP left it, so it is a settling read (decisions::ReadKind::SETTLING).

Only a tracked device can be marked; begin_tracking() and clear() drop the mark, so a newer command or remote activity never inherits it.

Definition at line 210 of file status_poll_policy.cpp.

◆ on_exchange_ended()

void esphome::home_io_control::StatusPollPolicy::on_exchange_ended ( uint32_t now,
uint32_t delay_ms )

An exchange ended at now.

While a burst is open its catch-up becomes due delay_ms after now, later or earlier than before; a delay_ms of 0 (the catch-up is switched off) closes the burst instead. No-op without an open burst.

Definition at line 377 of file status_poll_policy.cpp.

◆ on_exchange_failed()

uint32_t esphome::home_io_control::StatusPollPolicy::on_exchange_failed ( const std::string & device_id,
bool auth_like,
uint32_t now,
bool device_moving = false )

Record a failed background poll; apply backoff or clear tracking if the window expired.

When device_moving is true, no failure streak is running and fewer than MOVING_POLL_MISSES_SKIPPED misses in a row have been skipped, the miss is skipped instead: the next poll keeps the normal cadence (settle_delay_ms() without a remaining time, at most STATUS_RETRY_AFTER_FAIL_MS) and the failure streaks are left alone.

Parameters
device_idDevice whose poll failed.
auth_likeTrue when the failed exchange saw a 0x3C challenge.
nowCurrent millis().
device_movingTrue when a single-try poll of a device believed travelling failed.
Returns
The delay applied in ms, or 0 if tracking was cleared.

Definition at line 154 of file status_poll_policy.cpp.

Here is the call graph for this function:

◆ on_foreign_frame()

ForeignAction esphome::home_io_control::StatusPollPolicy::on_foreign_frame ( const std::string & device_id,
ForeignFrameKind kind,
const std::string & controller,
uint8_t cmd,
uint32_t now,
uint32_t last_status_ms )

Decide what an overheard frame of another controller means for this device.

Order: a pending foreign-armed poll answers first (PUSH_PENDING for any frame, timer pushed out); a request that writes ARMs; any other request ARMs only when neither last_status_ms nor the last read-triggered poll is younger than FOREIGN_READ_RESYNC_MS (0 = never, so the first read polls); a challenge is IGNOREd when the last request heard from the same controller was within FOREIGN_CHALLENGE_AFTER_REQUEST_MS and not a write, otherwise it ARMs. Every request updates the last-request record; a challenge does not. ARM and PUSH_PENDING set the pending due time; an ARM from a read stamps the read-poll time.

Parameters
device_idRegistered device the frame concerns.
kindRequest to the device, or the device's challenge to another controller.
controllerThe other controller: the request's source, or the challenge's destination.
cmdCommand of the frame.
nowCurrent millis().
last_status_msmillis() of the device's last authenticated status; 0 = never.

Definition at line 293 of file status_poll_policy.cpp.

Here is the call graph for this function:

◆ on_linked_remote_activity()

void esphome::home_io_control::StatusPollPolicy::on_linked_remote_activity ( )

A linked remote was heard: open a burst, or keep the open one.

Only the exchanges that end while it is open set its due time (on_exchange_ended()), so a burst during which the hub never used the radio never comes due.

Definition at line 375 of file status_poll_policy.cpp.

◆ on_moving_report()

MovingReportAction esphome::home_io_control::StatusPollPolicy::on_moving_report ( const std::string & device_id,
uint32_t now,
bool may_open )

Decide what a status report that reads as moving means for the follow-up window.

An open window is followed and its deadline stays: a later report never extends it. A window whose deadline has passed is closed and reported ended (see pop_ended_device()); the report that finds it expired does not reopen it, so a poll the hub scheduled itself cannot chain windows. Without a window, the report opens one at now when may_open allows it.

Parameters
device_idDevice the report belongs to.
nowCurrent millis().
may_openTrue when this kind of device may start tracking from a report alone.

Definition at line 69 of file status_poll_policy.cpp.

Here is the call graph for this function:

◆ on_remote_poll_ran()

void esphome::home_io_control::StatusPollPolicy::on_remote_poll_ran ( const std::string & device_id)

The poll armed by foreign traffic ran (or was dropped): nothing is pending any more.

Definition at line 287 of file status_poll_policy.cpp.

◆ on_trusted_report()

void esphome::home_io_control::StatusPollPolicy::on_trusted_report ( const std::string & device_id,
std::optional< uint16_t > remaining_s,
uint32_t now )

Aim or re-aim the predicted-end read from a trusted status report of a moving device.

A remaining time, whatever its size (0 included), plans the read at now + remaining time + PREDICTED_END_MARGIN_MS, replacing an earlier aim; an aim past the end of the follow-up window is not planned. A count that did not fall since the last aimed report counts as stale; after PREDICTED_END_STALE_REPORTS in a row the read is given up and only progress reads remain (a falling count aims again). No count (remaining_s empty) drops the aim: a report that stopped, or a device that sends none. A report also withdraws a predicted-end read already popped but not yet sent, since it replaces the prediction that called for it.

The poll that confirms a stop off target is never predicted: its report passes no count, and its delay stays the default one (see decisions::classify_stopped_report()).

Parameters
device_idDevice the report belongs to; tracked devices only.
remaining_sUsable remaining travel time in seconds, empty when there is none.
nowCurrent millis().

Definition at line 84 of file status_poll_policy.cpp.

◆ pop_due_device()

std::optional< std::string > esphome::home_io_control::StatusPollPolicy::pop_due_device ( uint32_t now)
nodiscard

Return and consume the first device with a poll overdue.

A device's predicted-end read (on_trusted_report()) wins over its progress read: when it is due, the device is returned with its predicted-end mark set (take_settling_read()) and a progress read due too is dropped. A progress read due while the predicted-end read follows within PREDICTED_END_DROPS_PROGRESS_WITHIN_MS is dropped as well; the predicted-end read stays planned. Clears expired tracking entries as a side effect. Returns nullopt if nothing is due.

Definition at line 336 of file status_poll_policy.cpp.

Here is the call graph for this function:

◆ pop_ended_device()

std::optional< std::string > esphome::home_io_control::StatusPollPolicy::pop_ended_device ( )
nodiscard

Return and consume a device whose polling window ended without the device being reported at rest: the window expired with a poll still pending (pop_due_device()), or the failure ladder no longer fits in it (on_exchange_failed()).

An explicit clear() — a stopped report, a failed build — is not "ran out" and is never returned. Returns nullopt when there is none.

Definition at line 367 of file status_poll_policy.cpp.

◆ set_confirm_stopped()

void esphome::home_io_control::StatusPollPolicy::set_confirm_stopped ( const std::string & device_id,
bool needed )

Mark (or unmark) the device's next poll as the one confirming a stop off target, so it is a settling read too.

Every trusted status report sets it from its own verdict, so a report that no longer needs confirming (moving again, or at rest) drops a mark an earlier one left. Only a tracked device can be marked; begin_tracking() and clear() drop the mark as for the STOP mark.

Parameters
device_idDevice whose next poll is meant.
neededTrue when the latest report stopped off target for the first time.

Definition at line 225 of file status_poll_policy.cpp.

◆ set_interval()

void esphome::home_io_control::StatusPollPolicy::set_interval ( const std::string & device_id,
uint32_t interval_ms )

Set the configured follow-up poll interval (ms; 0 = legacy one-shot settle only).

Definition at line 30 of file status_poll_policy.cpp.

◆ set_next_update()

void esphome::home_io_control::StatusPollPolicy::set_next_update ( const std::string & device_id,
uint32_t abs_time )

Schedule the next poll at an absolute millis() timestamp.

Definition at line 132 of file status_poll_policy.cpp.

◆ take_confirm_stopped()

bool esphome::home_io_control::StatusPollPolicy::take_confirm_stopped ( const std::string & device_id)
nodiscard

Consume the mark set by set_confirm_stopped(): true once, for the first poll dispatched after it.

Definition at line 231 of file status_poll_policy.cpp.

◆ take_due_catchup()

bool esphome::home_io_control::StatusPollPolicy::take_due_catchup ( uint32_t now)
nodiscard

True once when the open burst's catch-up is due at now.

The burst is closed first, so the catch-up's own reads, which are exchanges too, do not reopen it. Wrap-safe across a millis() rollover.

Definition at line 392 of file status_poll_policy.cpp.

◆ take_settling_read()

bool esphome::home_io_control::StatusPollPolicy::take_settling_read ( const std::string & device_id)
nodiscard

Consume the marks (none short-circuits another) for the poll being dispatched.

Returns
True when that poll settles a position: it follows an accepted STOP, confirms a stop off target, or is the predicted-end read.

Definition at line 245 of file status_poll_policy.cpp.

Here is the call graph for this function:

◆ take_state_unknown()

bool esphome::home_io_control::StatusPollPolicy::take_state_unknown ( const std::string & device_id)
nodiscard

Consume the mark set by mark_state_unknown(): true once, for the status read dispatched after it.

Definition at line 390 of file status_poll_policy.cpp.

◆ take_stop_settle()

bool esphome::home_io_control::StatusPollPolicy::take_stop_settle ( const std::string & device_id)
nodiscard

Consume the mark set by mark_stop_settle(): true once, for the first poll dispatched after it.

Definition at line 216 of file status_poll_policy.cpp.


The documentation for this class was generated from the following files: