node-red-contrib-ccu 4.1.0 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,35 @@ Notable changes to node-red-contrib-ccu. Format follows
5
5
  user-visible symptom and the cause, not the commit list (the release notes
6
6
  append commits automatically).
7
7
 
8
+ ## 4.2.0 (2026-09-04)
9
+
10
+ ### Added
11
+
12
+ - New node **ccu-homeassistant**: publishes Home Assistant MQTT
13
+ auto-discovery configurations (device-based, HA >= 2024.11) for a
14
+ checkbox-selected set of devices. It is a companion to the ccu-mqtt
15
+ node and reuses its topic templates and payload format, so the
16
+ discovery configs point at the topics ccu-mqtt already publishes and
17
+ consumes; wire its output to the same mqtt-out node. Entities: switch,
18
+ light (dimmers), cover (blinds/shutters incl. tilt), climate (HM and
19
+ HmIP thermostats), binary_sensor (contact, rotary handle, motion,
20
+ presence, smoke, water), event (keys), lock (KeyMatic), sensor (energy,
21
+ weather, maintenance) plus, optionally, disabled-by-default entities for
22
+ every other datapoint. Unchecking a device removes it from Home
23
+ Assistant on the next deploy. (Roadmap B-16)
24
+ - ccu-mqtt: the setValue topic accepts Home Assistant's command words —
25
+ `OPEN`, `CLOSE`, `STOP`, `ON`, `OFF` on LEVEL and `AUTO-MODE`,
26
+ `MANU-MODE`, `BOOST-MODE`, `COMFORT-MODE`, `LOWERING-MODE` on the
27
+ read-only CONTROL_MODE of HM thermostats (translated to the `*_MODE`
28
+ actions).
29
+
30
+ ### Fixed
31
+
32
+ - ccu-mqtt: channels without a ReGa name produced topics with an empty
33
+ segment (`hm/status//STATE`); the channel address is used instead.
34
+ - Closing a ccu-mqtt or ccu-rpc-event node threw inside the connection's
35
+ deregister, so the node was never reported as closed on deploy.
36
+
8
37
  ## 4.1.0 (2026-09-04)
9
38
 
10
39
  ### Fixed
package/HANDOFF.md CHANGED
@@ -7,13 +7,15 @@ Lab addresses and credentials are intentionally **not** in this file
7
7
 
8
8
  ## State
9
9
 
10
- - **4.0.0 released 2026-09-02** (npm latest, OIDC provenance, GitHub
11
- release). Master is at `4.1.0-dev.5`+, **CI fully green** (lint + Node
12
- 22/24 × Node-RED 4/5).
13
- - In the Unreleased (4.1.0) changelog: binrpc 4.2.0, B-14
14
- (LEVEL_2 → COMBINED_PARAMETER, unverified on hardware), paramsets
15
- fetch/join tooling. Phase 3: cast/topic/message/castSysvar extracted,
16
- 43 unit tests (`npm run test:pure`).
10
+ - **4.0.0 released 2026-09-02, 4.1.0 released 2026-09-04** (npm latest
11
+ = 4.1.0, OIDC provenance, GitHub releases). 4.1.0 = binrpc 4.2.0, B-14
12
+ (LEVEL_2 → COMBINED_PARAMETER, unverified on hardware by decision),
13
+ paramsets fetch/join tooling and the regenerated `paramsets.json`
14
+ (+605 keys from the production CCU and two lab CCUs). Phase 3:
15
+ cast/topic/message/castSysvar extracted, 43 unit tests
16
+ (`npm run test:pure`, 71 on the B-16 branch).
17
+ - Branch `b-16-homeassistant` (4.2.0) is pushed and **CI green** on all
18
+ legs including the mocha integration suite.
17
19
  - Issue tracker fully triaged; B-6/B-14 archived; roadmap is current.
18
20
 
19
21
  ## Decisions (2026-09-04)
@@ -50,14 +52,55 @@ Lab addresses and credentials are intentionally **not** in this file
50
52
  (ccu-value node writing LEVEL_2 to the HmIP-FBL's `:4` channel on
51
53
  the Node-RED test box, log shows the COMBINED_PARAMETER remap) stays
52
54
  valid if it is ever wanted.
53
- 3. **Release 4.1.0** — in progress 2026-09-04: CHANGELOG heading dated,
54
- `npm pkg set version=4.1.0`, commit, push, CI green, `git tag v4.1.0
55
- && git push origin v4.1.0` — release.yml publishes via OIDC and
56
- creates the GitHub release from the CHANGELOG.
57
- 4. **Release 4.2.0 = B-16** right after: user does the editor smoke test
58
- on a lab CCU (the branch build is installed on both), then rebase the
59
- branch onto master, push for CI, merge, date the CHANGELOG section,
60
- version 4.2.0, tag. B-2 moves to 4.3.0.
55
+ 3. ~~Release 4.1.0~~ **done 2026-09-04** (tag v4.1.0, release.yml green,
56
+ npm latest 4.1.0). Follow-up worth doing: comment on #136/#154/#175
57
+ that 4.1.0 contains the LEVEL_2 fix and ask for confirmation on real
58
+ hardware (needs the user's go — outward-facing).
59
+ 4. **Release 4.2.0 = B-16** — editor smoke test done by the user
60
+ 2026-09-04 (ok), released the same day: branch merged into master
61
+ with `--no-ff` (never rebase with `-X theirs` — it silently keeps the
62
+ branch side of conflicting doc hunks, which bit twice today), CHANGELOG
63
+ dated, version 4.2.0, tag v4.2.0. B-16 archived. B-2 is 4.3.0.
64
+
65
+ ## B-16 branch `b-16-homeassistant` (2026-09-04, target 4.2.0)
66
+
67
+ - Implemented and committed on the branch (not pushed): ccu-homeassistant
68
+ node + `lib/haroles.js` + `lib/hadiscovery.js` (ported from hm2mqtt.js;
69
+ channel TYPE is the primary role key because only ~45 % of the shipped
70
+ VALUES descriptions carry CONTROL hints), 24 unit tests, ccu-mqtt HA
71
+ command words + empty-name
72
+ topic fix, ccu-connection `deregister` fix and `type=devices` admin
73
+ endpoint, README section, `examples/home-assistant.json`, CHANGELOG
74
+ "Unreleased (4.2.0)". Details in ROADMAP B-16.
75
+ - Local `npm test`: lint + 71 pure tests green. The mocha integration
76
+ suite cannot run on this WSL machine (hm-simulator's port 8181 →
77
+ EADDRINUSE, identical on master) — push the branch and let CI run it.
78
+ - **Lab test done 2026-09-04** on the CCU3 lab box (branch build
79
+ installed into RedMatic, `node-red-contrib-aedes` as broker inside
80
+ Node-RED, flow tab "B-16 Home Assistant" left deployed there) against
81
+ Home Assistant 2026.9.0 in docker on WSL: 3 wired devices discovered
82
+ (232 entities, 47 enabled), switch round trip on/off, DRI16 event
83
+ entities, removal on untick — all good after fixing three payload
84
+ defects HA had rejected (see ROADMAP B-16). Scripts for the whole setup
85
+ (install, deploy, HA onboarding, status via comms websocket) are in
86
+ this session's scratchpad; the lab hand-over note lists the HA
87
+ container and login.
88
+ - Second round on the OpenCCU lab box (branch build installed there too,
89
+ flow tab "B-16 Home Assistant" with topic prefix `hm2/` and plain
90
+ payloads, publishing to the CCU3 box's broker): HmIP-PDT light round
91
+ trip with brightness verified, HmIP-WRC2 events discovered, no HA
92
+ warnings.
93
+ - she (Smart Home Engine) as consumer: the user moved their she dev
94
+ instance to the test broker, and both lab flows now publish there as
95
+ well (second mqtt-broker config in each flow), so that instance's
96
+ HA-discovery view lists the 5 lab devices (no orphaned/duplicate
97
+ flags) — the quick check for future B-16 changes; a private she on the
98
+ lab broker exists too. Details and addresses in the lab hand-over note.
99
+ - Still open: editor smoke test in a browser on a lab box (device table,
100
+ ccu-mqtt select), a real key press (event entity), CI. Cover/climate
101
+ payloads have no lab hardware — unit tests only.
102
+ - Merge after 4.1.0 is released (rebase onto master; the CHANGELOG has
103
+ separate Unreleased sections, so this is trivial).
61
104
 
62
105
  ## Infrastructure (this does not travel via git; addresses live outside the repo)
63
106
 
package/README.md CHANGED
@@ -28,6 +28,19 @@ Some example flows can be found in the [RedMatic Wiki](https://github.com/rdmtc/
28
28
 
29
29
  **Starting with Version 3.x these Nodes need Node-RED >= 1.0 to work correctly**
30
30
 
31
+ ## Home Assistant
32
+
33
+ The `ccu-homeassistant` node publishes
34
+ [MQTT discovery](https://www.home-assistant.io/integrations/mqtt/#mqtt-discovery) configurations (device-based,
35
+ Home Assistant >= 2024.11) for the devices you tick in its config dialog. It is a companion to the `ccu-mqtt` node:
36
+ it reuses that node's topic templates and payload format, so state and commands keep flowing through `ccu-mqtt` and
37
+ the discovery configs simply point Home Assistant at those topics. Wire both nodes to the same `mqtt out` node and
38
+ feed the `hm/set/#` topics from an `mqtt in` node into `ccu-mqtt` — see
39
+ [examples/home-assistant.json](examples/home-assistant.json). One Home Assistant device is created per Homematic
40
+ device with switch, light, cover, climate, binary_sensor, event, lock and sensor entities; every other datapoint can
41
+ optionally be included as a disabled-by-default entity. Unticking a device removes it from Home Assistant on the
42
+ next deploy.
43
+
31
44
  ## Configuration Examples
32
45
 
33
46
  The communication with the Homematic CCU needs independent connections in two directions. Node-red-contrib-ccu connects to the CCU's interface listeners (e.g. 2001/TCP for BidCos-RF) while the CCU connects to node-red-contrib-ccu's BINRPC/XMLRPC listeners (2048/tcp and 2049/tcp in examples below).
package/ROADMAP.md CHANGED
@@ -25,9 +25,12 @@ Decisions (D-n) stay here as the record of why things are the way they
25
25
  are; answered open questions are rewritten in place
26
26
  (`**answered <date>** — …`).
27
27
 
28
- Status 2026-09-02: **4.0.0 is released** (npm latest, OIDC provenance,
29
- GitHub release). Phases 1 and 2 are done and archived. Next: Phase 3
30
- (refactor & tests) and the Phase 4 backlog (B-1…B-16); work continues on
28
+ Status 2026-09-04: **4.0.0 (2026-09-02) and 4.1.0 (2026-09-04) are
29
+ released** (npm latest, OIDC provenance, GitHub releases); 4.1.0 carries
30
+ the regenerated device descriptions and the LEVEL_2 fix; **4.2.0
31
+ (2026-09-04) = B-16**, the Home Assistant discovery node, lab-verified and
32
+ archived. B-2 moved to 4.3.0. Phases 1 and 2 are done and archived. Next:
33
+ Phase 3 (refactor & tests) and the Phase 4 backlog; work continues on
31
34
  master with CI (Node 22/24 × Node-RED 4/5) as the gate. Research basis:
32
35
  the GitHub tracker/PRs/forks, homematic-forum.de, Node-RED release notes and
33
36
  scorecard criteria, and the hm2mqtt.js 3.0 rewrite (same author), which
@@ -189,24 +192,24 @@ to 4.3.0**. B-3/B-5 ride along when ready; B-12/B-13 later. The four
189
192
  needs-info issues (#111, #145, #146, #151) are closed as
190
193
  unreproducible if the reporters have not responded by ~2026-12.
191
194
 
192
- | ID | Item | Source |
193
- | ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- |
194
- | B-1 | Regenerate `paramsets.json` via a live-CCU XML-RPC fetch — **groundwork done 2026-09-02, full analysis in [docs/paramsets.md](docs/paramsets.md)**: the file is the runtime getParamsetDescription cache (grown 2018–2020 from contributed user dumps; firmware parsing is a dead end for HmIP — MIN/MAX come from compiled Java). **Tools done 2026-09-02** (`tools/paramsets-fetch.js` + modernized `paramsets-join.js`, smoke-tested against the live CCU; reporter dumps join with the same tool). **Lab dumps joined 2026-09-04** (CCU3 3.89.8 "Charly" with HmIPW-DRAP/DRI16/DRS8, OpenCCU 3.89.8 with HmIP-PDT/WRC2/RFUSB): +58 keys, 9 refreshed (HmIPW entries gained COMBINED_PARAMETER etc.), file now key-sorted (one-time reorder). **Production regen done 2026-09-04** (4.1.0-dev.7): fetched read-only from the author's CCU3 on 3.87.6 at 600 ms/call (~25 min, 962 keys) — +547 keys, 32 refreshed, 70 device type/firmware combos across BidCos-RF, BidCos-Wired, HmIP and the HmIP-HEATING 2.0.0 group; the "HmIP-only" assumption about that box was wrong. Rule for the production CCU: read-only, slow, and only client calls — its RPC callbacks reach nothing but the Node-RED test box. Remaining: collect reporter dumps (#177 BSL-V2, #144 WRCD, #159 CuxD — requested in the issues 2026-09-02). Data-only issues: [#112](https://github.com/rdmtc/node-red-contrib-ccu/issues/112) (likely CCU-side limit — live CCU still reports MAX=3, retest), [#117](https://github.com/rdmtc/node-red-contrib-ccu/issues/117) (entry exists, retest), [#159](https://github.com/rdmtc/node-red-contrib-ccu/issues/159) (needs CUxD user dump). The LEVEL_2/BSL/WRCD issues moved to B-14/B-15 (code, not data). | tracker + forum |
195
- | B-2 | Dynamic node configuration via msg — recurring theme [#172](https://github.com/rdmtc/node-red-contrib-ccu/issues/172), [#71](https://github.com/rdmtc/node-red-contrib-ccu/issues/71), [#103](https://github.com/rdmtc/node-red-contrib-ccu/issues/103), [#80](https://github.com/rdmtc/node-red-contrib-ccu/issues/80), [#56](https://github.com/rdmtc/node-red-contrib-ccu/issues/56), plus [#148](https://github.com/rdmtc/node-red-contrib-ccu/issues/148) (SOUNDFILE_LIST via msg), [#158](https://github.com/rdmtc/node-red-contrib-ccu/issues/158) (subflow env config) and [#133](https://github.com/rdmtc/node-red-contrib-ccu/issues/133) — the latter confirmed still broken in 4.0.0: `setValues()` writes msg values into `config` permanently, so the first message's filters stick. Design properly rather than merging PR #173's auto-subscribe | tracker |
196
- | B-3 | Fix the ccu-mqtt node bugs verified in hm2mqtt ROADMAP §1.3 (see §8.2); also [#115](https://github.com/rdmtc/node-red-contrib-ccu/issues/115) get/update method (fresh user interest Apr 2026), [#22](https://github.com/rdmtc/node-red-contrib-ccu/issues/22) missing RPC-topic GUI, [#167](https://github.com/rdmtc/node-red-contrib-ccu/issues/167) stale rooms/functions | hm2mqtt |
197
- | B-4 | Fix/remove the dead `isLocal` detection (`/etc/lighttpd/conf.d/proxy.conf` grep, `ccu-connection.js:346` — file is a stub on firmware ≥ 3.87, so local installs silently go through the proxy) | hm2mqtt §15.4 |
198
- | B-5 | Configurable ping checks ([#44](https://github.com/rdmtc/node-red-contrib-ccu/issues/44)), sysvar node property/status improvements ([#54](https://github.com/rdmtc/node-red-contrib-ccu/issues/54), [#56](https://github.com/rdmtc/node-red-contrib-ccu/issues/56), [#52](https://github.com/rdmtc/node-red-contrib-ccu/issues/52) last-event status, [#124](https://github.com/rdmtc/node-red-contrib-ccu/issues/124) re-read descriptions on poll, [#166](https://github.com/rdmtc/node-red-contrib-ccu/issues/166) immediate sysvar echo, [#96](https://github.com/rdmtc/node-red-contrib-ccu/issues/96) uncertain-filter option) | tracker |
199
- | B-6 | ✅ **done 2026-09-02** — delivered upstream as binrpc 4.1/4.2 (zero deps, frame reassembly); picked up here as `^4.2.0` in dev.4. Archived: [roadmap-archive/B-6.md](roadmap-archive/B-6.md) | deferred → upstream |
200
- | B-7 | Triage the remaining ~60 open issues (snapshot in §12) against phases; close what 4.0 fixes | tracker |
201
- | B-8 | Global object: expose CCU metadata/values via a global context object (old todo item) | old TODO |
202
- | B-9 | Value node: datapoint autocomplete / multiselect (rpc and rpc-event already have it) | old TODO |
203
- | B-10 | Submit/display node polish (old todo items): submit autocomplete, limit list to 10 cmds, fix display LED, display beep, payload via msg | old TODO |
204
- | B-11 | Re-init robustness after a CCU outage (found live in the 2026-09-02 smoke test): (a) `rpcCheckInit` returns without rescheduling itself when the interface has no devices in the metadata cache, so interfaces without paired devices (e.g. BidCos-RF on an HmIP-only CCU) never ping and never re-init — after a CCU reboot they stay dead until Node-RED is restarted; (b) a failed `rpcInit` (e.g. the shutting-down CCU answers XML-RPC with an HTML error page → "Unknown XML-RPC tag 'TITLE'") has no retry of its own, so combined with (a) one failed re-init is final; (c) the hardcoded 600 s HmIP-RF pingTimeout means up to 10 min of silent event loss after a CCU reboot — make it configurable together with B-5/#44. Fix shape: arm the watchdog regardless of metadata, retry failed inits with backoff. | smoke test |
205
- | B-12 | Complete the [#27](https://github.com/rdmtc/node-red-contrib-ccu/issues/27) checklist: authentication and TLS for all interface connections (two of four items from 2019 still open; ptweety's TLS-warning reactivation in §9 is related groundwork) | tracker |
206
- | B-13 | Party/holiday mode support ([#161](https://github.com/rdmtc/node-red-contrib-ccu/issues/161), [#156](https://github.com/rdmtc/node-red-contrib-ccu/issues/156)): PARTY_TIME_START/END must be written atomically (putParamset/combined parameter); possibly a dedicated node | tracker |
207
- | B-14 | ✅ **done 2026-09-02** (dev.5) — LEVEL_2 writes remapped to COMBINED_PARAMETER (`L2=<pct>`) in setValue; fixes #136/#154/#175 pending hardware confirmation. Archived: [roadmap-archive/B-14.md](roadmap-archive/B-14.md) | B-1 research |
208
- | B-15 | New HmIP channel types in the signal/display nodes: BSL 2.x replaces DIMMER_VIRTUAL_RECEIVER with OPTICAL_SIGNAL_RECEIVER (LEVEL/COLOR/COLOR_BEHAVIOUR — without COLOR_BEHAVIOUR in the putParamset the LED stays dark, [#177](https://github.com/rdmtc/node-red-contrib-ccu/issues/177)); HmIP-WRCD ch3 is ACOUSTIC_DISPLAY_RECEIVER with DISPLAY_DATA_* datapoints ([#144](https://github.com/rdmtc/node-red-contrib-ccu/issues/144)). Paramset entries for both need reporter dumps. See docs/paramsets.md §4. | B-1 research |
209
- | B-16 | **New node `ccu-homeassistant`: Home Assistant MQTT auto-discovery for a checkbox-selected set of devices** (decided 2026-09-04: a dedicated node, not an option on ccu-mqtt). It is a companion to an existing ccu-mqtt node, not a replacement: its config references one ccu-mqtt node of the flow (select populated via `RED.nodes.eachNode`, type `ccu-mqtt`, same ccu-connection) and **reuses that node's configured topics** — `topicOutputEvent` as HA state topics, `topicInputSetValue` as command topics, `topicOutputSysvar` for sysvars later — plus its payload format (`payloadOutput` mqsh-basic/extended/plain → matching `value_template`, e.g. `{{ value_json.val }}`). State and commands keep flowing through ccu-mqtt; the new node only emits the retained discovery configs `{topic, payload, retain: true}` for the same downstream mqtt-out node (no broker connection of its own), republishes them on deploy/reconnect, and publishes empty retained configs for devices that were unchecked (removal from HA). **Device selection like RedMatic-HomeKit's `redmatic-homekit-homematic-devices` node**: the config dialog loads all devices of the connection from the `/ccu` admin endpoint into a table (checkbox · name · address · type, "enable all"/"disable all" buttons, filter box, optionally expandable per-channel rows), stored as a `devices` object keyed by address — but **opt-in**: nothing is checked, hence nothing published, until the user ticks a device. Mapping modeled on hm2mqtt.js [`lib/hadiscovery.js`](https://github.com/hobbyquaker/hm2mqtt.js/blob/master/lib/hadiscovery.js) (README section "Home Assistant"): one HA device per Homematic device, device-based discovery payloads `homeassistant/device/<id>/config` (HA ≥ 2024.11; prefix configurable), entities derived from the paramset descriptions' `CONTROL` hints — switch (SWITCH.STATE, HmIP virtual receivers), light (dimmers), cover (blind position/tilt/direction), climate (HM/HmIP thermostats, modes/presets), binary_sensor (contact/motion/presence/smoke/water), event (key press short/long), lock (KEYMATIC), sensor (energy, weather, maintenance) — port hm2mqtt's mapping table rather than re-deriving it. **Constraint found 2026-09-04 (corrected the same day):** only 290 of the 647 VALUES entries in the shipped `paramsets.json` carry `CONTROL` hints (the older contributed user dumps were stripped of them), and the persisted runtime cache of existing installs inherits that — so a pure CONTROL-based mapping would silently skip roughly half the device types. Key the mapping on the channel `TYPE` from the device metadata (always present) and use CONTROL only as a refinement where the cache has it (live fetches and the B-1 regen bring CONTROL in; the fetch tool stores the full response). B-3 is not a prerequisite (HA commands use the setValue path, which casts in the connection), but its trivial fixes ride along. Builds on Phase 3's extracted `lib/topic.js` so the HA node computes exactly ccu-mqtt's topics. **Runs on branch `b-16-homeassistant`, target 4.2.0** (decided 2026-09-04; 4.1.0 stays the small data release). Known gaps upstream too: RGBW lights, sirens, garage doors, sysvars/programs as entities. | user request |
195
+ | ID | Item | Source |
196
+ | ---- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- |
197
+ | B-1 | Regenerate `paramsets.json` via a live-CCU XML-RPC fetch — **groundwork done 2026-09-02, full analysis in [docs/paramsets.md](docs/paramsets.md)**: the file is the runtime getParamsetDescription cache (grown 2018–2020 from contributed user dumps; firmware parsing is a dead end for HmIP — MIN/MAX come from compiled Java). **Tools done 2026-09-02** (`tools/paramsets-fetch.js` + modernized `paramsets-join.js`, smoke-tested against the live CCU; reporter dumps join with the same tool). **Lab dumps joined 2026-09-04** (CCU3 3.89.8 "Charly" with HmIPW-DRAP/DRI16/DRS8, OpenCCU 3.89.8 with HmIP-PDT/WRC2/RFUSB): +58 keys, 9 refreshed (HmIPW entries gained COMBINED_PARAMETER etc.), file now key-sorted (one-time reorder). **Production regen done 2026-09-04** (4.1.0-dev.7): fetched read-only from the author's CCU3 on 3.87.6 at 600 ms/call (~25 min, 962 keys) — +547 keys, 32 refreshed, 70 device type/firmware combos across BidCos-RF, BidCos-Wired, HmIP and the HmIP-HEATING 2.0.0 group; the "HmIP-only" assumption about that box was wrong. Rule for the production CCU: read-only, slow, and only client calls — its RPC callbacks reach nothing but the Node-RED test box. Remaining: collect reporter dumps (#177 BSL-V2, #144 WRCD, #159 CuxD — requested in the issues 2026-09-02). Data-only issues: [#112](https://github.com/rdmtc/node-red-contrib-ccu/issues/112) (likely CCU-side limit — live CCU still reports MAX=3, retest), [#117](https://github.com/rdmtc/node-red-contrib-ccu/issues/117) (entry exists, retest), [#159](https://github.com/rdmtc/node-red-contrib-ccu/issues/159) (needs CUxD user dump). The LEVEL_2/BSL/WRCD issues moved to B-14/B-15 (code, not data). | tracker + forum |
198
+ | B-2 | Dynamic node configuration via msg — recurring theme [#172](https://github.com/rdmtc/node-red-contrib-ccu/issues/172), [#71](https://github.com/rdmtc/node-red-contrib-ccu/issues/71), [#103](https://github.com/rdmtc/node-red-contrib-ccu/issues/103), [#80](https://github.com/rdmtc/node-red-contrib-ccu/issues/80), [#56](https://github.com/rdmtc/node-red-contrib-ccu/issues/56), plus [#148](https://github.com/rdmtc/node-red-contrib-ccu/issues/148) (SOUNDFILE_LIST via msg), [#158](https://github.com/rdmtc/node-red-contrib-ccu/issues/158) (subflow env config) and [#133](https://github.com/rdmtc/node-red-contrib-ccu/issues/133) — the latter confirmed still broken in 4.0.0: `setValues()` writes msg values into `config` permanently, so the first message's filters stick. Design properly rather than merging PR #173's auto-subscribe | tracker |
199
+ | B-3 | Fix the ccu-mqtt node bugs verified in hm2mqtt ROADMAP §1.3 (see §8.2); also [#115](https://github.com/rdmtc/node-red-contrib-ccu/issues/115) get/update method (fresh user interest Apr 2026), [#22](https://github.com/rdmtc/node-red-contrib-ccu/issues/22) missing RPC-topic GUI, [#167](https://github.com/rdmtc/node-red-contrib-ccu/issues/167) stale rooms/functions | hm2mqtt |
200
+ | B-4 | Fix/remove the dead `isLocal` detection (`/etc/lighttpd/conf.d/proxy.conf` grep, `ccu-connection.js:346` — file is a stub on firmware ≥ 3.87, so local installs silently go through the proxy) | hm2mqtt §15.4 |
201
+ | B-5 | Configurable ping checks ([#44](https://github.com/rdmtc/node-red-contrib-ccu/issues/44)), sysvar node property/status improvements ([#54](https://github.com/rdmtc/node-red-contrib-ccu/issues/54), [#56](https://github.com/rdmtc/node-red-contrib-ccu/issues/56), [#52](https://github.com/rdmtc/node-red-contrib-ccu/issues/52) last-event status, [#124](https://github.com/rdmtc/node-red-contrib-ccu/issues/124) re-read descriptions on poll, [#166](https://github.com/rdmtc/node-red-contrib-ccu/issues/166) immediate sysvar echo, [#96](https://github.com/rdmtc/node-red-contrib-ccu/issues/96) uncertain-filter option) | tracker |
202
+ | B-6 | ✅ **done 2026-09-02** — delivered upstream as binrpc 4.1/4.2 (zero deps, frame reassembly); picked up here as `^4.2.0` in dev.4. Archived: [roadmap-archive/B-6.md](roadmap-archive/B-6.md) | deferred → upstream |
203
+ | B-7 | Triage the remaining ~60 open issues (snapshot in §12) against phases; close what 4.0 fixes | tracker |
204
+ | B-8 | Global object: expose CCU metadata/values via a global context object (old todo item) | old TODO |
205
+ | B-9 | Value node: datapoint autocomplete / multiselect (rpc and rpc-event already have it) | old TODO |
206
+ | B-10 | Submit/display node polish (old todo items): submit autocomplete, limit list to 10 cmds, fix display LED, display beep, payload via msg | old TODO |
207
+ | B-11 | Re-init robustness after a CCU outage (found live in the 2026-09-02 smoke test): (a) `rpcCheckInit` returns without rescheduling itself when the interface has no devices in the metadata cache, so interfaces without paired devices (e.g. BidCos-RF on an HmIP-only CCU) never ping and never re-init — after a CCU reboot they stay dead until Node-RED is restarted; (b) a failed `rpcInit` (e.g. the shutting-down CCU answers XML-RPC with an HTML error page → "Unknown XML-RPC tag 'TITLE'") has no retry of its own, so combined with (a) one failed re-init is final; (c) the hardcoded 600 s HmIP-RF pingTimeout means up to 10 min of silent event loss after a CCU reboot — make it configurable together with B-5/#44. Fix shape: arm the watchdog regardless of metadata, retry failed inits with backoff. | smoke test |
208
+ | B-12 | Complete the [#27](https://github.com/rdmtc/node-red-contrib-ccu/issues/27) checklist: authentication and TLS for all interface connections (two of four items from 2019 still open; ptweety's TLS-warning reactivation in §9 is related groundwork) | tracker |
209
+ | B-13 | Party/holiday mode support ([#161](https://github.com/rdmtc/node-red-contrib-ccu/issues/161), [#156](https://github.com/rdmtc/node-red-contrib-ccu/issues/156)): PARTY_TIME_START/END must be written atomically (putParamset/combined parameter); possibly a dedicated node | tracker |
210
+ | B-14 | ✅ **done 2026-09-02** (dev.5) — LEVEL_2 writes remapped to COMBINED_PARAMETER (`L2=<pct>`) in setValue; fixes #136/#154/#175 pending hardware confirmation. Archived: [roadmap-archive/B-14.md](roadmap-archive/B-14.md) | B-1 research |
211
+ | B-15 | New HmIP channel types in the signal/display nodes: BSL 2.x replaces DIMMER_VIRTUAL_RECEIVER with OPTICAL_SIGNAL_RECEIVER (LEVEL/COLOR/COLOR_BEHAVIOUR — without COLOR_BEHAVIOUR in the putParamset the LED stays dark, [#177](https://github.com/rdmtc/node-red-contrib-ccu/issues/177)); HmIP-WRCD ch3 is ACOUSTIC_DISPLAY_RECEIVER with DISPLAY_DATA_* datapoints ([#144](https://github.com/rdmtc/node-red-contrib-ccu/issues/144)). Paramset entries for both need reporter dumps. See docs/paramsets.md §4. | B-1 research |
212
+ | B-16 | ✅ **done 2026-09-04** (4.2.0) — new `ccu-homeassistant` node: Home Assistant MQTT auto-discovery for checkbox-selected devices, companion to ccu-mqtt (reuses its topics/payload format); lab-verified against HA 2026.9 and she. Archived: [roadmap-archive/B-16.md](roadmap-archive/B-16.md) | user request |
210
213
 
211
214
  ## 8. Bug inventory (diagnosed, not yet fixed)
212
215
 
@@ -0,0 +1,127 @@
1
+ [
2
+ {
3
+ "id": "ccu-mqtt-example",
4
+ "type": "ccu-mqtt",
5
+ "name": "ccu ⇄ mqtt",
6
+ "ccuConfig": "ccu-conn-example",
7
+ "cache": true,
8
+ "topicOutputEvent": "hm/status/${channelName}/${datapoint}",
9
+ "topicInputSetValue": "hm/set/${channelNameOrAddress}/${datapoint}",
10
+ "topicOutputSysvar": "hm/status/${name}",
11
+ "topicInputSysvar": "hm/set/${name}",
12
+ "topicInputPutParam": "hm/paramset/${channelNameOrAddress}/${paramset}/${param}",
13
+ "topicInputPutParamset": "hm/paramset/${channelNameOrAddress}/${paramset}",
14
+ "topicInputRpc": "hm/rpc/${iface}/${method}/${command}/${callid}",
15
+ "topicOutputRpc": "hm/response/${callid}",
16
+ "topicCounters": "hm/status/counter/${iface}/${rxtx}",
17
+ "payloadOutput": "mqsh-extended",
18
+ "x": 380,
19
+ "y": 100,
20
+ "wires": [["mqtt-out-example"]]
21
+ },
22
+ {
23
+ "id": "mqtt-in-example",
24
+ "type": "mqtt in",
25
+ "name": "hm/set/#",
26
+ "topic": "hm/set/#",
27
+ "qos": "0",
28
+ "datatype": "auto-detect",
29
+ "broker": "mqtt-broker-example",
30
+ "nl": false,
31
+ "rap": true,
32
+ "rh": 0,
33
+ "inputs": 0,
34
+ "x": 160,
35
+ "y": 100,
36
+ "wires": [["ccu-mqtt-example"]]
37
+ },
38
+ {
39
+ "id": "mqtt-out-example",
40
+ "type": "mqtt out",
41
+ "name": "",
42
+ "topic": "",
43
+ "qos": "",
44
+ "retain": "",
45
+ "respTopic": "",
46
+ "contentType": "",
47
+ "userProps": "",
48
+ "correl": "",
49
+ "expiry": "",
50
+ "broker": "mqtt-broker-example",
51
+ "x": 640,
52
+ "y": 140,
53
+ "wires": []
54
+ },
55
+ {
56
+ "id": "ccu-ha-example",
57
+ "type": "ccu-homeassistant",
58
+ "name": "Home Assistant discovery",
59
+ "ccuConfig": "ccu-conn-example",
60
+ "mqttNode": "ccu-mqtt-example",
61
+ "prefix": "homeassistant",
62
+ "generic": true,
63
+ "devices": {},
64
+ "x": 400,
65
+ "y": 180,
66
+ "wires": [["mqtt-out-example"]]
67
+ },
68
+ {
69
+ "id": "inject-republish",
70
+ "type": "inject",
71
+ "name": "republish discovery",
72
+ "props": [{"p": "payload"}],
73
+ "repeat": "",
74
+ "crontab": "",
75
+ "once": false,
76
+ "onceDelay": 0.1,
77
+ "topic": "",
78
+ "payload": "",
79
+ "payloadType": "date",
80
+ "x": 170,
81
+ "y": 180,
82
+ "wires": [["ccu-ha-example"]]
83
+ },
84
+ {
85
+ "id": "comment-ha",
86
+ "type": "comment",
87
+ "name": "Tick the devices to publish in the Home Assistant node's config dialog, then deploy",
88
+ "info": "",
89
+ "x": 330,
90
+ "y": 40,
91
+ "wires": []
92
+ },
93
+ {
94
+ "id": "mqtt-broker-example",
95
+ "type": "mqtt-broker",
96
+ "name": "Broker",
97
+ "broker": "mqtt-broker-hostname-or-ip",
98
+ "port": "1883",
99
+ "clientid": "",
100
+ "autoConnect": true,
101
+ "usetls": false,
102
+ "protocolVersion": "4",
103
+ "keepalive": "60",
104
+ "cleansession": true,
105
+ "autoUnsubscribe": true
106
+ },
107
+ {
108
+ "id": "ccu-conn-example",
109
+ "type": "ccu-connection",
110
+ "name": "CCU",
111
+ "host": "ccu3-hostname-or-ip",
112
+ "regaEnabled": true,
113
+ "bcrfEnabled": true,
114
+ "iprfEnabled": true,
115
+ "virtEnabled": false,
116
+ "bcwiEnabled": false,
117
+ "cuxdEnabled": false,
118
+ "jackEnabled": false,
119
+ "regaPoll": true,
120
+ "regaInterval": "30",
121
+ "rpcPingTimeout": "60",
122
+ "rpcInitAddress": "",
123
+ "rpcServerHost": "",
124
+ "rpcBinPort": "2047",
125
+ "rpcXmlPort": "2048"
126
+ }
127
+ ]
@@ -208,6 +208,39 @@ module.exports = function (RED) {
208
208
  break;
209
209
  }
210
210
 
211
+ case 'devices': {
212
+ // ccu-homeassistant editor: every device (not channel) of every, or the
213
+ // given, interface with its channels
214
+ const all = (config.metadata && config.metadata.devices) || {};
215
+ const ifaces = request.query.iface ? [request.query.iface] : Object.keys(all);
216
+ ifaces.forEach((iface) => {
217
+ const devices = all[iface] || {};
218
+ Object.keys(devices).forEach((addr) => {
219
+ const device = devices[addr];
220
+ if (!device || device.PARENT) {
221
+ return;
222
+ }
223
+
224
+ object[addr] = {
225
+ name: config.channelNames[addr],
226
+ type: device.TYPE,
227
+ iface,
228
+ firmware: device.FIRMWARE,
229
+ channels: (device.CHILDREN || [])
230
+ .filter((ch) => devices[ch])
231
+ .map((ch) => ({
232
+ address: ch,
233
+ name: config.channelNames[ch],
234
+ type: devices[ch].TYPE,
235
+ })),
236
+ };
237
+ });
238
+ });
239
+
240
+ res.status(200).send(JSON.stringify(object));
241
+ break;
242
+ }
243
+
211
244
  case 'rooms':
212
245
  res.status(200).send(
213
246
  JSON.stringify({
@@ -688,8 +721,10 @@ module.exports = function (RED) {
688
721
  * @returns {*}
689
722
  */
690
723
  deregister(node, done) {
691
- delete node.users[node.id];
692
- return done();
724
+ delete this.users[node.id];
725
+ if (typeof done === 'function') {
726
+ done();
727
+ }
693
728
  }
694
729
 
695
730
  /**