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.
5.7 KiB
| title | description |
|---|---|
| Zone & unit numbering | 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() 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 1–16 |
| 17 – 32 | X-10 house code X+1, modules 1–16 |
| 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.pcaconfig 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.RequestUnitStatushas two payload forms. The short form'sstartandendare single bytes (max 255). The long form takes BE u16s (max 65535) — seeclsOLMsgRequestUnitStatus.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
RequestUnitStatusreply at ~62 records regardless ofMessageLengthheadroom; querying a wider range NAKs.OmniClientV1Adapterchunks status polls into batches of 40 to stay well under that.
If you want to see the live mapping for your panel, run:
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.