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

The main IO-Homecontrol component. More...

#include <hub_core.h>

Inheritance diagram for esphome::home_io_control::IOHomeControlComponent:
Collaboration diagram for esphome::home_io_control::IOHomeControlComponent:

Classes

struct  RequestOptions
 Per-request knobs of exchange_and_record_(). More...
struct  ExecuteRequestSpec
 Everything one execute-family operation needs beyond its own guard and frame builder. More...

Public Types

using ManagementActionResult = esphome::home_io_control::ManagementActionResult
 Result payload used by hub-level management actions such as rename.

Public Member Functions

 IOHomeControlComponent ()
 Initialize ExchangeEngine, PairingEngine, and ManagementActions with double-pointer/ reference indirection so that test assignments (comp.radio_ = &mock) propagate through all collaborators without calling setup().
void setup () override
 Initialize hardware (radio and device registry).
void loop () override
 Main loop: process pending operations and drive radio state machine.
void dump_config () override
 Dump configuration and radio debug info to the log.
float get_setup_priority () const override
 Get setup priority (HARDWARE to initialize early).
void spi_enable () override
 Enable the SPI bus.
void spi_disable () override
 Disable the SPI bus.
uint8_t spi_transfer (uint8_t data) override
 Transfer one byte full‑duplex.
void spi_write (uint8_t data) override
 Write one byte (MOSI only).
uint8_t spi_read () override
 Read one byte (MISO only).
void set_radio_test_mode (bool active)
 Suspend the hub's normal loop (packet processing, hopping, polling).
RadioDriver * get_radio () const
 Get the underlying radio driver (for diagnostics and test tooling).
void set_rst_pin (InternalGPIOPin *pin)
 Set the radio reset pin.
void set_dio0_pin (InternalGPIOPin *pin)
 Set the DIO0 interrupt pin (SX1276).
void set_dio4_pin (InternalGPIOPin *pin)
 Set the DIO4 preamble‑detect pin (SX1276, optional).
void set_dio1_pin (InternalGPIOPin *pin)
 Set the DIO1 interrupt pin (SX1262; also carries the LR1121's DIO9 IRQ line).
void set_busy_pin (InternalGPIOPin *pin)
 Set the BUSY pin (SX1262/LR1121).
void set_fem_en_pin (InternalGPIOPin *pin)
 Set the front‑end module enable pin.
void set_vfem_pin (InternalGPIOPin *pin)
 Set the VFEM power pin.
void set_fem_pa_pin (InternalGPIOPin *pin)
 Set the FEM PA switch pin.
void set_fem_profile (FemProfile profile)
 Set which FEM part fem_pa_pin is wired to (fem: in YAML) — selects whether the SX1262 driver drives that pin per-transmission (GC1109/KCT8103L/XY16P35) or leaves it static-HIGH (NONE, the legacy raw-pin behaviour).
void set_node_id (const std::string &id)
 Set the controller's node ID (hex string).
void set_system_key (const std::string &key)
 Set the system key (hex string).
void set_tx_power (uint8_t power)
 Set transmit power (dBm).
void set_pa_pin (uint8_t pa_pin)
 Set PA boost pin configuration.
void set_radio_type (const std::string &type)
 Set radio type ("sx1276", "sx1262", or "lr1121"); required by the YAML schema.
void set_tcxo_voltage (uint8_t voltage)
 Set the SX1262/LR1121 TCXO control-voltage code (0-based, TCXO_VOLTAGE_OPTIONS in hub_validators.py: 1_6V=0x00 .
void set_tuning_config (const TuningConfig &config)
 Apply the tuning configuration generated from YAML / UI entities.
void update_tuning_number (const std::string &name, float value)
 Receive a numeric tuning update from a HA number entity.
void update_tuning_select (const std::string &name, const std::string &value)
 Receive a select tuning update from a HA select entity.
float get_tuning_number_value (const std::string &name) const
 Current value of a numeric tuning parameter, used to seed a HA number entity on boot.
std::string get_tuning_select_value (const std::string &name) const
 Current option string of a select tuning parameter, used to seed a HA select entity on boot.
std::string describe_last_commander (const IoDevice &dev) const
 Render a device's "last commanded by" string, resolving this hub's own node ID.
void add_linked_remote (const std::string &remote_id, const std::string &device_id)
 Declare that a remote (identified by its node ID) controls a registered device.
void add_linked_remote_class (DeviceType type, const std::string &device_id)
 Declare that a device class's typed 1W broadcasts (e.g.
virtual bool apply_optimistic_target (const std::string &device_id, float target_io_position)
 Set an optimistic target position ahead of a confirming poll/response, and notify.
virtual bool apply_optimistic_stop (const std::string &device_id)
 Predict that a device has stopped (e.g.
virtual bool apply_optimistic_tilt (const std::string &device_id, float tilt_percent)
 Set an optimistic slat angle ahead of a confirming status poll, and notify.
void add_exposed_sender (const std::string &sender_id)
 Allow a 1W sender (identified by its node ID) to fire the esphome.home_io_control_sender_event event to Home Assistant.
void add_oneway_controller (const OneWayControllerIdentity &identity)
 Register a configured 1W controller identity (see oneway_controller.h).
const OneWayControllerRegistry & oneway_controllers () const
void send_oneway_command (const std::string &controller_id, CoverCommand cmd)
 Queue a 1W named command, sent as the given controller identity.
void send_oneway_position (const std::string &controller_id, uint8_t position)
 Queue a 1W numeric position, sent as the given controller identity.
void send_oneway_action (const std::string &controller_id, OneWayButtonAction action)
 Queue whichever of position/command a generated button's action resolves to.
void send_oneway_enroll (const std::string &controller_id)
 Queue a 1W enrollment for the given controller identity — the enroll button's press handler.
void send_oneway_unenroll (const std::string &controller_id)
 Queue a standalone 1W un-enrollment (remove-controller) for the given controller identity, reached only through the explicitly-named oneway_remove_controller native API action — the same 0x39 send_oneway_enroll() also fires as its own prelude, but here alone.
void add_oneway_command_report_callback (OneWayCommandReportFn callback)
 Subscribe to the report emitted after every 1W command attempt.
OneWayTransmitter & oneway_transmitter ()
const PairingTelemetry & pairing_telemetry () const
void set_pairing_result_callback (std::function< void()> cb)
 Register a callback invoked once, right after every discover_and_pair() attempt completes — used by the "Last Pairing Result" text sensor to publish a fresh value.
uint32_t device_event_count () const
const std::string & last_device_event () const
bool record_probe_reply_event (const IoFrame &reply)
 Record a diagnostic probe's reply on the "Last Device Event" sensor when it is a device event report (decisions::is_device_event_report()), such as the event a subscribe_event probe draws at once.
void set_device_event_callback (std::function< void()> cb)
 Register a callback invoked after every recorded device event, used by the "Last Device Event" text sensor.
virtual void set_key_extraction_armed (bool armed)
 Arm or disarm the "Recover System Key" (key extraction) responder.
void set_key_extraction_armed_callback (std::function< void(bool)> cb)
 Register a callback invoked whenever the key-extraction armed state changes — manual toggle, successful extraction, or auto-off timeout — so the switch entity can keep its displayed state in sync when the hub disarms itself rather than the user.
virtual void set_oneway_key_adoption_armed (bool armed)
 Arm or disarm the 1W controller-key adoption listener.
void set_oneway_key_adoption_armed_callback (std::function< void(bool)> cb)
 Register a callback invoked whenever the 1W key-adoption armed state changes — manual toggle, successful adoption, or auto-off timeout — so the switch entity stays in sync when the hub disarms itself rather than the user.
bool oneway_key_adoption_armed () const
 Whether the 1W key-adoption listener is currently armed.
void set_diagnostic_probes_enabled (bool enabled)
 Set whether DiagnosticProbes::probe_device()/probe_sweep() are allowed to run.
bool diagnostic_probes_enabled () const
 Whether diagnostic probes are enabled for this build.
virtual void add_device (const std::string &device_id)
 Add a device to the registry by device ID only (undeclared/legacy path).
virtual void add_device (const std::string &device_id, const DeviceConfig &cfg)
 Add a device to the registry with full metadata from a YAML declaration.
virtual IoDevice * get_device (const std::string &device_id)
 Retrieve a device by ID; returns nullptr if not found.
bool radio_stopped_responding () const
 True once loop() has seen the radio latch a failure after setup (a runtime BUSY timeout, for example).
virtual void set_device_travel_speed (const std::string &device_id, TravelSpeed speed)
 Select a device's travel speed at runtime (see IOHomeCoverTravelSpeedSelect and IOHomeCoverSilentSwitch).
virtual void register_device_callback (DeviceUpdateCallback cb)
 Register a callback invoked when any device updates.
virtual void set_device_status_poll_interval (const std::string &device_id, uint32_t poll_interval_ms)
 Configure the optional follow-up polling interval for a registered device.
virtual void set_device_rain_poll_interval (const std::string &device_id, uint32_t interval_ms)
 Opt a registered device into the periodic rain sensor poll (a read of its minimum limitation).
virtual void set_device_sun_poll_interval (const std::string &device_id, uint32_t interval_ms)
 Opt a registered device into the periodic sun level poll (a subscription to EVENT_LOCAL_SENSOR, whose answer carries the value; ADR 0064).
virtual void set_device_battery_level_poll_interval (const std::string &device_id, uint32_t interval_ms)
 Opt a registered device into the periodic battery level poll (a subscription to EVENT_BATTERY_LEVEL_CHANGE, whose answer carries the level; ADR 0064).
virtual void set_device_status_refresh_interval (const std::string &device_id, uint32_t interval_ms)
 Opt a registered device into the status refresh at rest: a status read whenever the device has not reported its status for a whole interval.
virtual bool set_device_position (const std::string &device_id, uint8_t position)
 Send a position command to a device.
virtual bool set_device_tilt (const std::string &device_id, uint8_t tilt_percent)
 Send a tilt command to a tilt‑capable cover.
virtual bool set_device_position_and_tilt (const std::string &device_id, uint8_t position, uint8_t tilt_percent)
 Set both position and tilt of a tilt-capable cover in one atomic command.
virtual bool request_device_status (const std::string &device_id)
 Request current status from a device.
virtual bool request_device_limitation (const std::string &device_id)
 Read the device's minimum limitation and derive its rain sensor state from the reply.
virtual bool request_device_sun_level (const std::string &device_id)
 Subscribe the device to EVENT_LOCAL_SENSOR and publish the sun value its answer carries.
virtual bool request_device_battery_level (const std::string &device_id)
 Subscribe the device to EVENT_BATTERY_LEVEL_CHANGE and publish the level its answer carries.
virtual bool request_device_name (const std::string &device_id)
 Request the stored device name from a device.
virtual ManagementActionResult rename_device (const std::string &device_id, const std::string &new_name)
 Rename a device and verify the result by reading the name back.
virtual ManagementActionResult identify_device (const std::string &device_id)
 Trigger a device's physical identify (brief jog/flash) so a user can confirm which physical motor a device ID maps to.
virtual ManagementActionResult force_open_device (const std::string &device_id)
 Move a cover device to fully open at elevated priority, intended to bypass wind/rain soft locks.
virtual ManagementActionResult scan_paired_devices ()
 Broadcast a roll-call and report every device that answers (see ManagementActions::scan_paired_devices() for the full contract: only key-holding devices answer, DeviceRegistry is never written, and zero replies is a successful result).
virtual ManagementActionResult probe_device (const std::string &device_id, const std::string &probe, const std::string &index)
 Send a single diagnostic probe frame to a registered device and report the raw reply (see DiagnosticProbes::probe_device() for the full contract, argument formats, and safety gating).
virtual ManagementActionResult probe_sweep (const std::string &device_id, const std::string &probe, const std::string &first_index, const std::string &last_index)
 Walk a bounded index range, one probe_device() call per index (see DiagnosticProbes::probe_sweep()).
virtual ManagementActionResult heating_control (const std::string &device_id, const std::string &function, const std::string &value)
 Run one 2W heating/climate function (CMD_WRITE_PRIVATE 0x20) against a registered climate device — the heating_control hub action.
virtual bool discover_and_pair ()
 Discover and pair a device that is in pairing mode.
virtual bool set_light_position (const std::string &device_id, uint8_t position)
 Send an arbitrary IO position (0-100) to a light entity.
virtual bool set_fan_position (const std::string &device_id, uint8_t position)
 Send a heat level to an exterior heater (a fan entity) as an IO position.
virtual bool set_light_state (const std::string &device_id, bool on)
 Semantic binary helper for light entities.
virtual bool set_switch_state (const std::string &device_id, bool on)
 Semantic binary helper for switch entities.
virtual bool set_lock_state (const std::string &device_id, bool locked)
 Semantic lock helper for lock entities.
virtual bool send_heating_command (const std::string &device_id, HeatingFunction fn, float value)
 Run one heating function on the heater's private register protocol (CMD_WRITE_PRIVATE 0x20): a write for a settable register, a read for a read-only one (power_on, midnight_sync).
virtual bool set_heating_level (const std::string &device_id, uint8_t level)
 Set the heating level of a heater that is commanded with levels (the plain electrical heater).
virtual bool set_heating_temperature (const std::string &device_id, uint16_t main_parameter, const HeatingFp &fp)
 Command a heater that carries a temperature or an alias in its main parameter (the heating temperature interface and the heat pump).
virtual bool set_water_heater_target (const std::string &device_id, float celsius)
 Set a water heater's target temperature.
virtual bool set_water_heater_mode (const std::string &device_id, DhwMode mode)
 Set a water heater's operating mode: a write of register 0x0006 (encode_dhw_mode_write()).
virtual bool set_water_heater_boost (const std::string &device_id, bool on)
 Start or end a water heater's boost: a duration write of register 0x0000, then an EXECUTE with the operating-mode word FP16 (DHW_OPERATING_MODE_BOOST_ON, or DHW_OPERATING_MODE_OFF to end).
virtual bool set_water_heater_away (const std::string &device_id, bool on)
 Start or end a water heater's away (holiday) mode: a duration write of register 0x0005 (255, until turned off), then an EXECUTE with FP16 DHW_OPERATING_MODE_AWAY_ON, or DHW_OPERATING_MODE_OFF to end.
virtual void set_device_temperature_range (const std::string &device_id, float min_c, float max_c)
 Set the temperature encoding range of a heater that carries a temperature in its main parameter (YAML min_temperature: / max_temperature:).
virtual bool read_heating_register (const std::string &device_id, HeatingFunction fn, float *value_out, uint8_t max_tries)
 Read one register of a heater and fold the decoded value into IoDevice::heating.
virtual void queue_set_device_position (const std::string &device_id, uint8_t position)
 Queue an async position update; returns immediately, executed in loop().
virtual bool queue_device_command (const std::string &device_id, CoverCommand cmd)
 Queue an async named command (STOP, FAVORITE, VENT, PARTIAL, PEDESTRIAN, FORCE_OPEN); returns immediately, executed in loop().
virtual void queue_set_device_tilt (const std::string &device_id, uint8_t tilt_percent)
 Queue an async tilt update; returns immediately, executed in loop().
virtual void queue_set_device_position_and_tilt (const std::string &device_id, uint8_t position, uint8_t tilt_percent)
 Queue an async combined position+tilt update; returns immediately, executed in loop().
virtual void queue_request_device_status (const std::string &device_id)
 Queue an async status request; returns immediately, executed in loop().
virtual void queue_request_device_limitation (const std::string &device_id)
 Queue an async minimum-limitation read for the rain sensor poll; executed in loop() as a background operation (yields to commands and 1W activity).
virtual void queue_request_device_sun_level (const std::string &device_id)
 Queue an async sun level poll; executed in loop() as a background operation.
virtual void queue_request_device_battery_level (const std::string &device_id)
 Queue an async battery level poll; executed in loop() as a background operation.
virtual void queue_request_device_name (const std::string &device_id)
 Queue an async device-name request; returns immediately, executed in loop().
virtual void queue_discover_and_pair ()
 Queue a pairing operation; executed in loop() when radio idle.
void trigger_scan_paired_devices ()
 Entry point for the "Scan Paired Devices" button: run the roll-call and publish its report to the log and the Home Assistant result event, exactly as the native API action does.
virtual void queue_set_light_position (const std::string &device_id, uint8_t position)
 Async form of set_light_position() that keeps radio work serialized on the main loop.
virtual void queue_set_fan_position (const std::string &device_id, uint8_t position)
 Async form of set_fan_position() that keeps radio work serialized on the main loop.
virtual void queue_set_light_state (const std::string &device_id, bool on)
 Async form of set_light_state() that keeps radio work serialized on the main loop.
virtual void queue_set_switch_state (const std::string &device_id, bool on)
 Async form of set_switch_state() that keeps radio work serialized on the main loop.
virtual void queue_set_lock_state (const std::string &device_id, bool locked)
 Async form of set_lock_state() that keeps radio work serialized on the main loop.
Public Member Functions inherited from esphome::home_io_control::SpiAccess
virtual ~SpiAccess ()=default

Protected Types

enum class  EventReading : uint8_t { SUN_LEVEL , BATTERY_LEVEL }
 The two subscription-answer sensor polls (ADR 0064). More...
enum class  RequestResult : uint8_t { FAILED , UNCONFIRMED , ERROR_REPLY , REPLY }
 What exchange_and_record_() found. More...

Protected Member Functions

bool transmit_frame_ (const IoFrame &frame, uint32_t freq, uint16_t preamble)
 Transmit a raw IoFrame on the current frequency with given preamble length.
ExchangeOutcome send_and_receive_ (const IoFrame &request, IoFrame &response, uint32_t freq, const decisions::AttemptRequest &attempts=EXCHANGE_RETRY_COUNT)
 Main request/response exchange with retry and automatic authentication.
bool authenticate_request_ (const IoFrame &request, uint32_t freq)
 Handle an inbound authenticated command from a device (status updates, etc.).
void process_received_packet_ (const RadioRxPacket &packet)
 Parse a received frame, merge supported device state or metadata, and notify callbacks.
void apply_status_update_ (const std::string &id, IoDevice &dev, const IoFrame &frame)
 Handle an authenticated CMD_STATUS_UPDATE from a registered device: a device event report (decisions::is_device_event_report()) is recorded, any other 0x71 is applied as a position update.
bool record_if_device_event_ (const IoFrame &frame, bool reached_unhandled_fallback)
 Record frame as a device event when it qualifies: its source is a registered device and it is either a device event report (decisions::is_device_event_report()), or any frame that reached the unhandled-command fallback while diagnostic_probes is on.
void record_device_event_ (const IoFrame &frame)
 Record a device event report, or a frame from a registered device that nothing else here handles: log it raw, count it, and publish it on the "Last Device Event" sensor.
bool key_extraction_awaiting_reply_ () const
 True while the key-extraction responder is mid-attempt and still within its bounded listen window.
void listen_for_key_extraction_peer_ ()
 One idle pass of listening for the key-extraction responder's peer, in place of the generic idle hop while key_extraction_awaiting_reply_().
void update_device_status_ (const IoFrame &frame, bool trust_position=true)
 Extract supported position or metadata info from a response frame and merge it into the device record.
void note_status_reported_ (const std::string &device_id)
 The device just reported its status: move its status refresh (if it has one) a whole interval out.
void record_1w_activity_ (uint32_t now)
 Record that a 1W frame just went out on the radio — ours or someone else's — updating last_1w_activity_ms_ and — when this frame starts a new burst (see decisions::oneway_burst_started_fresh()) — first_1w_activity_ms_.
void record_oneway_pairing_gesture_ (const IoFrame &frame, uint32_t now)
 If frame matches a 1W remote's pairing gesture (decisions::is_one_way_pairing_gesture()), remember it (src/dst/cmd plus the radio's last-capture RSSI) in recent_oneway_pairing_sighting_ so a fresh discover_and_pair() attempt can seed its telemetry with it — see RecentOneWayPairingSighting's doc comment (issue #27/#65).
void schedule_status_poll_ (const std::string &device_id, uint32_t delay_ms)
 Schedule a delayed status poll for a registered device using the Component timeout API.
void schedule_heating_poll_ (const std::string &device_id, uint32_t delay_ms)
 Arm the heater's regular-cadence poll timer.
void begin_status_poll_tracking_ (const std::string &device_id, uint32_t initial_delay_ms)
 Begin bounded follow-up polling for a device after a command or overheard remote activity.
void settle_ended_status_tracking_ ()
 Settle every device whose polling window ran out (StatusPollPolicy::pop_ended_device()).
void arm_execute_confirmation_poll_ (const std::string &device_id, bool for_stop)
 Arm the confirming poll that follows a command, because a CMD_EXECUTE reply is never trusted for position (see update_device_status_()'s trust_position parameter) and therefore leaves the hub with no idea where the device actually is.
void schedule_device_polls_ (const std::vector< std::string > &device_ids, uint32_t delay_ms)
 Schedule status polls for a fixed list of devices (shared by the id-linked and class-linked 1W paths).
bool defer_background_poll_ () const
 Whether loop() should skip dispatching the queue this iteration because the pending work is a background poll and either a 1W remote transmitted very recently, or a key-extraction attempt is mid-flight.
void act_on_foreign_frame_ (const std::string &device_id, ForeignFrameKind kind, const std::string &controller, uint8_t cmd)
 Decide, and act on, what a frame of another controller means for one registered device: a heard write, or a device challenge that follows no heard read, arms a tracked poll; any other frame arms one only if the device was not read recently (StatusPollPolicy::on_foreign_frame()); while such a poll is pending the frame only pushes its timer out.
void note_foreign_challenge_ (const IoFrame &frame)
 Hand a registered device's challenge (0x3C) to another controller to act_on_foreign_frame_().
bool act_on_overheard_request_ (const IoFrame &frame)
 Hand another controller's frame to act_on_foreign_frame_(): per the registered device it is addressed to, or per device linked to its source when that is a linked 2W controller.
std::vector< std::string > resolve_1w_target_devices_ (const OneWayFrameInfo &info, const std::string &src_id) const
 Resolve the set of devices a 1W frame should affect: devices linked to the sending remote by node ID, plus — when the frame targets a typed broadcast (e.g.
bool apply_optimistic_linked_state_ (const OneWayFrameInfo &info, const std::vector< std::string > &device_ids)
 Apply optimistic target state to every device in device_ids, when the decoded frame carries a resolvable intent.
void follow_linked_remote_press_ (const OneWayFrameInfo &info, const std::string &src_id)
 React to a deduplicated 1W press from a remote: apply the optimistic state to the devices it controls (resolve_1w_target_devices_()), schedule their status polls (at once after a STOP, otherwise after remote_activity_poll_delay_ms) and, when switched on, open the catch-up burst (StatusPollPolicy::on_linked_remote_activity(), ADR 0080).
void maybe_fire_sender_event_ (const OneWayFrameInfo &info, bool linked, const std::string &src_id)
 Fire the sender HA event for a decoded 1W frame, if the sender is exposed.
bool handle_error_response_ (const std::string &device_id, const IoFrame &request, const IoFrame &response, uint32_t retry_after_fail_ms)
 Handle an explicit CMD_ERROR_RESP refusal from the device: record the result code, stamp link health, and schedule the poll backoff.
void apply_rain_poll_result_ (const std::string &device_id, RainSensorState reading, const std::string &limit_text, bool unanswered)
 Fold one rain poll outcome into the device's rain sensor state and tell subscribers.
bool request_event_reading_ (const std::string &device_id, EventReading kind)
 Shared body of request_device_sun_level() and request_device_battery_level(): defer while the device moves, subscribe, decode the answer, fold the result into the device record.
PeriodicPollPolicy & event_reading_policy_ (EventReading kind)
 The schedule of kind's poll.
void apply_event_reading_ (const std::string &device_id, EventReading kind, const std::optional< uint16_t > &reading, bool unanswered)
 Fold one poll outcome into the device record: a reading replaces the value and clears the miss count; a miss keeps the last value until PERIODIC_POLL_FAILURES_BEFORE_UNKNOWN.
void queue_due_periodic_polls_ ()
 Queue every periodic poll that is due: the sensor polls (rain, sun level, battery level) and the status refresh at rest.
void queue_due_catchup_reads_ ()
 Read every device with linked_remotes once, when a burst of linked-remote activity has been followed by remote_activity_catchup_poll_ms without an exchange (ADR 0080).
ExchangeOutcome exchange_past_device_event_ (const IoFrame &request, IoFrame &response, const decisions::AttemptRequest &attempts)
 send_and_receive_() on the command channel, except that a device event report (decisions::is_device_event_report()) taken as the reply is recorded (record_device_event_()) and the request asked once more; a second report in a row, or one answering an EXECUTE that is not safe to repeat, ends it as FAILED.
RequestResult exchange_and_record_ (const std::string &device_id, const IoFrame &request, IoFrame &response, const RequestOptions &options)
 Run one authenticated request/response exchange on the standard command channel and record its outcome: exchange-outcome and timeout counters, link health, challenge-seen handling, CMD_ERROR_RESP handling, debug logs and (when requested) the status-poll backoff.
bool execute_request_and_update_ (const std::string &device_id, const IoFrame &request, bool warn_on_no_response, uint32_t retry_after_fail_ms=0, const decisions::AttemptRequest &attempts=EXCHANGE_RETRY_COUNT)
 Shared request/response helper for high-level operations: exchange_and_record_() plus update_device_status_() on a reply.
bool run_execute_operation_ (const std::string &device_id, const ExecuteRequestSpec &spec, const std::function< bool(const IoDevice &)> &accepts, const char *rejection_profile, const std::function< bool(IoFrame &, const IoDevice &)> &build)
 Funnel for the four execute-family operations: runs try_execute_operation_() and, on any false return (the command will not reach the device), withdraws the optimistic prediction the entity applied at control() time via DeviceRegistry::rollback_optimistic().
bool try_execute_operation_ (const std::string &device_id, const ExecuteRequestSpec &spec, const std::function< bool(const IoDevice &)> &accepts, const char *rejection_profile, const std::function< bool(IoFrame &, const IoDevice &)> &build)
 Shared skeleton for the four execute-family operations (position, named command, tilt, position+tilt): device lookup + initialized guard, capability guard, poll-tracking start, "Sending ..." log, frame build, exchange, failure backoff, and the settle poll.
decisions::AttemptRequest cover_poll_attempts_ (const std::string &device_id, bool scheduler_managed, bool state_unknown=false)
 Attempts for a cover's status read: its read kind (a settling read or a look at a busy device, decisions::scheduled_poll_read_kind()), consuming the poll's STOP and confirming-read marks.
decisions::AttemptRequest heater_poll_attempts_ (const std::string &device_id, bool scheduler_managed)
 Attempts for a heater's status read: the count-based budget heaters keep (decisions::scheduled_poll_max_tries()).
bool execute_device_command_ (const std::string &device_id, CoverCommand cmd)
 Execute a named device command (STOP, FAVORITE, VENT, PARTIAL, PEDESTRIAN, FORCE_OPEN) via the authenticated exchange.
template<typename F>
void execute_oneway_ (F &&send)
 Shared bookkeeping for every 1W transmit: mark the radio busy for the duration of send, then record it as 1W activity so background polls back off for it exactly as they do for a remote's burst — the radio is equally busy either way.
void execute_oneway_command_ (const std::string &controller_id, CoverCommand cmd)
 Send a queued 1W named command.
void execute_oneway_position_ (const std::string &controller_id, uint8_t position)
 Send a queued 1W numeric position.
void execute_oneway_enroll_ (const std::string &controller_id)
 Send a queued 1W enrollment (add-controller).
void execute_oneway_unenroll_ (const std::string &controller_id)
 Send a queued 1W un-enrollment (remove-controller).
void notify_device_update_ (const std::string &id)
 Fire all registered device update callbacks for the given device ID.
void schedule_background_poll_backoff_ (const std::string &device_id, bool auth_like, bool device_moving=false)
 Apply backoff after a failed background status poll and log the result.
bool exchange_heating_ (const std::string &device_id, const char *label, const IoFrame &request, IoFrame &response, uint8_t max_tries)
 The exchange every heating frame shares: send on the command channel, record the outcome (exchange counters, link health, error result code), notify the entities and report whether the device answered with CMD_WRITE_PRIVATE_ACK.
bool read_private_register_ (const std::string &device_id, uint8_t reg_hi, uint8_t reg_lo, const char *label, IoFrame &response, uint8_t max_tries)
 Read one private register raw: build the read request, run exchange_heating_() and check that the reply echoes the register.
void check_heater_model_ (const std::string &device_id, uint8_t max_tries)
 The one-off model check of a heater kind that has model rows (device_offers_models()).
void poll_programme_period_ (const std::string &device_id, const HeatingProfile &profile, uint8_t max_tries)
 Read the temperature in force of a heater's programme, when the programme runs.
bool poll_heating_device_ (const std::string &device_id)
 Poll a heater: read its profile's poll registers (stopping at the first failure), then the programme's temperature in force (poll_programme_period_()), then its boot registers until each has been read once, then, on a heater kind with model rows, the one-off model check (check_heater_model_()) once the device has answered a read.
bool read_dhw_register_ (const std::string &device_id, uint8_t index, const char *label, IoFrame &response, uint8_t max_tries)
 Read one family-0x00 register of a water heater raw (read_private_register_() gated on device_feature::WATER_HEATER).
bool read_dhw_reading_ (const std::string &device_id, uint8_t index, uint8_t max_tries)
 Read one family-0x00 register of a water heater and fold its value into IoDevice::dhw.
bool read_dhw_status_ (const std::string &device_id, uint8_t max_tries)
 Read a water heater's target, capabilities and boost and away state: the status read DHW_STATUS_FPI1 / DHW_STATUS_FPI2 (create_status_mp_fp_read()), whose reply update_device_status_() folds into IoDevice::dhw.
bool write_dhw_register_ (const std::string &device_id, const char *operation, uint8_t index, const uint8_t *payload, size_t payload_len)
 Write one family-0x00 register of a water heater, then read it back.
bool set_dhw_operating_mode_ (const std::string &device_id, DhwOperatingFeature which, bool on)
 Switch a water heater's boost or away through the operating-mode word (ADR 0081).
const IoDevice * water_heater_for_write_ (const std::string &device_id, const char *operation)
 The water heater device_id names, or nullptr when it is unknown, the hub is not set up yet, or the device is no water heater (that case is logged).
bool execute_dhw_ (const std::string &device_id, const char *action, const std::function< bool(IoFrame &, const IoDevice &)> &build)
 Send one water heater EXECUTE (target or operating mode) through try_execute_operation_(), which gates on device_feature::WATER_HEATER and arms the settle poll; on acceptance the next poll moves to HEATING_POST_WRITE_POLL_DELAY_MS from now so the heating state follows.
bool poll_dhw_device_ (const std::string &device_id)
 Poll a water heater: the status read for its target, capabilities and boost and away state (read_dhw_status_()), then its water temperature, mode, heating state, boost and away duration and energy registers (stopping at the first failure), then its brand until it has been read once (logged at INFO).
void process_pending_operation_ ()
 Pop next pending operation from the queue and execute it (set position, request status, discover).
void log_exchange_debug_ (const char *device_id) const
 Log the last exchange debug snapshot (delegates to exchange_engine_).
void log_exchange_unconfirmed_debug_ (const char *device_id) const
 Log the last exchange debug snapshot for an accepted-but-unconfirmed exchange, at INFO.
void apply_tuning_to_radio_ ()
 Apply the current tuning configuration to the active radio driver.
void resolve_start_preamble_default_ ()
 Resolve normal_start_preamble from the driver when YAML did not set it (ADR 0042).
void register_management_actions_ ()
 Register hub-level Home Assistant actions; called from setup().
void api_rename_device_ (const std::string &device_id, const std::string &new_name)
 Native API callback: rename a registered device.
void api_identify_device_ (const std::string &device_id)
 Native API callback: trigger a registered device's physical identify.
void api_force_open_device_ (const std::string &device_id)
 Native API callback: force-open a registered cover device.
void api_scan_paired_devices_ ()
 Native API callback: broadcast a roll-call scan of already-paired devices.
void api_oneway_set_position_ (const std::string &controller_id, const std::string &position)
 Native API callback: queue a 1W position for a controller identity.
void api_oneway_remove_controller_ (const std::string &controller_id)
 Native API callback: queue a 1W un-enrollment (remove-controller) for a controller identity.
void api_probe_device_ (const std::string &device_id, const std::string &probe, const std::string &index)
 Native API callback: run a single diagnostic probe against a registered device.
void api_probe_sweep_ (const std::string &device_id, const std::string &probe, const std::string &first_index, const std::string &last_index)
 Native API callback: run a bounded diagnostic probe sweep against a registered device.
void api_heating_control_ (const std::string &device_id, const std::string &function, const std::string &value)
 Native API callback: run a heating/climate function (CMD_WRITE_PRIVATE 0x20) against a registered climate device.
void hop_frequency_ ()
 Delegate channel hop to ExchangeEngine (which owns last_hop_us_).
RadioDriver * select_and_construct_radio_ (const char **chip_name_out)
 Select and construct the radio driver named by the required radio_type config field.
void dump_oneway_controllers_config_ () const
 Emit the 1W controller identities to the config dump — node, class, and the resolved ACEI / broadcast (ADR 0031).

Protected Attributes

RadioDriver * radio_ {nullptr}
InternalGPIOPin * rst_pin_ {nullptr}
InternalGPIOPin * dio0_pin_ {nullptr}
 SX1276 DIO0 interrupt.
InternalGPIOPin * dio4_pin_ {nullptr}
 SX1276 DIO4 preamble detect (optional).
InternalGPIOPin * dio1_pin_ {nullptr}
 SX1262 DIO1 interrupt; also carries the LR1121's DIO9 IRQ line.
InternalGPIOPin * busy_pin_ {nullptr}
 SX1262/LR1121 BUSY pin.
InternalGPIOPin * fem_en_pin_ {nullptr}
 Front-end module enable.
InternalGPIOPin * vfem_pin_ {nullptr}
 Front-end module power.
InternalGPIOPin * fem_pa_pin_ {nullptr}
 Front-end module PA switch.
FemProfile fem_profile_ {FemProfile::NONE}
 Which FEM part fem_pa_pin_ belongs to, if any.
std::string node_id_str_
std::string system_key_str_
std::string radio_type_
 "sx1276", "sx1262", or "lr1121"; required by the YAML schema.
std::string radio_failure_reason_
 Why setup() gave up on the radio, or empty.
bool radio_failure_reported_ {false}
 Set once loop() has reported a radio that latched a failure after setup, so the report (an error line, ESPHome's warning status and a republish of every device) is made once, not on every loop.
uint8_t node_id_ [NODE_ID_SIZE] {}
uint8_t system_key_ [AES_KEY_SIZE] {}
uint8_t tx_power_ {DEFAULT_TX_POWER_DBM}
uint8_t pa_pin_ {DEFAULT_PA_PIN_PA_BOOST}
uint8_t tcxo_voltage_ {DEFAULT_TCXO_VOLTAGE_SETTING_1P8V}
 SX1262/LR1121 TCXO voltage setting (default 1.8 V).
bool initialized_ {false}
bool busy_ {false}
uint32_t last_pairing_end_ms_ {0}
 millis() when the last pairing attempt ended; 0 before the first one (see queue_discover_and_pair()).
bool radio_test_mode_ {false}
 When true, loop() is suspended for loopback testing.
TuningConfig tuning_ {}
 Runtime tuning overrides.
DeviceRegistry registry_
std::vector< std::string > exposed_senders_
 1W sender node IDs (remotes or sensors) allowed to fire the sender HA event (add_exposed_sender).
std::function< void()> pairing_result_callback_
 Invoked once after every pairing attempt completes; see set_pairing_result_callback().
uint32_t device_event_count_ {0}
 Device events recorded since boot, the last one's text and its subscriber; see record_device_event_().
std::string last_device_event_
std::function< void()> device_event_callback_
bool diagnostic_probes_enabled_ {false}
 Whether diagnostic probes (DiagnosticProbes::probe_device()/probe_sweep()) are enabled.
StatusPollPolicy poll_policy_
PeriodicPollPolicy rain_poll_policy_
 Schedule of the opt-in rain sensor poll.
PeriodicPollPolicy sun_poll_policy_
 Schedule of the opt-in sun level poll.
PeriodicPollPolicy battery_level_poll_policy_
 Schedule of the opt-in battery level poll.
PeriodicPollPolicy status_refresh_policy_
 Schedule of the opt-in status refresh at rest.
OperationQueue op_queue_
PairingTelemetry pairing_telemetry_
 Per-attempt pairing telemetry.
RecentOneWayPairingSighting recent_oneway_pairing_sighting_ {}
 Most recent 1W pairing-gesture frame seen on the hub's normal passive RX path (e.g.
ExchangeEngine exchange_engine_
 Owns all authenticated exchange and LBT/hop logic.
PairingEngine pairing_engine_
 Owns the three-phase device pairing flow.
ManagementActions management_actions_
 Owns rename, identify, force-open, scan_paired_devices, and other hub-level HA actions.
OneWayTransmitter oneway_transmitter_
 Owns the 1W controller identities, their rolling-sequence counters and the transmit burst.
OnewayKeyAdoption oneway_key_adoption_
 Opt-in, receive-only 1W controller-key adoption listener (oneway_key_adoption.cpp).
KeyExtractionResponder key_extraction_
 Device-role responder for the "Recover System Key" feature (key_extraction_responder.cpp).
std::vector< OneWayCommandReportFn > oneway_report_callbacks_
 Subscribers to the per-command 1W report; one per "Last 1W Command" sensor.
decisions::OneWayDedupState last_1w_logged_ {}
 Identity of the last processed 1W frame, for burst suppression; see decisions::is_duplicate_1w_frame() for why the intent bytes are part of the key.
uint32_t last_1w_activity_ms_ {0}
 millis() of the most recent 1W frame of any kind, including ones dropped as duplicates — a repeat still means the remote is transmitting.
uint32_t first_1w_activity_ms_ {0}
 millis() of the first 1W frame in the current burst.

Detailed Description

The main IO-Homecontrol component.

Manages the protocol layer and delegates radio operations to a RadioDriver instance.

Inherits SPIDevice so that ESPHome's Python codegen can configure SPI pins. Implements SpiAccess to provide the radio driver with SPI bus access.

Definition at line 96 of file hub_core.h.

Member Typedef Documentation

◆ ManagementActionResult

Result payload used by hub-level management actions such as rename.

Alias of the standalone esphome::home_io_control::ManagementActionResult struct so that callers using the nested name IOHomeControlComponent::ManagementActionResult continue to work.

Definition at line 167 of file hub_core.h.

Member Enumeration Documentation

◆ EventReading

The two subscription-answer sensor polls (ADR 0064).

Enumerator
SUN_LEVEL 

EVENT_LOCAL_SENSOR, IoDevice::sun_level.

BATTERY_LEVEL 

EVENT_BATTERY_LEVEL_CHANGE, IoDevice::battery_level.

Definition at line 1157 of file hub_core.h.

◆ RequestResult

What exchange_and_record_() found.

Enumerator
FAILED 

No usable reply (silence, or an unconfirmed acceptance of a request that needs a payload).

UNCONFIRMED 

A CMD_EXECUTE the device accepted but never closed; counted as success, no reply frame.

ERROR_REPLY 

The device refused with CMD_ERROR_RESP; handle_error_response_() has recorded it.

REPLY 

The device answered; the caller interprets the reply frame.

Definition at line 1195 of file hub_core.h.

Constructor & Destructor Documentation

◆ IOHomeControlComponent()

esphome::home_io_control::IOHomeControlComponent::IOHomeControlComponent ( )
inline

Initialize ExchangeEngine, PairingEngine, and ManagementActions with double-pointer/ reference indirection so that test assignments (comp.radio_ = &mock) propagate through all collaborators without calling setup().

Definition at line 105 of file hub_core.h.

Here is the call graph for this function:

Member Function Documentation

◆ act_on_foreign_frame_()

void esphome::home_io_control::IOHomeControlComponent::act_on_foreign_frame_ ( const std::string & device_id,
ForeignFrameKind kind,
const std::string & controller,
uint8_t cmd )
protected

Decide, and act on, what a frame of another controller means for one registered device: a heard write, or a device challenge that follows no heard read, arms a tracked poll; any other frame arms one only if the device was not read recently (StatusPollPolicy::on_foreign_frame()); while such a poll is pending the frame only pushes its timer out.

A frame that arms nothing changes neither the tracking window nor the failure streaks.

Parameters
device_idRegistered device the frame concerns.
kindRequest to the device, or the device's challenge to another controller.
controllerThe other controller's node ID (request source, or challenge destination).
cmdCommand of the heard frame.

Definition at line 552 of file hub_status.cpp.

Here is the call graph for this function:

◆ act_on_overheard_request_()

bool esphome::home_io_control::IOHomeControlComponent::act_on_overheard_request_ ( const IoFrame & frame)
protected

Hand another controller's frame to act_on_foreign_frame_(): per the registered device it is addressed to, or per device linked to its source when that is a linked 2W controller.

Parameters
frameA parsed 2W frame that is not a status reply.
Returns
true when the frame was another controller's request and has been handled.

Definition at line 593 of file hub_status.cpp.

Here is the call graph for this function:

◆ add_device() [1/2]

void esphome::home_io_control::IOHomeControlComponent::add_device ( const std::string & device_id)
virtual

Add a device to the registry by device ID only (undeclared/legacy path).

Type, subtype and optimistic_state default to UNKNOWN / 0 / true, with no overrides; use the DeviceConfig overload when metadata comes from a YAML declaration.

Parameters
device_idHexadecimal node ID string.

Definition at line 396 of file hub_core.cpp.

Here is the call graph for this function:

◆ add_device() [2/2]

void esphome::home_io_control::IOHomeControlComponent::add_device ( const std::string & device_id,
const DeviceConfig & cfg )
virtual

Add a device to the registry with full metadata from a YAML declaration.

Parameters
device_idHexadecimal node ID string.
cfgDevice type/subtype/overrides/optimistic-state metadata.

Definition at line 398 of file hub_core.cpp.

Here is the call graph for this function:

◆ add_exposed_sender()

void esphome::home_io_control::IOHomeControlComponent::add_exposed_sender ( const std::string & sender_id)
inline

Allow a 1W sender (identified by its node ID) to fire the esphome.home_io_control_sender_event event to Home Assistant.

"Sender" is deliberately broader than "remote": the same 1W broadcast mechanism carries handheld/wall remotes and wind/rain sensors alike (they differ only in the originator byte inside the payload, not in how they address the radio) — see decode_1w_frame(). Overheard 1W traffic is always DEBUG-logged regardless of this list; this only controls which senders are allowed to reach Home Assistant as an event, independent of whether the sender is also linked to a device via add_linked_remote. Empty by default — a sender must be explicitly opted in.

Parameters
sender_idNode ID of the 1W sender (remote or sensor).

Definition at line 323 of file hub_core.h.

◆ add_linked_remote()

void esphome::home_io_control::IOHomeControlComponent::add_linked_remote ( const std::string & remote_id,
const std::string & device_id )
inline

Declare that a remote (identified by its node ID) controls a registered device.

When activity from this remote is overheard, a status poll is scheduled for the device. This is needed for 1W remotes whose destination address differs from the device's 2W ID.

Parameters
remote_idNode ID of the remote control.
device_idNode ID of the device it controls.

Definition at line 266 of file hub_core.h.

Here is the call graph for this function:

◆ add_linked_remote_class()

void esphome::home_io_control::IOHomeControlComponent::add_linked_remote_class ( DeviceType type,
const std::string & device_id )
inline

Declare that a device class's typed 1W broadcasts (e.g.

"all awnings") also apply to device_id, matching how 1W remotes address a device class rather than a single node.

Parameters
typeDevice class the broadcast targets.
device_idNode ID of the device to add to that class.

Definition at line 274 of file hub_core.h.

Here is the call graph for this function:

◆ add_oneway_command_report_callback()

void esphome::home_io_control::IOHomeControlComponent::add_oneway_command_report_callback ( OneWayCommandReportFn callback)
inline

Subscribe to the report emitted after every 1W command attempt.

A list rather than a single slot: each identity gets its own "Last 1W Command" sensor, and each filters the reports down to its own handle.

Parameters
callbackInvoked for every attempt, successful or not.

Definition at line 403 of file hub_core.h.

◆ add_oneway_controller()

void esphome::home_io_control::IOHomeControlComponent::add_oneway_controller ( const OneWayControllerIdentity & identity)
inline

Register a configured 1W controller identity (see oneway_controller.h).

Called once per oneway_controllers: entry from generated code. Both the source address and the key are already resolved at schema time — a derived address is computed there so a collision with the hub's own address or another identity fails the build rather than silently desyncing a transmitter at runtime.

Parameters
identityFully-resolved controller identity.

Definition at line 331 of file hub_core.h.

Here is the call graph for this function:

◆ api_force_open_device_()

void esphome::home_io_control::IOHomeControlComponent::api_force_open_device_ ( const std::string & device_id)
inlineprotected

Native API callback: force-open a registered cover device.

Definition at line 1499 of file hub_core.h.

Here is the call graph for this function:

◆ api_heating_control_()

void esphome::home_io_control::IOHomeControlComponent::api_heating_control_ ( const std::string & device_id,
const std::string & function,
const std::string & value )
inlineprotected

Native API callback: run a heating/climate function (CMD_WRITE_PRIVATE 0x20) against a registered climate device.

Definition at line 1523 of file hub_core.h.

Here is the call graph for this function:

◆ api_identify_device_()

void esphome::home_io_control::IOHomeControlComponent::api_identify_device_ ( const std::string & device_id)
inlineprotected

Native API callback: trigger a registered device's physical identify.

Definition at line 1497 of file hub_core.h.

Here is the call graph for this function:

◆ api_oneway_remove_controller_()

void esphome::home_io_control::IOHomeControlComponent::api_oneway_remove_controller_ ( const std::string & controller_id)
inlineprotected

Native API callback: queue a 1W un-enrollment (remove-controller) for a controller identity.

Definition at line 1509 of file hub_core.h.

Here is the call graph for this function:

◆ api_oneway_set_position_()

void esphome::home_io_control::IOHomeControlComponent::api_oneway_set_position_ ( const std::string & controller_id,
const std::string & position )
inlineprotected

Native API callback: queue a 1W position for a controller identity.

Definition at line 1505 of file hub_core.h.

Here is the call graph for this function:

◆ api_probe_device_()

void esphome::home_io_control::IOHomeControlComponent::api_probe_device_ ( const std::string & device_id,
const std::string & probe,
const std::string & index )
inlineprotected

Native API callback: run a single diagnostic probe against a registered device.

Definition at line 1513 of file hub_core.h.

Here is the call graph for this function:

◆ api_probe_sweep_()

void esphome::home_io_control::IOHomeControlComponent::api_probe_sweep_ ( const std::string & device_id,
const std::string & probe,
const std::string & first_index,
const std::string & last_index )
inlineprotected

Native API callback: run a bounded diagnostic probe sweep against a registered device.

Definition at line 1517 of file hub_core.h.

Here is the call graph for this function:

◆ api_rename_device_()

void esphome::home_io_control::IOHomeControlComponent::api_rename_device_ ( const std::string & device_id,
const std::string & new_name )
inlineprotected

Native API callback: rename a registered device.

Definition at line 1493 of file hub_core.h.

Here is the call graph for this function:

◆ api_scan_paired_devices_()

void esphome::home_io_control::IOHomeControlComponent::api_scan_paired_devices_ ( )
inlineprotected

Native API callback: broadcast a roll-call scan of already-paired devices.

Definition at line 1503 of file hub_core.h.

Here is the call graph for this function:

◆ apply_event_reading_()

void esphome::home_io_control::IOHomeControlComponent::apply_event_reading_ ( const std::string & device_id,
EventReading kind,
const std::optional< uint16_t > & reading,
bool unanswered )
protected

Fold one poll outcome into the device record: a reading replaces the value and clears the miss count; a miss keeps the last value until PERIODIC_POLL_FAILURES_BEFORE_UNKNOWN.

Logs a change at INFO and tells subscribers in every case.

Parameters
device_idTarget device ID.
kindWhich reading.
readingThe decoded value of an answered poll, empty for a miss.
unansweredTrue when the device sent nothing back at all, so the miss is retried once after PERIODIC_POLL_MISS_RETRY_MS before it counts.

Definition at line 747 of file hub_operations.cpp.

Here is the call graph for this function:

◆ apply_optimistic_linked_state_()

bool esphome::home_io_control::IOHomeControlComponent::apply_optimistic_linked_state_ ( const OneWayFrameInfo & info,
const std::vector< std::string > & device_ids )
protected

Apply optimistic target state to every device in device_ids, when the decoded frame carries a resolvable intent.

Skips devices whose known type doesn't match the frame's typed-broadcast target (an "all awnings" press must not optimistically move a linked shutter — it is still polled by schedule_device_polls_()). No-op per device when that device has optimistic_state == false (see DeviceRegistry::apply_optimistic_target()).

Parameters
infoAlready-decoded 1W frame info (see decode_1w_frame()).
device_idsDevices to apply optimistic state to (see resolve_1w_target_devices_()).
Returns
true if the intent resolved to a STOP (caller should poll immediately).

Definition at line 644 of file hub_status.cpp.

Here is the call graph for this function:

◆ apply_optimistic_stop()

virtual bool esphome::home_io_control::IOHomeControlComponent::apply_optimistic_stop ( const std::string & device_id)
inlinevirtual

Predict that a device has stopped (e.g.

on STOP), and notify. No-op when the device is unknown or has optimistic_state == false. See DeviceRegistry::apply_optimistic_stop() for why this records a prediction rather than a clear. Restorable: if the STOP then fails, the movement prediction it replaced comes back. Virtual (like add_device/get_device) so platform unit tests can substitute a mock registry.

Parameters
device_idTarget device ID.
Returns
true if the optimistic stop was applied.

Definition at line 296 of file hub_core.h.

Here is the call graph for this function:

◆ apply_optimistic_target()

virtual bool esphome::home_io_control::IOHomeControlComponent::apply_optimistic_target ( const std::string & device_id,
float target_io_position )
inlinevirtual

Set an optimistic target position ahead of a confirming poll/response, and notify.

No-op when the device is unknown or has optimistic_state == false. See DeviceRegistry::apply_optimistic_target() for the full contract. Virtual (like add_device/get_device) so platform unit tests can substitute a mock registry.

Parameters
device_idTarget device ID.
target_io_positionTarget position in IO units (0=open, 100=closed).
Returns
true if the optimistic state was applied.

Definition at line 285 of file hub_core.h.

Here is the call graph for this function:

◆ apply_optimistic_tilt()

virtual bool esphome::home_io_control::IOHomeControlComponent::apply_optimistic_tilt ( const std::string & device_id,
float tilt_percent )
inlinevirtual

Set an optimistic slat angle ahead of a confirming status poll, and notify.

No-op when the device is unknown, has optimistic_state == false, or is not tilt-capable. See DeviceRegistry::apply_optimistic_tilt() for the full contract and for why a tilt command cannot rely on its own reply the way a position command can. Virtual like the other device-registry accessors so a test double can override it if it needs to; MockPlatformHubBase deliberately does not, and exercises the real registry.

Parameters
device_idTarget device ID.
tilt_percentSlat angle in the same percent scale as IoDevice::tilt (0-100).
Returns
true if the optimistic tilt was applied.

Definition at line 310 of file hub_core.h.

Here is the call graph for this function:

◆ apply_rain_poll_result_()

void esphome::home_io_control::IOHomeControlComponent::apply_rain_poll_result_ ( const std::string & device_id,
RainSensorState reading,
const std::string & limit_text,
bool unanswered )
protected

Fold one rain poll outcome into the device's rain sensor state and tell subscribers.

Parameters
device_idTarget device ID.
readingDRY or RAIN for an answered poll, UNKNOWN for a miss.
limit_textRendering of the reported limit for the state-change log, empty for a miss.
unansweredTrue when the device sent nothing usable back at all (no reply, no error), so the miss is retried once after PERIODIC_POLL_MISS_RETRY_MS before it counts.

Definition at line 629 of file hub_operations.cpp.

Here is the call graph for this function:

◆ apply_status_update_()

void esphome::home_io_control::IOHomeControlComponent::apply_status_update_ ( const std::string & id,
IoDevice & dev,
const IoFrame & frame )
protected

Handle an authenticated CMD_STATUS_UPDATE from a registered device: a device event report (decisions::is_device_event_report()) is recorded, any other 0x71 is applied as a position update.

Parameters
idThe device's node ID string.
devThe device record.
frameThe status update.

Definition at line 698 of file hub_status.cpp.

Here is the call graph for this function:

◆ apply_tuning_to_radio_()

void esphome::home_io_control::IOHomeControlComponent::apply_tuning_to_radio_ ( )
protected

Apply the current tuning configuration to the active radio driver.

Only chip-specific parameters are forwarded; the rest are consumed by the pairing flow and LBT logic. This is called once at the end of setup() and again whenever a UI-driven change modifies a radio parameter.

Definition at line 217 of file hub_core.cpp.

Here is the call graph for this function:

◆ arm_execute_confirmation_poll_()

void esphome::home_io_control::IOHomeControlComponent::arm_execute_confirmation_poll_ ( const std::string & device_id,
bool for_stop )
protected

Arm the confirming poll that follows a command, because a CMD_EXECUTE reply is never trusted for position (see update_device_status_()'s trust_position parameter) and therefore leaves the hub with no idea where the device actually is.

Re-arms the bounded tracking window rather than only setting a due time: the same untrusted reply clears that window whenever it claims the device is stopped, and pop_due_device() discards a due poll that has no active window. An already-scheduled earlier poll wins.

Parameters
device_idDevice the command was sent to.
for_stopTrue for STOP (and position POS_STOP), which settles under STOP_SETTLE_POLL_CAP_MS instead of the normal settle cadence.

Definition at line 157 of file hub_operations.cpp.

Here is the call graph for this function:

◆ authenticate_request_()

bool esphome::home_io_control::IOHomeControlComponent::authenticate_request_ ( const IoFrame & request,
uint32_t freq )
protected

Handle an inbound authenticated command from a device (status updates, etc.).

Delegate inbound authentication to ExchangeEngine.

Parameters
requestInbound authenticated request (e.g., CMD_STATUS_UPDATE).
freqRF frequency the packet arrived on.
Returns
true if authentication succeeded; false otherwise.

Definition at line 335 of file hub_core.cpp.

Here is the call graph for this function:

◆ begin_status_poll_tracking_()

void esphome::home_io_control::IOHomeControlComponent::begin_status_poll_tracking_ ( const std::string & device_id,
uint32_t initial_delay_ms )
protected

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

Parameters
device_idID of the device to poll.
initial_delay_msDelay before the first follow-up poll.

Definition at line 481 of file hub_status.cpp.

Here is the call graph for this function:

◆ check_heater_model_()

void esphome::home_io_control::IOHomeControlComponent::check_heater_model_ ( const std::string & device_id,
uint8_t max_tries )
protected

The one-off model check of a heater kind that has model rows (device_offers_models()).

Reads the model name (register 0x0119) and logs it at INFO, and compares whether the towel-dryer mode register (0x0136) holds a value with the declared io_model: (decisions::classify_heater_model_hint()), logging a WARN when they disagree. Nothing it finds changes behaviour. Done once both reads were answered, or after decisions::HEATER_MODEL_CHECK_MAX_RUNS runs.

Parameters
device_idTarget device ID.
max_triesTransmit-attempt cap of each read (the poll's).

Definition at line 1053 of file hub_operations.cpp.

Here is the call graph for this function:

◆ cover_poll_attempts_()

decisions::AttemptRequest esphome::home_io_control::IOHomeControlComponent::cover_poll_attempts_ ( const std::string & device_id,
bool scheduler_managed,
bool state_unknown = false )
nodiscardprotected

Attempts for a cover's status read: its read kind (a settling read or a look at a busy device, decisions::scheduled_poll_read_kind()), consuming the poll's STOP and confirming-read marks.

Parameters
device_idDevice being polled.
scheduler_managedTrue when StatusPollPolicy is tracking the device (a ladder stands behind the poll).
state_unknownTrue for a catch-up read (StatusPollPolicy::take_state_unknown()).

Definition at line 487 of file hub_operations.cpp.

Here is the call graph for this function:

◆ defer_background_poll_()

bool esphome::home_io_control::IOHomeControlComponent::defer_background_poll_ ( ) const
inlinenodiscardprotected

Whether loop() should skip dispatching the queue this iteration because the pending work is a background poll and either a 1W remote transmitted very recently, or a key-extraction attempt is mid-flight.

Thin wrapper binding the component's state to decisions::defer_background_poll_for_1w_activity(), plus a second, independent yield condition: a background poll is a blocking exchange that owns the radio for 1-3 s, and dispatching one while the key-extraction responder is listening for its peer's next frame (an expected CMD_KEY_TRANSFER (0x32), say) would swallow it — see listen_for_key_extraction_peer_() for the other half of that listen. Only background polls yield here, same as the 1W rule: a user command must never wait on either kind of background activity.

Definition at line 1075 of file hub_core.h.

Here is the call graph for this function:

◆ describe_last_commander()

std::string esphome::home_io_control::IOHomeControlComponent::describe_last_commander ( const IoDevice & dev) const
nodiscard

Render a device's "last commanded by" string, resolving this hub's own node ID.

Thin wrapper over detail::describe_last_commander() (entity_helpers.h); exists because the hub's node ID is not reachable from a companion entity.

Parameters
devDevice record to read.
Returns
See detail::describe_last_commander().

Definition at line 1652 of file hub_operations.cpp.

Here is the call graph for this function:

◆ device_event_count()

uint32_t esphome::home_io_control::IOHomeControlComponent::device_event_count ( ) const
inlinenodiscard
Returns
How many device events record_device_event_() has recorded since boot.

Definition at line 420 of file hub_core.h.

◆ diagnostic_probes_enabled()

bool esphome::home_io_control::IOHomeControlComponent::diagnostic_probes_enabled ( ) const
inlinenodiscard

Whether diagnostic probes are enabled for this build.

Definition at line 494 of file hub_core.h.

◆ discover_and_pair()

bool esphome::home_io_control::IOHomeControlComponent::discover_and_pair ( )
virtual

Discover and pair a device that is in pairing mode.

Discover and pair a device in pairing mode.

Returns
true if pairing completed successfully; false otherwise.

The hub wrapper manages the busy_ flag so loop() stops hopping and polling while the blocking pairing exchange is in progress. All protocol logic is in PairingEngine::discover_and_pair().

Definition at line 22 of file hub_pairing.cpp.

Here is the call graph for this function:

◆ dump_config()

void esphome::home_io_control::IOHomeControlComponent::dump_config ( )
override

Dump configuration and radio debug info to the log.

Definition at line 569 of file hub_core.cpp.

Here is the call graph for this function:

◆ dump_oneway_controllers_config_()

void esphome::home_io_control::IOHomeControlComponent::dump_oneway_controllers_config_ ( ) const
protected

Emit the 1W controller identities to the config dump — node, class, and the resolved ACEI / broadcast (ADR 0031).

Factored out of dump_config() to keep its cognitive complexity under the clang-tidy threshold.

Definition at line 637 of file hub_core.cpp.

Here is the call graph for this function:

◆ event_reading_policy_()

PeriodicPollPolicy & esphome::home_io_control::IOHomeControlComponent::event_reading_policy_ ( EventReading kind)
protected

The schedule of kind's poll.

Parameters
kindWhich reading.
Returns
The PeriodicPollPolicy instance that schedules it.

Definition at line 659 of file hub_operations.cpp.

◆ exchange_and_record_()

IOHomeControlComponent::RequestResult esphome::home_io_control::IOHomeControlComponent::exchange_and_record_ ( const std::string & device_id,
const IoFrame & request,
IoFrame & response,
const RequestOptions & options )
protected

Run one authenticated request/response exchange on the standard command channel and record its outcome: exchange-outcome and timeout counters, link health, challenge-seen handling, CMD_ERROR_RESP handling, debug logs and (when requested) the status-poll backoff.

It does not interpret a reply — callers decide what a REPLY means.

Parameters
device_idTarget device ID.
requestOutbound request frame.
[out]responseThe device's reply, valid for RequestResult::REPLY and ERROR_REPLY.
optionsSee RequestOptions.
Returns
What happened, see RequestResult.

Definition at line 195 of file hub_operations.cpp.

Here is the call graph for this function:

◆ exchange_heating_()

bool esphome::home_io_control::IOHomeControlComponent::exchange_heating_ ( const std::string & device_id,
const char * label,
const IoFrame & request,
IoFrame & response,
uint8_t max_tries )
protected

The exchange every heating frame shares: send on the command channel, record the outcome (exchange counters, link health, error result code), notify the entities and report whether the device answered with CMD_WRITE_PRIVATE_ACK.

Parameters
device_idTarget device ID.
labelWhat was sent, for the log ("set_temperature", "read room_temperature").
requestThe framed CMD_WRITE_PRIVATE request.
[out]responseThe device's reply; valid when true is returned.
max_triesTransmit-attempt cap forwarded to send_and_receive_().
Returns
true only if the reply is a CMD_WRITE_PRIVATE_ACK.

Definition at line 888 of file hub_operations.cpp.

Here is the call graph for this function:

◆ exchange_past_device_event_()

ExchangeOutcome esphome::home_io_control::IOHomeControlComponent::exchange_past_device_event_ ( const IoFrame & request,
IoFrame & response,
const decisions::AttemptRequest & attempts )
protected

send_and_receive_() on the command channel, except that a device event report (decisions::is_device_event_report()) taken as the reply is recorded (record_device_event_()) and the request asked once more; a second report in a row, or one answering an EXECUTE that is not safe to repeat, ends it as FAILED.

Parameters
requestOutbound request frame.
responseFilled with the reply on SUCCESS_WITH_RESPONSE; never a device event report then.
attemptsAttempt budget per send, as for send_and_receive_().
Returns
The exchange outcome.

Definition at line 176 of file hub_operations.cpp.

Here is the call graph for this function:

◆ execute_device_command_()

bool esphome::home_io_control::IOHomeControlComponent::execute_device_command_ ( const std::string & device_id,
CoverCommand cmd )
protected

Execute a named device command (STOP, FAVORITE, VENT, PARTIAL, PEDESTRIAN, FORCE_OPEN) via the authenticated exchange.

A named position (NAMED_POSITIONS) goes out only to a device whose features include its bit.

Parameters
device_idTarget device ID.
cmdNamed command to execute.
Returns
true if device acknowledged; false otherwise, including a named position the device's features lack (nothing is sent).

Definition at line 425 of file hub_operations.cpp.

Here is the call graph for this function:

◆ execute_dhw_()

bool esphome::home_io_control::IOHomeControlComponent::execute_dhw_ ( const std::string & device_id,
const char * action,
const std::function< bool(IoFrame &, const IoDevice &)> & build )
protected

Send one water heater EXECUTE (target or operating mode) through try_execute_operation_(), which gates on device_feature::WATER_HEATER and arms the settle poll; on acceptance the next poll moves to HEATING_POST_WRITE_POLL_DELAY_MS from now so the heating state follows.

Parameters
device_idTarget device ID.
actionOperation name for the logs.
buildBuilds the EXECUTE for the device.
Returns
true when the device accepted the EXECUTE.

Definition at line 1390 of file hub_operations.cpp.

Here is the call graph for this function:

◆ execute_oneway_()

template<typename F>
void esphome::home_io_control::IOHomeControlComponent::execute_oneway_ ( F && send)
inlineprotected

Shared bookkeeping for every 1W transmit: mark the radio busy for the duration of send, then record it as 1W activity so background polls back off for it exactly as they do for a remote's burst — the radio is equally busy either way.

Every 1W execute must go through this; a future one that skips it would compile, pass, and silently break poll-deferral.

Parameters
sendCallable that performs the actual transmit; takes no arguments.

Definition at line 1308 of file hub_core.h.

Here is the call graph for this function:

◆ execute_oneway_command_()

void esphome::home_io_control::IOHomeControlComponent::execute_oneway_command_ ( const std::string & controller_id,
CoverCommand cmd )
protected

Send a queued 1W named command.

Unlike its 2W sibling this returns nothing: there is no acknowledgement to report, and success here would only mean "bytes left the radio".

Parameters
controller_idController-identity handle.
cmdNamed command to send.

Definition at line 1701 of file hub_operations.cpp.

Here is the call graph for this function:

◆ execute_oneway_enroll_()

void esphome::home_io_control::IOHomeControlComponent::execute_oneway_enroll_ ( const std::string & controller_id)
protected

Send a queued 1W enrollment (add-controller).

See execute_oneway_command_().

Parameters
controller_idController-identity handle.

Definition at line 1709 of file hub_operations.cpp.

Here is the call graph for this function:

◆ execute_oneway_position_()

void esphome::home_io_control::IOHomeControlComponent::execute_oneway_position_ ( const std::string & controller_id,
uint8_t position )
protected

Send a queued 1W numeric position.

See execute_oneway_command_().

Parameters
controller_idController-identity handle.
positionTarget position 0–100.

Definition at line 1705 of file hub_operations.cpp.

Here is the call graph for this function:

◆ execute_oneway_unenroll_()

void esphome::home_io_control::IOHomeControlComponent::execute_oneway_unenroll_ ( const std::string & controller_id)
protected

Send a queued 1W un-enrollment (remove-controller).

See execute_oneway_command_().

Parameters
controller_idController-identity handle.

Definition at line 1713 of file hub_operations.cpp.

Here is the call graph for this function:

◆ execute_request_and_update_()

bool esphome::home_io_control::IOHomeControlComponent::execute_request_and_update_ ( const std::string & device_id,
const IoFrame & request,
bool warn_on_no_response,
uint32_t retry_after_fail_ms = 0,
const decisions::AttemptRequest & attempts = EXCHANGE_RETRY_COUNT )
protected

Shared request/response helper for high-level operations: exchange_and_record_() plus update_device_status_() on a reply.

Parameters
device_idTarget device ID.
requestOutbound request frame.
warn_on_no_responseIf true, logs a warning when no response is received.
retry_after_fail_msIf non-zero, schedules next status poll after this delay on failure.
attemptsAttempt cap or read kind, forwarded to send_and_receive_(). Defaults to the full EXCHANGE_RETRY_COUNT; a cover's status poll passes its read kind (decisions::scheduled_poll_read_kind()).
Returns
true when the device replied, or when a CMD_EXECUTE was accepted without a reply — every other command's unconfirmed acceptance is still a failure here (see ExchangeOutcome and decisions::retry_after_unconfirmed_accept_is_safe()).

Definition at line 292 of file hub_operations.cpp.

Here is the call graph for this function:

◆ follow_linked_remote_press_()

void esphome::home_io_control::IOHomeControlComponent::follow_linked_remote_press_ ( const OneWayFrameInfo & info,
const std::string & src_id )
protected

React to a deduplicated 1W press from a remote: apply the optimistic state to the devices it controls (resolve_1w_target_devices_()), schedule their status polls (at once after a STOP, otherwise after remote_activity_poll_delay_ms) and, when switched on, open the catch-up burst (StatusPollPolicy::on_linked_remote_activity(), ADR 0080).

No-op for a remote that controls none.

Parameters
infoAlready-decoded 1W frame info (see decode_1w_frame()).
src_idSender's node ID as a string (already computed by the caller).

Definition at line 632 of file hub_status.cpp.

Here is the call graph for this function:

◆ force_open_device()

virtual ManagementActionResult esphome::home_io_control::IOHomeControlComponent::force_open_device ( const std::string & device_id)
inlinevirtual

Move a cover device to fully open at elevated priority, intended to bypass wind/rain soft locks.

Safety-sensitive: queues CoverCommand::FORCE_OPEN through the normal cover-command dispatch path. Only confirms the command was queued; the movement outcome arrives later via the device's normal cover-state/polling pipeline, so verified is always false. The lock-bypass behavior itself is experimental and unconfirmed against an active lock — see ManagementActions::force_open_device()'s doxygen for details.

Parameters
device_idTarget device ID.
Returns
Structured result describing whether the command was queued.

Definition at line 620 of file hub_core.h.

Here is the call graph for this function:

◆ get_device()

IoDevice * esphome::home_io_control::IOHomeControlComponent::get_device ( const std::string & device_id)
virtual

Retrieve a device by ID; returns nullptr if not found.

Parameters
device_idHexadecimal node ID.
Returns
Pointer to IoDevice, or nullptr.

Definition at line 402 of file hub_core.cpp.

Here is the call graph for this function:

◆ get_radio()

RadioDriver * esphome::home_io_control::IOHomeControlComponent::get_radio ( ) const
inlinenodiscard

Get the underlying radio driver (for diagnostics and test tooling).

Definition at line 200 of file hub_core.h.

◆ get_setup_priority()

float esphome::home_io_control::IOHomeControlComponent::get_setup_priority ( ) const
inlinenodiscardoverride

Get setup priority (HARDWARE to initialize early).

Returns
setup_priority::HARDWARE.

Definition at line 177 of file hub_core.h.

◆ get_tuning_number_value()

float esphome::home_io_control::IOHomeControlComponent::get_tuning_number_value ( const std::string & name) const
nodiscard

Current value of a numeric tuning parameter, used to seed a HA number entity on boot.

Return the current value of a numeric tuning parameter.

Parameters
nameYAML key of the parameter.
Returns
Current value, or 0 for an unknown key.

Mirror of update_tuning_number(); used by IOHomeTuningNumber::setup() to publish the boot-time value so the Home Assistant slider reflects the active configuration (default or YAML override) without restating any default on the Python side.

Definition at line 278 of file hub_core.cpp.

Here is the call graph for this function:

◆ get_tuning_select_value()

std::string esphome::home_io_control::IOHomeControlComponent::get_tuning_select_value ( const std::string & name) const
nodiscard

Current option string of a select tuning parameter, used to seed a HA select entity on boot.

Return the current option string of a select tuning parameter.

Parameters
nameYAML key of the parameter.
Returns
Current value formatted as its YAML option string, or empty for an unknown key.

Mirror of update_tuning_select(); used by IOHomeTuningSelect::setup() to publish the boot-time option so the Home Assistant dropdown reflects the active configuration. The returned strings match the YAML/UI option labels exactly. The command list is returned as a comma-separated preset string (e.g. "0x28,0x2E") matching the dropdown options.

Definition at line 293 of file hub_core.cpp.

Here is the call graph for this function:

◆ handle_error_response_()

bool esphome::home_io_control::IOHomeControlComponent::handle_error_response_ ( const std::string & device_id,
const IoFrame & request,
const IoFrame & response,
uint32_t retry_after_fail_ms )
protected

Handle an explicit CMD_ERROR_RESP refusal from the device: record the result code, stamp link health, and schedule the poll backoff.

Split out of exchange_and_record_() to keep that function's outcome dispatch readable — a refusal is a distinct concern from "what did the exchange achieve".

Parameters
device_idTarget device ID.
requestOutbound request frame that drew the refusal.
responseThe CMD_ERROR_RESP frame.
retry_after_fail_msIf non-zero, schedules next status poll after this delay.
Returns
Always false; a refusal is never a success.

Definition at line 315 of file hub_operations.cpp.

Here is the call graph for this function:

◆ heater_poll_attempts_()

decisions::AttemptRequest esphome::home_io_control::IOHomeControlComponent::heater_poll_attempts_ ( const std::string & device_id,
bool scheduler_managed )
nodiscardprotected

Attempts for a heater's status read: the count-based budget heaters keep (decisions::scheduled_poll_max_tries()).

Parameters
device_idDevice being polled.
scheduler_managedTrue when StatusPollPolicy is tracking the device.

Definition at line 503 of file hub_operations.cpp.

Here is the call graph for this function:

◆ heating_control()

virtual ManagementActionResult esphome::home_io_control::IOHomeControlComponent::heating_control ( const std::string & device_id,
const std::string & function,
const std::string & value )
inlinevirtual

Run one 2W heating/climate function (CMD_WRITE_PRIVATE 0x20) against a registered climate device — the heating_control hub action.

Experimental: the register protocol is unvalidated on real Atlantic/Thermor/Sauter hardware. A write is reported as acknowledged by the device, never as confirmed; the register reads (window_open) put the decoded value into the result message, and power_on / midnight_sync log their ACK payload at DEBUG. See ManagementActions::heating_control() for argument formats.

Parameters
device_idTarget device ID.
functionHeating function name.
valueFunction-specific value string.
Returns
Structured result describing success and any validation/exchange failure.

Definition at line 666 of file hub_core.h.

Here is the call graph for this function:

◆ hop_frequency_()

void esphome::home_io_control::IOHomeControlComponent::hop_frequency_ ( )
protected

Delegate channel hop to ExchangeEngine (which owns last_hop_us_).

Definition at line 305 of file hub_core.cpp.

Here is the call graph for this function:

◆ identify_device()

virtual ManagementActionResult esphome::home_io_control::IOHomeControlComponent::identify_device ( const std::string & device_id)
inlinevirtual

Trigger a device's physical identify (brief jog/flash) so a user can confirm which physical motor a device ID maps to.

Parameters
device_idTarget device ID.
Returns
Structured result describing success and any validation failure. verified is always false — there is no readback for a physical identify jog.

Definition at line 607 of file hub_core.h.

Here is the call graph for this function:

◆ key_extraction_awaiting_reply_()

bool esphome::home_io_control::IOHomeControlComponent::key_extraction_awaiting_reply_ ( ) const
inlinenodiscardprotected

True while the key-extraction responder is mid-attempt and still within its bounded listen window.

Thin forwarder to KeyExtractionResponder::awaiting_reply() (key_extraction_responder.h) — kept on the hub because defer_background_poll_() and tests/hub/hub_core_test.cpp reach it here, mirroring the two set_key_extraction_armed* bindings.

Definition at line 986 of file hub_core.h.

Here is the call graph for this function:

◆ last_device_event()

const std::string & esphome::home_io_control::IOHomeControlComponent::last_device_event ( ) const
inlinenodiscard
Returns
The most recent device event rendered as #<n> t=<uptime s> <SRC> <cmd> <payload hex>, or an empty string before the first one. The counter makes a repeated identical report a new value, which Home Assistant's history needs (it records state changes only).

Definition at line 425 of file hub_core.h.

◆ listen_for_key_extraction_peer_()

void esphome::home_io_control::IOHomeControlComponent::listen_for_key_extraction_peer_ ( )
protected

One idle pass of listening for the key-extraction responder's peer, in place of the generic idle hop while key_extraction_awaiting_reply_().

Inside the session window (KeyExtractionResponder::in_session_hold()) it keeps the radio on the session's channel, where the peer's in-session frame comes; after it, a rotating listen over all three channels for one KEY_EXTRACTION_SCAN_SLICE_MS slice, handing a received frame to process_received_packet_(). While a discovery answer waits for its slot, the slice ends at that slot (and is skipped once it has come), so the scheduler sends the answer on time.

Definition at line 489 of file hub_core.cpp.

Here is the call graph for this function:

◆ log_exchange_debug_()

void esphome::home_io_control::IOHomeControlComponent::log_exchange_debug_ ( const char * device_id) const
inlineprotected

Log the last exchange debug snapshot (delegates to exchange_engine_).

Definition at line 1476 of file hub_core.h.

Here is the call graph for this function:

◆ log_exchange_unconfirmed_debug_()

void esphome::home_io_control::IOHomeControlComponent::log_exchange_unconfirmed_debug_ ( const char * device_id) const
inlineprotected

Log the last exchange debug snapshot for an accepted-but-unconfirmed exchange, at INFO.

Definition at line 1479 of file hub_core.h.

Here is the call graph for this function:

◆ loop()

void esphome::home_io_control::IOHomeControlComponent::loop ( )
override

Main loop: process pending operations and drive radio state machine.

Definition at line 410 of file hub_core.cpp.

Here is the call graph for this function:

◆ maybe_fire_sender_event_()

void esphome::home_io_control::IOHomeControlComponent::maybe_fire_sender_event_ ( const OneWayFrameInfo & info,
bool linked,
const std::string & src_id )
protected

Fire the sender HA event for a decoded 1W frame, if the sender is exposed.

DEBUG-logs the reason when it does not fire (API disconnected / sender not exposed) so a live log capture can distinguish "never reached this check" from "reached it and skipped".

Parameters
infoAlready-decoded 1W frame info (see decode_1w_frame()).
linkedTrue if the sender is linked to at least one registered device.
src_idSender's node ID as a string (already computed by the caller).

Definition at line 675 of file hub_status.cpp.

Here is the call graph for this function:

◆ note_foreign_challenge_()

void esphome::home_io_control::IOHomeControlComponent::note_foreign_challenge_ ( const IoFrame & frame)
protected

Hand a registered device's challenge (0x3C) to another controller to act_on_foreign_frame_().

A challenge addressed to this hub, from an unregistered node, or a 0x3D is left alone.

Parameters
frameAn exchange-internal frame (is_exchange_internal_command()).

Definition at line 581 of file hub_status.cpp.

Here is the call graph for this function:

◆ note_status_reported_()

void esphome::home_io_control::IOHomeControlComponent::note_status_reported_ ( const std::string & device_id)
protected

The device just reported its status: move its status refresh (if it has one) a whole interval out.

Parameters
device_idDevice that reported.

Definition at line 374 of file hub_core.cpp.

Here is the call graph for this function:

◆ notify_device_update_()

void esphome::home_io_control::IOHomeControlComponent::notify_device_update_ ( const std::string & id)
protected

Fire all registered device update callbacks for the given device ID.

Parameters
idDevice ID that updated.

Definition at line 339 of file hub_core.cpp.

Here is the call graph for this function:

◆ oneway_controllers()

const OneWayControllerRegistry & esphome::home_io_control::IOHomeControlComponent::oneway_controllers ( ) const
inlinenodiscard
Returns
The configured 1W controller identities.

Definition at line 336 of file hub_core.h.

Here is the call graph for this function:

◆ oneway_key_adoption_armed()

bool esphome::home_io_control::IOHomeControlComponent::oneway_key_adoption_armed ( ) const
inlinenodiscard

Whether the 1W key-adoption listener is currently armed.

Returns
true while armed.

Definition at line 482 of file hub_core.h.

Here is the call graph for this function:

◆ oneway_transmitter()

OneWayTransmitter & esphome::home_io_control::IOHomeControlComponent::oneway_transmitter ( )
inlinenodiscard
Returns
The 1W transmit collaborator, for diagnostics and the sequence-resync path.

Definition at line 408 of file hub_core.h.

◆ pairing_telemetry()

const PairingTelemetry & esphome::home_io_control::IOHomeControlComponent::pairing_telemetry ( ) const
inlinenodiscard
Returns
The telemetry recorded for the most recent (or in-progress) pairing attempt.

Definition at line 411 of file hub_core.h.

◆ poll_dhw_device_()

bool esphome::home_io_control::IOHomeControlComponent::poll_dhw_device_ ( const std::string & device_id)
protected

Poll a water heater: the status read for its target, capabilities and boost and away state (read_dhw_status_()), then its water temperature, mode, heating state, boost and away duration and energy registers (stopping at the first failure), then its brand until it has been read once (logged at INFO).

The same ladder, try band and cadence as poll_heating_device_(): a failure moves the retry onto the StatusPollPolicy ladder, and the next regular poll is armed one interval out. Called from request_device_status() for a device with device_feature::WATER_HEATER.

Parameters
device_idTarget device ID.
Returns
true when the status read and every register were answered.

Definition at line 1345 of file hub_operations.cpp.

Here is the call graph for this function:

◆ poll_heating_device_()

bool esphome::home_io_control::IOHomeControlComponent::poll_heating_device_ ( const std::string & device_id)
protected

Poll a heater: read its profile's poll registers (stopping at the first failure), then the programme's temperature in force (poll_programme_period_()), then its boot registers until each has been read once, then, on a heater kind with model rows, the one-off model check (check_heater_model_()) once the device has answered a read.

A failure moves the retry onto the StatusPollPolicy ladder; either way the next regular poll is armed one interval out (the device's status_poll_interval, else HEATING_POLL_DEFAULT_INTERVAL_MS). Called from request_device_status() for climate devices.

Parameters
device_idTarget device ID.
Returns
true when all four registers were read.

Definition at line 1125 of file hub_operations.cpp.

Here is the call graph for this function:

◆ poll_programme_period_()

void esphome::home_io_control::IOHomeControlComponent::poll_programme_period_ ( const std::string & device_id,
const HeatingProfile & profile,
uint8_t max_tries )
protected

Read the temperature in force of a heater's programme, when the programme runs.

Sends nothing unless programme_period_active() holds for the readings the poll just made. When the temperature fits neither period it forgets the eco setback, so the boot registers read it again.

Parameters
device_idTarget device ID.
profileThe device's profile; its programme_period must not be nullptr.
max_triesTransmit-attempt cap of the read (the poll's).

Definition at line 1110 of file hub_operations.cpp.

Here is the call graph for this function:

◆ probe_device()

virtual ManagementActionResult esphome::home_io_control::IOHomeControlComponent::probe_device ( const std::string & device_id,
const std::string & probe,
const std::string & index )
inlinevirtual

Send a single diagnostic probe frame to a registered device and report the raw reply (see DiagnosticProbes::probe_device() for the full contract, argument formats, and safety gating).

Protocol-research instrumentation for opcodes this codebase has not decoded — see docs/diagnostic-probes.md and ADR 0024.

Parameters
device_idTarget device ID.
probeProbe name ("private_fn", "status_ext", "general_info3", "private2", "private2_short", "status_mp_fp", "status_fp_high", "limitation", "register_00", or "register_01"; the full list is in DiagnosticProbes::probe_device()).
indexFunction ID / selector block / modifier, as a decimal or 0x-prefixed hex string; ignored for "general_info3" and "status_mp_fp"; the FPI2 bitmap for "status_fp_high"; 0 (minimum) or 1 (maximum) for "limitation".
Returns
Structured result whose message carries the reply's command byte and raw hex.

Definition at line 640 of file hub_core.h.

Here is the call graph for this function:

◆ probe_sweep()

virtual ManagementActionResult esphome::home_io_control::IOHomeControlComponent::probe_sweep ( const std::string & device_id,
const std::string & probe,
const std::string & first_index,
const std::string & last_index )
inlinevirtual

Walk a bounded index range, one probe_device() call per index (see DiagnosticProbes::probe_sweep()).

Parameters
device_idTarget device ID.
probeProbe name, same as probe_device().
first_indexFirst index in the sweep (inclusive).
last_indexLast index in the sweep (inclusive).
Returns
Structured result whose message is one line per index.

Definition at line 651 of file hub_core.h.

Here is the call graph for this function:

◆ process_pending_operation_()

void esphome::home_io_control::IOHomeControlComponent::process_pending_operation_ ( )
protected

Pop next pending operation from the queue and execute it (set position, request status, discover).

Definition at line 1717 of file hub_operations.cpp.

Here is the call graph for this function:

◆ process_received_packet_()

void esphome::home_io_control::IOHomeControlComponent::process_received_packet_ ( const RadioRxPacket & packet)
protected

Parse a received frame, merge supported device state or metadata, and notify callbacks.

Parameters
packetRaw radio packet containing a parsed IoFrame.

Definition at line 924 of file hub_status.cpp.

Here is the call graph for this function:

◆ queue_device_command()

bool esphome::home_io_control::IOHomeControlComponent::queue_device_command ( const std::string & device_id,
CoverCommand cmd )
virtual

Queue an async named command (STOP, FAVORITE, VENT, PARTIAL, PEDESTRIAN, FORCE_OPEN); returns immediately, executed in loop().

PEDESTRIAN is experimental.

Existing entity/button callers (cover, favorite, vent, partial and pedestrian buttons) intentionally ignore the return value — they always target a known, already-registered device. It exists so force_open_device() can report enqueue rejection distinctly from a queued-but-not-yet-run command.

Parameters
device_idTarget device ID.
cmdNamed command to send.
Returns
true if the hub is initialized, the device is registered, and the command matches its capability class (so the command was enqueued); false otherwise.

Definition at line 1553 of file hub_operations.cpp.

Here is the call graph for this function:

◆ queue_discover_and_pair()

void esphome::home_io_control::IOHomeControlComponent::queue_discover_and_pair ( )
virtual

Queue a pairing operation; executed in loop() when radio idle.

Queue a discovery-and-pair request with elevated priority.

A press handled within PAIRING_STALE_PRESS_MS of the end of an attempt is dropped with a log line: pairing blocks loop(), so a press made while it ran is only handled once it ends, when the device has usually left its pairing mode.

Flushes any pending status/name poll operations (which would consume time during the device's limited pairing window) and pushes discovery to the front of the queue. Duplicate requests are suppressed.

Definition at line 1643 of file hub_operations.cpp.

Here is the call graph for this function:

◆ queue_due_catchup_reads_()

void esphome::home_io_control::IOHomeControlComponent::queue_due_catchup_reads_ ( )
protected

Read every device with linked_remotes once, when a burst of linked-remote activity has been followed by remote_activity_catchup_poll_ms without an exchange (ADR 0080).

Each read is a one-off status read marked state-unknown (StatusPollPolicy::mark_state_unknown()); it opens no follow-up window of its own, an answer that says moving does.

Definition at line 528 of file hub_core.cpp.

Here is the call graph for this function:

◆ queue_due_periodic_polls_()

void esphome::home_io_control::IOHomeControlComponent::queue_due_periodic_polls_ ( )
protected

Queue every periodic poll that is due: the sensor polls (rain, sun level, battery level) and the status refresh at rest.

Definition at line 543 of file hub_core.cpp.

Here is the call graph for this function:

◆ queue_request_device_battery_level()

void esphome::home_io_control::IOHomeControlComponent::queue_request_device_battery_level ( const std::string & device_id)
virtual

Queue an async battery level poll; executed in loop() as a background operation.

Parameters
device_idTarget device ID.

Definition at line 1626 of file hub_operations.cpp.

Here is the call graph for this function:

◆ queue_request_device_limitation()

void esphome::home_io_control::IOHomeControlComponent::queue_request_device_limitation ( const std::string & device_id)
virtual

Queue an async minimum-limitation read for the rain sensor poll; executed in loop() as a background operation (yields to commands and 1W activity).

Parameters
device_idTarget device ID.

Definition at line 1614 of file hub_operations.cpp.

Here is the call graph for this function:

◆ queue_request_device_name()

void esphome::home_io_control::IOHomeControlComponent::queue_request_device_name ( const std::string & device_id)
virtual

Queue an async device-name request; returns immediately, executed in loop().

Parameters
device_idTarget device ID.

Definition at line 1632 of file hub_operations.cpp.

Here is the call graph for this function:

◆ queue_request_device_status()

void esphome::home_io_control::IOHomeControlComponent::queue_request_device_status ( const std::string & device_id)
virtual

Queue an async status request; returns immediately, executed in loop().

Parameters
device_idTarget device ID.

Definition at line 1606 of file hub_operations.cpp.

Here is the call graph for this function:

◆ queue_request_device_sun_level()

void esphome::home_io_control::IOHomeControlComponent::queue_request_device_sun_level ( const std::string & device_id)
virtual

Queue an async sun level poll; executed in loop() as a background operation.

Parameters
device_idTarget device ID.

Definition at line 1620 of file hub_operations.cpp.

Here is the call graph for this function:

◆ queue_set_device_position()

void esphome::home_io_control::IOHomeControlComponent::queue_set_device_position ( const std::string & device_id,
uint8_t position )
virtual

Queue an async position update; returns immediately, executed in loop().

If a pending SET_TILT operation for the same device is already in the queue, the two are coalesced into a single SET_POSITION_AND_TILT command to avoid two radio exchanges. This transparently handles Home Assistant sending cover.set_cover_position and cover.set_cover_tilt_position as separate rapid calls.

Parameters
device_idTarget device ID.
positionDesired position (0–100).

Definition at line 1528 of file hub_operations.cpp.

Here is the call graph for this function:

◆ queue_set_device_position_and_tilt()

void esphome::home_io_control::IOHomeControlComponent::queue_set_device_position_and_tilt ( const std::string & device_id,
uint8_t position,
uint8_t tilt_percent )
virtual

Queue an async combined position+tilt update; returns immediately, executed in loop().

Parameters
device_idTarget device ID.
positionDesired position (0–100).
tilt_percentDesired tilt (0–100).

Definition at line 1596 of file hub_operations.cpp.

Here is the call graph for this function:

◆ queue_set_device_tilt()

void esphome::home_io_control::IOHomeControlComponent::queue_set_device_tilt ( const std::string & device_id,
uint8_t tilt_percent )
virtual

Queue an async tilt update; returns immediately, executed in loop().

If a pending SET_POSITION operation for the same device is already in the queue, the two are coalesced into a single SET_POSITION_AND_TILT command to avoid two radio exchanges. This transparently handles Home Assistant sending cover.set_cover_position and cover.set_cover_tilt_position as separate rapid calls.

Parameters
device_idTarget device ID.
tilt_percentDesired tilt (0–100).

Definition at line 1573 of file hub_operations.cpp.

Here is the call graph for this function:

◆ queue_set_fan_position()

void esphome::home_io_control::IOHomeControlComponent::queue_set_fan_position ( const std::string & device_id,
uint8_t position )
virtual

Async form of set_fan_position() that keeps radio work serialized on the main loop.

Parameters
device_idTarget device ID.
positionDesired IO position (0-100).

Definition at line 1677 of file hub_operations.cpp.

Here is the call graph for this function:

◆ queue_set_light_position()

void esphome::home_io_control::IOHomeControlComponent::queue_set_light_position ( const std::string & device_id,
uint8_t position )
virtual

Async form of set_light_position() that keeps radio work serialized on the main loop.

queue_set_light_state() is a thin binary-position wrapper around this.

Parameters
device_idTarget device ID.
positionDesired IO position (0-100).

Definition at line 1671 of file hub_operations.cpp.

Here is the call graph for this function:

◆ queue_set_light_state()

void esphome::home_io_control::IOHomeControlComponent::queue_set_light_state ( const std::string & device_id,
bool on )
virtual

Async form of set_light_state() that keeps radio work serialized on the main loop.

Parameters
device_idTarget device ID.
onDesired on/off state.

Definition at line 1683 of file hub_operations.cpp.

Here is the call graph for this function:

◆ queue_set_lock_state()

void esphome::home_io_control::IOHomeControlComponent::queue_set_lock_state ( const std::string & device_id,
bool locked )
virtual

Async form of set_lock_state() that keeps radio work serialized on the main loop.

Parameters
device_idTarget device ID.
lockedDesired locked/unlocked state.

Definition at line 1687 of file hub_operations.cpp.

Here is the call graph for this function:

◆ queue_set_switch_state()

void esphome::home_io_control::IOHomeControlComponent::queue_set_switch_state ( const std::string & device_id,
bool on )
virtual

Async form of set_switch_state() that keeps radio work serialized on the main loop.

Parameters
device_idTarget device ID.
onDesired on/off state.

Definition at line 1693 of file hub_operations.cpp.

Here is the call graph for this function:

◆ radio_stopped_responding()

bool esphome::home_io_control::IOHomeControlComponent::radio_stopped_responding ( ) const
inlinenodiscard

True once loop() has seen the radio latch a failure after setup (a runtime BUSY timeout, for example).

Sticky: a failed driver never recovers without a reboot. Every device's Active Issue sensor reports it.

Definition at line 513 of file hub_core.h.

◆ read_dhw_reading_()

bool esphome::home_io_control::IOHomeControlComponent::read_dhw_reading_ ( const std::string & device_id,
uint8_t index,
uint8_t max_tries )
protected

Read one family-0x00 register of a water heater and fold its value into IoDevice::dhw.

A value the decoder does not take (an empty value, a mode byte never seen) is logged at DEBUG and leaves the reading as it was; it is still an answer, not a failed read.

Parameters
device_idTarget device ID.
indexOne of the DHW_REG_* registers.
max_triesTransmit-attempt cap.
Returns
true when the device answered.

Definition at line 1307 of file hub_operations.cpp.

Here is the call graph for this function:

◆ read_dhw_register_()

bool esphome::home_io_control::IOHomeControlComponent::read_dhw_register_ ( const std::string & device_id,
uint8_t index,
const char * label,
IoFrame & response,
uint8_t max_tries )
protected

Read one family-0x00 register of a water heater raw (read_private_register_() gated on device_feature::WATER_HEATER).

Parameters
device_idTarget device ID.
indexLow byte of the register.
labelWhat is read, for the log ("dhw_water_temperature").
[out]responseThe reply; its value bytes start at HEATING_REPLY_VALUE_OFFSET.
max_triesTransmit-attempt cap forwarded to read_private_register_().
Returns
true when the device answered with the register's echo.

Definition at line 1198 of file hub_operations.cpp.

Here is the call graph for this function:

◆ read_dhw_status_()

bool esphome::home_io_control::IOHomeControlComponent::read_dhw_status_ ( const std::string & device_id,
uint8_t max_tries )
protected

Read a water heater's target, capabilities and boost and away state: the status read DHW_STATUS_FPI1 / DHW_STATUS_FPI2 (create_status_mp_fp_read()), whose reply update_device_status_() folds into IoDevice::dhw.

Parameters
device_idTarget device ID.
max_triesTransmit-attempt cap.
Returns
true when the device answered.

Definition at line 1332 of file hub_operations.cpp.

Here is the call graph for this function:

◆ read_heating_register()

bool esphome::home_io_control::IOHomeControlComponent::read_heating_register ( const std::string & device_id,
HeatingFunction fn,
float * value_out,
uint8_t max_tries )
virtual

Read one register of a heater and fold the decoded value into IoDevice::heating.

Same gate as send_heating_command(); the read itself is read_private_register_(). A reply that decodes (decode_heating_reply()) updates the device record and notifies the entity callbacks, so what an entity shows is what the heater reported.

Parameters
device_idTarget device ID (hex string).
fnRegister to read; must be readable (see heating_function_is_readable()).
[out]value_outDecoded value (NaN for a room-temperature sensor fault); pass nullptr when only the stored reading is wanted.
max_triesTransmit-attempt cap: EXCHANGE_RETRY_COUNT for a read the user waits on (the action, the read-back of a write), the scheduled-poll band for the background poll.
Returns
true only if the device answered and the reply decoded to a value for fn.

Definition at line 1006 of file hub_operations.cpp.

Here is the call graph for this function:

◆ read_private_register_()

bool esphome::home_io_control::IOHomeControlComponent::read_private_register_ ( const std::string & device_id,
uint8_t reg_hi,
uint8_t reg_lo,
const char * label,
IoFrame & response,
uint8_t max_tries )
protected

Read one private register raw: build the read request, run exchange_heating_() and check that the reply echoes the register.

The one place a register read is framed and sent; read_heating_register() decodes on top of it, and the reads no HeatingFunction describes (a model name in ASCII, "is there a value at all") use it directly. Gated by device_accepts_register_probe(); the request is built by encode_heating_register_read(), which cannot produce a write.

Parameters
device_idTarget device ID.
reg_hiHigh byte of the register.
reg_loLow byte of the register.
labelWhat is read, for the log ("model_name").
[out]responseThe reply; its value bytes start at HEATING_REPLY_VALUE_OFFSET (none for a register the device does not hold).
max_triesTransmit-attempt cap forwarded to exchange_heating_().
Returns
true when the device answered with the register's echo.

Definition at line 974 of file hub_operations.cpp.

Here is the call graph for this function:

◆ record_1w_activity_()

void esphome::home_io_control::IOHomeControlComponent::record_1w_activity_ ( uint32_t now)
protected

Record that a 1W frame just went out on the radio — ours or someone else's — updating last_1w_activity_ms_ and — when this frame starts a new burst (see decisions::oneway_burst_started_fresh()) — first_1w_activity_ms_.

Called both from process_received_packet_() for an overheard remote's frame and from execute_oneway_command_()/execute_oneway_position_() (hub_operations.cpp) for a frame this hub just transmitted itself. That second case is deliberate, not a misuse of a receive-path hook: our own burst should defer background polls exactly like a remote's does, because it puts the same 1W traffic on the same shared channel the polls would otherwise use, and the devices it targets need the same settling time either way.

Parameters
nowmillis() at which this frame was seen or sent.

Definition at line 847 of file hub_status.cpp.

Here is the call graph for this function:

◆ record_device_event_()

void esphome::home_io_control::IOHomeControlComponent::record_device_event_ ( const IoFrame & frame)
protected

Record a device event report, or a frame from a registered device that nothing else here handles: log it raw, count it, and publish it on the "Last Device Event" sensor.

The recording never answers the frame and never applies it to the device record, whatever it claims to carry (ADR 0022, ADR 0060). The one acknowledgement is the ordinary one: a CMD_STATUS_UPDATE addressed to this hub is authenticated and acknowledged with CMD_STATUS_UPDATE_RESP before it gets here, whatever event it carries. Logs at INFO with diagnostic_probes: true and at DEBUG otherwise, since a subscription outlives the build that made it and must not fill a normal build's log.

Parameters
frameThe received frame; its source is a registered device.

Definition at line 897 of file hub_status.cpp.

Here is the call graph for this function:

◆ record_if_device_event_()

bool esphome::home_io_control::IOHomeControlComponent::record_if_device_event_ ( const IoFrame & frame,
bool reached_unhandled_fallback )
protected

Record frame as a device event when it qualifies: its source is a registered device and it is either a device event report (decisions::is_device_event_report()), or any frame that reached the unhandled-command fallback while diagnostic_probes is on.

Parameters
frameThe received frame.
reached_unhandled_fallbackTrue from the fallback after every other handler declined.
Returns
true when the frame was recorded.

Definition at line 881 of file hub_status.cpp.

Here is the call graph for this function:

◆ record_oneway_pairing_gesture_()

void esphome::home_io_control::IOHomeControlComponent::record_oneway_pairing_gesture_ ( const IoFrame & frame,
uint32_t now )
protected

If frame matches a 1W remote's pairing gesture (decisions::is_one_way_pairing_gesture()), remember it (src/dst/cmd plus the radio's last-capture RSSI) in recent_oneway_pairing_sighting_ so a fresh discover_and_pair() attempt can seed its telemetry with it — see RecentOneWayPairingSighting's doc comment (issue #27/#65).

A no-op for any other frame. Called from process_received_packet_()'s 1W-frame path, unconditionally (before the burst-dedup check, like record_1w_activity_()) so a repeated gesture frame still refreshes the timestamp (and RSSI).

Parameters
frameParsed 1W frame (CTRL0 1W bit already confirmed set by the caller).
nowmillis() at which this frame was seen.

Definition at line 856 of file hub_status.cpp.

Here is the call graph for this function:

◆ record_probe_reply_event()

bool esphome::home_io_control::IOHomeControlComponent::record_probe_reply_event ( const IoFrame & reply)

Record a diagnostic probe's reply on the "Last Device Event" sensor when it is a device event report (decisions::is_device_event_report()), such as the event a subscribe_event probe draws at once.

The reply is only recorded, never applied.

Parameters
replyThe probe's reply frame.
Returns
true when it was recorded.

Definition at line 893 of file hub_status.cpp.

Here is the call graph for this function:

◆ register_device_callback()

virtual void esphome::home_io_control::IOHomeControlComponent::register_device_callback ( DeviceUpdateCallback cb)
inlinevirtual

Register a callback invoked when any device updates.

Parameters
cbCallable with signature void(const std::string&, const IoDevice&).

Definition at line 521 of file hub_core.h.

Here is the call graph for this function:

◆ register_management_actions_()

void esphome::home_io_control::IOHomeControlComponent::register_management_actions_ ( )
inlineprotected

Register hub-level Home Assistant actions; called from setup().

Definition at line 1491 of file hub_core.h.

Here is the call graph for this function:

◆ rename_device()

virtual ManagementActionResult esphome::home_io_control::IOHomeControlComponent::rename_device ( const std::string & device_id,
const std::string & new_name )
inlinevirtual

Rename a device and verify the result by reading the name back.

Parameters
device_idTarget device ID.
new_nameRequested UTF-8 device name.
Returns
Structured result describing success, verification, and any validation failure.

Definition at line 599 of file hub_core.h.

Here is the call graph for this function:

◆ request_device_battery_level()

bool esphome::home_io_control::IOHomeControlComponent::request_device_battery_level ( const std::string & device_id)
virtual

Subscribe the device to EVENT_BATTERY_LEVEL_CHANGE and publish the level its answer carries.

Same rules as request_device_sun_level().

Parameters
device_idTarget device ID.
Returns
true if an answer of the captured shape arrived and was applied.

Definition at line 655 of file hub_operations.cpp.

Here is the call graph for this function:

◆ request_device_limitation()

bool esphome::home_io_control::IOHomeControlComponent::request_device_limitation ( const std::string & device_id)
virtual

Read the device's minimum limitation and derive its rain sensor state from the reply.

Unauthenticated read (CMD_LIMITATION_STATUS_REQ); the reply is accepted only inside this exchange (ADR 0022) and never reaches update_device_status_(), so a poll cannot move the device's position or target. A moving device is not asked: the poll is deferred instead.

Parameters
device_idTarget device ID.
Returns
true if a usable limitation reply arrived and was applied.

Definition at line 578 of file hub_operations.cpp.

Here is the call graph for this function:

◆ request_device_name()

bool esphome::home_io_control::IOHomeControlComponent::request_device_name ( const std::string & device_id)
virtual

Request the stored device name from a device.

Parameters
device_idTarget device ID.
Returns
true if a name response frame was received and processed.

Definition at line 774 of file hub_operations.cpp.

Here is the call graph for this function:

◆ request_device_status()

bool esphome::home_io_control::IOHomeControlComponent::request_device_status ( const std::string & device_id)
virtual

Request current status from a device.

Parameters
device_idTarget device ID.
Returns
true if status frame was received and processed.

Definition at line 511 of file hub_operations.cpp.

Here is the call graph for this function:

◆ request_device_sun_level()

bool esphome::home_io_control::IOHomeControlComponent::request_device_sun_level ( const std::string & device_id)
virtual

Subscribe the device to EVENT_LOCAL_SENSOR and publish the sun value its answer carries.

The answer is accepted only inside this exchange (decisions::is_subscription_answer(), ADR 0064) and never reaches the position decode. A moving device is not asked: the poll is deferred instead.

Parameters
device_idTarget device ID.
Returns
true if an answer of the captured shape arrived and was applied.

Definition at line 651 of file hub_operations.cpp.

Here is the call graph for this function:

◆ request_event_reading_()

bool esphome::home_io_control::IOHomeControlComponent::request_event_reading_ ( const std::string & device_id,
EventReading kind )
protected

Shared body of request_device_sun_level() and request_device_battery_level(): defer while the device moves, subscribe, decode the answer, fold the result into the device record.

Parameters
device_idTarget device ID.
kindWhich reading to poll.
Returns
true if an answer of the captured shape arrived and was applied.

Definition at line 692 of file hub_operations.cpp.

Here is the call graph for this function:

◆ resolve_1w_target_devices_()

std::vector< std::string > esphome::home_io_control::IOHomeControlComponent::resolve_1w_target_devices_ ( const OneWayFrameInfo & info,
const std::string & src_id ) const
nodiscardprotected

Resolve the set of devices a 1W frame should affect: devices linked to the sending remote by node ID, plus — when the frame targets a typed broadcast (e.g.

"all awnings") — devices linked to that device class, deduplicated so a device linked both ways is touched once.

Parameters
infoAlready-decoded 1W frame info (see decode_1w_frame()).
src_idSender's node ID as a string (already computed by the caller).
Returns
Deduplicated device IDs (may be empty).

Definition at line 615 of file hub_status.cpp.

Here is the call graph for this function:

◆ resolve_start_preamble_default_()

void esphome::home_io_control::IOHomeControlComponent::resolve_start_preamble_default_ ( )
protected

Resolve normal_start_preamble from the driver when YAML did not set it (ADR 0042).

Take the directed start preamble from the driver when YAML did not choose one.

Runs once, after the radio exists and before the first transmit. How much preamble a start frame needs depends on what the driver actually puts on air, so the default is the driver's to give (ADR 0042); an explicit normal_start_preamble: always wins, including a shorter value. The resolved value is reported by dump_config(), not from here — see the note in its body.

Definition at line 229 of file hub_core.cpp.

Here is the call graph for this function:

◆ run_execute_operation_()

bool esphome::home_io_control::IOHomeControlComponent::run_execute_operation_ ( const std::string & device_id,
const ExecuteRequestSpec & spec,
const std::function< bool(const IoDevice &)> & accepts,
const char * rejection_profile,
const std::function< bool(IoFrame &, const IoDevice &)> & build )
protected

Funnel for the four execute-family operations: runs try_execute_operation_() and, on any false return (the command will not reach the device), withdraws the optimistic prediction the entity applied at control() time via DeviceRegistry::rollback_optimistic().

Wrapping rather than inlining the rollback keeps every current and future failure exit covered by one call.

Parameters
device_idTarget device ID.
specPre-formatted action phrase and the settle-as-stop flag.
acceptsCapability guard; returns false to reject the operation for this device.
rejection_profileExpected-profile label for the rejection log.
buildFills the request frame from the resolved device; returns false on failure.
Returns
true when the exchange succeeded and the settle poll was armed.

Definition at line 337 of file hub_operations.cpp.

Here is the call graph for this function:

◆ scan_paired_devices()

virtual ManagementActionResult esphome::home_io_control::IOHomeControlComponent::scan_paired_devices ( )
inlinevirtual

Broadcast a roll-call and report every device that answers (see ManagementActions::scan_paired_devices() for the full contract: only key-holding devices answer, DeviceRegistry is never written, and zero replies is a successful result).

Returns
Structured result whose message is the full multi-line report.

Definition at line 627 of file hub_core.h.

Here is the call graph for this function:

◆ schedule_background_poll_backoff_()

void esphome::home_io_control::IOHomeControlComponent::schedule_background_poll_backoff_ ( const std::string & device_id,
bool auth_like,
bool device_moving = false )
protected

Apply backoff after a failed background status poll and log the result.

Parameters
device_idTarget device ID.
auth_likeTrue when the failed exchange saw a 0x3C challenge.
device_movingTrue when the failed request was a single-try status poll of a device the hub believes is travelling; its first misses keep the normal cadence (StatusPollPolicy::on_exchange_failed()).

Definition at line 378 of file hub_core.cpp.

Here is the call graph for this function:

◆ schedule_device_polls_()

void esphome::home_io_control::IOHomeControlComponent::schedule_device_polls_ ( const std::vector< std::string > & device_ids,
uint32_t delay_ms )
protected

Schedule status polls for a fixed list of devices (shared by the id-linked and class-linked 1W paths).

Parameters
device_idsDevices to poll.
delay_msPoll delay in milliseconds.

Definition at line 545 of file hub_status.cpp.

Here is the call graph for this function:

◆ schedule_heating_poll_()

void esphome::home_io_control::IOHomeControlComponent::schedule_heating_poll_ ( const std::string & device_id,
uint32_t delay_ms )
protected

Arm the heater's regular-cadence poll timer.

Own timer id (decisions::heating_poll_timer_id()), so remote-activity polls scheduled by schedule_status_poll_() never replace it.

Parameters
device_idID of the heater.
delay_msDelay in milliseconds before the poll is queued.

Definition at line 537 of file hub_status.cpp.

Here is the call graph for this function:

◆ schedule_status_poll_()

void esphome::home_io_control::IOHomeControlComponent::schedule_status_poll_ ( const std::string & device_id,
uint32_t delay_ms )
protected

Schedule a delayed status poll for a registered device using the Component timeout API.

Parameters
device_idID of the device to poll.
delay_msDelay in milliseconds before polling.
Note
Uses ESPHome's set_timeout() mechanism; the callback executes in loop(). A zero delay schedules immediately on the next loop iteration.

Definition at line 522 of file hub_status.cpp.

Here is the call graph for this function:

◆ select_and_construct_radio_()

RadioDriver * esphome::home_io_control::IOHomeControlComponent::select_and_construct_radio_ ( const char ** chip_name_out)
protected

Select and construct the radio driver named by the required radio_type config field.

Kept as its own method rather than inlined into setup(): the three-way chip branch (SX1276/SX1262/LR1121) is enough logic on its own that folding it into setup() pushes that function's cognitive complexity past clang-tidy's threshold. Validates the pins each driver needs and logs a clear error (without calling mark_failed() itself — the caller decides how to react) when a required pin is missing. On success, *chip_name_out is set to a static string naming the selected chip (used for logging), and the returned pointer is the heap-allocated (not yet initialized) driver instance.

Parameters
chip_name_outOutput: human-readable chip name for logging (always set, even on failure, to the best-known name for error messages).
Returns
Newly allocated RadioDriver, or nullptr if pin validation or allocation failed.

Definition at line 164 of file hub_core.cpp.

Here is the call graph for this function:

◆ send_and_receive_()

ExchangeOutcome esphome::home_io_control::IOHomeControlComponent::send_and_receive_ ( const IoFrame & request,
IoFrame & response,
uint32_t freq,
const decisions::AttemptRequest & attempts = EXCHANGE_RETRY_COUNT )
protected

Main request/response exchange with retry and automatic authentication.

Delegate outbound exchange to ExchangeEngine and manage the busy_ flag.

Parameters
requestOutbound request IoFrame.
responseOutput: received response IoFrame.
freqRF frequency in Hz.
attemptsA transmit-attempt cap (forwarded to ExchangeEngine::send_and_receive()), or a read kind whose plan the engine builds for request (ExchangeEngine::plan_read()).
Returns
true if exchange succeeded; false otherwise.

Definition at line 313 of file hub_core.cpp.

Here is the call graph for this function:

◆ send_heating_command()

bool esphome::home_io_control::IOHomeControlComponent::send_heating_command ( const std::string & device_id,
HeatingFunction fn,
float value )
virtual

Run one heating function on the heater's private register protocol (CMD_WRITE_PRIVATE 0x20): a write for a settable register, a read for a read-only one (power_on, midnight_sync).

Both the heating_control hub action and the climate entity's writes call this; together with read_heating_register() it is the only place heating frames are built and sent, through one shared exchange helper.

Flow: registry lookup -> device_supports_climate_control() gate (rejected via detail::log_rejected_operation()) -> encode_heating_payload() -> create_write_private() (with the device's low_power flag) -> a plain send_and_receive_(). Deliberately NOT routed through execute_request_and_update_(): that helper is cover/position-shaped (status decode, poll backoff). A CMD_WRITE_PRIVATE_ACK (0x21) reply is success; anything else (including CMD_ERROR_RESP) is failure. The exchange still feeds the device-agnostic Last Contact / Exchange Failures link-health sensors. The ack carries no state: a caller that wants the value the heater now holds reads it back with read_heating_register(). An acknowledged write also moves the heater's next poll to HEATING_POST_WRITE_POLL_DELAY_MS from now, so the regulator state (heating / idle) follows the change.

Parameters
device_idTarget device ID (hex string).
fnHeating function to send.
valueFunction-specific value (degrees C, a HeatingMode as float, 0/1, or ignored) — see encode_heating_payload().
Returns
true only if the device answered with CMD_WRITE_PRIVATE_ACK.

Definition at line 938 of file hub_operations.cpp.

Here is the call graph for this function:

◆ send_oneway_action()

void esphome::home_io_control::IOHomeControlComponent::send_oneway_action ( const std::string & controller_id,
OneWayButtonAction action )
inline

Queue whichever of position/command a generated button's action resolves to.

The mapping is applied here, at enqueue time, so the queue only ever holds concrete operations — OPEN and CLOSE are positions on the wire, not commands, and nothing downstream should have to know that twice.

Parameters
controller_idController-identity handle from oneway_controllers:.
actionButton action to send.

Definition at line 369 of file hub_core.h.

Here is the call graph for this function:

◆ send_oneway_command()

void esphome::home_io_control::IOHomeControlComponent::send_oneway_command ( const std::string & controller_id,
CoverCommand cmd )
inline

Queue a 1W named command, sent as the given controller identity.

Goes through the operation queue like every other radio operation (ADR 0013), so a 1W burst can never interleave with a 2W exchange. Unlike a 2W command this reports nothing back: 1W has no reply, so a queued command that a device ignores is indistinguishable from one it obeyed. The "Last 1W Command" diagnostic reports what was transmitted, which is the only half of that the hub can know.

Parameters
controller_idController-identity handle from oneway_controllers:.
cmdNamed command (STOP, FAVORITE, VENT, FORCE_OPEN); PARTIAL and PEDESTRIAN have no 1W encoding and are not transmitted.

Definition at line 350 of file hub_core.h.

Here is the call graph for this function:

◆ send_oneway_enroll()

void esphome::home_io_control::IOHomeControlComponent::send_oneway_enroll ( const std::string & controller_id)
inline

Queue a 1W enrollment for the given controller identity — the enroll button's press handler.

Sends 0x39 (self-directed) then 0x30, back to back — see OneWayTransmitter::send_enrollment().

Parameters
controller_idController-identity handle from oneway_controllers:.

Definition at line 384 of file hub_core.h.

Here is the call graph for this function:

◆ send_oneway_position()

void esphome::home_io_control::IOHomeControlComponent::send_oneway_position ( const std::string & controller_id,
uint8_t position )
inline

Queue a 1W numeric position, sent as the given controller identity.

Parameters
controller_idController-identity handle from oneway_controllers:.
positionTarget position 0–100 (0 = fully open, 100 = fully closed), as the user means it; the transmitter mirrors it on the wire for an inverted identity (effective_inverted()).

Definition at line 358 of file hub_core.h.

Here is the call graph for this function:

◆ send_oneway_unenroll()

void esphome::home_io_control::IOHomeControlComponent::send_oneway_unenroll ( const std::string & controller_id)
inline

Queue a standalone 1W un-enrollment (remove-controller) for the given controller identity, reached only through the explicitly-named oneway_remove_controller native API action — the same 0x39 send_oneway_enroll() also fires as its own prelude, but here alone.

Warning
Works only inside the receiver's programming window. Confirmed on a Somfy Izymo dimmer only: put the receiver in its programming mode first, then fire this; with no window open it changes nothing. Other receivers are untested. See ADR 0026 § Consequences.
Parameters
controller_idController-identity handle from oneway_controllers:.

Definition at line 394 of file hub_core.h.

Here is the call graph for this function:

◆ set_busy_pin()

void esphome::home_io_control::IOHomeControlComponent::set_busy_pin ( InternalGPIOPin * pin)
inline

Set the BUSY pin (SX1262/LR1121).

Definition at line 212 of file hub_core.h.

◆ set_device_battery_level_poll_interval()

void esphome::home_io_control::IOHomeControlComponent::set_device_battery_level_poll_interval ( const std::string & device_id,
uint32_t interval_ms )
virtual

Opt a registered device into the periodic battery level poll (a subscription to EVENT_BATTERY_LEVEL_CHANGE, whose answer carries the level; ADR 0064).

Parameters
device_idTarget device ID.
interval_msPoll interval in milliseconds; zero removes the device from the schedule.

Definition at line 361 of file hub_core.cpp.

Here is the call graph for this function:

◆ set_device_event_callback()

void esphome::home_io_control::IOHomeControlComponent::set_device_event_callback ( std::function< void()> cb)
inline

Register a callback invoked after every recorded device event, used by the "Last Device Event" text sensor.

Single-slot, mirrors set_pairing_result_callback().

Parameters
cbCallable with no arguments.

Definition at line 437 of file hub_core.h.

◆ set_device_position()

bool esphome::home_io_control::IOHomeControlComponent::set_device_position ( const std::string & device_id,
uint8_t position )
virtual

Send a position command to a device.

Parameters
device_idTarget device ID.
positionDesired position, 0–100 (open→closed). Named commands (STOP, FAVORITE, VENT) go through execute_device_command_()/create_execute_command() instead.
Returns
true if device acknowledged; false on timeout or radio error, or when the device's features do not accept the value (an intermediate position on a device without device_feature::LEVELS): nothing is sent and the optimistic target is withdrawn.

Definition at line 405 of file hub_operations.cpp.

Here is the call graph for this function:

◆ set_device_position_and_tilt()

bool esphome::home_io_control::IOHomeControlComponent::set_device_position_and_tilt ( const std::string & device_id,
uint8_t position,
uint8_t tilt_percent )
virtual

Set both position and tilt of a tilt-capable cover in one atomic command.

Parameters
device_idTarget device ID.
positionDesired position (0–100, open→closed).
tilt_percentDesired tilt (0–100).
Returns
true if device acknowledged; false otherwise.

Definition at line 469 of file hub_operations.cpp.

Here is the call graph for this function:

◆ set_device_rain_poll_interval()

void esphome::home_io_control::IOHomeControlComponent::set_device_rain_poll_interval ( const std::string & device_id,
uint32_t interval_ms )
virtual

Opt a registered device into the periodic rain sensor poll (a read of its minimum limitation).

Parameters
device_idTarget device ID.
interval_msPoll interval in milliseconds; zero removes the device from the schedule.

Definition at line 349 of file hub_core.cpp.

Here is the call graph for this function:

◆ set_device_status_poll_interval()

void esphome::home_io_control::IOHomeControlComponent::set_device_status_poll_interval ( const std::string & device_id,
uint32_t poll_interval_ms )
virtual

Configure the optional follow-up polling interval for a registered device.

Parameters
device_idTarget device ID.
poll_interval_msPoll interval in milliseconds; zero keeps the legacy one-shot settle poll only.

Definition at line 343 of file hub_core.cpp.

Here is the call graph for this function:

◆ set_device_status_refresh_interval()

void esphome::home_io_control::IOHomeControlComponent::set_device_status_refresh_interval ( const std::string & device_id,
uint32_t interval_ms )
virtual

Opt a registered device into the status refresh at rest: a status read whenever the device has not reported its status for a whole interval.

Parameters
device_idTarget device ID.
interval_msRefresh interval in milliseconds; zero removes the device from the schedule.

Definition at line 368 of file hub_core.cpp.

Here is the call graph for this function:

◆ set_device_sun_poll_interval()

void esphome::home_io_control::IOHomeControlComponent::set_device_sun_poll_interval ( const std::string & device_id,
uint32_t interval_ms )
virtual

Opt a registered device into the periodic sun level poll (a subscription to EVENT_LOCAL_SENSOR, whose answer carries the value; ADR 0064).

Parameters
device_idTarget device ID.
interval_msPoll interval in milliseconds; zero removes the device from the schedule.

Definition at line 355 of file hub_core.cpp.

Here is the call graph for this function:

◆ set_device_temperature_range()

void esphome::home_io_control::IOHomeControlComponent::set_device_temperature_range ( const std::string & device_id,
float min_c,
float max_c )
virtual

Set the temperature encoding range of a heater that carries a temperature in its main parameter (YAML min_temperature: / max_temperature:).

Parameters
device_idTarget device ID.
min_cLower end of the range in degrees Celsius.
max_cUpper end; must exceed min_c.

Definition at line 880 of file hub_operations.cpp.

Here is the call graph for this function:

◆ set_device_tilt()

bool esphome::home_io_control::IOHomeControlComponent::set_device_tilt ( const std::string & device_id,
uint8_t tilt_percent )
virtual

Send a tilt command to a tilt‑capable cover.

Parameters
device_idTarget device ID.
tilt_percentDesired tilt (0–100).
Returns
true if device acknowledged; false otherwise.

Definition at line 458 of file hub_operations.cpp.

Here is the call graph for this function:

◆ set_device_travel_speed()

void esphome::home_io_control::IOHomeControlComponent::set_device_travel_speed ( const std::string & device_id,
TravelSpeed speed )
virtual

Select a device's travel speed at runtime (see IOHomeCoverTravelSpeedSelect and IOHomeCoverSilentSwitch).

Virtual so platform tests can substitute a mock registry.

Parameters
device_idHexadecimal node ID string.
speedSpeed profile of the device's position moves.

Definition at line 404 of file hub_core.cpp.

Here is the call graph for this function:

◆ set_dhw_operating_mode_()

bool esphome::home_io_control::IOHomeControlComponent::set_dhw_operating_mode_ ( const std::string & device_id,
DhwOperatingFeature which,
bool on )
protected

Switch a water heater's boost or away through the operating-mode word (ADR 0081).

Refused and logged when FP15 has been read and lacks the feature's capability bit. On: the duration register write (its ack is logged, a missed one does not stop the sequence), then one EXECUTE with MAIN_PARAMETER_KEEP and the feature's FP16. Off: the EXECUTE with DHW_OPERATING_MODE_OFF only. After an accepted EXECUTE the status is read at once and the next poll moves to HEATING_POST_WRITE_POLL_DELAY_MS from now.

Parameters
device_idTarget device ID.
whichBoost or away.
ontrue to start it, false to end it (which ends the other too).
Returns
true when the device accepted the EXECUTE.

Definition at line 1480 of file hub_operations.cpp.

Here is the call graph for this function:

◆ set_diagnostic_probes_enabled()

void esphome::home_io_control::IOHomeControlComponent::set_diagnostic_probes_enabled ( bool enabled)
inline

Set whether DiagnosticProbes::probe_device()/probe_sweep() are allowed to run.

Set once from the diagnostic_probes: YAML boolean (__init__.py); off by default, so a build that doesn't opt in never sends an undecoded probe opcode. Not a runtime toggle: there is no entity and nothing else calls this after setup — the gate is "was this build configured with `diagnostic_probes: true`", not a state a user flips per session.

Parameters
enabledDesired state.

Definition at line 491 of file hub_core.h.

◆ set_dio0_pin()

void esphome::home_io_control::IOHomeControlComponent::set_dio0_pin ( InternalGPIOPin * pin)
inline

Set the DIO0 interrupt pin (SX1276).

Definition at line 206 of file hub_core.h.

◆ set_dio1_pin()

void esphome::home_io_control::IOHomeControlComponent::set_dio1_pin ( InternalGPIOPin * pin)
inline

Set the DIO1 interrupt pin (SX1262; also carries the LR1121's DIO9 IRQ line).

Definition at line 210 of file hub_core.h.

◆ set_dio4_pin()

void esphome::home_io_control::IOHomeControlComponent::set_dio4_pin ( InternalGPIOPin * pin)
inline

Set the DIO4 preamble‑detect pin (SX1276, optional).

Definition at line 208 of file hub_core.h.

◆ set_fan_position()

bool esphome::home_io_control::IOHomeControlComponent::set_fan_position ( const std::string & device_id,
uint8_t position )
virtual

Send a heat level to an exterior heater (a fan entity) as an IO position.

Mapped to the shared execute path, like set_light_position().

Parameters
device_idTarget device ID.
positionDesired IO position (0-100): 0 = full heat, 100 = off (the KLF 200 exterior heating mapping, MP = position x 0x200).
Returns
true if device acknowledged.

Definition at line 800 of file hub_operations.cpp.

Here is the call graph for this function:

◆ set_fem_en_pin()

void esphome::home_io_control::IOHomeControlComponent::set_fem_en_pin ( InternalGPIOPin * pin)
inline

Set the front‑end module enable pin.

Definition at line 214 of file hub_core.h.

◆ set_fem_pa_pin()

void esphome::home_io_control::IOHomeControlComponent::set_fem_pa_pin ( InternalGPIOPin * pin)
inline

Set the FEM PA switch pin.

Definition at line 218 of file hub_core.h.

◆ set_fem_profile()

void esphome::home_io_control::IOHomeControlComponent::set_fem_profile ( FemProfile profile)
inline

Set which FEM part fem_pa_pin is wired to (fem: in YAML) — selects whether the SX1262 driver drives that pin per-transmission (GC1109/KCT8103L/XY16P35) or leaves it static-HIGH (NONE, the legacy raw-pin behaviour).

Definition at line 222 of file hub_core.h.

◆ set_heating_level()

bool esphome::home_io_control::IOHomeControlComponent::set_heating_level ( const std::string & device_id,
uint8_t level )
virtual

Set the heating level of a heater that is commanded with levels (the plain electrical heater).

A main-parameter-only EXECUTE through the execute-family funnel; the settle poll that follows reads the level back with the ordinary status read, and the climate entity shows that reading. Experimental: unconfirmed on hardware.

Parameters
device_idTarget device ID (hex string).
levelHeating level low byte (heating_level::*).
Returns
true when the device accepted the command.

Definition at line 848 of file hub_operations.cpp.

Here is the call graph for this function:

◆ set_heating_temperature()

bool esphome::home_io_control::IOHomeControlComponent::set_heating_temperature ( const std::string & device_id,
uint16_t main_parameter,
const HeatingFp & fp )
virtual

Command a heater that carries a temperature or an alias in its main parameter (the heating temperature interface and the heat pump).

A main-parameter-only EXECUTE, or one that also carries functional parameter 9 when the profile sends mode flags, through the execute-family funnel; the settle poll that follows reads the state back with the ordinary status read. Experimental: unconfirmed on hardware.

Parameters
device_idTarget device ID (hex string).
main_parameterThe 16-bit main parameter (encode_temperature_main_parameter() or an alias).
fpThe functional parameter that accompanies it, if any (kind NONE sends a main-parameter-only EXECUTE).
Returns
true when the device accepted the command.

Definition at line 859 of file hub_operations.cpp.

Here is the call graph for this function:

◆ set_key_extraction_armed()

virtual void esphome::home_io_control::IOHomeControlComponent::set_key_extraction_armed ( bool armed)
inlinevirtual

Arm or disarm the "Recover System Key" (key extraction) responder.

Thin forwarder to the KeyExtractionResponder collaborator (key_extraction_responder.h). Arming picks a fresh throwaway node ID, resets the pairing_responder state machine to ARMED_IDLE, and schedules a 10-minute auto-off. While armed, the 0x28/0x2C/0x31/0x32 branches in process_received_packet_() emulate an unpaired device so a user's existing hub can pair to it and hand over its node_id/system_key (see pairing_responder.h). Disarming — manual, via the HA switch, on successful extraction, or on auto-off — immediately stops those branches from responding; it never touches the real device registry or the hub's own node_id_/ system_key_. Virtual so platform unit tests can substitute a mock hub, matching every other queue_*‍/set_* entry point on this component.

Parameters
armedDesired state.

Definition at line 451 of file hub_core.h.

Here is the call graph for this function:

◆ set_key_extraction_armed_callback()

void esphome::home_io_control::IOHomeControlComponent::set_key_extraction_armed_callback ( std::function< void(bool)> cb)
inline

Register a callback invoked whenever the key-extraction armed state changes — manual toggle, successful extraction, or auto-off timeout — so the switch entity can keep its displayed state in sync when the hub disarms itself rather than the user.

Single-slot, mirrors set_pairing_result_callback().

Parameters
cbCallable receiving the new armed state.

Definition at line 458 of file hub_core.h.

Here is the call graph for this function:

◆ set_light_position()

bool esphome::home_io_control::IOHomeControlComponent::set_light_position ( const std::string & device_id,
uint8_t position )
virtual

Send an arbitrary IO position (0-100) to a light entity.

Internally mapped to the shared execute path. set_light_state() is a thin binary-position wrapper around this, used by dimmable lights to send anything other than the two binary extremes.

Parameters
device_idTarget device ID.
positionDesired IO position (0-100); this device family's convention maps 0 to full brightness and 100 to off, the same 0-100 scale platform_cover.cpp uses.
Returns
true if device acknowledged.

Definition at line 785 of file hub_operations.cpp.

Here is the call graph for this function:

◆ set_light_state()

bool esphome::home_io_control::IOHomeControlComponent::set_light_state ( const std::string & device_id,
bool on )
virtual

Semantic binary helper for light entities.

Internally mapped to the shared execute path.

Parameters
device_idTarget device ID.
onDesired on/off state.
Returns
true if device acknowledged.

Definition at line 815 of file hub_operations.cpp.

Here is the call graph for this function:

◆ set_lock_state()

bool esphome::home_io_control::IOHomeControlComponent::set_lock_state ( const std::string & device_id,
bool locked )
virtual

Semantic lock helper for lock entities.

Internally mapped to the shared execute path.

Parameters
device_idTarget device ID.
lockedDesired locked/unlocked state.
Returns
true if device acknowledged.

Definition at line 833 of file hub_operations.cpp.

Here is the call graph for this function:

◆ set_node_id()

void esphome::home_io_control::IOHomeControlComponent::set_node_id ( const std::string & id)
inline

Set the controller's node ID (hex string).

Definition at line 224 of file hub_core.h.

◆ set_oneway_key_adoption_armed()

virtual void esphome::home_io_control::IOHomeControlComponent::set_oneway_key_adoption_armed ( bool armed)
inlinevirtual

Arm or disarm the 1W controller-key adoption listener.

Thin forwarder to the OnewayKeyAdoption collaborator (oneway_key_adoption.h) — while armed, an overheard CMD_ONEWAY_ADD_CONTROLLER broadcast is decrypted and reported once, after which the listener disarms itself (one adoption per arm). Receive-only: unlike 2W key extraction this never transmits, it only listens for a frame a 1W device broadcasts of its own accord. Virtual so platform unit tests can substitute a mock hub, matching every other queue_*‍/set_* entry point on this component.

Parameters
armedDesired state.

Definition at line 469 of file hub_core.h.

Here is the call graph for this function:

◆ set_oneway_key_adoption_armed_callback()

void esphome::home_io_control::IOHomeControlComponent::set_oneway_key_adoption_armed_callback ( std::function< void(bool)> cb)
inline

Register a callback invoked whenever the 1W key-adoption armed state changes — manual toggle, successful adoption, or auto-off timeout — so the switch entity stays in sync when the hub disarms itself rather than the user.

Single-slot, mirrors set_key_extraction_armed_callback().

Parameters
cbCallable receiving the new armed state.

Definition at line 476 of file hub_core.h.

Here is the call graph for this function:

◆ set_pa_pin()

void esphome::home_io_control::IOHomeControlComponent::set_pa_pin ( uint8_t pa_pin)
inline

Set PA boost pin configuration.

Definition at line 230 of file hub_core.h.

◆ set_pairing_result_callback()

void esphome::home_io_control::IOHomeControlComponent::set_pairing_result_callback ( std::function< void()> cb)
inline

Register a callback invoked once, right after every discover_and_pair() attempt completes — used by the "Last Pairing Result" text sensor to publish a fresh value.

Single-slot: only one platform instance is expected per hub.

Parameters
cbCallable with no arguments.

Definition at line 417 of file hub_core.h.

◆ set_radio_test_mode()

void esphome::home_io_control::IOHomeControlComponent::set_radio_test_mode ( bool active)
inline

Suspend the hub's normal loop (packet processing, hopping, polling).

Used by loopback test configs to take exclusive control of the radio.

Definition at line 197 of file hub_core.h.

◆ set_radio_type()

void esphome::home_io_control::IOHomeControlComponent::set_radio_type ( const std::string & type)
inline

Set radio type ("sx1276", "sx1262", or "lr1121"); required by the YAML schema.

Definition at line 232 of file hub_core.h.

◆ set_rst_pin()

void esphome::home_io_control::IOHomeControlComponent::set_rst_pin ( InternalGPIOPin * pin)
inline

Set the radio reset pin.

Definition at line 204 of file hub_core.h.

◆ set_switch_state()

bool esphome::home_io_control::IOHomeControlComponent::set_switch_state ( const std::string & device_id,
bool on )
virtual

Semantic binary helper for switch entities.

Internally mapped to the shared execute path.

Parameters
device_idTarget device ID.
onDesired on/off state.
Returns
true if device acknowledged.

Definition at line 819 of file hub_operations.cpp.

Here is the call graph for this function:

◆ set_system_key()

void esphome::home_io_control::IOHomeControlComponent::set_system_key ( const std::string & key)
inline

Set the system key (hex string).

Definition at line 226 of file hub_core.h.

◆ set_tcxo_voltage()

void esphome::home_io_control::IOHomeControlComponent::set_tcxo_voltage ( uint8_t voltage)
inline

Set the SX1262/LR1121 TCXO control-voltage code (0-based, TCXO_VOLTAGE_OPTIONS in hub_validators.py: 1_6V=0x00 .

. 3_3V=0x07), or TCXO_VOLTAGE_NONE (0xFF) for a board with a bare crystal and no DIO3-controlled TCXO.

Definition at line 236 of file hub_core.h.

◆ set_tuning_config()

void esphome::home_io_control::IOHomeControlComponent::set_tuning_config ( const TuningConfig & config)
inline

Apply the tuning configuration generated from YAML / UI entities.

Definition at line 239 of file hub_core.h.

◆ set_tx_power()

void esphome::home_io_control::IOHomeControlComponent::set_tx_power ( uint8_t power)
inline

Set transmit power (dBm).

Definition at line 228 of file hub_core.h.

◆ set_vfem_pin()

void esphome::home_io_control::IOHomeControlComponent::set_vfem_pin ( InternalGPIOPin * pin)
inline

Set the VFEM power pin.

Definition at line 216 of file hub_core.h.

◆ set_water_heater_away()

bool esphome::home_io_control::IOHomeControlComponent::set_water_heater_away ( const std::string & device_id,
bool on )
virtual

Start or end a water heater's away (holiday) mode: a duration write of register 0x0005 (255, until turned off), then an EXECUTE with FP16 DHW_OPERATING_MODE_AWAY_ON, or DHW_OPERATING_MODE_OFF to end.

See set_dhw_operating_mode_() for the sequence. Ending away also ends a boost (ADR 0081). Gated on device_feature::WATER_HEATER.

Todo
Experimental: confirm on a real water heater that this starts and ends the holiday mode.
Parameters
device_idTarget device ID (hex string).
ontrue to start away, false to end it.
Returns
true when the device accepted the EXECUTE; false for a refused or unacknowledged command.

Definition at line 1524 of file hub_operations.cpp.

Here is the call graph for this function:

◆ set_water_heater_boost()

bool esphome::home_io_control::IOHomeControlComponent::set_water_heater_boost ( const std::string & device_id,
bool on )
virtual

Start or end a water heater's boost: a duration write of register 0x0000, then an EXECUTE with the operating-mode word FP16 (DHW_OPERATING_MODE_BOOST_ON, or DHW_OPERATING_MODE_OFF to end).

See set_dhw_operating_mode_() for the sequence. Ending a boost also ends away, because the off word switches both (ADR 0081). Gated on device_feature::WATER_HEATER.

Todo
Experimental: confirm on a real water heater that this starts and ends a boost.
Parameters
device_idTarget device ID (hex string).
ontrue to start a boost, false to end it.
Returns
true when the device accepted the EXECUTE; false for a refused or unacknowledged command.

Definition at line 1520 of file hub_operations.cpp.

Here is the call graph for this function:

◆ set_water_heater_mode()

bool esphome::home_io_control::IOHomeControlComponent::set_water_heater_mode ( const std::string & device_id,
DhwMode mode )
virtual

Set a water heater's operating mode: a write of register 0x0006 (encode_dhw_mode_write()).

The register is read back at once, so the entity shows what the heater then holds, and so is the target (the status read of the poll), which the mode decides. The next poll moves to HEATING_POST_WRITE_POLL_DELAY_MS from now so the heating state follows the change. Gated on device_feature::WATER_HEATER. The heater's display follows the mode (issue #198).

Parameters
device_idTarget device ID (hex string).
modeMode to write.
Returns
true only if the device acknowledged the write; a missed read-back does not change that.

Definition at line 1445 of file hub_operations.cpp.

Here is the call graph for this function:

◆ set_water_heater_target()

bool esphome::home_io_control::IOHomeControlComponent::set_water_heater_target ( const std::string & device_id,
float celsius )
virtual

Set a water heater's target temperature.

A main-parameter-only EXECUTE with the target on the relative scale over DHW_TARGET_MIN_C.. DHW_TARGET_MAX_C (encode_dhw_target()), through the execute-family exchange without the cover's movement bookkeeping. The settle poll that follows (poll_dhw_device_()) reads the target back from the status reply. Gated on device_feature::WATER_HEATER. The heater's display follows the target (issue #198).

Parameters
device_idTarget device ID (hex string).
celsiusTarget in degrees Celsius; a value outside the heater's range is refused, not clamped.
Returns
true when the device accepted the command.

Definition at line 1376 of file hub_operations.cpp.

Here is the call graph for this function:

◆ settle_ended_status_tracking_()

void esphome::home_io_control::IOHomeControlComponent::settle_ended_status_tracking_ ( )
protected

Settle every device whose polling window ran out (StatusPollPolicy::pop_ended_device()).

A device still settling — its last report said "stopped" off its target and the confirming poll never came back — is taken as at rest there: with no poll left, the device's own flag stands. Any other device is left as it is.

Definition at line 487 of file hub_status.cpp.

Here is the call graph for this function:

◆ setup()

void esphome::home_io_control::IOHomeControlComponent::setup ( )
override

Initialize hardware (radio and device registry).

Initialize the IO‑Homecontrol component and radio hardware.

This is the main setup entry point called by ESPHome during startup. The sequence:

  1. Parse node_id and system_key from hex strings (fails early if malformed).
  2. Initialize the SPI bus via spi_setup().
  3. Construct the driver named by the required radio_type YAML field ("sx1276", "sx1262", or "lr1121").
  4. Allocate the appropriate RadioDriver (SX1276 needs DIO0; SX1262/LR1121 need BUSY+DIO1, DIO1 carrying the LR1121's DIO9 IRQ line).
  5. Call radio_->init() which performs chip reset, calibration, and register configuration.
  6. Enter normal loop() operation with radio in RX mode.
Note
setup() raises ESPHome's blocking-warning threshold (warn_if_blocking_over_) for this component to 2.5 s, because radio init and every exchange exceed the default 30–50 ms.

Definition at line 77 of file hub_core.cpp.

Here is the call graph for this function:

◆ spi_disable()

void esphome::home_io_control::IOHomeControlComponent::spi_disable ( )
inlineoverridevirtual

Disable the SPI bus.

Implements esphome::home_io_control::SpiAccess.

Definition at line 183 of file hub_core.h.

◆ spi_enable()

void esphome::home_io_control::IOHomeControlComponent::spi_enable ( )
inlineoverridevirtual

Enable the SPI bus.

Implements esphome::home_io_control::SpiAccess.

Definition at line 181 of file hub_core.h.

◆ spi_read()

uint8_t esphome::home_io_control::IOHomeControlComponent::spi_read ( )
inlineoverridevirtual

Read one byte (MISO only).

Returns
Received byte.

Implements esphome::home_io_control::SpiAccess.

Definition at line 193 of file hub_core.h.

◆ spi_transfer()

uint8_t esphome::home_io_control::IOHomeControlComponent::spi_transfer ( uint8_t data)
inlineoverridevirtual

Transfer one byte full‑duplex.

Parameters
dataByte to send.
Returns
Received byte.

Implements esphome::home_io_control::SpiAccess.

Definition at line 187 of file hub_core.h.

◆ spi_write()

void esphome::home_io_control::IOHomeControlComponent::spi_write ( uint8_t data)
inlineoverridevirtual

Write one byte (MOSI only).

Parameters
dataByte to send.

Implements esphome::home_io_control::SpiAccess.

Definition at line 190 of file hub_core.h.

◆ transmit_frame_()

bool esphome::home_io_control::IOHomeControlComponent::transmit_frame_ ( const IoFrame & frame,
uint32_t freq,
uint16_t preamble )
protected

Transmit a raw IoFrame on the current frequency with given preamble length.

Delegate LBT transmit to ExchangeEngine.

Parameters
frameIoFrame to transmit.
freqRF frequency in Hz.
preamblePreamble length in bytes (e.g. LONG_PREAMBLE, SHORT_PREAMBLE, or a tuning-configured value such as normal_start_preamble).

Definition at line 308 of file hub_core.cpp.

Here is the call graph for this function:

◆ trigger_scan_paired_devices()

void esphome::home_io_control::IOHomeControlComponent::trigger_scan_paired_devices ( )

Entry point for the "Scan Paired Devices" button: run the roll-call and publish its report to the log and the Home Assistant result event, exactly as the native API action does.

Deliberately not queued through OperationQueue, unlike queue_discover_and_pair(): the roll-call has no priority, coalescing or dedup semantics to preserve, and it already runs this way from the native API action. What it is guarded on is busy_ — a button, unlike an API action, is also reachable from an ESPHome automation, which can fire from inside a blocking exchange (an entity callback -> on_value: -> button.press: chain) and would otherwise re-enter ExchangeEngine mid-exchange. See ADR 0013 for why one blocking radio operation at a time is the whole concurrency model. A press while busy_ still fires the log/event pair (a failed result), matching every other rejected management action rather than going silent.

Blocks the ESPHome loop for up to roughly 6 × pairing_discovery_wait_ms (both power-class passes, three channels each; fewer if scan_power_classes narrows the sweep) and will log the "operation took a long time" warning, same as the action — see docs/pairing.md.

Definition at line 1656 of file hub_operations.cpp.

Here is the call graph for this function:

◆ try_execute_operation_()

bool esphome::home_io_control::IOHomeControlComponent::try_execute_operation_ ( const std::string & device_id,
const ExecuteRequestSpec & spec,
const std::function< bool(const IoDevice &)> & accepts,
const char * rejection_profile,
const std::function< bool(IoFrame &, const IoDevice &)> & build )
protected

Shared skeleton for the four execute-family operations (position, named command, tilt, position+tilt): device lookup + initialized guard, capability guard, poll-tracking start, "Sending ..." log, frame build, exchange, failure backoff, and the settle poll.

The four public methods supply only their guard predicate, rejection profile label, and frame builder. Called only through run_execute_operation_(), which owns the failure rollback.

Parameters
device_idTarget device ID.
specPre-formatted action phrase and the settle-as-stop flag.
acceptsCapability guard; returns false to reject the operation for this device.
rejection_profileExpected-profile label for the rejection log.
buildFills the request frame from the resolved device; returns false on failure.
Returns
true when the exchange succeeded and the settle poll was armed.

Definition at line 366 of file hub_operations.cpp.

Here is the call graph for this function:

◆ update_device_status_()

void esphome::home_io_control::IOHomeControlComponent::update_device_status_ ( const IoFrame & frame,
bool trust_position = true )
protected

Extract supported position or metadata info from a response frame and merge it into the device record.

Parameters
frameIoFrame containing a supported inbound command such as CMD_PRIVATE_RESP, CMD_STATUS_UPDATE, CMD_GET_NAME_RESP, or CMD_GET_INFO2_RESP.
trust_positionFalse to apply is_stopped but skip target/position decode for a CMD_PRIVATE_RESP — the immediate reply to our own just-sent CMD_EXECUTE echoes stale pre-command target/current values on at least some devices (see tests/corpus/captures/exchange/somfy_awning_exchange_ack_reports_stale_target_*.yaml), so execute_request_and_update_() passes false there; every other caller trusts as before.

Definition at line 745 of file hub_status.cpp.

Here is the call graph for this function:

◆ update_tuning_number()

void esphome::home_io_control::IOHomeControlComponent::update_tuning_number ( const std::string & name,
float value )

Receive a numeric tuning update from a HA number entity.

Update a numeric tuning parameter from a Home Assistant number entity.

Parses the parameter name and applies the new value to the in-memory tuning configuration. Radio-affecting parameters are forwarded to the active driver immediately; the change is logged in YAML-compatible form so it can be copied back into the configuration file.

Definition at line 243 of file hub_core.cpp.

Here is the call graph for this function:

◆ update_tuning_select()

void esphome::home_io_control::IOHomeControlComponent::update_tuning_select ( const std::string & name,
const std::string & value )

Receive a select tuning update from a HA select entity.

Update a select tuning parameter from a Home Assistant select entity.

Parses the selected option string and applies it to the in-memory tuning configuration. Radio-affecting parameters are forwarded to the active driver immediately; the change is logged in YAML-compatible form.

Definition at line 260 of file hub_core.cpp.

Here is the call graph for this function:

◆ water_heater_for_write_()

const IoDevice * esphome::home_io_control::IOHomeControlComponent::water_heater_for_write_ ( const std::string & device_id,
const char * operation )
protected

The water heater device_id names, or nullptr when it is unknown, the hub is not set up yet, or the device is no water heater (that case is logged).

The gate of every water heater write.

Parameters
device_idTarget device ID.
operationWhat is being written, for the rejection log line.
Returns
The device record, or nullptr.

Definition at line 1403 of file hub_operations.cpp.

Here is the call graph for this function:

◆ write_dhw_register_()

bool esphome::home_io_control::IOHomeControlComponent::write_dhw_register_ ( const std::string & device_id,
const char * operation,
uint8_t index,
const uint8_t * payload,
size_t payload_len )
protected

Write one family-0x00 register of a water heater, then read it back.

Shared by the mode setter and the boost and away duration writes, each of which encodes its own payload. Gated on device_feature::WATER_HEATER; the write has the full retry budget, the read-back (read_dhw_reading_()) updates IoDevice::dhw, and the next poll moves to HEATING_POST_WRITE_POLL_DELAY_MS from now.

Parameters
device_idTarget device ID.
operationWhat is written, for the log ("hot water mode").
indexThe register written, which is also the one read back.
payloadThe encoded write (0C 61 00 <index> <value>).
payload_lenIts length.
Returns
true only if the device acknowledged the write; a missed read-back does not change that.

Definition at line 1414 of file hub_operations.cpp.

Here is the call graph for this function:

Member Data Documentation

◆ battery_level_poll_policy_

PeriodicPollPolicy esphome::home_io_control::IOHomeControlComponent::battery_level_poll_policy_
protected

Schedule of the opt-in battery level poll.

Definition at line 1622 of file hub_core.h.

◆ busy_

bool esphome::home_io_control::IOHomeControlComponent::busy_ {false}
protected

Definition at line 1600 of file hub_core.h.

◆ busy_pin_

InternalGPIOPin* esphome::home_io_control::IOHomeControlComponent::busy_pin_ {nullptr}
protected

SX1262/LR1121 BUSY pin.

Definition at line 1575 of file hub_core.h.

◆ device_event_callback_

std::function<void()> esphome::home_io_control::IOHomeControlComponent::device_event_callback_
protected

Definition at line 1614 of file hub_core.h.

◆ device_event_count_

uint32_t esphome::home_io_control::IOHomeControlComponent::device_event_count_ {0}
protected

Device events recorded since boot, the last one's text and its subscriber; see record_device_event_().

Definition at line 1612 of file hub_core.h.

◆ diagnostic_probes_enabled_

bool esphome::home_io_control::IOHomeControlComponent::diagnostic_probes_enabled_ {false}
protected

Whether diagnostic probes (DiagnosticProbes::probe_device()/probe_sweep()) are enabled.

False by default so a build that didn't opt in via diagnostic_probes: true never sends an undecoded probe opcode. See set_diagnostic_probes_enabled().

Definition at line 1618 of file hub_core.h.

◆ dio0_pin_

InternalGPIOPin* esphome::home_io_control::IOHomeControlComponent::dio0_pin_ {nullptr}
protected

SX1276 DIO0 interrupt.

Definition at line 1572 of file hub_core.h.

◆ dio1_pin_

InternalGPIOPin* esphome::home_io_control::IOHomeControlComponent::dio1_pin_ {nullptr}
protected

SX1262 DIO1 interrupt; also carries the LR1121's DIO9 IRQ line.

Definition at line 1574 of file hub_core.h.

◆ dio4_pin_

InternalGPIOPin* esphome::home_io_control::IOHomeControlComponent::dio4_pin_ {nullptr}
protected

SX1276 DIO4 preamble detect (optional).

Definition at line 1573 of file hub_core.h.

◆ exchange_engine_

ExchangeEngine esphome::home_io_control::IOHomeControlComponent::exchange_engine_
protected

Owns all authenticated exchange and LBT/hop logic.

Definition at line 1634 of file hub_core.h.

◆ exposed_senders_

std::vector<std::string> esphome::home_io_control::IOHomeControlComponent::exposed_senders_
protected

1W sender node IDs (remotes or sensors) allowed to fire the sender HA event (add_exposed_sender).

Config-time list (populated once from YAML), not a per-frame allocation.

Definition at line 1608 of file hub_core.h.

◆ fem_en_pin_

InternalGPIOPin* esphome::home_io_control::IOHomeControlComponent::fem_en_pin_ {nullptr}
protected

Front-end module enable.

Definition at line 1576 of file hub_core.h.

◆ fem_pa_pin_

InternalGPIOPin* esphome::home_io_control::IOHomeControlComponent::fem_pa_pin_ {nullptr}
protected

Front-end module PA switch.

Definition at line 1578 of file hub_core.h.

◆ fem_profile_

FemProfile esphome::home_io_control::IOHomeControlComponent::fem_profile_ {FemProfile::NONE}
protected

Which FEM part fem_pa_pin_ belongs to, if any.

Definition at line 1579 of file hub_core.h.

◆ first_1w_activity_ms_

uint32_t esphome::home_io_control::IOHomeControlComponent::first_1w_activity_ms_ {0}
protected

millis() of the first 1W frame in the current burst.

Advances to the new frame's timestamp whenever the gap since last_1w_activity_ms_ reaches ONEWAY_QUIET_PERIOD_MS (the previous burst has already released any deferred poll, so this one starts fresh); otherwise holds at the burst's start. Bounds defer_background_poll_() via ONEWAY_POLL_DEFER_CAP_MS.

Definition at line 1675 of file hub_core.h.

◆ initialized_

bool esphome::home_io_control::IOHomeControlComponent::initialized_ {false}
protected

Definition at line 1599 of file hub_core.h.

◆ key_extraction_

KeyExtractionResponder esphome::home_io_control::IOHomeControlComponent::key_extraction_
protected

Device-role responder for the "Recover System Key" feature (key_extraction_responder.cpp).

Owns the pairing_responder::ResponderContext, the throwaway-ID/auto-off/grace-window machinery, and the device-role reply TX. Declared after registry_/radio_/tuning_/node_id_ (which it references) and after oneway_key_adoption_ so member-init order matches the initializer list.

Definition at line 1652 of file hub_core.h.

◆ last_1w_activity_ms_

uint32_t esphome::home_io_control::IOHomeControlComponent::last_1w_activity_ms_ {0}
protected

millis() of the most recent 1W frame of any kind, including ones dropped as duplicates — a repeat still means the remote is transmitting.

0 until the first is seen. Gates background polls in loop(); see decisions::defer_background_poll_for_1w_activity().

Definition at line 1670 of file hub_core.h.

◆ last_1w_logged_

decisions::OneWayDedupState esphome::home_io_control::IOHomeControlComponent::last_1w_logged_ {}
protected

Identity of the last processed 1W frame, for burst suppression; see decisions::is_duplicate_1w_frame() for why the intent bytes are part of the key.

Definition at line 1666 of file hub_core.h.

◆ last_device_event_

std::string esphome::home_io_control::IOHomeControlComponent::last_device_event_
protected

Definition at line 1613 of file hub_core.h.

◆ last_pairing_end_ms_

uint32_t esphome::home_io_control::IOHomeControlComponent::last_pairing_end_ms_ {0}
protected

millis() when the last pairing attempt ended; 0 before the first one (see queue_discover_and_pair()).

Definition at line 1602 of file hub_core.h.

◆ management_actions_

ManagementActions esphome::home_io_control::IOHomeControlComponent::management_actions_
protected

Owns rename, identify, force-open, scan_paired_devices, and other hub-level HA actions.

Definition at line 1636 of file hub_core.h.

◆ node_id_

uint8_t esphome::home_io_control::IOHomeControlComponent::node_id_[NODE_ID_SIZE] {}
protected

Definition at line 1592 of file hub_core.h.

◆ node_id_str_

std::string esphome::home_io_control::IOHomeControlComponent::node_id_str_
protected

Definition at line 1582 of file hub_core.h.

◆ oneway_key_adoption_

OnewayKeyAdoption esphome::home_io_control::IOHomeControlComponent::oneway_key_adoption_
protected

Opt-in, receive-only 1W controller-key adoption listener (oneway_key_adoption.cpp).

Armed via the "Recover 1W Controller Key" switch; observes an overheard CMD_ONEWAY_ADD_CONTROLLER and reports the key once, then disarms. Declared after oneway_transmitter_ so member-init order matches the initializer list.

Definition at line 1646 of file hub_core.h.

◆ oneway_report_callbacks_

std::vector<OneWayCommandReportFn> esphome::home_io_control::IOHomeControlComponent::oneway_report_callbacks_
protected

Subscribers to the per-command 1W report; one per "Last 1W Command" sensor.

Definition at line 1662 of file hub_core.h.

◆ oneway_transmitter_

OneWayTransmitter esphome::home_io_control::IOHomeControlComponent::oneway_transmitter_
protected

Owns the 1W controller identities, their rolling-sequence counters and the transmit burst.

The third collaborator that drives the radio (ADR 0004), and the only one that awaits nothing — 1W has no reply to wait for.

Definition at line 1641 of file hub_core.h.

◆ op_queue_

OperationQueue esphome::home_io_control::IOHomeControlComponent::op_queue_
protected

Definition at line 1624 of file hub_core.h.

◆ pa_pin_

uint8_t esphome::home_io_control::IOHomeControlComponent::pa_pin_ {DEFAULT_PA_PIN_PA_BOOST}
protected

Definition at line 1595 of file hub_core.h.

◆ pairing_engine_

PairingEngine esphome::home_io_control::IOHomeControlComponent::pairing_engine_
protected

Owns the three-phase device pairing flow.

Definition at line 1635 of file hub_core.h.

◆ pairing_result_callback_

std::function<void()> esphome::home_io_control::IOHomeControlComponent::pairing_result_callback_
protected

Invoked once after every pairing attempt completes; see set_pairing_result_callback().

Definition at line 1610 of file hub_core.h.

◆ pairing_telemetry_

PairingTelemetry esphome::home_io_control::IOHomeControlComponent::pairing_telemetry_
protected

Per-attempt pairing telemetry.

PairingEngine records into it and, during an attempt, attaches it to ExchangeEngine as its TransmitObserver.

Definition at line 1627 of file hub_core.h.

◆ poll_policy_

StatusPollPolicy esphome::home_io_control::IOHomeControlComponent::poll_policy_
protected

Definition at line 1619 of file hub_core.h.

◆ radio_

RadioDriver* esphome::home_io_control::IOHomeControlComponent::radio_ {nullptr}
protected

Definition at line 1568 of file hub_core.h.

◆ radio_failure_reason_

std::string esphome::home_io_control::IOHomeControlComponent::radio_failure_reason_
protected

Why setup() gave up on the radio, or empty.

Printed by dump_config so log clients that connect after boot see the cause, not only ESPHome's generic "marked FAILED" line.

Definition at line 1587 of file hub_core.h.

◆ radio_failure_reported_

bool esphome::home_io_control::IOHomeControlComponent::radio_failure_reported_ {false}
protected

Set once loop() has reported a radio that latched a failure after setup, so the report (an error line, ESPHome's warning status and a republish of every device) is made once, not on every loop.

Definition at line 1591 of file hub_core.h.

◆ radio_test_mode_

bool esphome::home_io_control::IOHomeControlComponent::radio_test_mode_ {false}
protected

When true, loop() is suspended for loopback testing.

Definition at line 1603 of file hub_core.h.

◆ radio_type_

std::string esphome::home_io_control::IOHomeControlComponent::radio_type_
protected

"sx1276", "sx1262", or "lr1121"; required by the YAML schema.

Definition at line 1584 of file hub_core.h.

◆ rain_poll_policy_

PeriodicPollPolicy esphome::home_io_control::IOHomeControlComponent::rain_poll_policy_
protected

Schedule of the opt-in rain sensor poll.

Definition at line 1620 of file hub_core.h.

◆ recent_oneway_pairing_sighting_

RecentOneWayPairingSighting esphome::home_io_control::IOHomeControlComponent::recent_oneway_pairing_sighting_ {}
protected

Most recent 1W pairing-gesture frame seen on the hub's normal passive RX path (e.g.

a PROG press's WRITE_PRIVATE/1W-remove/discover-alt broadcast), remembered so PairingEngine can seed a fresh discover_and_pair() attempt's telemetry with it — see record_oneway_pairing_gesture_() and RecentOneWayPairingSighting's doc comment (issue #27/#65). Declared before pairing_engine_, which holds a reference to it, so member-init order matches the initializer list.

Definition at line 1633 of file hub_core.h.

◆ registry_

DeviceRegistry esphome::home_io_control::IOHomeControlComponent::registry_
protected

Definition at line 1605 of file hub_core.h.

◆ rst_pin_

InternalGPIOPin* esphome::home_io_control::IOHomeControlComponent::rst_pin_ {nullptr}
protected

Definition at line 1571 of file hub_core.h.

◆ status_refresh_policy_

PeriodicPollPolicy esphome::home_io_control::IOHomeControlComponent::status_refresh_policy_
protected

Schedule of the opt-in status refresh at rest.

Definition at line 1623 of file hub_core.h.

◆ sun_poll_policy_

PeriodicPollPolicy esphome::home_io_control::IOHomeControlComponent::sun_poll_policy_
protected

Schedule of the opt-in sun level poll.

Definition at line 1621 of file hub_core.h.

◆ system_key_

uint8_t esphome::home_io_control::IOHomeControlComponent::system_key_[AES_KEY_SIZE] {}
protected

Definition at line 1593 of file hub_core.h.

◆ system_key_str_

std::string esphome::home_io_control::IOHomeControlComponent::system_key_str_
protected

Definition at line 1583 of file hub_core.h.

◆ tcxo_voltage_

uint8_t esphome::home_io_control::IOHomeControlComponent::tcxo_voltage_ {DEFAULT_TCXO_VOLTAGE_SETTING_1P8V}
protected

SX1262/LR1121 TCXO voltage setting (default 1.8 V).

Definition at line 1596 of file hub_core.h.

◆ tuning_

TuningConfig esphome::home_io_control::IOHomeControlComponent::tuning_ {}
protected

Runtime tuning overrides.

Definition at line 1604 of file hub_core.h.

◆ tx_power_

uint8_t esphome::home_io_control::IOHomeControlComponent::tx_power_ {DEFAULT_TX_POWER_DBM}
protected

Definition at line 1594 of file hub_core.h.

◆ vfem_pin_

InternalGPIOPin* esphome::home_io_control::IOHomeControlComponent::vfem_pin_ {nullptr}
protected

Front-end module power.

Definition at line 1577 of file hub_core.h.


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