|
Home IO Control
ESPHome add-on for IO-Homecontrol devices
|
Runtime state of a paired IO‑Homecontrol device. More...
#include <proto_device_model.h>
Public Attributes | |
| uint8_t | node_id [NODE_ID_SIZE] {} |
| Device's 3‑byte radio address. | |
| DeviceType | type {DeviceType::UNKNOWN} |
| Device type (shutter, awning, etc.). | |
| uint8_t | subtype {0} |
| Device subtype (manufacturer‑specific). | |
| DeviceModel | model {DeviceModel::NONE} |
| YAML-declared product model below the subtype (io_model:); never on the wire. | |
| char | name [DEVICE_NAME_BUFFER_SIZE] {} |
| Cached UTF-8 device name decoded from Latin-1 wire payloads. | |
| float | position {UNKNOWN_POSITION} |
| Current position: 0=open, 100=closed, or UNKNOWN_POSITION. | |
| float | tilt {UNKNOWN_POSITION} |
| Current tilt: 0=closed, 100=open, or UNKNOWN_POSITION. | |
| float | target {UNKNOWN_POSITION} |
| Target position the device is moving toward. | |
| bool | is_stopped {true} |
| True if device is not moving. | |
| ExecutionState | execution_state {ExecutionState::UNDEFINED} |
| Execution state of the last status report that carried one; UNDEFINED until then, and for a device that has no motion. | |
| StopCandidate | stop_candidate {} |
| Last off-target "stopped" report, to confirm the next one. | |
| bool | reports_remaining_time {false} |
| The device has sent a nonzero remaining time in a status reply, so its zero means "about to stop" rather than "not provided". | |
| DeviceFeatures | features {0} |
| What this device can do, resolved by resolve_device_features(). | |
| DeviceCapabilityClass | entity_class |
| Class of the entity that declared the device; UNKNOWN for a device no entity declared (the type's class then applies). | |
| std::optional< bool > | invert_override = std::nullopt |
| YAML invert_position: when declared; wins over the kind's default. | |
| bool | inverted {false} |
| True if open/close positions are swapped (e.g., horizontal awning). | |
| TravelSpeed | travel_speed {TravelSpeed::FAST} |
| Speed profile of position moves. | |
| bool | optimistic_state {true} |
| True if target may be set ahead of a confirming poll/response. | |
| bool | low_power {false} |
| YAML-declared: this target is a low-power / duty-cycled receiver, so directed frames set CTRL1_LOW_POWER and use the long wake-up preamble. | |
| bool | dimmable {false} |
| YAML-declared dimmable: true of a LIGHT entity. | |
| uint8_t | last_result_code {0} |
| Last CMD_ERROR_RESP result byte (0 = none recorded). | |
| uint32_t | last_result_at_ms {0} |
| millis() timestamp of last_result_code, 0 when none recorded. | |
| uint8_t | last_commander [NODE_ID_SIZE] {} |
| Node ID of the controller that last commanded this device, as reported verbatim by the device in its own status payload. | |
| uint8_t | last_command_originator {0} |
| That command's Command Originator byte (ORIGINATOR_* in proto_constants.h). | |
| bool | has_last_command {false} |
| True once a status reply carried a well-formed last-command record. | |
| bool | limited_by_rain {false} |
| Derived from observed status replies, never from a prediction (decisions::is_rain_limited(); ADR 0030 keeps predictions apart): the last move was ordered by the rain sensor, or a position command was clamped while rain protection was recently active. | |
| uint32_t | last_rain_evidence_ms {0} |
| millis() of the last status reply that named the rain sensor as the last commander; 0 = never. | |
| uint32_t | last_status {0} |
| millis() timestamp of last received status. | |
| int16_t | last_rssi_dbm {RSSI_UNKNOWN_DBM} |
| Most recent raw RSSI sample (dBm), or RSSI_UNKNOWN_DBM. | |
| int16_t | rssi_ema_scaled {RSSI_UNKNOWN_DBM} |
| Smoothed RSSI as fixed point in 1/RSSI_EMA_SCALE dBm — read through device_rssi_ema_dbm(), updated by detail::update_link_health() in hub_internal.h. | |
| uint32_t | last_seen_ms {0} |
| millis() of the last frame received from this device (any command), 0 = never. | |
| uint32_t | last_moving_evidence_ms |
| millis() of the last sign this device is travelling (see note_moving_evidence(), clear_moving_evidence()), 0 = never. | |
| uint32_t | moving_until_ms {0} |
| millis() at which the remaining time of the last trusted moving report has run out (plus PREDICTED_END_MARGIN_MS), 0 = unknown. | |
| uint16_t | exchange_timeout_count {0} |
| Cumulative count of outbound exchanges to this device with no valid response (see detail::record_exchange_timeout() in hub_internal.h). | |
| uint16_t | exchange_attempt_count {0} |
| Cumulative attempts (ExchangeEngine::DebugInfo::tries, 1-based per exchange) across those timed-out exchanges only — attempts within an ultimately successful exchange are not counted (deliberate scope limit). | |
| uint16_t | exchange_unconfirmed_count {0} |
| Cumulative count of exchanges this device authenticated and then never closed: it answered with a 0x3C challenge, we answered that, and no final reply arrived. | |
| bool | confirms_execute {false} |
| True once this device has answered a CMD_EXECUTE with a reply that closed the exchange (a status, or an error). | |
| OptimisticState | optimistic {} |
| Hub-side predictions; see OptimisticState. Never observation. | |
| RainSensorState | rain_sensor {RainSensorState::UNKNOWN} |
| Rain state from the opt-in minimum-limitation poll. | |
| std::optional< uint16_t > | sun_level |
| Raw sun value from the opt-in EVENT_LOCAL_SENSOR poll. | |
| std::optional< uint16_t > | battery_level |
| Battery level in percent (0-100) from the opt-in EVENT_BATTERY_LEVEL_CHANGE poll (decode_battery_level_event()); same rules as sun_level. | |
| BatteryState | battery {BatteryState::NOT_REPORTED} |
| Coarse battery level from byte 1 of the device's own status: a reply to a status poll or an authenticated CMD_STATUS_UPDATE. | |
| float | temperature_range_min_c |
| Lower end of the temperature encoding range of a heater that carries a temperature in its main parameter (YAML min_temperature:). | |
| float | temperature_range_max_c |
| Upper end of that range (YAML max_temperature:). | |
| HeatingReadings | heating {} |
| What the hub has read from a heater over the private register protocol (room temperature, setpoint, mode, regulator state). | |
| DhwReadings | dhw {} |
| What the hub has read from a water heater (device_feature::WATER_HEATER): family-0x00 registers and the status reply's target. | |
| bool | battery_entities {false} |
| YAML-declared (battery: true): the battery entities exist, so the status log line names the level even when the device reports none. | |
| bool | has_system_key {false} |
| YAML-declared (system_key:): this device keeps a key of its own. | |
| uint8_t | system_key [AES_KEY_SIZE] {} |
| The device's own key; meaningful only when has_system_key. | |
| bool | registered_by_pairing {false} |
| Added by a pairing in this boot, not declared in YAML. | |
| uint8_t | model_check_attempts {0} |
| Runs of the hub's one-off model check (a heater kind with model rows: model name read, declared-model hint) so far; the check stops after it completes or after a bounded number of runs. | |
| bool | model_checked {false} |
| The model check completed: both of its reads were answered. | |
Runtime state of a paired IO‑Homecontrol device.
Definition at line 485 of file proto_device_model.h.
| BatteryState esphome::home_io_control::IoDevice::battery {BatteryState::NOT_REPORTED} |
Coarse battery level from byte 1 of the device's own status: a reply to a status poll or an authenticated CMD_STATUS_UPDATE.
Never from an execute ack (its layout follows the request) or an overheard frame (ADR 0022).
Definition at line 592 of file proto_device_model.h.
| bool esphome::home_io_control::IoDevice::battery_entities {false} |
YAML-declared (battery: true): the battery entities exist, so the status log line names the level even when the device reports none.
Definition at line 607 of file proto_device_model.h.
| std::optional<uint16_t> esphome::home_io_control::IoDevice::battery_level |
Battery level in percent (0-100) from the opt-in EVENT_BATTERY_LEVEL_CHANGE poll (decode_battery_level_event()); same rules as sun_level.
Independent of battery, the coarse status-byte level.
Definition at line 589 of file proto_device_model.h.
| bool esphome::home_io_control::IoDevice::confirms_execute {false} |
True once this device has answered a CMD_EXECUTE with a reply that closed the exchange (a status, or an error).
Learned at runtime and never stored: it separates a device whose missing reply is an anomaly from one that never sends one (see decisions::retry_after_unconfirmed_accept_is_safe()).
Definition at line 575 of file proto_device_model.h.
| DhwReadings esphome::home_io_control::IoDevice::dhw {} |
What the hub has read from a water heater (device_feature::WATER_HEATER): family-0x00 registers and the status reply's target.
Set only from decoded replies; stays "never read" for every other device type.
Definition at line 604 of file proto_device_model.h.
| bool esphome::home_io_control::IoDevice::dimmable {false} |
YAML-declared dimmable: true of a LIGHT entity.
Resolver input: it alone decides a light's device_feature::LEVELS (unless the kind is main parameter only; light subtype 58 is on/off only, VELUX KLF 200 API v3.18, App. 2).
Definition at line 519 of file proto_device_model.h.
| DeviceCapabilityClass esphome::home_io_control::IoDevice::entity_class |
Class of the entity that declared the device; UNKNOWN for a device no entity declared (the type's class then applies).
Resolver input.
Definition at line 504 of file proto_device_model.h.
| uint16_t esphome::home_io_control::IoDevice::exchange_attempt_count {0} |
Cumulative attempts (ExchangeEngine::DebugInfo::tries, 1-based per exchange) across those timed-out exchanges only — attempts within an ultimately successful exchange are not counted (deliberate scope limit).
Definition at line 563 of file proto_device_model.h.
| uint16_t esphome::home_io_control::IoDevice::exchange_timeout_count {0} |
Cumulative count of outbound exchanges to this device with no valid response (see detail::record_exchange_timeout() in hub_internal.h).
Definition at line 561 of file proto_device_model.h.
| uint16_t esphome::home_io_control::IoDevice::exchange_unconfirmed_count {0} |
Cumulative count of exchanges this device authenticated and then never closed: it answered with a 0x3C challenge, we answered that, and no final reply arrived.
Counted separately from exchange_timeout_count because the two have different causes and different fixes — silence from the start means the device never heard us, while silence after a challenge means the reply was lost on the way back (or our challenge answer never landed). For a CMD_EXECUTE this outcome is treated as success and raises no failure count, so without this counter it is invisible in the diagnostics.
Definition at line 566 of file proto_device_model.h.
| ExecutionState esphome::home_io_control::IoDevice::execution_state {ExecutionState::UNDEFINED} |
Execution state of the last status report that carried one; UNDEFINED until then, and for a device that has no motion.
Definition at line 496 of file proto_device_model.h.
| DeviceFeatures esphome::home_io_control::IoDevice::features {0} |
What this device can do, resolved by resolve_device_features().
Every capability check on a registered device reads this word.
Definition at line 502 of file proto_device_model.h.
| bool esphome::home_io_control::IoDevice::has_last_command {false} |
True once a status reply carried a well-formed last-command record.
Definition at line 535 of file proto_device_model.h.
| bool esphome::home_io_control::IoDevice::has_system_key {false} |
YAML-declared (system_key:): this device keeps a key of its own.
Every exchange with it uses system_key below instead of the hub's key.
Definition at line 609 of file proto_device_model.h.
| HeatingReadings esphome::home_io_control::IoDevice::heating {} |
What the hub has read from a heater over the private register protocol (room temperature, setpoint, mode, regulator state).
Set only from decoded replies; stays "never read" for every other device type.
Definition at line 601 of file proto_device_model.h.
| std::optional<bool> esphome::home_io_control::IoDevice::invert_override = std::nullopt |
YAML invert_position: when declared; wins over the kind's default.
Resolver input.
Definition at line 508 of file proto_device_model.h.
| bool esphome::home_io_control::IoDevice::inverted {false} |
True if open/close positions are swapped (e.g., horizontal awning).
Resolved: invert_override, else device_feature::INVERTED.
Definition at line 510 of file proto_device_model.h.
| bool esphome::home_io_control::IoDevice::is_stopped {true} |
True if device is not moving.
Definition at line 495 of file proto_device_model.h.
| uint8_t esphome::home_io_control::IoDevice::last_command_originator {0} |
That command's Command Originator byte (ORIGINATOR_* in proto_constants.h).
Only meaningful when has_last_command.
Definition at line 533 of file proto_device_model.h.
| uint8_t esphome::home_io_control::IoDevice::last_commander[NODE_ID_SIZE] {} |
Node ID of the controller that last commanded this device, as reported verbatim by the device in its own status payload.
All zeroes until a status reply carrying the record has been decoded (see decode_last_command_record() in proto_codecs.h).
Definition at line 529 of file proto_device_model.h.
| uint32_t esphome::home_io_control::IoDevice::last_moving_evidence_ms |
millis() of the last sign this device is travelling (see note_moving_evidence(), clear_moving_evidence()), 0 = never.
Hub-side belief, not observation.
Definition at line 555 of file proto_device_model.h.
| uint32_t esphome::home_io_control::IoDevice::last_rain_evidence_ms {0} |
millis() of the last status reply that named the rain sensor as the last commander; 0 = never.
Memory for the clamp rule, aged out by RAIN_EVIDENCE_HOLD_MS.
Definition at line 542 of file proto_device_model.h.
| uint32_t esphome::home_io_control::IoDevice::last_result_at_ms {0} |
millis() timestamp of last_result_code, 0 when none recorded.
Definition at line 528 of file proto_device_model.h.
| uint8_t esphome::home_io_control::IoDevice::last_result_code {0} |
Last CMD_ERROR_RESP result byte (0 = none recorded).
See command_result_name()/is_limitation_result() in proto_constants.h. Cleared by the next successful status/command reply for this device. Note: 0 is also the real RESULT_UNKNOWN_STATUS_REPLY wire value, so that specific explicit reply is indistinguishable here from "nothing recorded yet" — a known, accepted tradeoff.
Definition at line 523 of file proto_device_model.h.
| int16_t esphome::home_io_control::IoDevice::last_rssi_dbm {RSSI_UNKNOWN_DBM} |
Most recent raw RSSI sample (dBm), or RSSI_UNKNOWN_DBM.
Definition at line 546 of file proto_device_model.h.
| uint32_t esphome::home_io_control::IoDevice::last_seen_ms {0} |
millis() of the last frame received from this device (any command), 0 = never.
Definition at line 554 of file proto_device_model.h.
| uint32_t esphome::home_io_control::IoDevice::last_status {0} |
millis() timestamp of last received status.
Definition at line 545 of file proto_device_model.h.
| bool esphome::home_io_control::IoDevice::limited_by_rain {false} |
Derived from observed status replies, never from a prediction (decisions::is_rain_limited(); ADR 0030 keeps predictions apart): the last move was ordered by the rain sensor, or a position command was clamped while rain protection was recently active.
Separate from last_result_code, which only an explicit CMD_ERROR_RESP sets.
Definition at line 536 of file proto_device_model.h.
| bool esphome::home_io_control::IoDevice::low_power {false} |
YAML-declared: this target is a low-power / duty-cycled receiver, so directed frames set CTRL1_LOW_POWER and use the long wake-up preamble.
A protocol-reported class exists (discovery Multi Information Byte) but is surfaced through the pairing/scan snippet, never applied at runtime.
Definition at line 515 of file proto_device_model.h.
| DeviceModel esphome::home_io_control::IoDevice::model {DeviceModel::NONE} |
YAML-declared product model below the subtype (io_model:); never on the wire.
Resolver input, like dimmable.
Definition at line 489 of file proto_device_model.h.
| uint8_t esphome::home_io_control::IoDevice::model_check_attempts {0} |
Runs of the hub's one-off model check (a heater kind with model rows: model name read, declared-model hint) so far; the check stops after it completes or after a bounded number of runs.
Runtime only.
Definition at line 616 of file proto_device_model.h.
| bool esphome::home_io_control::IoDevice::model_checked {false} |
The model check completed: both of its reads were answered.
Definition at line 619 of file proto_device_model.h.
| uint32_t esphome::home_io_control::IoDevice::moving_until_ms {0} |
millis() at which the remaining time of the last trusted moving report has run out (plus PREDICTED_END_MARGIN_MS), 0 = unknown.
Written by note_moving_until(); dropped with the moving evidence.
Definition at line 558 of file proto_device_model.h.
| char esphome::home_io_control::IoDevice::name[DEVICE_NAME_BUFFER_SIZE] {} |
Cached UTF-8 device name decoded from Latin-1 wire payloads.
Definition at line 491 of file proto_device_model.h.
| uint8_t esphome::home_io_control::IoDevice::node_id[NODE_ID_SIZE] {} |
Device's 3‑byte radio address.
Definition at line 486 of file proto_device_model.h.
| OptimisticState esphome::home_io_control::IoDevice::optimistic {} |
Hub-side predictions; see OptimisticState. Never observation.
Definition at line 579 of file proto_device_model.h.
| bool esphome::home_io_control::IoDevice::optimistic_state {true} |
True if target may be set ahead of a confirming poll/response.
Definition at line 514 of file proto_device_model.h.
| float esphome::home_io_control::IoDevice::position {UNKNOWN_POSITION} |
Current position: 0=open, 100=closed, or UNKNOWN_POSITION.
Definition at line 492 of file proto_device_model.h.
| RainSensorState esphome::home_io_control::IoDevice::rain_sensor {RainSensorState::UNKNOWN} |
Rain state from the opt-in minimum-limitation poll.
Set only from a limitation reply inside an exchange the hub started; independent of limited_by_rain, which is derived from status replies.
Definition at line 580 of file proto_device_model.h.
| bool esphome::home_io_control::IoDevice::registered_by_pairing {false} |
Added by a pairing in this boot, not declared in YAML.
The record is lost at reboot, so reports still print its YAML block, and a later pairing may replace it (DeviceRegistry::get_declared()).
Definition at line 613 of file proto_device_model.h.
| bool esphome::home_io_control::IoDevice::reports_remaining_time {false} |
The device has sent a nonzero remaining time in a status reply, so its zero means "about to stop" rather than "not provided".
Definition at line 500 of file proto_device_model.h.
| int16_t esphome::home_io_control::IoDevice::rssi_ema_scaled {RSSI_UNKNOWN_DBM} |
Smoothed RSSI as fixed point in 1/RSSI_EMA_SCALE dBm — read through device_rssi_ema_dbm(), updated by detail::update_link_health() in hub_internal.h.
Fixed point (rather than whole dBm) keeps sub-dBm EMA contributions from vanishing to integer truncation, so the average converges on a stable signal instead of stalling up to RSSI_EMA_SCALE−1 dBm away. RSSI_UNKNOWN_DBM before the first sample.
Definition at line 547 of file proto_device_model.h.
| StopCandidate esphome::home_io_control::IoDevice::stop_candidate {} |
Last off-target "stopped" report, to confirm the next one.
Definition at line 499 of file proto_device_model.h.
| uint8_t esphome::home_io_control::IoDevice::subtype {0} |
Device subtype (manufacturer‑specific).
Definition at line 488 of file proto_device_model.h.
| std::optional<uint16_t> esphome::home_io_control::IoDevice::sun_level |
Raw sun value from the opt-in EVENT_LOCAL_SENSOR poll.
(decode_sun_level_event()); empty until the first answer and after PERIODIC_POLL_FAILURES_BEFORE_UNKNOWN misses. Set only from the answer to a subscription the hub sent.
Definition at line 584 of file proto_device_model.h.
| uint8_t esphome::home_io_control::IoDevice::system_key[AES_KEY_SIZE] {} |
The device's own key; meaningful only when has_system_key.
Key material: never logged outside a bannered report block.
Definition at line 611 of file proto_device_model.h.
| float esphome::home_io_control::IoDevice::target {UNKNOWN_POSITION} |
Target position the device is moving toward.
Definition at line 494 of file proto_device_model.h.
| float esphome::home_io_control::IoDevice::temperature_range_max_c |
Upper end of that range (YAML max_temperature:).
Definition at line 599 of file proto_device_model.h.
| float esphome::home_io_control::IoDevice::temperature_range_min_c |
Lower end of the temperature encoding range of a heater that carries a temperature in its main parameter (YAML min_temperature:).
Definition at line 596 of file proto_device_model.h.
| float esphome::home_io_control::IoDevice::tilt {UNKNOWN_POSITION} |
Current tilt: 0=closed, 100=open, or UNKNOWN_POSITION.
Definition at line 493 of file proto_device_model.h.
| TravelSpeed esphome::home_io_control::IoDevice::travel_speed {TravelSpeed::FAST} |
Speed profile of position moves.
Like inverted, a YAML-declared preference: nothing on the wire reports it.
Definition at line 512 of file proto_device_model.h.
| DeviceType esphome::home_io_control::IoDevice::type {DeviceType::UNKNOWN} |
Device type (shutter, awning, etc.).
Definition at line 487 of file proto_device_model.h.