What's Changed
Integration
- Fix permanent mass deletion of entity-registry entries after a transient auth error (aiohomematic#3215): the startup orphan cleanup now refuses to run when it would remove more than half of the integration's registry entries — this guards against the central reporting
RUNNING(clients connected) while the device descriptions failed to load, which previously wiped hundreds of entities and re-detected devices as new - Set
EventDeviceClass.DOORBELLfor HmIP-DBB event entities so they work with the new Home Assistantdoorbellautomation trigger; all other event entities continue to useEventDeviceClass.BUTTON - Routed the event entity device class through the
EntityDescriptionRegistry(newHmEventEntityDescription,event()factory,EVENT_RULES, default forDataPointCategory.EVENT_GROUP) instead of hardcoding it on the entity class - Chore: sysvar/program marker filtering is now fully daemon-side for the openccu-loom backend. The integration no longer threads
sysvar_markers/program_markersinto the loomCentralConfig— the daemon (api ≥ 1.9.0) applies the marker + internal filter and resolves enabled-by-default itself, which the loom client reads off the wire. The direct-CCU backend is unchanged (it still passes the markers to aiohomematic). Requiresopenccu-loom-client==2026.6.18(2026.6.18 fixes a keyword-only regression wheremake_sysvar_data_pointappliedenabled_defaultpositionally and raised at sysvar spawn time, and adopts aiohomematic's lint suite + keyword-only enforcement across the client's public surface; pinsopenccu-loom-types==0.1.20). - Feat: active mDNS browse in the user-initiated loom setup. Choosing the openccu-loom backend from the menu now browses the LAN for
_openccu-loom._tcp.local.daemons: exactly one auto-selects straight to the token step, several are offered in a selection list (with a "manual entry" escape), and none falls back to the manual connection form. Selecting a daemon continues into the same token → CCU-selection steps as the passive discovery. - Feat: mDNS (zeroconf) discovery of openccu-loom daemons. Daemons advertising
_openccu-loom._tcp.local.are discovered automatically; after the user supplies the daemon's bearer token, the flow readsGET /system/ccuand lets the user pick which CCU to add (name/serial) instead of typing an instance name — the chosen CCU's name becomes the central selector and its serial the entry's unique_id. Host/port/TLS come from the mDNS advertisement (the daemon listener is plain). Requiresopenccu-loom-client==2026.6.16(newlist_ccushelper). The discovery path is gated by the loom-backend master switch. - Feat: the options flow is now backend-aware for the openccu-loom backend. A loom entry's menu drops the daemon-owned steps (interfaces, programs & system variables) and its connection step edits the daemon endpoint (host, port, TLS, bearer token) instead of CCU credentials (
loom_connection). The advanced-settings step shows only the HA-side toggles that apply to loom — system notifications, sub-devices and the config panel — since the daemon owns CCU-behaviour parity (hub scans, markers, light/cover behaviour, …) per-central in its own admin UI. The direct-CCU options flow is unchanged. - Feat: CCU↔loom backend switching preserves entities, and hub entities now survive a delete + re-add. Hub / sysvar / program / install-mode / internal / virtual-remote entity unique_ids are now anchored on the CCU serial instead of
entry_id[-10:](the entry_id is regenerated on a delete + re-add, which previously orphaned them;central_idincontrol_unit.py). On the direct-CCU backend, existing registries are re-anchored once at setup (_async_migrate_aiohomematic_hub_unique_ids), and switching back from loom strips theloom_namespace (_async_restore_aiohomematic_unique_ids) — both schemes now differ only by that namespace, so the CCU↔loom round-trip is lossless for the entity set both backends produce. If the connected CCU serial ever changes (a radio-module / Funkmodul swap), hub entities are re-anchored onto the new serial, the entry's unique_id is updated and the entry reloaded (_async_reanchor_hub_unique_ids_on_serial_change) — a rare event that previously also produced a duplicate config entry. History, area and customisations follow the entity throughout. All rewrites are string-level, idempotent and entry-scoped. - Feat:
sub_devices_enablednow works with the openccu-loom backend. The loom client models the daemon's channel groups (Device.has_sub_devices,Channel.is_in_multi_group/group_masterwith aiohomematicChannelNameDatanaming), so multi-group devices split into the same HA sub-devices as the direct-CCU backend (verified: 45/45 devices split identically, 0 entity-to-sub-device assignment diffs across 1728 matched entities). The advanced-settings options step no longer crashes for loom entries (the loomquery_facade.get_un_ignore_candidateswas an async coroutine; it is now synchronous with the aiohomematic signature). - Feat:
LOOM_BACKEND_SELECTABLEmaster switch (const.py). WhenFalse, the config-flow backend menu is skipped — a fresh setup goes straight to the direct-CCU step and the loom path behaves as if it did not exist (existing loom entries are untouched). - Feat: the loom
CentralConfigreceives the Home Assistant UI language (hass.config.language), so the loom backend composes locale-aware schedule/parameter names (e.g. "Zeitplan"). - Feat: sysvar/program description markers are passed into the loom backend (marker-driven hub-entity visibility, parity with the direct-CCU backend).
- Fix: sub-device areas —
suggested_areais now carried on every device-creatingDeviceInfo(event, device-update and channel-bound hub entities, not just the generic path). HA appliessuggested_areaonly at device creation, so on the loom backend — where devices are recreated on every fresh spawn — room-assigned devices previously lost their area whenever one of those entities registered first. The via device is seeded with its own room (maintenance channel) instead of the calling sub-device's area. - Fix: the device-update (
HUB_UPDATE) platform fetches existing hub data points at setup, not only via the new-data-point signal — the loom adapter emitsDataPointsCreatedEventduringcentral.start, before the platforms subscribe, so the system-update entity was previously lost. - Fix:
generic_entityguardsdata_point.channelagainstNonein the sub-device split (loom data points may resolve no channel; aiohomematic data points are unaffected). - Fix: enum sensors that also report a unit of measurement (e.g. door/window contact
STATEon the openccu-loom backend) failed to be added — Home Assistant rejects a unit on the non-numericenumdevice class (ValueError: … has a unit of measurement … non-numeric device class: enum).AioHomematicSensorno longer assigns a unit when the data point carries enumvalues. - Chore: pin
openccu-loom-client==2026.6.15— per-channel schedule switches now follow the WEEK_PROFILE channel, so devices that carry a climate CDP yet expose their schedule on a dedicated WEEK_PROFILE channel (HmIP-WGTC) regain their schedule switches (paired with the daemon-side normalize pass). - Chore:
backend_types._pairis now generic (tuple[type[T], ...]), soisinstancechecks against the backend-agnostic dispatch tuples narrow to the aiohomematic type — mypy strict passes again across all platform files (27 errors resolved without runtime changes); the loom twin duck-types the aiohomematic class, documented in one place instead of per-call-site casts. - Chore: updated tests for the dual-backend flow — config-flow tests navigate the new backend menu (
user→central), device-action tests patch theDP_ACTION_OR_BUTTONdispatch tuple, and light tests match the fixed-color dispatch tuple.
Testing
- Test: three-way godevccu parity e2e suite (
tests/e2e/, opt-inpytest -m e2e -n0). A single godevccu backend feeds three north-bound surfaces — the aiohomematic backend (direct XML-RPC/JSON-RPC), the openccu-loom-client backend (REST/WS via a local openccu-loom daemon) and the daemon's MQTT discovery (via a real Mosquitto broker into HA'smqttintegration) — each scraped in its own Home Assistant instance and diffed for identical devices, entities, names and card attributes. Skipped unless the external Go binaries and Mosquitto are present. Enforces entity-set parity across all three planes (test_entity_set_parity) modulo a documented by-design allowlist (hub system-update; mqtt-discovery omits program buttons, install-mode and backup admin entities). Residual name/attribute drift — the loom multi-channelchNmarker (needs paramset-description-level presence the daemon does not expose) and the mqtt discovery's HA-idiomatic naming — is reported and tracked asxfail. Requires godevccu ≥ 0.1.4 (channelIds: []notnull), openccu-loom daemon api ≥ 1.7.0 + openccu-loom-types ≥ 0.1.19 + openccu-loom-client ≥ 2026.6.15 (calculated-DP names, schedule-switch target-channel names and WGTC schedule switches match the direct-CCU twin).
Dependencies
New runtime dependency: openccu-loom-client==2026.6.19 (pins openccu-loom-types==0.1.22)
The openccu-loom backend is new in 2.8.0 — an alternative to the direct-CCU (aiohomematic) backend that talks to an openccu-loom daemon over REST/WS. The client reached full parity with the direct-CCU backend across structure, values, names, attributes and HA cards over the 2.8.0 beta cycle (final fresh-spawn measurement: 1962 entities matched, residuals are by-design instance differences). Highlights:
- Live state delivery: value and custom-DP pushes reach Home Assistant — the default WS subscriptions now carry the
datapoint.*/custom_data_point.*topic prefixes (entities no longer froze on their bootstrap value). Channel-group switch CDPs (STATE@3/4/5) readis_onfrom the channel's genericSTATEdata point as a fallback, so a switched actuator no longer snaps back to off. - Climate cards populate current/target temperature and humidity (read from the daemon's CDP state with a field-DP fallback);
preset_modesalways listsnone;modes/profilescarry real aiohomematic enum members. - Hub layer: system variables, programs, per-device firmware updates, event groups, calculated data points, and hub singletons (alarm/service messages, inbox, metrics, connectivity, install mode, system update) spawn as HA entities with aiohomematic-parity unique ids and names.
- Visibility parity: the daemon's
usageverdict gates entity creation (no_create/ignored/eventskipped,ce_primary/ce_secondaryabsorbed by the custom DP); sysvars classify by type with the extended marker (read-only sensor/binary_sensor vs. writable switch/select/number/text) and exclude CCU-internal/scratch variables (${…},OldVal/pcCCUID, fixed ids 40/41). - Naming: generic, custom, calculated and combined data points compose locale-aware names matching aiohomematic (channel
chN/vchNmarkers,label_omittedcollapse, calculated/combinedtranslated_name). - Schedule layer: week-profile sensors and per-channel schedule switches; combined duration number for sirens.
- Multi-central correctness: foreign-central sysvars/programs/connectivity no longer leak into an entry;
SystemInformation.ccu_typedefaults to OpenCCU so the system-update entity spawns. - Final pin
openccu-loom-types==0.1.22(daemon api ≥ 1.9.0): sysvar/programenabled_defaultis resolved daemon-side (the marker + internal-inclusion filter is no longer applied client-side), on top of the channel-group, schedule, hub-singleton andavailable_target_channelscontract accumulated since 0.1.17.openccu-loom-client==2026.6.19is a dependency-bump release over 2026.6.18 (types 0.1.21 → 0.1.22, ruff, pytest); 2026.6.18 adopted aiohomematic's lint suite and fixed a keyword-onlymake_sysvar_data_pointregression.
Bump aiohomematic to 2026.6.3
- Sensors no longer report a spurious
0after a CCU restart (#3228): thefetch_all_device_databulk-load script now skips empty (not-yet-measured) numeric values instead of coercing them to"0", so a data point such asACTUAL_TEMPERATUREstays unset and Home Assistant keeps the restored last value until a real measurement arrives (a real0reading is unaffected) - Fix HmIP-RGBW / HmIP-DRG-DALI cannot be switched on (briefly flashes, then turns off again) (#3210)
- Make interrupted device creation observable —
CancelledErrormid-build now logs a clear warning instead of silently abandoning the run with zero entities (#3213) - Revert the contract/event-type extraction (#3214): public event types stay in
aiohomematic.central.events, no separateaiohomematic-contractruntime dependency
aiohomematic-config remains at 2026.5.0
- No API or behavior changes for the integration since 2.7.2
homematicip-local-frontend
- Bundled
homematic-config.jsrebuilt; the prior 2.7.2 build already covered HA 2026.6 compatibility ("HA 2026.6 Compatibility —ha-radioRemoval (#60)")