|
Home IO Control
ESPHome add-on for IO-Homecontrol devices
|
Functions | |
| uint8_t | round_percent (float fraction) |
| Convert a 0.0-1.0 HA fraction (position, tilt, or brightness) to a 0-100 IO percent. | |
| bool | is_binary_entity_position (uint8_t position) |
| Is the given position value an on/off binary encoding? | |
| bool | known_device_matches_entity_class (const IoDevice &dev, DeviceCapabilityClass expected) |
| Does the device's type match the expected HA entity class? | |
| bool | known_device_supports_status_requests (const IoDevice &dev) |
| Does the device support status requests? | |
| bool | known_device_accepts_execute_position (const IoDevice &dev, uint8_t position) |
| Can this device accept an execute (position) command? | |
| bool | known_device_accepts_execute_tilt (const IoDevice &dev) |
| Can this device accept a tilt command? | |
| void | log_rejected_operation (const std::string &device_id, const IoDevice &dev, const char *operation, const char *expected) |
| Log a rejected operation with capability mismatch details. | |
| void | log_component_capture (const RadioDriver *radio, const char *stage, const uint8_t *buf, uint8_t len, const IoFrame *frame=nullptr) |
| Log a frame at the "io_capture" tag with structured fields. | |
| void | log_frame_issue (IOHomeControlComponent *component, const char *direction, const char *reason, const IoFrame &frame, uint8_t len) |
| Log a frame‑level issue (unregistered endpoints, unsupported commands). | |
| void | log_1w_remote_frame (const OneWayFrameInfo &info, const std::vector< std::string > *linked_devices=nullptr) |
| Log an already-decoded 1W remote frame at DEBUG level. | |
| bool | is_exposed_sender (const std::vector< std::string > &exposed_senders, const std::string &sender_id) |
| Whether a 1W sender is on the exposed_senders allowlist for the sender HA event. | |
| std::string | format_name_and_hex (const char *name, uint8_t value) |
| Format a name/value pair as "name(0xXX)", e.g. "execute(0x00)". | |
| std::string | describe_learned_device_type (DeviceType type) |
| Build the YAML line to add once a device's type is learned at runtime. | |
| std::map< std::string, std::string > | build_sender_event_data (const OneWayFrameInfo &info, bool linked) |
| Build the Home Assistant event data map for a decoded 1W sender frame. | |
| void | normalize_stopped_state (IoDevice &dev) |
| Normalize stopped state: some devices briefly report stopped before target/current converge. | |
| void | update_link_health (IoDevice &dev, RadioDriver *radio) |
| Update per-device link-health stats from the radio's last capture. | |
| void | record_exchange_timeout (IoDevice &dev, uint8_t tries) |
| Record that an outbound exchange to this device timed out (no valid response). | |
| void | log_status_update (const std::string &id, const IoDevice &dev, const char *suffix="") |
| Log a concise status‑update line used by inbound handlers. | |
| void | log_command_result (const std::string &id, uint8_t result, uint8_t request_cmd=0, bool include_request_cmd=false) |
| Log a decoded CMD_ERROR_RESP result with optional request-command context. | |
| void | record_command_result (IoDevice &dev, const std::string &id, uint8_t result, uint8_t request_cmd=0, bool include_request_cmd=false) |
| Store a decoded CMD_ERROR_RESP result on the device and log it. | |
| void | clear_command_result (IoDevice &dev) |
| Clear a previously recorded CMD_ERROR_RESP result, if any. | |
Variables | |
| constexpr const char * | TAG = "home_io_control" |
| Shared log tag for hub-level messages. | |
| constexpr uint32_t | ONEWAY_DEDUP_WINDOW_MS = 2000 |
| Suppress a repeated 1W log/poll for the same remote and the same intent within this window. | |
| constexpr float | BINARY_ENTITY_ON_POSITION_THRESHOLD |
| Shared 0-100 cutoff: values below this mean binary "on". | |
| constexpr const char * | ONEWAY_SENDER_EVENT = "esphome.home_io_control_sender_event" |
| Home Assistant event fired when a decoded 1W frame carries a command intent from an exposed sender (a physical remote button press, or a wind/rain sensor's triggered command). | |
| constexpr size_t | NAME_AND_HEX_BUFFER_SIZE = 40 |
| Buffer size for format_name_and_hex(): longest command name plus "(0xXX)" and a margin. | |
| constexpr size_t | LEARNED_DEVICE_TYPE_HEX_BUFFER_SIZE = 24 |
| Buffer size for describe_learned_device_type()'s hex fallback: "io_device_type: 0xXX" plus margin. | |
|
inline |
Build the Home Assistant event data map for a decoded 1W sender frame.
Only meaningful when info.has_intent is true (the caller gates emission on that); the intent field is only populated by decode_1w_frame() in that case.
| info | Already-decoded 1W frame info (see decode_1w_frame()). |
| linked | True if this sender is linked to at least one registered device. |
Definition at line 277 of file hub_internal.h.
|
inline |
Clear a previously recorded CMD_ERROR_RESP result, if any.
A stale limitation reason (e.g. a rain lockout from an hour ago) is worse than none once the device has since replied normally, so every successful status/command reply for a device clears it. Called from the CMD_PRIVATE_RESP and CMD_STATUS_UPDATE branches of update_device_status_() — not from CMD_GET_NAME_RESP/CMD_GET_INFO2_RESP, which are metadata lookups unrelated to whether the device's last movement command succeeded. Like record_command_result(), does not notify subscribers itself — both existing call sites clear before their own notify_device_update_() call, which is what actually publishes this change.
| dev | Device to clear. |
Definition at line 411 of file hub_internal.h.
|
inline |
Build the YAML line to add once a device's type is learned at runtime.
Logged when io_device_type was left unset in YAML and an INFO2 response just resolved it for the first time this boot (ADR 0018: nothing persists, so this repeats on every reboot until the user copies the line in). Reuses yaml_device_type_name() so the exact syntax always matches what the pairing snippet and the Python schema accept.
| type | The now-known device type. Must not be DeviceType::UNKNOWN. |
Definition at line 261 of file hub_internal.h.
|
inline |
Format a name/value pair as "name(0xXX)", e.g. "execute(0x00)".
Definition at line 244 of file hub_internal.h.
|
inline |
Is the given position value an on/off binary encoding?
| position | Position value to test. |
Definition at line 64 of file hub_internal.h.
|
inline |
Whether a 1W sender is on the exposed_senders allowlist for the sender HA event.
"Sender" covers both remotes and wind/rain sensors — they use the identical 1W broadcast mechanism and differ only in the originator byte inside the payload, not in addressing. Overheard 1W traffic is always DEBUG-logged regardless of this check (see log_1w_remote_frame()); this only gates whether the event reaches Home Assistant. Deliberately separate from linked_devices — a sender can be event-enabled without controlling any registered device (e.g. to trigger an HA automation with no matching cover/light/switch), or vice versa.
| exposed_senders | Configured allowlist (exposed_senders YAML key, empty by default). |
| sender_id | Node ID of the 1W sender that sent the frame. |
Definition at line 236 of file hub_internal.h.
|
inline |
Can this device accept an execute (position) command?
Checks capability and, for unknown types, allows binary positions for light/switch.
| dev | IoDevice to check. |
| position | Position value being sent. |
Definition at line 90 of file hub_internal.h.
|
inline |
Can this device accept a tilt command?
| dev | IoDevice to check. |
Definition at line 108 of file hub_internal.h.
|
inline |
Does the device's type match the expected HA entity class?
UNKNOWN devices always match to keep imported/discovered devices working.
| dev | IoDevice to check. |
| expected | Desired capability class (COVER, LIGHT, SWITCH, etc.). |
Definition at line 73 of file hub_internal.h.
|
inline |
Does the device support status requests?
UNKNOWN devices pass through.
| dev | IoDevice to check. |
Definition at line 81 of file hub_internal.h.
|
inline |
Log an already-decoded 1W remote frame at DEBUG level.
Formats a concise DEBUG log line showing remote ID, target type, command intent, and priority. When the remote is linked to devices, appends the linked device IDs. Takes the already-decoded OneWayFrameInfo so callers that also build a HA event (see build_sender_event_data()) decode the frame once, not twice.
| info | Already-decoded 1W frame info (see decode_1w_frame()). |
| linked_devices | Optional pointer to device IDs this remote is linked to. |
Definition at line 191 of file hub_internal.h.
|
inline |
Log a decoded CMD_ERROR_RESP result with optional request-command context.
| id | Device ID. |
| result | Result byte from CMD_ERROR_RESP data[0]. |
| request_cmd | Original outbound request command when known. |
| include_request_cmd | True to include request_cmd in the log line. |
Definition at line 370 of file hub_internal.h.
|
inline |
Log a frame at the "io_capture" tag with structured fields.
Used for protocol‑level debugging (phases: component, tx, rx, parse_ok/parse_fail).
| radio | Radio driver instance (provides chip name and capture). |
| stage | String label for the current phase. |
| buf | Raw bytes being logged. |
| len | Length of buf. |
| frame | Optional parsed IoFrame for decoded fields (cmd, src, dst). |
Definition at line 135 of file hub_internal.h.
|
inline |
Log a frame‑level issue (unregistered endpoints, unsupported commands).
| component | Pointer to the component (for device lookup). |
| direction | "tx" or "rx". |
| reason | Short issue label (e.g., "unregistered_device"). |
| frame | Parsed frame. |
| len | Serialized length. |
Definition at line 161 of file hub_internal.h.
|
inline |
Log a rejected operation with capability mismatch details.
| device_id | Device ID string. |
| dev | IoDevice that rejected the command. |
| operation | Human‑readable operation name (e.g., "set position"). |
| expected | Expected capability class or profile name. |
Definition at line 121 of file hub_internal.h.
|
inline |
Log a concise status‑update line used by inbound handlers.
| id | Device ID. |
| dev | Current device state. |
| suffix | Optional suffix added after the state string (e.g., " (status update)"). |
Definition at line 360 of file hub_internal.h.
|
inline |
Normalize stopped state: some devices briefly report stopped before target/current converge.
| dev | Device record to update (may clear is_stopped if positions differ). |
Definition at line 296 of file hub_internal.h.
|
inline |
Store a decoded CMD_ERROR_RESP result on the device and log it.
Single place both CMD_ERROR_RESP call sites (the unsolicited status path and the reply to our own EXECUTE) route through, so the store-and-log policy cannot drift between them. Does not notify subscribers itself — callers already call notify_device_update_() once per handled frame; call it after this.
| dev | Device that returned the result. |
| id | Device ID (for the log line). |
| result | Result byte from CMD_ERROR_RESP data[0]. |
| request_cmd | Original outbound request command when known. |
| include_request_cmd | True to include request_cmd context in the log line. |
Definition at line 394 of file hub_internal.h.
|
inline |
Record that an outbound exchange to this device timed out (no valid response).
Called once per failed exchange from execute_request_and_update_()'s "no valid response" branch — the single place every device-directed exchange already reads ExchangeEngine::DebugInfo. Both counters saturate at UINT16_MAX instead of wrapping, matching PairingTelemetry's counters.
| dev | Device the failed exchange was addressed to. |
| tries | Number of attempts the failed exchange made (DebugInfo::tries, 1-based). |
Definition at line 349 of file hub_internal.h.
|
inline |
Convert a 0.0-1.0 HA fraction (position, tilt, or brightness) to a 0-100 IO percent.
Rounds rather than truncates: HA quantizes call values to 0-255 before they ever reach us, so its "50%" is 128/255=0.50196, not exactly 0.5 — a truncating cast compounds that quantization into a consistent ~1% bias, caught on real hardware in both platform_cover.cpp (position and tilt) and platform_light.cpp (brightness). Callers apply their own invert/complement logic (e.g. 1.0F - fraction) before calling this; it only owns the rounding.
| fraction | Value in [0.0, 1.0]. |
Definition at line 55 of file hub_internal.h.
|
inline |
Update per-device link-health stats from the radio's last capture.
Called for every frame whose src is a registered device, regardless of command type or whether that command's own payload was well-formed — any such frame is real evidence the device is reachable and at this signal strength. The two call sites cover both ways such a frame arrives: update_device_status_() (inbound status path) and execute_request_and_update_()'s explicit-refusal branch (a CMD_ERROR_RESP reply to our own request, which returns before reaching the status path). Always stamps last_seen_ms; only touches the RSSI fields when radio is non-null and its last capture is valid (real drivers always populate a valid capture before a frame is handed off, but tests calling this path directly without a radio, or without exercising RX through it, must not crash or fabricate an RSSI).
| dev | Device that sent the frame. |
| radio | Radio driver to read the last capture from; may be nullptr. |
Definition at line 319 of file hub_internal.h.
|
inlineconstexpr |
Shared 0-100 cutoff: values below this mean binary "on".
Definition at line 39 of file hub_internal.h.
|
inlineconstexpr |
Buffer size for describe_learned_device_type()'s hex fallback: "io_device_type: 0xXX" plus margin.
Definition at line 251 of file hub_internal.h.
|
inlineconstexpr |
Buffer size for format_name_and_hex(): longest command name plus "(0xXX)" and a margin.
Definition at line 241 of file hub_internal.h.
|
inlineconstexpr |
Suppress a repeated 1W log/poll for the same remote and the same intent within this window.
Wide on purpose: it collapses both the 4×/40ms reliability burst and a held button into one logical press. A different intent from the same remote (a stop after a move) is not a duplicate and passes through immediately — see decisions::is_duplicate_1w_frame().
Definition at line 38 of file hub_internal.h.
|
inlineconstexpr |
Home Assistant event fired when a decoded 1W frame carries a command intent from an exposed sender (a physical remote button press, or a wind/rain sensor's triggered command).
Definition at line 222 of file hub_internal.h.
|
inlineconstexpr |
Shared log tag for hub-level messages.
Definition at line 33 of file hub_internal.h.