|
Home IO Control
ESPHome add-on for IO-Homecontrol devices
|
Per-device poll scheduling, failure backoff, and follow-up-poll state machine. More...
#include "proto_timing.h"#include <algorithm>#include <cstdint>#include <map>#include <optional>#include <set>#include <string>#include <vector>Go to the source code of this file.
Classes | |
| struct | esphome::home_io_control::PollTracking |
| Per-device poll scheduling state. More... | |
| struct | esphome::home_io_control::ForeignTraffic |
| Per-device bookkeeping of overheard foreign traffic. More... | |
| class | esphome::home_io_control::StatusPollPolicy |
| Per-hub poll scheduling and failure-backoff policy. More... | |
Namespaces | |
| namespace | esphome |
| namespace | esphome::home_io_control |
Enumerations | |
| enum class | esphome::home_io_control::ForeignFrameKind : uint8_t { esphome::home_io_control::REQUEST_TO_DEVICE , esphome::home_io_control::DEVICE_CHALLENGE_TO_OTHER } |
| What an overheard frame of another controller is. More... | |
| enum class | esphome::home_io_control::ForeignAction : uint8_t { esphome::home_io_control::IGNORE , esphome::home_io_control::ARM , esphome::home_io_control::PUSH_PENDING } |
| What the hub does about an overheard foreign frame. More... | |
| enum class | esphome::home_io_control::MovingReportAction : uint8_t { esphome::home_io_control::FOLLOW , esphome::home_io_control::OPEN , esphome::home_io_control::END , esphome::home_io_control::NONE } |
| What the hub does with a status report that reads as moving. More... | |
Functions | |
| uint32_t | esphome::home_io_control::settle_delay_ms (uint32_t interval_ms, uint32_t remaining_delay_ms, bool cap_for_stop) |
| Resolve the follow-up settle-poll delay while a device may still be moving. | |
Variables | |
| static constexpr uint8_t | esphome::home_io_control::MOVING_POLL_MISSES_SKIPPED = 2 |
| Consecutive failed polls of a moving device that are skipped rather than backed off. | |
| static constexpr uint32_t | esphome::home_io_control::MAX_TRACKED_STATUS_POLL_WINDOW_MS = 240000 |
| Hard stop for bounded follow-up polling after a command, remote activity or the first moving report, measured from the moment the window opens (ADR 0061, amended by ADR 0079). | |
| static constexpr uint32_t | esphome::home_io_control::INITIAL_STATUS_REQUEST_DELAY_MS = 5000 |
| Delay before the first post-boot status request from an entity. | |
| static constexpr uint32_t | esphome::home_io_control::HEATING_POLL_DEFAULT_INTERVAL_MS = 300000 |
| Interval between regular polls of a heater (its status_poll_interval overrides it). | |
| static constexpr uint32_t | esphome::home_io_control::HEATING_POST_WRITE_POLL_DELAY_MS = 45000 |
| Delay of the extra heater poll after a register write the heater acknowledged. | |
| static constexpr uint32_t | esphome::home_io_control::FOREIGN_READ_RESYNC_MS = 600000 |
| How long a device's authenticated status or this hub's own read-triggered poll keeps a further overheard read from triggering another poll (0 = never polled, so the first read polls). | |
| static constexpr uint32_t | esphome::home_io_control::FOREIGN_CHALLENGE_AFTER_REQUEST_MS = 100 |
| A device challenges a request 2.5-3.3 ms after it; 100 ms is far above that and far below the next request. | |
| static constexpr uint32_t | esphome::home_io_control::ONEWAY_QUIET_PERIOD_MS = 700 |
| Hold queued background polls back for this long after any 1W frame, so a poll the hub itself scheduled does not occupy the (half-duplex) radio while the remote is still transmitting. | |
| static constexpr uint32_t | esphome::home_io_control::ONEWAY_POLL_DEFER_CAP_MS = 5000 |
| Hard cap on how long sustained 1W traffic may hold a background poll back in total, measured from the start of the burst rather than the most recent frame. | |
| static constexpr uint32_t | esphome::home_io_control::DEFAULT_SETTLE_POLL_DELAY_MS = 3000 |
| Default follow-up settle-poll delay used while a device may still be moving, when no explicit poll interval is configured (interval_ms == 0). | |
| static constexpr uint32_t | esphome::home_io_control::STOP_SETTLE_POLL_CAP_MS = 1000 |
| Upper bound on the settle-poll delay after a STOP command. | |
Background-poll retry delays after silent failures (no reply received) | |
| static constexpr uint32_t | esphome::home_io_control::STATUS_RETRY_AFTER_FAIL_MS = 5000 |
| First retry after a silent failure. | |
| static constexpr uint32_t | esphome::home_io_control::STATUS_RETRY_AFTER_FAIL_STEP2_MS = 15000 |
| Second retry after a silent failure. | |
| static constexpr uint32_t | esphome::home_io_control::STATUS_RETRY_AFTER_FAIL_STEP3_MS = 30000 |
| Third retry after a silent failure. | |
| static constexpr uint32_t | esphome::home_io_control::STATUS_RETRY_AFTER_FAIL_STEP4_MS = 60000 |
| Fourth retry after a silent failure. | |
| static constexpr uint32_t | esphome::home_io_control::STATUS_RETRY_AFTER_FAIL_MAX_MS = 300000 |
| Steady-state backoff after many silent failures. | |
Background-poll retry delays after auth-shaped failures (0x3C challenge seen) | |
A device that challenges the poll is awake and heard it. A single such miss is usually a closing reply lost while the device switched its load — on a cover, the motor stopping at the end of its travel (issue #178) — so the first retry waits no longer than after a silent miss. Only a repeated one, which is what a wrong key looks like, backs off far: there every further try is a full authenticated exchange that cannot succeed. | |
| static constexpr uint32_t | esphome::home_io_control::STATUS_AUTH_RETRY_AFTER_FAIL_MS |
| First retry after a challenge-seen failure. | |
| static constexpr uint32_t | esphome::home_io_control::STATUS_AUTH_RETRY_AFTER_FAIL_STEP2_MS = 30000 |
| Second retry. | |
| static constexpr uint32_t | esphome::home_io_control::STATUS_AUTH_RETRY_AFTER_FAIL_STEP3_MS = 120000 |
| Third retry. | |
| static constexpr uint32_t | esphome::home_io_control::STATUS_AUTH_RETRY_AFTER_FAIL_MAX_MS = 300000 |
| Steady-state after repeated auth failures. | |
Predicted-end read | |
A moving cover that reports how long it has left is read once more, with the settling plan, a second after that time has run out: the position it reports then is the final one. That holds for every count, a short one or 0 included: the read at the end is the one most likely to meet the second in which the motor switches its load and a reply is lost. The ordinary progress reads keep running in between and stay single tries. The aim, the dropped progress read and the final-position read at count + 1 s are confirmed on a Somfy Sunea io awning (tests/corpus/captures/statuspoll/somfy_awning_statuspoll_close_with_remaining_time_predicted_end_read_sx1262.yaml).
| |
| static constexpr uint32_t | esphome::home_io_control::PREDICTED_END_MARGIN_MS = 1000 |
| static constexpr uint32_t | esphome::home_io_control::PREDICTED_END_DROPS_PROGRESS_WITHIN_MS = 1000 |
| A progress read due within this long before the predicted-end read is dropped: the settling read follows at once and a read of its own in front of it only fills the air. | |
| static constexpr uint8_t | esphome::home_io_control::PREDICTED_END_STALE_REPORTS = 3 |
| Reports in a row whose remaining time did not fall below the previous one before the count is taken as frozen and the predicted-end read is given up (progress reads only). | |
Frozen-count back-off | |
A count that has stopped falling is a cover that is waiting or stuck, not one that is nearly there, so the progress reads that follow back off instead of returning to the 3 s cadence (ADR 0079, amending ADR 0076). The steps grow with each further report whose count did not fall and stop at the last; a falling count starts over. The back-off only begins after PREDICTED_END_STALE_REPORTS reports in a row that did not fall, and the slowest falling counts seen drop at every poll (3 s between two polls on a VELUX SML, 1 s per second on a Somfy awning), so a slow but alive count is not taken as frozen. 10 s, 15 s and 20 s keep a cover that starts after waiting within 20 s of being seen, while a stuck one costs a read per 20 s instead of one per 3 s.
| |
| static constexpr uint32_t | esphome::home_io_control::FROZEN_COUNT_BACKOFF_FIRST_MS = 10000 |
| Delay after the first frozen report. | |
| static constexpr uint32_t | esphome::home_io_control::FROZEN_COUNT_BACKOFF_SECOND_MS = 15000 |
| Delay after the second. | |
| static constexpr uint32_t | esphome::home_io_control::FROZEN_COUNT_BACKOFF_MAX_MS = 20000 |
| Delay after the third and every later one. | |
Per-device poll scheduling, failure backoff, and follow-up-poll state machine.
Owns all per-device poll bookkeeping (intervals, deadlines, failure counters). Pure logic with injected timestamps — fully host-testable without a clock mock.
Definition in file status_poll_policy.h.