docs: add Hardware specs reference + Zone & unit numbering explanation

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.
This commit is contained in:
Ryan Malloy 2026-05-11 13:23:58 -06:00
parent f7be0f7b18
commit 9ea05c3b94
3 changed files with 284 additions and 0 deletions

View File

@ -62,6 +62,7 @@ export default defineConfig({
items: [ items: [
{ label: 'Protocol', slug: 'reference/protocol' }, { label: 'Protocol', slug: 'reference/protocol' },
{ label: 'File format', slug: 'reference/file-format' }, { label: 'File format', slug: 'reference/file-format' },
{ label: 'Hardware specs', slug: 'reference/hardware-specs' },
{ label: 'Library API', slug: 'reference/library-api' }, { label: 'Library API', slug: 'reference/library-api' },
{ label: 'HA entities', slug: 'reference/ha-entities' }, { label: 'HA entities', slug: 'reference/ha-entities' },
{ label: 'HA services', slug: 'reference/ha-services' }, { label: 'HA services', slug: 'reference/ha-services' },
@ -72,6 +73,7 @@ export default defineConfig({
collapsed: false, collapsed: false,
items: [ items: [
{ label: 'Two non-public quirks', slug: 'explanation/quirks' }, { label: 'Two non-public quirks', slug: 'explanation/quirks' },
{ label: 'Zone & unit numbering', slug: 'explanation/zone-unit-numbering' },
{ label: 'Architecture', slug: 'explanation/architecture' }, { label: 'Architecture', slug: 'explanation/architecture' },
{ label: 'The PC Access bug', slug: 'explanation/pc-access-bug' }, { label: 'The PC Access bug', slug: 'explanation/pc-access-bug' },
], ],

View File

@ -0,0 +1,144 @@
---
title: Zone & unit numbering
description: How the Omni Pro II maps physical hardware to its 1-176 zone and 1-511 unit address space — and why your panel may report units in the 257+ range even with no 16th-house-code X-10 module installed.
---
A panel that looks like it has 8 zones and a dozen lights to a homeowner
is actually addressing into a much larger fixed map of 176 zone slots
and 511 unit slots. The mapping is part of the controller's firmware,
not configurable. If you walk the panel with
[`OmniClientV1.iter_names()`](/reference/library-api/) and see units at
index 257 or 393, this is why.
This page is a literal transcription of *Appendix C* of HAI's *OmniPro II
Installation Manual 3-2*, p74 — distilled from the live mapping our
firmware-2.12 panel actually reports.
## Zones (1-176)
Every group of 16 zones is one physical board / enclosure.
| Index range | Source |
|---|---|
| 1 16 | Controller (onboard) |
| 17 32 | 1st **10A06** hardwire expander board |
| 33 48 | 2nd **10A06** hardwire expander board |
| 49 64 | 1st **17A00** expansion enclosure |
| 65 80 | 2nd **17A00** expansion enclosure |
| 81 96 | 3rd **17A00** expansion enclosure |
| 97 112 | 4th **17A00** expansion enclosure |
| 113 128| 5th **17A00** expansion enclosure |
| 129 144| 6th **17A00** expansion enclosure |
| 145 160| 7th **17A00** expansion enclosure |
| 161 176| 8th **17A00** expansion enclosure |
The hardware cap is 176, regardless of how many your installer wired up.
Slots without a physical sensor still respond to `RequestZoneStatus`
they just return `status=0, loop=0` (or the analog-loop "no transponder"
sentinel `0x80`).
## Units (1-511)
The unit address space mixes **four protocol families** — X-10, ALC,
physical outputs, and "flags" — into one flat number line. Which one
each block lands in is fixed by the firmware:
### X-10 (1 256, by house code)
X-10 modules are addressed `(house_code, unit_id)` on the wire but Omni
flattens that to a single integer: each consecutive house code gets the
next 16 indices. The installer picks the *starting* house code "X" at
setup time; the controller occupies X through X+15 (16 house codes).
| Index range | Source |
|---|---|
| 1 16 | X-10 house code **X** (start), modules 116 |
| 17 32 | X-10 house code **X+1**, modules 116 |
| 33 48 | X-10 house code **X+2** |
| 49 64 | X-10 house code **X+3** |
| 65 80 | X-10 house code **X+4** |
| 81 96 | X-10 house code **X+5** |
| 97 112 | X-10 house code **X+6** |
| 113 128 | X-10 house code **X+7** |
| 129 144 | X-10 house code **X+8** |
| 145 160 | X-10 house code **X+9** |
| 161 176 | X-10 house code **X+10** |
| 177 192 | X-10 house code **X+11** |
| 193 208 | X-10 house code **X+12** |
| 209 224 | X-10 house code **X+13** |
| 225 240 | X-10 house code **X+14** |
| 241 256 | X-10 house code **X+15** |
### ALC bus (parallel address space)
ALC ("Advanced Lighting Control") devices share the X-10 slots
above, but only every other range within a 64-block module/branch:
| Index range | Source |
|---|---|
| 1 31 | ALC Module 1, Branch 1 (addresses 1-31) |
| 33 63 | ALC Module 1, Branch 2 |
| 65 95 | ALC Module 1, Branch 3 |
| 97 127 | ALC Module 1, Branch 4 |
| 129 159 | ALC Module 2, Branch 1 |
| 161 191 | ALC Module 2, Branch 2 |
| 193 223 | ALC Module 2, Branch 3 |
| 225 255 | ALC Module 2, Branch 4 |
ALC and X-10 numbering deliberately overlap: if you've wired an ALC
device at module 1 / branch 1 / addr 5, it lives at unit index 5 — same
slot the X-10 firmware would otherwise have for house-code-X module 5.
You pick one or the other; the panel won't drive both into the same
slot.
### Physical outputs (257 392)
Real relay/voltage outputs on the controller and expansion enclosures:
| Index range | Source |
|---|---|
| 257 272 | Outputs 1-16, 1st **17A00** expansion enclosure |
| 273 288 | Outputs 1-16, 2nd **17A00** |
| 289 304 | Outputs 1-16, 3rd **17A00** |
| 305 320 | Outputs 1-16, 4th **17A00** |
| 321 336 | Outputs 1-16, 5th **17A00** |
| 337 352 | Outputs 1-16, 6th **17A00** |
| 353 368 | Outputs 1-16, 7th **17A00** |
| 369 384 | Outputs 1-16, 8th **17A00** |
| 385 392 | Voltage outputs 1-8 on the controller itself |
### Flags (393 511)
The top 119 unit slots aren't hardware — they're **flags**: panel
variables an installer can write Programming Lines against. Flags
behave like units on the wire (you can `turn_unit_on(400)` to set
flag 400), but no physical load moves.
| Index range | Source |
|---|---|
| 393 511 | Flags (panel variables) |
## Why this matters for omni-pca
* **`OmniClientV1.iter_names()`** streams names for any defined slot in
the full 1-511 range. If your `.pca` config defined sprinkler
controllers as outputs 1-10 on the first 17A00, you'll see them as
units 257-266 — even though only 8 "real" lights are wired up.
* **`RequestUnitStatus` has two payload forms.** The short form's `start`
and `end` are single bytes (max 255). The long form takes BE u16s
(max 65535) — see `clsOLMsgRequestUnitStatus.cs:18-31`. Our v1 client
picks the right form automatically based on the requested range.
* **Per-poll record cap.** Firmware 2.12 caps a single
`RequestUnitStatus` reply at ~62 records regardless of `MessageLength`
headroom; querying a wider range NAKs. `OmniClientV1Adapter` chunks
status polls into batches of 40 to stay well under that.
If you want to see the live mapping for *your* panel, run:
```bash
cd omni-pca
uv run python dev/probe_v1_client.py
```
— it dumps every defined name across all object types and lets you
correlate user-facing labels with their underlying unit index.

View File

@ -0,0 +1,138 @@
---
title: Hardware specs
description: Omni Pro II controller capacities, electrical specs, environmental ranges, and expansion limits — distilled from HAI's official product spec sheet and installation manual.
---
The numbers below are the Omni Pro II controller's hardcoded capacity
ceilings: the protocol's `RequestProperties` / `RequestStatus` ranges, the
`SystemStatus` payload size, the .pca file's fixed-size names tables, and
every cap in `clsCapOMNI_PRO_II.cs` derive from these. They're the
reason `OmniClientV1` chunks polls and uses the long-form
`RequestUnitStatus` for unit numbers above 255 — see
[zone & unit numbering](/explanation/zone-unit-numbering/) for the address
layout that yields those high numbers.
References for everything on this page: HAI's *OmniPro II Product
Specifications* (part 20A00-2, 2012-10) and *OmniPro II Installation
Manual 3.2*, both available from
[quadomated.com](https://www.quadomated.com/technology/automation/home-automation-controller-hai-omnipro-ii/).
## Capacity ceilings
What the controller can address at most — these set the upper bounds for
every typed entity in HA.
| Object | Limit | Notes |
|---|---:|---|
| Zones | 176 | 16 onboard + 160 across expansion |
| Hardwire zone expansions (10A06) | 2 | 16 zones each → 32 |
| Expansion enclosures (17A00) | 8 | 16 zones + 16 outputs each |
| Units (lighting addresses) | 511 | X-10 / ALC / HLC / outputs / flags combined |
| Areas | 8 | true partitioning |
| Thermostats (Omnistat2) | 64 | |
| Buttons (named macros) | 128 | |
| Lighting scenes | 128 | |
| Programs | 1500 | |
| User codes | 99 | |
| Messages | 128 | stored on panel |
| Consoles (LCD keypads) | 16 | |
| OmniTouch 5.7e (IP) | 16 | |
| Access control card readers | 16 | |
| Access cards / keytags | 99 | |
| Serial ports (onboard) | 5 | |
| Serial expansion total | 6 | with one expansion |
| 12 V trigger outputs (with expansion) | 8 (136) | |
| Vocabulary words (built-in) | 550 | plus custom vocabulary |
| Battery standby (typical) | 24 hours | with derated outputs (see below) |
## Communicator + comms
| Field | Value |
|---|---|
| Built-in digital communicator | yes |
| Reporting formats | Contact ID, 4/2, 3/1 |
| Extra phone numbers for voice notify | 8 |
| Ethernet port | yes (built-in, 100 Mbit) |
| Flash memory | yes (field firmware updates) |
| Network port | UDP and TCP on 4369 by default |
## Electrical
From the installation manual's *Specifications* chapter (p64).
| Parameter | Value |
|---|---|
| Mains | 120 VAC, 60 Hz, 60 W |
| Transformer | 24 VAC, 1.67 A, 40 VA |
| Battery (backup) | 12 V, 7 Ah, sealed lead-acid |
| Nominal DC bus | 10 13.7 VDC (≤0.5 Vpp ripple) |
| Low-voltage cut-out | ≈9 VDC |
| Device fuse | polyfuse, 1.35 A |
| Horns fuse | polyfuse, 1.35 A |
| Battery fuse | polyfuse, 4.00 A |
Polyfuses self-reset; no field replacement needed.
### Per-output current (max)
| Output | Max current |
|---|---:|
| AUX 12 V (one source) | 1.0 A |
| SWITCH 12 V (one source) | 1.0 A |
| CONSOLE bus | 1.0 A |
| OUTPUTS 1-8 (each) | 100 mA |
| **Combined: AUX + SWITCH + CONSOLE + OUTPUTS 1-8** | **1.0 A total** |
| INT HORN + EXT HORN combined | 1.0 A |
### Derated for 24-hour battery standby
If the install needs to run for 24 h on the backup battery alone:
| Output group | Combined max |
|---|---:|
| AUX 12 V + SWITCH 12 V + CONSOLE + OUTPUTS 1-8 | 250 mA |
| INT HORN + EXT HORN | 300 mA |
Typical current at nominal voltage:
- Controller idle: 135 mA
- LCD console: 35 mA backlight off, 100 mA backlight on
## Physical
| Item | Dimensions | Weight |
|---|---|---|
| Controller (W × H × D) | 13″ × 13″ × 4.5″ | ≈10 lb |
| LCD console (W × H × D) | 4.6″ × 4.5″ × 1.2″ | ≈0.5 lb |
## Environmental
| Parameter | Range |
|---|---|
| Operating temperature | 32 °F 122 °F (0 °C 50 °C) |
| Operating humidity | 10 95 % RH, non-condensing |
## Listings
* UL Listed residential burglar + fire
* SIA CP-01 compliant (false-alarm-reduction)
* California Title 24 compliant
* 3-year warranty (HAI)
## Languages
Built-in (selectable at install time):
English (default), Latin American Spanish, European Spanish, Catalan,
Italian, French, Traditional Chinese, Simplified Chinese.
## Part numbers
| Part | Description |
|---|---|
| 20A00-2 | OmniPro II with steel enclosure |
| 20A00-8 | OmniPro II on mounting plate (for structured-wiring cans) |
| 20A00-21 | OmniPro II board only |
| 10A06-1 | 16-zone hardwire expansion board |
| 17A00 | 16-zone / 16-output expansion enclosure |
| 42A00-1 | Wireless receiver |
| 45A00-1 | Wireless receiver (alt model) |