|
Home IO Control
ESPHome add-on for IO-Homecontrol devices
|
An ESPHome external component for controlling IO-Homecontrol 2W devices (two-way, with device feedback). Control shutters, blinds, awnings, openers, curtains, and other IO-Homecontrol devices directly from ESPHome and Home Assistant using an ESP32 board with an SX1276 or SX1262 radio module.
Get Involved
Support is greatly appreciated - whether you're helping with testing devices that I don't own, give feedback or submit pull requests.
You need an ESP32 board with an SX1276 or SX1262 radio module operating at 868 MHz.
The table below lists board mappings that are known to be plausible for this component. Confirmed means they were tested in this repo. Untested means the GPIO mapping was taken from vendor documentation and still needs real IO-homecontrol validation here.
| Board | Radio | Status | spi: pins | home_io_control: pins | Notes |
|---|---|---|---|---|---|
| Heltec WiFi LoRa32 v2 | SX1276 | ✅ Confirmed to work | clk_pin: 5, mosi_pin: 27, miso_pin: 19 | cs_pin: 18, rst_pin: 14, dio0_pin: 26 | Matches config/heltec-wifi-lora-32-v2.yaml, the SX1276 cover example with OLED status display |
| Heltec WiFi LoRa32 V3 / V3.2 | SX1262 | ✅ Confirmed to work | clk_pin: 9, mosi_pin: 10, miso_pin: 11 | cs_pin: 8, rst_pin: 12, dio1_pin: 14, busy_pin: 13 | Use radio_type: sx1262 and tcxo_voltage: 1_8V; matches config/heltec-wifi-lora-32-v3.yaml, the SX1262 cover example with OLED status display |
| LilyGO T3-S3 SX1262 | SX1262 | Untested | clk_pin: 5, mosi_pin: 6, miso_pin: 3 | cs_pin: 7, rst_pin: 8, dio1_pin: 33, busy_pin: 34 | should have the same mapping on v1.2 and v1.3; start with radio_type: sx1262 |
| LilyGO T3-S3 SX1276 | SX1276 | Untested | clk_pin: 5, mosi_pin: 6, miso_pin: 3 | cs_pin: 7, rst_pin: 8, dio0_pin: 9 | |
| LilyGO LoRa32 V1.3 SX1276 | SX1276 | Untested | clk_pin: 5, mosi_pin: 27, miso_pin: 19 | cs_pin: 18, rst_pin: 14, dio0_pin: 26 | |
| LilyGO T-Beam 1W SX1262 | SX1262 | Untested | clk_pin: 13, mosi_pin: 11, miso_pin: 12 | cs_pin: 15, rst_pin: 3, dio1_pin: 1, busy_pin: 38 | vendor docs suggest that fem_en_pin: 40 and fem_pa_pin: 21 might be needed |
| Any other ESP32 + SX1276/SX1262 | Either | Untested | Board-specific | Board-specific | Use the chip pinout and set the appropriate sx1276 or sx1262 radio_type |
Add to your ESPHome YAML configuration:
external_components: - source: github://laberning/home_io_control
Or for local development:
external_components: - source: type: local path: components
The full configuration reference lives in docs/home_io_control.md. That page contains all component parameters, platform-specific options and the pairing workflow.
io_device_type accepts both named values such as awning and raw numeric values such as 0x11. Pairing logs will use the named form when the schema exposes one, otherwise they will print the raw numeric type and ask you to report it upstream.
Both esp-idf and arduino framework are supported, but testing and development mostly happens on esp-idf.
esphome: name: io-homecontrol friendly_name: Home IO Control esp32: variant: esp32 logger: level: DEBUG wifi: ssid: !secret wifi_ssid password: !secret wifi_password api: encryption: key: !secret api_key ota: - platform: esphome password: !secret ota_password external_components: - source: github://laberning/home_io_control # Set the pinout for your device - this example uses Heltec WiFi LoRa32 v2. spi: clk_pin: 5 mosi_pin: 27 miso_pin: 19 home_io_control: cs_pin: 18 rst_pin: 14 dio0_pin: 26 # If this device was previously paired with another hub, enter that hub's # Node ID and System Key below to allow the devices to reconnect automatically. # Otherwise, generate new values according to the requirements below: # Node ID: Must be exactly 6 hexadecimal characters. node_id: "C0FFEE" # System Key: Must be exactly 32 hexadecimal characters. system_key: "00112233445566778899AABBCCDDEEFF" cover: - platform: home_io_control device_class: awning name: "Awning" # If the device ID is unknown, use the "Discover & Pair" button to discover it. io_device_id: "FEEB1E" io_device_type: "awning" io_subtype: 0 # Optional explicit override. If omitted, inversion follows the learned device type. invert_position: true # Optional bounded follow-up polling while movement is expected. status_poll_interval: 500ms button: - platform: home_io_control name: "Discover & Pair"
For all other examples, platform-specific options, and pairing instructions, use docs/home_io_control.md.
If a device does not emit unsolicited status updates on its own, set status_poll_interval on the affected cover:, light:, or switch: entry. Without that option, the hub still keeps the legacy single follow-up settle poll after a local command or overheard remote activity. With the option set, it continues polling only while the device still appears to be changing, and it stops automatically once the device reports a stable state or the bounded polling window expires. The minimum supported interval is 500ms.
The ESP32 can't communicate with the radio chip. Check your SPI pin configuration (CLK, MOSI, MISO, CS) and ensure they match your board's wiring.
The device hasn't reported its position yet. Try sending an Open or Close command — the device will report its position in the response.
The current code keeps the high-level protocol flow shared between both radios and applies the minimum number of radio-specific differences needed to make SX1262 reliable.
The build system uses Docker for firmware compilation and host tools for testing/linting. After setup, run make check to verify the full toolchain.
Use the Ubuntu command above inside a WSL2 distribution.
This project is only possible thanks to the effort and shared knowledge from these projects and their maintainers ❤️
This project is licensed under the MIT License.