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

Runtime state of a paired IO‑Homecontrol device. More...

#include <proto_device_model.h>

Collaboration diagram for esphome::home_io_control::IoDevice:

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.

Detailed Description

Runtime state of a paired IO‑Homecontrol device.

Definition at line 485 of file proto_device_model.h.

Member Data Documentation

◆ battery

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.

◆ battery_entities

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.

◆ battery_level

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.

◆ confirms_execute

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.

◆ dhw

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.

◆ dimmable

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.

◆ entity_class

DeviceCapabilityClass esphome::home_io_control::IoDevice::entity_class
Initial value:

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.

◆ exchange_attempt_count

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.

◆ exchange_timeout_count

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.

◆ exchange_unconfirmed_count

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.

◆ execution_state

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.

◆ features

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.

◆ has_last_command

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.

◆ has_system_key

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.

◆ heating

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.

◆ invert_override

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.

◆ inverted

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.

◆ is_stopped

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.

◆ last_command_originator

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.

◆ last_commander

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.

◆ last_moving_evidence_ms

uint32_t esphome::home_io_control::IoDevice::last_moving_evidence_ms
Initial value:
{
0}

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.

◆ last_rain_evidence_ms

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.

◆ last_result_at_ms

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.

◆ last_result_code

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.

◆ last_rssi_dbm

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.

◆ last_seen_ms

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.

◆ last_status

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.

◆ limited_by_rain

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.

◆ low_power

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.

◆ model

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.

◆ model_check_attempts

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.

◆ model_checked

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.

◆ moving_until_ms

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.

◆ name

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.

◆ node_id

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.

◆ optimistic

OptimisticState esphome::home_io_control::IoDevice::optimistic {}

Hub-side predictions; see OptimisticState. Never observation.

Definition at line 579 of file proto_device_model.h.

◆ optimistic_state

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.

◆ position

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.

◆ rain_sensor

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.

◆ registered_by_pairing

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.

◆ reports_remaining_time

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.

◆ rssi_ema_scaled

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.

◆ stop_candidate

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.

◆ subtype

uint8_t esphome::home_io_control::IoDevice::subtype {0}

Device subtype (manufacturer‑specific).

Definition at line 488 of file proto_device_model.h.

◆ sun_level

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.

◆ system_key

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.

◆ target

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.

◆ temperature_range_max_c

float esphome::home_io_control::IoDevice::temperature_range_max_c
Initial value:
{
HEATING_TEMPERATURE_RANGE_MAX_C}

Upper end of that range (YAML max_temperature:).

Definition at line 599 of file proto_device_model.h.

◆ temperature_range_min_c

float esphome::home_io_control::IoDevice::temperature_range_min_c
Initial value:
{
HEATING_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.

◆ tilt

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.

◆ travel_speed

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.

◆ type

DeviceType esphome::home_io_control::IoDevice::type {DeviceType::UNKNOWN}

Device type (shutter, awning, etc.).

Definition at line 487 of file proto_device_model.h.


The documentation for this struct was generated from the following file: