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

Owns the per-hub device table, update callbacks, and linked-remote associations. More...

#include <device_registry.h>

Collaboration diagram for esphome::home_io_control::DeviceRegistry:

Public Member Functions

void add (const std::string &device_id)
 Register a device by ID with default metadata (UNKNOWN type, subtype 0, not inverted).
void add (const std::string &device_id, const DeviceConfig &cfg)
 Register a device with full YAML-derived metadata.
void put (const std::string &device_id, IoDevice device)
 Insert or overwrite a device entry without deduplication or hex-validation checks.
IoDevice * get (const std::string &device_id)
 Retrieve a registered device by ID.
void set_dimmable (const std::string &device_id, bool dimmable)
 Set a device's dimmable flag (see IoDevice::dimmable).
void set_silent (const std::string &device_id, bool silent)
 Select a device's travel profile.
void subscribe (DeviceUpdateCallback cb)
 Register a callback that fires whenever a device's state changes.
void notify (const std::string &device_id)
 Invoke all registered callbacks for device_id.
void add_linked_remote (const std::string &remote_id, const std::string &device_id)
 Record that a remote node controls a registered device.
const std::vector< std::string > * linked_devices (const std::string &remote_id) const
 Retrieve the list of device IDs linked to a remote.
void add_linked_remote_class (DeviceType type, const std::string &device_id)
 Record that a remote's typed-broadcast presses (e.g.
const std::vector< std::string > * linked_devices_for_class (DeviceType type) const
 Retrieve the list of device IDs linked to a device class.
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.
bool apply_optimistic_stop (const std::string &device_id, bool restorable=false)
 Predict that a device has stopped (e.g.
bool apply_optimistic_tilt (const std::string &device_id, float tilt_percent)
 Set an optimistic slat angle ahead of a confirming poll, and notify.
bool rollback_optimistic (const std::string &device_id, bool failed_stop=false)
 Withdraw every prediction for a device after the command that produced them failed, and notify.
void confirm_optimistic_stop (const std::string &device_id)
 Mark a device's STOP as delivered: a later rollback must not restore the movement it replaced.
size_t size () const
size_t linked_remote_count () const
void for_each_linked_remote (const std::function< void(const std::string &, const std::vector< std::string > &)> &fn) const
 Invoke fn(remote_id, device_id_list) for every linked-remote entry.
std::map< std::string, IoDevice >::iterator begin ()
 Mutable begin iterator over (device_id, IoDevice) pairs (supports range-for in the poll loop).
std::map< std::string, IoDevice >::iterator end ()
 Mutable end iterator over (device_id, IoDevice) pairs.

Detailed Description

Owns the per-hub device table, update callbacks, and linked-remote associations.

All of the hub's add/get/subscribe/notify operations go through this class — IOHomeControlComponent holds no device state of its own. The class has no ESPHome dependencies beyond logging and is directly host-testable.

Definition at line 43 of file device_registry.h.

Member Function Documentation

◆ add() [1/2]

void esphome::home_io_control::DeviceRegistry::add ( const std::string & device_id)

Register a device by ID with default metadata (UNKNOWN type, subtype 0, not inverted).

No-op when device_id is already registered. Warns and returns when the hex string is invalid.

Parameters
device_idHexadecimal node ID string (e.g. "ABC123").

Definition at line 17 of file device_registry.cpp.

Here is the call graph for this function:

◆ add() [2/2]

void esphome::home_io_control::DeviceRegistry::add ( const std::string & device_id,
const DeviceConfig & cfg )

Register a device with full YAML-derived metadata.

No-op when device_id is already registered. Warns and returns when the hex string is invalid.

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

Definition at line 19 of file device_registry.cpp.

Here is the call graph for this function:

◆ add_linked_remote()

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

Record that a remote node controls a registered device.

When activity from the remote is overheard, a status poll is scheduled for the linked device.

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

Definition at line 64 of file device_registry.cpp.

◆ add_linked_remote_class()

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

Record that a remote's typed-broadcast presses (e.g.

"all awnings") should also apply to device_id, matching how 1W remotes address a device class rather than a single node. Independent of add_linked_remote()'s id-keyed map — a device may be linked both ways; callers dedup (see IOHomeControlComponent's 1W dispatch) so it is only touched once per press.

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

Definition at line 73 of file device_registry.cpp.

◆ apply_optimistic_stop()

bool esphome::home_io_control::DeviceRegistry::apply_optimistic_stop ( const std::string & device_id,
bool restorable = false )

Predict that a device has stopped (e.g.

on STOP), and notify.

No-op (and returns false) when the device is unknown or has optimistic_state == false. Records a Motion::STOPPED prediction rather than merely withdrawing the position prediction: a bare withdrawal would fall back to an observed is_stopped == false and keep the HA cover animating. The prediction is superseded by the next decoded status.

Parameters
device_idDevice to update.
restorableTrue for a STOP this hub is about to send: a movement prediction it replaces is kept so rollback_optimistic() can bring it back if the STOP fails. False for a stop that cannot fail from the hub's side (an overheard remote's STOP).
Returns
true if the optimistic stop was applied.

Definition at line 103 of file device_registry.cpp.

Here is the call graph for this function:

◆ apply_optimistic_target()

bool esphome::home_io_control::DeviceRegistry::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.

No-op (and returns false) when the device is unknown or has optimistic_state == false. Never touches position — only the caller's later poll/response settles that. Used by both the 1W linked-remote path and HA-issued 2W cover commands so the entity shows movement direction immediately instead of only after the confirming update arrives.

Parameters
device_idDevice to update.
target_io_positionTarget position in IO units (0=open, 100=closed).
Returns
true if the optimistic state was applied.

Definition at line 82 of file device_registry.cpp.

Here is the call graph for this function:

◆ apply_optimistic_tilt()

bool esphome::home_io_control::DeviceRegistry::apply_optimistic_tilt ( const std::string & device_id,
float tilt_percent )

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

No-op (and returns false) when the device is unknown, has optimistic_state == false, or is not a tilt-capable type. Nothing else can fill the gap: unlike a position command, a tilt command's own reply carries no slat angle this hub can use. The EXECUTE ack lays its payload out differently from a status reply and is not decoded for tilt at all (see the offset constants in hub_status.cpp and tests/corpus/captures/exchange/tilt_cover_exchange_ack_tilt_block*.yaml), so without this the entity would keep showing the pre-command angle until the next status poll seconds later.

Deliberately records no movement prediction, unlike apply_optimistic_target(): the HA movement animation is derived from main-position delta, and a tilt-only command does not move the main position — predicting motion would animate an open/close that is not happening. The EXECUTE ack settles is_stopped from the wire a fraction of a second later.

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

Definition at line 122 of file device_registry.cpp.

Here is the call graph for this function:

◆ begin()

std::map< std::string, IoDevice >::iterator esphome::home_io_control::DeviceRegistry::begin ( )
inline

Mutable begin iterator over (device_id, IoDevice) pairs (supports range-for in the poll loop).

Definition at line 190 of file device_registry.h.

◆ confirm_optimistic_stop()

void esphome::home_io_control::DeviceRegistry::confirm_optimistic_stop ( const std::string & device_id)

Mark a device's STOP as delivered: a later rollback must not restore the movement it replaced.

Leaves every prediction in place. No-op for an unknown device.

Parameters
device_idDevice that accepted the STOP.

Definition at line 164 of file device_registry.cpp.

◆ end()

std::map< std::string, IoDevice >::iterator esphome::home_io_control::DeviceRegistry::end ( )
inline

Mutable end iterator over (device_id, IoDevice) pairs.

Definition at line 192 of file device_registry.h.

◆ for_each_linked_remote()

void esphome::home_io_control::DeviceRegistry::for_each_linked_remote ( const std::function< void(const std::string &, const std::vector< std::string > &)> & fn) const

Invoke fn(remote_id, device_id_list) for every linked-remote entry.

Parameters
fnCallable receiving the remote ID and its associated device ID list.

Definition at line 170 of file device_registry.cpp.

◆ get()

IoDevice * esphome::home_io_control::DeviceRegistry::get ( const std::string & device_id)
nodiscard

Retrieve a registered device by ID.

Returns
Pointer to the stored IoDevice, or nullptr when not found.

Definition at line 39 of file device_registry.cpp.

