ADR 0023 — HmIP-Wired Is a ProductGroup, Not an Interface¶
- Status: Accepted
- Date: 2026-05-26
- Related: ADR 0002 (multi-CCU), SPECIFICATION.md §2.1 / §5
Context¶
OpenCCU-Loom carried InterfaceHmIPWired as a separate value in pkg/hmenum.Interface alongside InterfaceHmIPRF, mirroring the visible split between Wired and RF in the HmIP product line. On the CCU itself there is no matching split — both flavours share a single XML-RPC service (port 2010 / 42010) under the HmIP-RF interface ID. The duplication leaked into the codebase in three shapes:
DetectionPorts[InterfaceHmIPWired]carried the same plain and TLS ports asInterfaceHmIPRF.PrimaryClientCandidateInterfaceshad to explicitly exclude Wired to keep facade selection deterministic.- A configuration with both
HmIP-RFandHmIP-Wiredlisted would build two parallel XML-RPC clients against the same CCU port, registering the sameinterface_idtwice and racing against the daemon's own callback server.
aiohomematic — our CCU-side reference (CLAUDE.md §aiohomematic as a Reference) — handles this cleanly:
Interfaceenum (aiohomematic/const.py:1472) contains onlyHMIP_RF; there is noHMIP_WIREDmember.ProductGroupenum (aiohomematic/const.py:1429) carriesHMIPW = "HmIP-Wired"; classification happens via the device model-name prefix (get_product_groupinaiohomematic/client/interface_client.py:633).
Decision¶
Treat HmIP-Wired the same way aiohomematic does:
- Remove
InterfaceHmIPWiredfrompkg/hmenum.Interface. - Classify HmIP-Wired devices through the
ProductGroupmechanism (ProductGroupHmIPW), derived from the device model-name prefixhmipw-*viahmenum.ProductGroupForModel, with an interface fallback for devices whose model name does not match a canonical prefix. - Reject
HmIP-Wiredas an interface name inInterfaceSpec.Validatewith a message that points the operator at the ProductGroup-based classification path. No silent alias.
This is a deliberate alignment with aiohomematic, not a divergence, and it removes the duplicate XML-RPC client risk for installations that previously listed both interfaces.
Consequences¶
- Greenfield config break: configurations that name
HmIP-Wiredas an interface now fail validation at startup. Operators upgrading from a pre-release that exposed the dual-interface model must remove the redundant entry. Aligns with the project policy of "no backwards-compatibility shims for aiohomematic data" (CLAUDE.md). - One XML-RPC client per HmIP CCU service, never two. The
interface_idcollision is impossible. - Per-device classification via
hmenum.ProductGroupForModel(model, iface)becomes the authoritative source for "is this a Wired device?" — the function is a 1:1 port of aiohomematic'sget_product_group. - External wire identity unchanged:
ProductGroupHmIPWstill uses the wire token"HmIP-Wired"in REST, WebSocket, MQTT, and the snapshot diff schema. No external API breakage. - The
PushesConfigPendingFor(iface, group)helper inpkg/hmenum/interface.gonow carries the load for Wired-vs-RF decisions: the interface alone cannot distinguish them, so the ProductGroup wins.