omni-pca/dev/docker-compose.yml
Ryan Malloy 9726ee36bb
Some checks failed
Validate / Hassfest (push) Has been cancelled
Validate / HACS validation (push) Has been cancelled
dev: load real .pca fixtures into the mock-panel
Adds an OMNI_PCA_FIXTURE escape hatch so the mock can serve real
panel data instead of the synthetic five-zone state. With this in
place the dev stack is wire-indistinguishable from the source
panel for everything the HA integration touches: 330 programs,
16 zones, 44 units, 2 thermostats etc. from our test fixture.

- run_mock_panel.py: --pca / OMNI_PCA_FIXTURE accepts a path; the
  decryption key is auto-derived from a sibling PCA01.CFG when one
  exists (the common PC Access export layout), with --pca-key /
  OMNI_PCA_FIXTURE_KEY as override. Falls back to KEY_EXPORT for
  vanilla unsigned exports.
- docker-compose.yml: mount /home/kdm/home-auto/HAI as /fixtures
  read-only and surface OMNI_PCA_FIXTURE so dev/.env can drive it.
- dev/README.md: new section documenting fixture loading.
- dev/screenshot_overview.py: quick playwright helper for capturing
  the side-panel landing page with whatever fixture is loaded.
- dev/artifacts/screenshots/2026-05-17/real-pca-overview.png: snapshot
  of the Omni Programs side panel against the real .pca fixture
  (330 programs).
2026-05-17 13:06:19 -06:00

108 lines
4.0 KiB
YAML

# Local dev stack: real Home Assistant talking to a MockPanel running on
# the host. Lets you click around the UI and grab screenshots without a
# physical Omni controller.
#
# make dev-up # start
# make dev-logs # tail HA logs
# make dev-down # stop and clean
#
# On every container start the HA service pip-installs the local
# `omni-pca` library from ../ into site-packages (the version pinned in
# the integration manifest isn't on PyPI yet, and we want our latest
# v1/ subpackage available either way). Source changes in src/omni_pca
# require a ``docker compose restart homeassistant`` to take effect.
#
# Once running, open http://localhost:8123 and:
# 1. Onboard with any name / location.
# 2. Settings -> Devices & Services -> Add Integration ->
# "HAI/Leviton Omni Panel".
# 3. Use one of:
# Mock panel (TCP):
# host host.docker.internal
# port 14369
# transport TCP
# controller_key 000102030405060708090a0b0c0d0e0f
# Real panel (UDP, v1 wire protocol):
# host <panel IP, e.g. 192.168.1.9>
# port 4369
# transport UDP
# controller_key <32 hex chars from the panel's .pca file>
services:
mock-panel:
image: ghcr.io/astral-sh/uv:python3.14-bookworm-slim
working_dir: /tmp/mock
volumes:
- ../src:/tmp/mock/src:ro
- ./run_mock_panel.py:/tmp/mock/run_mock_panel.py:ro
# Mount the captured .pca fixtures read-only so the mock can
# optionally seed its state from a real export. Set
# OMNI_PCA_FIXTURE in dev/.env (or pass on the command line) to
# activate; left unset, the mock uses the hard-coded sample.
- /home/kdm/home-auto/HAI:/fixtures:ro
environment:
PYTHONPATH: /tmp/mock/src
OMNI_PCA_FIXTURE: ${OMNI_PCA_FIXTURE:-}
command:
- sh
- -c
- "uv pip install --system --quiet cryptography && python /tmp/mock/run_mock_panel.py --host 0.0.0.0 --port 14369"
ports:
- "14369:14369"
networks:
- default
homeassistant:
image: ghcr.io/home-assistant/home-assistant:2026.5
container_name: omni-pca-dev-ha
depends_on:
- mock-panel
volumes:
- ./ha-config:/config
- ../custom_components/omni_pca:/config/custom_components/omni_pca:ro
# Make the whole library project (pyproject + src/ + dist/) available
# so the entrypoint override below can pip-install from local source
# before /init starts. This gives HA real dist-info for
# ``omni-pca==2026.5.10`` (which isn't on PyPI yet) and ensures the
# v1 subpackage is present.
- ../:/opt/omni-pca-src:ro
# Keep 8123 mapped on localhost for direct access during development;
# public traffic comes in via caddy-docker-proxy on the `caddy` net.
ports:
- "8123:8123"
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
- TZ=America/Boise
networks:
- default
- caddy
labels:
caddy: juliet.warehack.ing
caddy.reverse_proxy: "{{upstreams 8123}}"
# HA uses WebSockets for the frontend (lovelace state updates,
# config flow, etc.) so we need the streaming-friendly settings
# from CLAUDE.md, otherwise caddy closes the socket every ~15s.
caddy.reverse_proxy.flush_interval: "-1"
caddy.reverse_proxy.transport: http
caddy.reverse_proxy.transport.read_timeout: "0"
caddy.reverse_proxy.transport.write_timeout: "0"
caddy.reverse_proxy.transport.keepalive: 5m
caddy.reverse_proxy.transport.keepalive_idle_conns: "10"
caddy.reverse_proxy.stream_timeout: 24h
caddy.reverse_proxy.stream_close_delay: 5s
# HA's image entrypoint is /init (s6-overlay). We pre-install our
# local library against site-packages so HA's manifest-requirement
# check finds it, then exec /init normally.
entrypoint:
- sh
- -c
- |
set -e
pip install --quiet --no-deps --upgrade /opt/omni-pca-src
exec /init
networks:
caddy:
external: true