◆ linked_devices()

const std::vector< std::string > * esphome::home_io_control::DeviceRegistry::linked_devices ( const std::string & remote_id) const
nodiscard

Retrieve the list of device IDs linked to a remote.

Returns
Pointer to the device-ID list, or nullptr when the remote is unknown.

Definition at line 68 of file device_registry.cpp.

◆ linked_devices_for_class()

const std::vector< std::string > * esphome::home_io_control::DeviceRegistry::linked_devices_for_class ( DeviceType type) const
nodiscard

Retrieve the list of device IDs linked to a device class.

Returns
Pointer to the device-ID list, or nullptr when no device is linked to that class.

Definition at line 77 of file device_registry.cpp.

◆ linked_remote_count()

size_t esphome::home_io_control::DeviceRegistry::linked_remote_count ( ) const
inlinenodiscard
Returns
Number of distinct linked-remote entries.

Definition at line 182 of file device_registry.h.

◆ notify()

void esphome::home_io_control::DeviceRegistry::notify ( const std::string & device_id)

Invoke all registered callbacks for device_id.

No-op when device_id is not in the registry.

Parameters
device_idDevice whose state just changed.

Definition at line 56 of file device_registry.cpp.

◆ put()

void esphome::home_io_control::DeviceRegistry::put ( const std::string & device_id,
IoDevice device )

Insert or overwrite a device entry without deduplication or hex-validation checks.

Used by the pairing flow which already validated the device during discovery.

Parameters
device_idHexadecimal node ID string.
deviceFully-built device to store.

Definition at line 37 of file device_registry.cpp.

◆ rollback_optimistic()

bool esphome::home_io_control::DeviceRegistry::rollback_optimistic ( const std::string & device_id,
bool failed_stop = false )

Withdraw every prediction for a device after the command that produced them failed, and notify.

Self-guarding: an empty overlay means nothing was predicted (including every device configured optimistic_state: false, whose apply_* calls all no-op), so there is nothing to withdraw and no reason to republish. Never touches an observed field — the device did not move, so its last reported position remains correct and stays on display.

A failed restorable STOP (apply_optimistic_stop()) is the exception: the device keeps doing what it was doing, so the movement prediction the STOP replaced comes back, and every other prediction is withdrawn as usual. Without that the entity would fall back to an observation that, on a device reporting nothing mid-travel, reads "moving, target = position" and shows as idle.

Parameters
device_idDevice whose failed command's predictions should be withdrawn.
failed_stopTrue when the failed command is a STOP. Only then does the replaced movement come back; any other failed command (e.g. a tilt run ahead of a still-queued STOP) withdraws everything.
Returns
true if a prediction was withdrawn or restored.

Definition at line 144 of file device_registry.cpp.

Here is the call graph for this function:

◆ set_dimmable()

void esphome::home_io_control::DeviceRegistry::set_dimmable ( const std::string & device_id,
bool dimmable )

Set a device's dimmable flag (see IoDevice::dimmable).

No-op when the device is unknown. Called by platform_light.cpp's setup() right after registration, since dimmable is a light-platform YAML choice, not something add()'s shared cover/light/switch/lock signature should carry for every entity type.

Parameters
device_idDevice to update.
dimmableNew value for IoDevice::dimmable.

Definition at line 44 of file device_registry.cpp.

Here is the call graph for this function:

◆ set_silent()

void esphome::home_io_control::DeviceRegistry::set_silent ( const std::string & device_id,
bool silent )

Select a device's travel profile.

Like set_dimmable() this is a declared preference with no protocol readback — nothing on the wire reports which profile a device is in.

Parameters
device_idHexadecimal node ID string.
silentTrue to send position moves in "silent operation" (slower) mode.

Definition at line 49 of file device_registry.cpp.

Here is the call graph for this function:

◆ size()

size_t esphome::home_io_control::DeviceRegistry::size ( ) const
inlinenodiscard
Returns
Number of registered devices.

Definition at line 179 of file device_registry.h.

◆ subscribe()

void esphome::home_io_control::DeviceRegistry::subscribe ( DeviceUpdateCallback cb)

Register a callback that fires whenever a device's state changes.

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

Definition at line 54 of file device_registry.cpp.


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