|
Home IO Control
ESPHome add-on for IO-Homecontrol devices
|
Getting a device onto your hub. There are two routes, and picking the right one first saves more time than anything else on this page.
flowchart TD
A[Do you have a working<br/>two-way IO-Homecontrol hub today?<br/>TaHoma, KLF200, KLR200,<br/>Connexoon, KIG300… — not just<br/>a 1W wall switch or remote] -->|Yes| B[Use key extraction]
A -->|No| C[Has a two-way hub ever<br/>controlled the device?]
C -->|No — it is new, or only ever<br/>driven by 1W remotes<br/>or wall switches| D[Use Discover & Pair]
C -->|Yes, a hub I<br/>no longer have| E[Factory reset it as its<br/>manual describes, then<br/>register its local remote<br/>again, if it has one]
E --> D
D --> F{Does it answer?}
F -->|Yes| I[Copy the YAML snippet<br/>from the log]
F -->|No| G[See The device is<br/>never found in<br/>Troubleshooting]
B --> H[Then press Scan Paired Devices<br/>to list everything on the key]
Key extraction is the route whenever you already own a two-way hub — one that runs its own "add a device" wizard, such as a TaHoma, Connexoon, Connectivity Kit, KLF200, KLR200 or KIG300. It recovers the same node_id/system_key your devices already trust, so nothing leaves its paired state and every device on that installation appears at once. Most field reports of a device that "never responds to discovery" have been resolved this way. A 1W-only wall switch or remote (a VELUX KLI, a Somfy Smoove) does not run that wizard and has nothing key extraction can recover from it — see Supported devices for which controls qualify. See Key extraction.
Discover & Pair is the route for a device that is genuinely unclaimed: new, or factory reset, with no hub holding its key.
A flag in the home_io_control: block adds a Home Assistant button that starts discovery and pairing:
home_io_control: # ... discover_and_pair_button: true
Between the device answering discovery and the key exchange starting, the hub sends a discover-confirm frame directly to that device and waits up to a few seconds for its acknowledgement — the same handshake every real controller in this project's corpus performs before proceeding. It never blocks pairing on its own: a refusal, a timeout, or nothing at all still lets the attempt continue. If a specific device seems to dislike this step, pairing_discover_confirm: skip in the tuning: block reverts to sending nothing there at all — see Radio tuning.
Expect this to take a few goes. The hub retries discovery three times per press, and it is still common to need two or three presses because the timing between PROG and the button matters. Press PROG again and repeat before you change any settings.
If the device never answers, read The device is never found before touching Radio tuning. A device that already belongs to a hub has nothing left to answer a discovery with, and no tuning changes that; key extraction does.
discover_and_pair_button: true also creates a companion "Last Pairing Result" diagnostic text sensor alongside the button. It updates after every attempt with a frozen, machine-readable summary:
| Field | Meaning |
|---|---|
| outcome | paired, no_response, invalid_response, or key_exchange_failed. |
| phase | The furthest stage the pairing state machine reached. |
| node / type | The paired device's node ID and type, or - if nothing was paired. |
| attempts | Number of discovery command retries sent. |
| lbt | Listen-before-talk retries consumed across the whole attempt; a channel-busy indicator. |
| dur_ms | Attempt duration in milliseconds. |
| heard | Total RX events seen, including ones the pairing classifiers rejected and a 1W gesture overheard just before the window opened (see the advisor below). |
| advice | Comma-separated advisor codes (see below), or none. |
The format is stable and versioned (the v1; prefix), so an automation can alert when outcome is not paired.
The log also gets a full human-readable summary of every TX, RX, rejected RX, listen-before-talk deferral and phase event, plus a total channel-hop count. When the overheard traffic tells a story, one or more pairing advisor WARN lines turn it into a diagnosis. The advisor also considers the 15 seconds before the button press: a PROG press completed just ahead of it is 1W traffic, not RF silence, and is reported as 1w_traffic.
| Advice code | When it fires | What it means |
|---|---|---|
| 1w_traffic | A 1W remote was seen performing 1W pairing (a broadcast to 00003F with a 1W pairing command byte). The broadcast does not identify a target, so this fires on any 1W pairing gesture in range. | A remote's PROG gesture was heard, and no device answered. That shows a gesture happened, not what state the device is in: the same frames have come just before a successful pairing, too. Check in order. 1. If a two-way hub already controls the device (a TaHoma, KLF200, KLR200, KIG300, and similar; not a 1W wall switch or remote), it is almost certainly paired to that hub: use key extraction. 2. Was the PROG press on a remote already registered to this device, released at the first jog? A longer hold can remove the remote, or reset the device straight after a power cut. On such a remote a PROG press is also the add/remove step, so give each attempt one press: a second press while the device is still in pairing mode can close the window the first press opened. 3. Was this the only device in pairing mode? One remote often drives several devices. 4. A Double Power Cut or factory reset is not a pairing gesture on its own. Afterwards a device with a local remote expects that remote to be registered again, as its manual describes, so do that first, then repeat 2. Some families document a separate gesture: a VELUX SSL has a physical P button that opens a 10-minute 2W registration window (see VELUX INTEGRA). |
| channel_busy | Listen-before-talk retries were exhausted and the same source was heard repeatedly during the wait. | A repeating beacon (usually a nearby remote or sensor) is flooding the channel and delaying discovery transmissions. Try again, or tune lbt_max_retries/lbt_rssi_threshold_dbm — see Radio tuning. |
| foreign_controller | A discovery response (0x29) was seen addressed to a node ID that is not this hub's. | Another controller (a TaHoma, say) is pairing the same device right now. Wait for it to finish, or make sure yours is the only controller with the device in pairing mode. |
| rf_silent | Nothing at all was heard on any channel during the whole discovery window. | Either the radio is not receiving (antenna, wiring, wrong tuning), or the channel was simply quiet for those few seconds. Look at the rest of the log first. If it shows other IO-Homecontrol frames being received (your remotes, a neighbour's devices), the radio works, and this reads as "the device did not answer". Only if nothing is ever received, check the antenna and radio tuning before pressing PROG again. |
Once you hold a system key — recovered from another hub, or established by pairing — a roll-call lists every device that trusts it, whether or not you have a YAML entity for it. Each device you have no entity for answers with a ready-to-paste snippet, and no pairing handshake is involved. This is the fastest way to bring up an installation after key extraction.
Enable it from the hub block, not as a button: entry:
home_io_control: # ... radio pins, node_id, system_key ... scan_paired_devices_button: true
The button and the scan_paired_devices action run the same roll-call. The action is always available; the button saves a trip to Developer Tools.
It takes no fields. Like the other actions it is named esphome.<node_name>_scan_paired_devices; for a config with name: hioc-heltec-v2:
action: esphome.hioc_heltec_v2_scan_paired_devices
The hub broadcasts a roll-call (CMD_DISCOVER_SPE_REQ, 0x2A) and listens for every device that holds its system key. Responders are grouped into a Known: section (already in your YAML) and an Unknown: section, and each unknown one gets a paste-ready block. Either section is omitted when it would be empty.