New reference page documenting the Omni Pro II's 14-byte program record
format. Mirrors file-format.mdx's structure: byte-offset table, enum
tables (ProgramType, ProgramCond, Days), worked example decoding a
real slot from the live fixture, callouts for the EVENT-only Mon/Day
swap on disk, and an explicit "what we don't yet know" section that
lists the gaps a future editor pass would have to close (cond bit
split, multi-record clausal encoding, RemarkID -> RemarkText lookup,
DPC capability flag, sunrise/sunset offset flag).
Sidebar adds the entry between File format and Hardware specs.
Two new pages distilled from HAI's official OmniPro II Installation
Manual 3-2 + Product Specifications datasheet (Quadomated mirror).
reference/hardware-specs.md
Capacity ceilings (176 zones, 511 units, 8 areas, 64 thermostats,
128 buttons, 1500 programs, 99 codes, 128 messages, etc.), digital
communicator + network features, electrical specs with the per-output
current caps and the 24-hour battery-standby derating numbers,
physical dimensions, environmental ranges, listings, languages, and
part-number lookup. The numbers here are the source of every cap in
clsCapOMNI_PRO_II.cs and the upper bounds for the protocol's range
fields, so anyone debugging "why does my panel NAK at index N" should
start here.
explanation/zone-unit-numbering.md
Appendix C of the install manual, transcribed and explained: how the
panel maps physical hardware to its 1-176 zone and 1-511 unit
address spaces. Documents the four overlapping families that share
the unit number line -- X-10 (1-256, by house code), ALC bus
(parallel address space within those slots), physical outputs
(257-392), and panel flags (393-511) -- which is why the working
panel reports units at index 257+ (sprinkler outputs on the first
17A00 expansion enclosure) and 393+ (named flags) even though only
a dozen lights are wired up.
Closes a real debugging mystery from Phase 2/3 of the v1+UDP work:
OmniClientV1's long-form RequestUnitStatus path (BE u16 start/end)
exists specifically to address units > 255, which only happens
because of this firmware-fixed address layout.
astro.config.mjs
Slot both new pages into the existing Reference and Explanation
sidebar groups.
Aligns with the warehack-ing host convention (matches birdcage-docs):
Dockerfile — multi-stage with named targets:
base shared npm ci + COPY
dev npx astro dev --host 0.0.0.0 --port 4321 (HMR enabled)
build npx astro build (produces /app/dist)
prod caddy:2-alpine serves /srv with /health probe + HEALTHCHECK
docker-compose.yml — picks the target via APP_ENV in .env:
build.target = ${APP_ENV:-dev}
caddy.reverse_proxy upstream port = ${APP_PORT:-4321}
Adds the streaming/HMR caddy labels CLAUDE.md requires for Vite-over-
Caddy: flush_interval=-1, transport.read/write_timeout=0, keepalive,
stream_timeout=24h, stream_close_delay=5s
Volume mounts ./src, ./public, astro.config.mjs (live in dev, harmless
in prod since the prod stage doesn't reference /app)
astro.config.mjs — vite.server.hmr block now picks up VITE_HMR_HOST
env var and configures host/protocol/clientPort for wss-on-443 HMR
through Caddy. Falls back to undefined when unset so plain
'npm run dev' still works.
Caddyfile — adds /health endpoint for the Dockerfile HEALTHCHECK,
SPA-style try_files fallback chain (path -> path/index.html -> /index.html).
Makefile — adds 'make dev' / 'make prod' that rewrite APP_ENV+APP_PORT
in .env then rebuild. Tail-logs after up/restart so you see startup
diagnostics without a separate 'make logs'.
.env.example — five vars (COMPOSE_PROJECT_NAME, APP_ENV, APP_PORT,
PUBLIC_DOMAIN, VITE_HMR_HOST), defaulting to prod mode against the
public hai-omni-pro-ii.warehack.ing domain. .env stays gitignored so
each environment (local, remote) can override.
Local container rebuilt + recreated, healthy, /health returns 200,
PUBLIC_DOMAIN locally still set to .l.warehack.ing in the host .env.
The .l.warehack.ing subdomain is the convention for the user's local
services. DNS for hai-omni-pro-ii.l.warehack.ing already resolves to
the host; caddy-docker-proxy picks up the new caddy label and routes
appropriately.
Patched .env, .env.example, docker-compose.yml, README.md,
astro.config.mjs.
Container rebuilt and restarted; verified caddy-docker-proxy is
serving 200 OK with 33051 bytes of rendered HTML on the internal
network, and the host-level Caddy issues a 308 redirect to https://
on the new hostname.
Astro 6 + Starlight 0.39 documentation site for omni-pca, organised
around the Diatáxis framework (Tutorials / How-to / Reference /
Explanation), plus a chronological Journey page and Changelog.
Theme: muted slate-blue with amber accents. astro-icon + lucide
preinstalled. Astro telemetry and Starlight devToolbar both off.
Deployment: multi-stage Dockerfile (node:25-alpine builder ->
caddy:2-alpine runtime), inner Caddy serves static dist on :80,
outer caddy-docker-proxy on the host terminates TLS for
hai-omni-pro-ii.warehack.ing.