node-red-contrib-ccu 4.3.0 → 4.4.1
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/.prettierignore +3 -0
- package/CHANGELOG.md +72 -0
- package/HANDOFF.md +54 -12
- package/README.md +42 -0
- package/ROADMAP.md +19 -15
- package/nodes/ccu-connection.html +25 -0
- package/nodes/ccu-connection.js +252 -11
- package/nodes/ccu-mqtt.js +12 -3
- package/nodes/ccu-poll.js +8 -1
- package/nodes/lib/metaprovider.js +716 -0
- package/package.json +1 -1
- package/roadmap-archive/B-17.md +106 -0
- package/roadmap-archive/README.md +3 -0
package/package.json
CHANGED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# B-17 — openccu-lite (a CCU without ReGaHSS)
|
|
2
|
+
|
|
3
|
+
**✅ done 2026-09-06** (`4.4.0`).
|
|
4
|
+
|
|
5
|
+
[openccu-lite](https://github.com/hobbyquaker/openccu-lite) is a Homematic
|
|
6
|
+
CCU firmware that drops ReGaHSS. The interface processes are the ones we
|
|
7
|
+
already talk to (`rfd` BidCos-RF/BIN-RPC, `hs485d`, `hmipserver`
|
|
8
|
+
XML-RPC) — but nothing listens on 8181/8183, `rega.exe`/`tclrega.exe` do
|
|
9
|
+
not exist, HM-Script is never interpreted, and there are no ReGa ids.
|
|
10
|
+
Everything this package took from the ReGa apart from names, rooms and
|
|
11
|
+
functions has no replacement there.
|
|
12
|
+
|
|
13
|
+
What it offers instead is `occulited`'s **metadata API**, a small JSON
|
|
14
|
+
store served under `/api/meta/v1/` behind the box's lighttpd, with a
|
|
15
|
+
Server-Sent-Events change stream. Its porting kit (`docs/porting-from-rega.md`,
|
|
16
|
+
`docs/PORTING-PROMPT.md`, `docs/meta-api.md` and the `fixtures/`
|
|
17
|
+
conformance corpus in the openccu-lite repository) is what this item
|
|
18
|
+
was implemented against.
|
|
19
|
+
|
|
20
|
+
## The rule the port follows
|
|
21
|
+
|
|
22
|
+
Keep the ReGa code path, add a provider, detect at runtime. On a CCU3,
|
|
23
|
+
RaspberryMatic or OpenCCU nothing changes: the same configuration, the
|
|
24
|
+
same messages, the same cache files.
|
|
25
|
+
|
|
26
|
+
## What was built
|
|
27
|
+
|
|
28
|
+
- **`nodes/lib/metaprovider.js`** — the counterpart of the `getRega*()`
|
|
29
|
+
methods. `detect()` is the feature test (`GET /api/meta/v1/version`,
|
|
30
|
+
no credential, 404 on a CCU). `MetaProvider` loads `GET /snapshot`,
|
|
31
|
+
then follows `GET /events/sse?since=<revision>`: `object.updated` and
|
|
32
|
+
`object.deleted` are applied to the in-memory document, everything
|
|
33
|
+
that can rewrite member paths (`node.*`, `enum.*`, `import`, an
|
|
34
|
+
explicit `resync`, a gap in the revisions) re-reads the snapshot.
|
|
35
|
+
`buildNames()` is pure and derives exactly what the rest of the code
|
|
36
|
+
already reads — `channelNames`, `channelRooms`, `channelFunctions`
|
|
37
|
+
keyed by the bare address (the API's ref is `<interface>.<address>`),
|
|
38
|
+
plus the `rooms` / `functions` name lists the editor asks for.
|
|
39
|
+
- **Rooms and functions are a tree** there (`room/eg/wohnzimmer`), not a
|
|
40
|
+
flat list. They are flattened to the arrays the nodes have always
|
|
41
|
+
published, ancestors included and most specific first, so a channel in
|
|
42
|
+
_Wohnzimmer_ below _Erdgeschoss_ matches a room filter on either name
|
|
43
|
+
and `msg.room` is still the room the user means.
|
|
44
|
+
- **Detection in the startup path** of `ccu-connection.js`: when the
|
|
45
|
+
ReGaHSS interface is ticked, the node probes once before deciding
|
|
46
|
+
between `startMeta()` and `getRegaData()`. The provider probes again
|
|
47
|
+
on every reconnect; three failed probes in a row hand control back to
|
|
48
|
+
the detection (a restored backup or a firmware swap under a running
|
|
49
|
+
Node-RED), and on the ReGa side a failing `getRegaData()` /
|
|
50
|
+
`refreshRegaData()` re-probes at most every five minutes. So a box
|
|
51
|
+
that changes kind is picked up in both directions without a redeploy.
|
|
52
|
+
- **Credential**: on the box the read-only local token
|
|
53
|
+
(`/usr/local/etc/occulite/local-token`) is read automatically, off the
|
|
54
|
+
box an _openccu-lite token_ field takes one created on the box's Users
|
|
55
|
+
page. `401`/`403` degrades to addresses-only, is logged once, and is
|
|
56
|
+
retried — never fatal. An _openccu-lite port_ field covers boxes whose
|
|
57
|
+
web server is not on 80/443 (it is also what the integration test
|
|
58
|
+
uses).
|
|
59
|
+
- **The ReGa-only nodes stay**: `ccu-sysvar`, `ccu-program`,
|
|
60
|
+
`ccu-script` and `ccu-poll` remain in the palette and in flows, the
|
|
61
|
+
connection logs one line about them when it starts, and every message
|
|
62
|
+
they get is rejected with `… are not available on this box
|
|
63
|
+
(openccu-lite has no ReGaHSS)` instead of breaking the connection.
|
|
64
|
+
- **No new dependency.** `node:http`/`node:https` rather than `fetch`,
|
|
65
|
+
because the connection node already offers "ignore invalid TLS
|
|
66
|
+
certificates", which `fetch` cannot express per request without
|
|
67
|
+
pulling in undici — and a Node stream is the natural shape for SSE.
|
|
68
|
+
|
|
69
|
+
## Tests
|
|
70
|
+
|
|
71
|
+
16 unit tests in `test/unit/metaprovider.test.js` (`npm run test:pure`):
|
|
72
|
+
`buildNames()` over the openccu-lite conformance corpus, copied verbatim
|
|
73
|
+
into `test/fixtures/openccu-lite/` (`valid-house`, `valid-empty`,
|
|
74
|
+
`valid-depth-8`), plus a fake `/api/meta/v1` server built from
|
|
75
|
+
`node:http` for detection (openccu-lite / a CCU's 404 / a 200 that is
|
|
76
|
+
not the metadata API / nothing listening), the 401 path, an event →
|
|
77
|
+
"names changed" round trip, the re-snapshot triggers, reconnects and the
|
|
78
|
+
"not an openccu-lite any more" hand-back. The existing ReGa specs are
|
|
79
|
+
untouched.
|
|
80
|
+
|
|
81
|
+
Verified against a real `occulited` (built from the openccu-lite
|
|
82
|
+
repository, `--listen 127.0.0.1:2132`, the `valid-house` fixture
|
|
83
|
+
imported) with `node-red-node-test-helper` driving a real
|
|
84
|
+
`ccu-connection` node: names, rooms and functions match the box; a
|
|
85
|
+
`PATCH /objects/{ref}` rename, a room rename and a `node.moved` all
|
|
86
|
+
reach `ccu.channelNames` / `ccu.channelRooms` in under 150 ms; the four
|
|
87
|
+
ReGa-only nodes error per message; `createMessage()` produces the same
|
|
88
|
+
`channelName` / `rooms` / `room` / `functions` / `function` fields as on
|
|
89
|
+
a CCU.
|
|
90
|
+
|
|
91
|
+
## Findings handed back to openccu-lite
|
|
92
|
+
|
|
93
|
+
1. `occulited`'s SSE endpoint does not flush the response header until
|
|
94
|
+
it has an event or a heartbeat to write, so an HTTP client cannot
|
|
95
|
+
tell "connected" from "still connecting" for up to 30 s. A client
|
|
96
|
+
that applies its ordinary request timeout to the open stream tears it
|
|
97
|
+
down on every cycle; this implementation arms a separate idle timeout
|
|
98
|
+
after the socket connects and reports "connected" once the snapshot
|
|
99
|
+
is in, not when the stream opens.
|
|
100
|
+
2. The porting prompt's example is `fetch`, which cannot do per-request
|
|
101
|
+
TLS verification settings in Node — worth a sentence in the kit,
|
|
102
|
+
since every integration that offers "ignore invalid certificates"
|
|
103
|
+
hits it.
|
|
104
|
+
|
|
105
|
+
Original item: openccu-lite port — names, rooms and functions from the
|
|
106
|
+
metadata API instead of ReGaHSS, ReGa path unchanged, runtime detection.
|
|
@@ -18,6 +18,9 @@ the roadmap's contents index (marked ✅ there, linking here).
|
|
|
18
18
|
|
|
19
19
|
**Backlog items**
|
|
20
20
|
|
|
21
|
+
- [B-17.md](B-17.md) — the openccu-lite port: names, rooms and
|
|
22
|
+
functions from the box's metadata API when it has no ReGaHSS ✅
|
|
23
|
+
2026-09-06 (4.4.0).
|
|
21
24
|
- [B-5.md](B-5.md) — ping toggle, value/age status lines, uncertain
|
|
22
25
|
filter, trailing sysvar re-poll, RSSI guard ✅ 2026-09-04 (4.3.0;
|
|
23
26
|
#44/#54/#52/#96/#166/#183/#124).
|