diff --git a/README.md b/README.md index b119f6b..e61271c 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,9 @@ Async Python client for HAI/Leviton Omni-Link II home automation panels — Omni Includes a Home Assistant custom component (`custom_components/omni_pca/`). +**Project home:** +**Documentation:** + ## Status **Alpha.** Built from a full reverse-engineering of HAI's PC Access 3.17 (the Windows installer/programmer app). The protocol layer captures two non-public quirks that public Omni-Link clients miss: @@ -11,14 +14,27 @@ Includes a Home Assistant custom component (`custom_components/omni_pca/`). 1. **Session key is not the ControllerKey.** Last 5 bytes are XORed with a controller-supplied SessionID nonce. 2. **Per-block XOR pre-whitening before AES.** First two bytes of every 16-byte block are XORed with the packet's sequence number. -See [`docs/PROTOCOL.md`](docs/PROTOCOL.md) for the full byte-level spec. +The full byte-level protocol spec lives at . -## Quick start (library) +## Install + +The library isn't on PyPI yet (pending), so install directly from the Gitea release: ```bash -uv add omni-pca +# Pinned to a specific release (recommended) +pip install "omni-pca @ git+https://git.supported.systems/warehack.ing/omni-pca.git@v2026.5.10" + +# Or the wheel from the release page +pip install https://git.supported.systems/warehack.ing/omni-pca/releases/download/v2026.5.10/omni_pca-2026.5.10-py3-none-any.whl + +# Or with uv +uv add "omni-pca @ git+https://git.supported.systems/warehack.ing/omni-pca.git@v2026.5.10" ``` +Once published to PyPI, the canonical install will be `pip install omni-pca`. + +## Quick start (library) + ```python import asyncio from omni_pca import OmniClient @@ -29,44 +45,71 @@ async def main(): port=4369, controller_key=bytes.fromhex("6ba7b4e9b4656de3cd7edd4c650cdb09"), ) as panel: - info = await panel.get_system_info() + info = await panel.get_system_information() print(info.model_name, info.firmware_version) asyncio.run(main()) ``` +For the panel walkthrough — connect, list zones, react to push events — see the [tutorial](https://hai-omni-pro-ii.warehack.ing/tutorials/first-script/). + ## Quick start (Home Assistant) -Copy `custom_components/omni_pca/` into your HA `config/custom_components/`, restart HA, then add the integration via Settings → Devices & Services. You'll need: +```bash +# Manual install — works on every HA flavour +cd /path/to/your/homeassistant/config/ +mkdir -p custom_components +cd custom_components +git clone https://git.supported.systems/warehack.ing/omni-pca tmp-omni +cp -r tmp-omni/custom_components/omni_pca . +rm -rf tmp-omni +``` + +Restart HA, then add the integration via **Settings → Devices & Services**. You'll need: - Panel IP / hostname - TCP port (default 4369) - ControllerKey as 32 hex chars -Get the ControllerKey from your `.pca` file using the included parser: +Get the ControllerKey from your `.pca` file using the bundled CLI: ```bash -uvx --from omni-pca omni-pca decode-pca path/to/Your.pca --field controller_key +omni-pca decode-pca '/path/to/Your.pca' --field controller_key ``` -The integration creates one HA device per panel plus typed entities for every named object on the controller: `alarm_control_panel` for areas, `light` for units, `binary_sensor`/`switch` for zones (state + bypass), `climate` for thermostats, `sensor` for analog zones and panel telemetry, `button` for panel macros, and `event` for the typed push-notification stream. See [`custom_components/omni_pca/README.md`](custom_components/omni_pca/README.md) for the entity table and service list. +The integration creates one HA device per panel plus typed entities for every named object on the controller: `alarm_control_panel` for areas, `light` for units, `binary_sensor` + `switch` for zones (state + bypass), `climate` for thermostats, `sensor` for analog zones and panel telemetry, `button` for panel macros, and `event` for the typed push-notification stream. See [`custom_components/omni_pca/README.md`](custom_components/omni_pca/README.md) for the full entity + service catalog, or the [HA install how-to](https://hai-omni-pro-ii.warehack.ing/how-to/install-in-home-assistant/) for the step-by-step. ## Without a panel — mock controller -For testing, the library ships a minimal Omni controller emulator: +The library ships a stateful `MockPanel` that emulates the controller side of the protocol over real TCP. Useful for offline development, integration tests, and demos: ```python from omni_pca.mock_panel import MockPanel async with MockPanel(controller_key=...).serve(port=14369): - # connect a real OmniClient to localhost:14369 — works end-to-end + # Connect a real OmniClient to localhost:14369 — full handshake + AES ... ``` +The local dev stack (`dev/docker-compose.yml`) packages a real Home Assistant container and the mock panel side-by-side so you can click through the integration without touching real hardware. See [the dev-stack tutorial](https://hai-omni-pro-ii.warehack.ing/tutorials/dev-stack/). + +## Tests + +```bash +uv sync --group ha +uv run pytest -q +``` + +351 tests across the protocol primitives, the mock panel, the OmniClient ↔ MockPanel end-to-end roundtrip, and an in-process Home Assistant harness driving the integration via the real config flow + service calls. + ## Versioning -Date-based ([CalVer](https://calver.org/)): `YYYY.M.D`. Bumped on backwards-incompatible changes. +Date-based ([CalVer](https://calver.org/)): `YYYY.M.D`. Bumped on backwards-incompatible changes. See [`CHANGELOG.md`](CHANGELOG.md). + +## License + +MIT. See [`LICENSE`](LICENSE). ## Acknowledgments -This client is independent and not affiliated with Leviton or HAI. Protocol details derived from clean-room analysis of the publicly-distributed PC Access installer. +This client is independent and not affiliated with Leviton or HAI. Protocol details derived from clean-room analysis of the publicly-distributed PC Access installer. The reverse-engineering arc is documented at .