{"id":50306333,"url":"https://github.com/shbatm/hacs-udi-iox","last_synced_at":"2026-05-28T16:31:43.646Z","repository":{"id":357027052,"uuid":"1234139708","full_name":"shbatm/hacs-udi-iox","owner":"shbatm","description":"Home Assistant Custom Component for interacting with Universal Devices, Inc eisy v6+","archived":false,"fork":false,"pushed_at":"2026-05-18T00:33:07.000Z","size":1211,"stargazers_count":0,"open_issues_count":5,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-18T02:41:57.118Z","etag":null,"topics":["eisy","hacs","hacs-integration","home-assistant","homeassistant","iox","isy","udi"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shbatm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"shbatm","custom":["https://www.buymeacoffee.com/shbatm"]}},"created_at":"2026-05-09T19:55:46.000Z","updated_at":"2026-05-18T00:33:10.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/shbatm/hacs-udi-iox","commit_stats":null,"previous_names":["shbatm/hacs-udi-iox"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/shbatm/hacs-udi-iox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shbatm%2Fhacs-udi-iox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shbatm%2Fhacs-udi-iox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shbatm%2Fhacs-udi-iox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shbatm%2Fhacs-udi-iox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shbatm","download_url":"https://codeload.github.com/shbatm/hacs-udi-iox/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shbatm%2Fhacs-udi-iox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33617718,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-28T02:00:06.440Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["eisy","hacs","hacs-integration","home-assistant","homeassistant","iox","isy","udi"],"created_at":"2026-05-28T16:31:43.530Z","updated_at":"2026-05-28T16:31:43.637Z","avatar_url":"https://github.com/shbatm.png","language":"Python","funding_links":["https://github.com/sponsors/shbatm","https://www.buymeacoffee.com/shbatm"],"categories":[],"sub_categories":[],"readme":"# hacs-udi-iox\n\n[![hacs_badge](https://img.shields.io/badge/HACS-Custom-41BDF5.svg?style=for-the-badge)](https://github.com/hacs/integration)\n\nHome Assistant custom component for **Universal Devices eisy** controllers running **IoX 6.0+**.\n\n## What's new vs. the core `isy994` integration\n\nIf you've used HA's built-in `isy994` for years, the things this integration adds on top:\n\n- **IoX programs are first-class HA devices.** Each program (and program folder) becomes its own device with `Run` / `Run Then` / `Run Else` / `Stop` / `Enable` / `Disable` buttons, an enable switch, a *Run at startup* toggle, and `Last Run` / `Last Finished` / `Next Scheduled Run` timestamp sensors. Triggering and observing IoX programs no longer requires a status program + actions program pair plus YAML.\n- **Native event entities for keypad / scene buttons.** KeypadLinc accessory buttons, RemoteLincs, and any nodedef with a `cmds.sends` list become `event.*` entities exposed through HA's device-trigger UI — no `udi_iox_control` bus events, no listening for raw control codes. Fires on every press, including same-type repeats. Replaces the legacy `sensor.\u003ckeypad\u003e_\u003cletter\u003e` integer-state hack.\n- **Scene members in the more-info dialog.** Each IoX scene (group) publishes its member nodes through HA's group framework, so opening a scene lists its member lights / switches / fans inline (mixed domains, same UX as a HA light group). Core `isy994` exposes scenes as bare switches with no member visibility. (Hidden member entities are omitted by HA's frontend, as with any group.)\n- **Suggested area from your IoX folder layout.** Organize nodes or programs into folders on the controller (`Kitchen`, `Garage`, …) and HA pre-fills each device's *Suggested Area* from the immediate parent folder.\n- **Dynamic device support.** Core `isy994` carries several hardcoded type-prefix tables to decide which HA platform each Insteon device belongs on — adding a new device class meant editing the integration. This integration reads each device's **nodedef from the controller** (the wire shape: accepts / sends / properties / editors). Insteon devices land on the same baseline platforms as core, but Z-Wave, Zigbee, Matter, and any PG3 node-server plugin all classify themselves automatically with no integration update needed.\n- **Z-Wave / Insteon configurables as native HA entities.** On Level, Ramp Rate, Backlight, ramp/scene values, Z-Wave configuration parameters — anything the controller publishes as an editor surfaces as a `number` / `select` / `switch` entity (no service calls, no YAML).\n- **WebSocket-only event stream + Repair-card lifecycle UX.** State updates ride a single WebSocket; entity availability follows WS health. New / removed / renamed devices on the controller surface as Repair cards prompting a reload instead of being silently missed.\n\n\u003e **Side-by-side notes:** the two integrations register distinct domains (`isy994` vs. `udi_iox`) and coexist on the same HA instance — useful for ISY-994 + eisy mixed setups. See [`docs/coexistence-with-core.md`](docs/coexistence-with-core.md) for a per-platform comparison.\n\n## Legacy Hardware Scope\n\nIf you have ISY-994 hardware, use the existing Home Assistant core [`isy994` integration](https://www.home-assistant.io/integrations/isy994/) (which stays on `pyisy` 3.x). The two integrations register distinct domains and coexist on the same HA instance.\n\nThe earlier-generation **Polisy** controller is end-of-life and no longer a target for this integration — the SSDP / DHCP discovery matchers have been narrowed to eisy. Polisy users can still configure the integration manually (the IoX 6 protocol is the same), but auto-discovery won't surface a Polisy on the network.\n\n## Why a separate repo\n\n`hacs-isy994` was a stable beta-testing channel for the upstream `isy994` integration which served its purpose, but I no longer want to maintain legacy hardware support for Home Assistant's core `isy994` and try to maintain both new features and legacy support in another repo. The eisy / IoX-6+ rewrite is a clean break: different library (`pyisyox` v6 with JWT/portal auth, WebSocket-only, classifier-driven entity routing, ergonomic Node wrappers). Forcing existing `hacs-isy994` users onto that rewrite would regress their working ISY-994 setups, so this is a new repo with a new domain.\n\n## Installation\n\n\u003e **IF YOU ARE USING THE CORE ISY994 INTEGRATION:** While they can co-exist side-by-side, you may wish to remove that integration before adding this one. For the large portion of entities that overlap, they will try to get the same `entity_id` and you will end up with everything suffixed with `domain.*_2`. To keep your dashboards intact as much as possible, remove the `isy994` integration, restart HA once (needed for installing this repo anyways) and then add this integration to restore the entities. Any `entity_id` that you manually renamed on the old integration will need to be renamed again.\n\n### Prerequisites\n\nBefore starting the setup flow, gather:\n\n- A **Universal Devices portal account** (the same email + password you use to sign in at \u003chttps://my.isy.io\u003e). The eisy on IoX 6+ authenticates against the portal — local admin credentials are not supported by the integration yet.\n  - If you don't have a portal account, follow the \"Sign up\" link on \u003chttps://my.isy.io\u003e and link your controller there first.\n- The **base URL of your eisy**, including the scheme and port. Examples:\n  - `https://eisy.local:443` (default portal-mode port on the local network)\n  - `https://192.168.1.50:443` (by IP)\n  - `https://eisy.example.com:443` (with a non-default hostname)\n\n  The default port for portal (JWT) auth is `443`. Visit `https://\u003cyour-controller\u003e/desc` in a browser to confirm the controller responds — if you get a self-signed-cert warning, that's normal.\n\n### HACS install\n\nThis is a HACS Custom Repository:\n\n1. Open HACS in Home Assistant: [![Open your Home Assistant instance and open a repository inside the Home Assistant Community Store.](https://my.home-assistant.io/badges/hacs_repository.svg)](https://my.home-assistant.io/redirect/hacs_repository/?repository=hacs-udi-iox\u0026owner=shbatm\u0026category=integration) (or HACS → ⋮ → Custom repositories → add `https://github.com/shbatm/hacs-udi-iox`, category Integration).\n2. Install, restart HA.\n3. Add the integration: [![Open your Home Assistant instance and start setting up a new integration.](https://my.home-assistant.io/badges/config_flow_start.svg)](https://my.home-assistant.io/redirect/config_flow_start/?domain=udi_iox) (or Settings → Devices \u0026 Services → **+ Add Integration** → search \"Universal Devices IoX\").\n\n### Setup parameters\n\nThe initial setup flow asks for the following. HA also recognises eisy controllers via SSDP and DHCP discovery — if your controller is on the same network as HA, the integration usually surfaces it automatically and prefills the `host` field; you only need to enter credentials.\n\n| Parameter | Required | Description |\n| --- | --- | --- |\n| **URL** (`host`) | yes | The full controller URL, e.g. `https://eisy.local:443`. Use the same URL you'd open in a browser. |\n| **Universal Devices portal email** (`username`) | yes | The email you registered at \u003chttps://my.isy.io\u003e. |\n| **Universal Devices portal password** (`password`) | yes | The password for that portal account. |\n| **Verify SSL certificate** (`verify_ssl`) | no (default: off) | Leave **off** unless you've installed a CA-trusted certificate on the controller — eisys ship with a self-signed cert that will fail verification. |\n\nAfter the credentials step the flow lands on the **Options** step (the same form is later available via the integration card's **Configure** button — see [Configuration](#configuration) below).\n\n## Removal\n\n1. Settings → Devices \u0026 Services → Universal Devices IoX → ⋮ → Delete (removes the config entry, its devices, and its entities).\n2. Optionally remove the repository in HACS (Integrations → Universal Devices IoX → ⋮ → Remove) and restart HA.\n\n## Configuration\n\nAll of these are revisitable at any time via **Settings → Devices \u0026 Services → Universal Devices IoX → Configure**. Changing them triggers a reload, so the new values take effect immediately.\n\n| Option | Default | Description |\n| --- | --- | --- |\n| **Node Sensor String** (`sensor_string`) | `{SENSOR}` | A node whose IoX name contains this exact string is forced onto the (binary) sensor platform instead of its classifier-assigned one (e.g. a generic Insteon I/O Linc input). The marker is matched verbatim **and stripped from the HA device/entity name** (so `Garbage Disposal {SENSOR}` → `Garbage Disposal`). Use a distinctive bracketed marker — the bracketed default avoids matching node-server entities that legitimately contain the word \"sensor\". |\n| **Ignore String** (`ignore_string`) | `{IGNORE ME}` | Any device, **program, or folder** whose IoX name contains this substring is skipped entirely — no entity/device is created. Add the substring to a node's, program's, or folder's name in the eisy admin UI to hide it (and everything under a folder) from HA without deleting it from the controller. |\n| **Restore Light Brightness** (`restore_light_state`) | off | When **on**, turning a light on from HA restores the previous brightness instead of using the device's built-in On Level (Insteon `OL`). When **off**, the device decides the start level — usually the right call for Insteon switches with a configured On Level. |\n| **Enable adding variables entities** (`enable_variables`) | on | When **off**, IoX variables (Integer + State) are not exposed as `number` entities. Turn off if you have many variables and only use them inside IoX programs (faster startup). |\n| **Enable adding program entities** (`enable_programs`) | on | When **off**, IoX programs are not exposed as switches / covers / locks / etc. Turn off if you don't drive IoX programs from HA. |\n| **Enable adding network resource entities** (`enable_networking`) | off | When **on**, IoX network resources (HTTP / TCP / UDP triggers configured under Network → Network Resources in the admin UI) are surfaced as buttons. |\n\n### Reauthentication\n\nIf you change your Universal Devices portal password the integration will detect the failed login on the next refresh and surface a Repair card prompting you to reauthenticate. The reauth flow asks for the username + password only — the host stays as-is.\n\n## Automations on button presses\n\nInsteon KeypadLinc accessory buttons (and any nodedef with a `cmds.sends`\nlist — most Insteon load/dimmer controls and many PG3 plugin sources)\nare exposed as `event` entities. Each press updates the entity's state\ntimestamp and sets its `event_type` attribute (`on`, `off`, `fast_on`,\n`fast_off`, `fade_up`, `fade_down`, `fade_stop`, …).\n\n**Use a device trigger for \"fire on every press.\"** Settings →\nAutomations \u0026 Scenes → Create Automation → When → Add trigger → Device,\npick the KeypadLinc / SwitchLinc / etc., and choose e.g. *\"… was switched\nOn\"*. This fires every time the button is pressed, even when the previous\npress was the same type — which is the behaviour most Insteon users\nexpect.\n\nEquivalent YAML:\n\n```yaml\ntrigger:\n  - platform: device\n    domain: udi_iox\n    device_id: \u003ccopy from the UI\u003e\n    entity_id: event.hallway_keypad_b\n    type: \"on\"\naction:\n  - service: light.toggle\n    target:\n      entity_id: light.kitchen_main\n```\n\n**Why not a state trigger?** A state trigger configured with `attribute:\nevent_type` and `to: \"on\"` only fires when the attribute *changes*: pressing\nthe same button twice in a row is the same `event_type` value both times,\nso the second press is silently dropped. The device trigger above sidesteps\nthis by matching against the new state's `event_type` on every update,\nnot just transitions.\n\n## Supported devices\n\nThe integration surfaces every device on your controller — Insteon, Z-Wave, Zigbee, Matter, and any [PG3 node-server plugin](https://www.universal-devices.com/polyglot/) you have installed. HA platform routing is driven by `pyisyox`'s classifier reading each device's nodedef, not a hard-coded table.\n\nIf you bridge a device through a PG3 plugin **and** Home Assistant has a first-party integration for that same device (Sonos, Hue, Rachio, Roku, Plex, Ecobee, Shelly, WLED, etc.), install HA's native integration directly. It will almost always be the better source of truth — local-push state, manufacturer-aware quirks, more device-specific features. The two coexist fine: this integration still exposes the device's IoX-side state (useful if your IoX programs reference the device), and the native integration handles the device itself.\n\nSee [`docs/supported-devices.md`](docs/supported-devices.md) for the full list of PG3 plugins with HA-native equivalents, the cases where the IoX path is the right call, and roadmap notes for the platforms still to come.\n\n## Reporting issues\n\nBug reports go through [GitHub Issues](https://github.com/shbatm/hacs-udi-iox/issues/new/choose) — the **Bug report** template walks you through the diagnostics + debug-log attachments most issues need. Two things to grab before you file:\n\n### 1. Diagnostics file\n\nCaptures a redacted snapshot of what the integration sees: nodes, programs, variables, WebSocket health, and the entry's options. It's the fastest way to confirm the wire shape of whatever's misbehaving. ([HA docs on diagnostics](https://www.home-assistant.io/integrations/diagnostics/))\n\n1. Open the integration: [![Open your Home Assistant instance and show an integration.](https://my.home-assistant.io/badges/integration.svg)](https://my.home-assistant.io/redirect/integration/?domain=udi_iox)\n2. Click on the hub device (e.g. *IoX-Testing*, your eisy's name).\n3. On the hub device page, click **⋮** in the **Device info** card → **Download diagnostics**.\n\n   ![Download diagnostics menu on the hub device card](docs/images/download-diagnostics.png)\n\n4. Attach the `.json` file to the issue.\n\nPII (passwords, portal email, host) is redacted; node addresses and names stay verbatim so triage keeps context.\n\n### 2. Debug log\n\nRequired for any state / event / command bug — the integration emits per-event lines at `DEBUG` so we can see which control / property a bad reading came in on. ([HA docs on enabling debug logging](https://www.home-assistant.io/docs/configuration/troubleshooting/#enabling-debug-logging))\n\n1. Open the integration: [![Open your Home Assistant instance and show an integration.](https://my.home-assistant.io/badges/integration.svg)](https://my.home-assistant.io/redirect/integration/?domain=udi_iox)\n2. Click **⋮** in the top-right corner of the integration page → **Enable debug logging**.\n\n   ![Enable debug logging menu on the integration page](docs/images/enable-debug-logging.png)\n\n3. **Reproduce the bug** — toggle the broken switch, fire the program, etc.\n4. Click **⋮** → **Disable debug logging** — HA automatically downloads the captured log file.\n5. Attach the file to the issue.\n\nDebug logging captures every WebSocket frame plus REST request, so keep the reproduction window short — even a few minutes generates several MB.\n\n## Roadmap\n\nOpen issues and milestones are tracked in [GitHub Issues](https://github.com/shbatm/hacs-udi-iox/issues).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshbatm%2Fhacs-udi-iox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshbatm%2Fhacs-udi-iox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshbatm%2Fhacs-udi-iox/lists"}