node-red-contrib-ccu 4.2.0 → 4.3.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 +96 -0
- package/HANDOFF.md +11 -3
- package/README.md +29 -0
- package/ROADMAP.md +112 -33
- package/nodes/ccu-alexa.html +3 -1
- package/nodes/ccu-connection.html +26 -0
- package/nodes/ccu-connection.js +87 -11
- package/nodes/ccu-display.js +29 -13
- package/nodes/ccu-get-value.html +3 -1
- package/nodes/ccu-mqtt.html +21 -4
- package/nodes/ccu-mqtt.js +126 -102
- package/nodes/ccu-rpc-event.html +6 -0
- package/nodes/ccu-rpc-event.js +31 -12
- package/nodes/ccu-set-value.html +38 -0
- package/nodes/ccu-set-value.js +59 -235
- package/nodes/ccu-signal.html +55 -1
- package/nodes/ccu-signal.js +52 -9
- package/nodes/ccu-switch.html +17 -4
- package/nodes/ccu-switch.js +28 -4
- package/nodes/ccu-sysvar.html +40 -1
- package/nodes/ccu-sysvar.js +78 -8
- package/nodes/ccu-value.html +27 -1
- package/nodes/ccu-value.js +69 -19
- package/nodes/lib/cast.js +59 -14
- package/nodes/lib/channelfilter.js +136 -0
- package/nodes/lib/dynconfig.js +81 -0
- package/nodes/lib/localccu.js +81 -0
- package/nodes/lib/message.js +6 -2
- package/nodes/lib/valuestatus.js +145 -0
- package/nodes/locales/de/ccu-display.html +17 -0
- package/nodes/locales/de/ccu-rpc-event.json +1 -0
- package/nodes/locales/de/ccu-sysvar.json +3 -2
- package/nodes/locales/de/ccu-value.json +2 -1
- package/nodes/locales/en-US/ccu-display.html +17 -0
- package/nodes/locales/en-US/ccu-rpc-event.json +3 -2
- package/nodes/locales/en-US/ccu-switch.html +12 -0
- package/nodes/locales/en-US/ccu-sysvar.json +3 -2
- package/nodes/locales/en-US/ccu-value.json +2 -1
- package/package.json +1 -1
- package/patch-certainonly.py +51 -0
- package/roadmap-archive/B-2.md +69 -0
- package/roadmap-archive/B-3.md +57 -0
- package/roadmap-archive/B-4.md +44 -0
- package/roadmap-archive/B-5.md +57 -0
- package/roadmap-archive/README.md +11 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# B-2 — Dynamic node configuration via msg
|
|
2
|
+
|
|
3
|
+
**✅ done 2026-09-04** (`4.3.0`) — issues #172, #71, #103, #80, #56,
|
|
4
|
+
#148, #185, #133.
|
|
5
|
+
|
|
6
|
+
The request arrived from every direction and was deliberately designed
|
|
7
|
+
once rather than patched per node (which is why PR #173's auto-subscribe
|
|
8
|
+
was closed rather than merged).
|
|
9
|
+
|
|
10
|
+
## The mechanism
|
|
11
|
+
|
|
12
|
+
`msg.config` is an object whose properties override the receiving node's
|
|
13
|
+
own configuration **for that message only**. `nodes/lib/dynconfig.js`
|
|
14
|
+
builds the effective configuration; the stored one is never touched.
|
|
15
|
+
|
|
16
|
+
Why a namespace rather than flat properties everywhere: an event message
|
|
17
|
+
already carries `channel`, `datapoint`, `deviceType`, `rooms` and friends,
|
|
18
|
+
so honouring those on the signal or display node would let any message
|
|
19
|
+
coming from an event node silently retarget it. `msg.ccu` was the obvious
|
|
20
|
+
namespace but is taken — it holds the CCU host name — hence `msg.config`.
|
|
21
|
+
|
|
22
|
+
Each node passes the list of keys it accepts; anything else in
|
|
23
|
+
`msg.config` is ignored, so a stray property cannot reach node internals.
|
|
24
|
+
The flat mechanism the value/get-value/set-value nodes always had (fill in
|
|
25
|
+
fields left empty in the dialog from `msg.channel`, `msg.rooms`, …) is
|
|
26
|
+
unchanged and keeps working; `msg.config` wins over it.
|
|
27
|
+
|
|
28
|
+
## Per node
|
|
29
|
+
|
|
30
|
+
- **set-value** — the whole filter plus `force`. This is also the fix for
|
|
31
|
+
#133: `setValues()` wrote message properties into `this.config`, so the
|
|
32
|
+
`if (!config[key])` guard skipped every later message and the node
|
|
33
|
+
stayed pinned to the first message's targets. The whitelist/blacklist
|
|
34
|
+
are keyed by the effective filter now, so an unchanged filter keeps the
|
|
35
|
+
caching benefit and a changed one is re-evaluated. The 200-line inline
|
|
36
|
+
matching chain moved to `nodes/lib/channelfilter.js` (pure, 14 tests),
|
|
37
|
+
which also fixed the device-name filter requiring the _channel_ to have
|
|
38
|
+
a ReGa name while comparing the _device_ name.
|
|
39
|
+
- **value** — `iface`, `channel`, `datapoint`. A message without a
|
|
40
|
+
payload writes nothing (the 4.0.0 guard) and now retargets the output
|
|
41
|
+
subscription, which is what #172 asked for. For a node with its own
|
|
42
|
+
channel/datapoint configured this is a no-op unless `msg.config`
|
|
43
|
+
overrides them, so no existing flow changes behaviour.
|
|
44
|
+
- **switch** — the source selection (`iface`/`channel`/`datapoint`/
|
|
45
|
+
`datapointProperty`/`sysvar`/`sysvarProperty`), so one node serves a
|
|
46
|
+
whole subflow (#103).
|
|
47
|
+
- **sysvar** — `name`, plus a typed input for _where the value comes
|
|
48
|
+
from_ (msg/flow/global/env) instead of always `msg.payload` (#56).
|
|
49
|
+
- **signal** — every command field including `soundList`/`dimmerList`,
|
|
50
|
+
which also accept a plain array of values instead of the editor's
|
|
51
|
+
list-of-objects shape (#148). The existing `<field>Type` typed inputs
|
|
52
|
+
keep working; `msg.config` wins over them.
|
|
53
|
+
- **display** — channel and the EP-WM55 settings, joining the lines,
|
|
54
|
+
colours and icons that were already overridable.
|
|
55
|
+
|
|
56
|
+
## Subflows (#158)
|
|
57
|
+
|
|
58
|
+
Node-RED substitutes `${PARAMETER}` in a node's string properties before
|
|
59
|
+
the node is constructed, so subflow parameters already worked at runtime —
|
|
60
|
+
but the editor's channel autocomplete cleared any value that was not a
|
|
61
|
+
known channel address, wiping the placeholder every time the dialog was
|
|
62
|
+
opened. Fixed in the value, get-value, switch, signal and alexa editors.
|
|
63
|
+
|
|
64
|
+
Not done: an explicit `env` type on the filter fields of the event nodes.
|
|
65
|
+
The `${PARAMETER}` route covers the use case and the filters are read once
|
|
66
|
+
at construction, so a typed input would need runtime evaluation for little
|
|
67
|
+
gain. Revisit if someone asks.
|
|
68
|
+
|
|
69
|
+
Original item: | B-2 | Dynamic node configuration via msg — recurring theme #172, #71, #103, #80, #56, plus #148 (SOUNDFILE_LIST via msg), #158 (subflow env config) and #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 |
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# B-3 — ccu-mqtt node fixes and additions
|
|
2
|
+
|
|
3
|
+
**✅ done 2026-09-04** (`4.3.0`) — issues #115, #22, #167, plus the three
|
|
4
|
+
findings from ROADMAP §8.2 that the hm2mqtt 3.0 rewrite had confirmed.
|
|
5
|
+
|
|
6
|
+
## Fixed
|
|
7
|
+
|
|
8
|
+
- **The writeable check never fired.** Both `putParam` and `putParamset`
|
|
9
|
+
tested `!(description.OPERATIONS) && 2`, which is `(!OPERATIONS) && 2` —
|
|
10
|
+
always falsy, since `OPERATIONS` is a non-zero number for every real
|
|
11
|
+
parameter. Read-only parameters were written regardless. Now
|
|
12
|
+
`!(OPERATIONS & 2)`, and the write is skipped.
|
|
13
|
+
- **`putParamset` cast against the wrong description.** It passed
|
|
14
|
+
`paramsetDescription[filter.param]` for every parameter; `filter.param`
|
|
15
|
+
only exists on the `putParam` topic, so it was `undefined` there and
|
|
16
|
+
the whole paramset went out uncast (strings where the CCU wanted
|
|
17
|
+
numbers or booleans). Each value is cast against its own description.
|
|
18
|
+
- **Enum names never worked.** The CCU returns them in `VALUE_LIST`, but
|
|
19
|
+
`lib/cast.js` and `lib/message.js` read `ENUM`, which no interface
|
|
20
|
+
process sends: all 9494 ENUM-typed datapoints in the shipped
|
|
21
|
+
`paramsets.json` carry `VALUE_LIST` and none carries `ENUM`. So
|
|
22
|
+
`msg.datapointEnum` and `msg.valueEnum` had always been `undefined`,
|
|
23
|
+
and writing e.g. `AUTO-MODE` to an enum datapoint fell through to the
|
|
24
|
+
numeric cast and produced `0`. `enumList()` reads `VALUE_LIST` with
|
|
25
|
+
`ENUM` as a fallback for hand-written data.
|
|
26
|
+
- **The divergent cast copy is gone.** `ccu-mqtt.paramCast` differed from
|
|
27
|
+
`lib/cast.js` only in clamping to MIN/MAX (and in producing `NaN` for
|
|
28
|
+
unparseable input, which XML-RPC cannot encode). `castValue` gained a
|
|
29
|
+
`clamp` option; the mqtt node passes it, the value nodes do not (#74).
|
|
30
|
+
- The empty-name topic bug (`hm/status//STATE` for channels without a
|
|
31
|
+
ReGa name) was already fixed in 4.2.0.
|
|
32
|
+
|
|
33
|
+
## Added
|
|
34
|
+
|
|
35
|
+
- **`get`** (#115): `hm/get/<channel>/<datapoint>` republishes the last
|
|
36
|
+
known value on its status topic. An empty datapoint republishes every
|
|
37
|
+
datapoint of the channel. Fresh user interest in April 2026.
|
|
38
|
+
- **`rpc`** (#22): the topic was already in the dispatcher's table, but
|
|
39
|
+
the class had no `rpc()` method, so `typeof this[command] === 'function'`
|
|
40
|
+
was false and the message was silently dropped; `topicOutputRpc` was
|
|
41
|
+
never read at all. That is why both fields sat commented out in the
|
|
42
|
+
editor since 2018 — exposing them would have created two settings that
|
|
43
|
+
do nothing. Both are visible now; the result or the error is published
|
|
44
|
+
on the response topic, and the never-working default topic loses its
|
|
45
|
+
meaningless `${command}` segment (migrated on dialog open). An empty
|
|
46
|
+
topic disables a command.
|
|
47
|
+
- **#167**: `getRegaData()` (channel names, rooms, functions, groups) ran
|
|
48
|
+
once, in the connection constructor; the recurring poll only refreshed
|
|
49
|
+
variables and programs. A function added in the CCU WebUI was therefore
|
|
50
|
+
invisible until the flow was redeployed. New connection option
|
|
51
|
+
_names/rooms refresh_ (minutes, default 15, 0 = off) re-reads channel
|
|
52
|
+
names, rooms and functions from the ReGa poll's tail.
|
|
53
|
+
|
|
54
|
+
`resolveChannel()` now holds the channel-name/address resolution the four
|
|
55
|
+
command handlers each had inline.
|
|
56
|
+
|
|
57
|
+
Original item: | B-3 | Fix the ccu-mqtt node bugs verified in hm2mqtt ROADMAP §1.3 (see §8.2); also #115 get/update method (fresh user interest Apr 2026), #22 missing RPC-topic GUI, #167 stale rooms/functions | hm2mqtt |
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# B-4 — Local-CCU detection
|
|
2
|
+
|
|
3
|
+
**✅ done 2026-09-04** (`4.3.0`).
|
|
4
|
+
|
|
5
|
+
When Node-RED runs on the CCU itself (RedMatic), the interface processes
|
|
6
|
+
can be reached directly on their 3xxxx ports — BINRPC for BidCos and
|
|
7
|
+
ReGa, and without the hop through the CCU's lighttpd proxy. The
|
|
8
|
+
connection node picked that up from:
|
|
9
|
+
|
|
10
|
+
```js
|
|
11
|
+
const rfdConf = fs.readFileSync('/etc/lighttpd/conf.d/proxy.conf').toString();
|
|
12
|
+
if (rfdConf.match(/"port"\s+=>\s+32001/)) {
|
|
13
|
+
this.isLocal = true;
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
On current firmware that file is a single line:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
include "/var/etc/lighttpd_proxy.conf"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
which itself only contains `include "/etc/lighttpd/conf.d/proxy_normal.conf"` —
|
|
24
|
+
the `"port" => 32001` markers are two levels down the include chain.
|
|
25
|
+
So the regex has not matched in years and every local install silently
|
|
26
|
+
went through the proxy on 1999/2000/2001/2010/9292.
|
|
27
|
+
|
|
28
|
+
Measured on a lab CCU3 with firmware 3.89.8: `proxy.conf` is the bare
|
|
29
|
+
include above, while 31999, 32001, 32010 and 39292 are all listening.
|
|
30
|
+
|
|
31
|
+
## Fix
|
|
32
|
+
|
|
33
|
+
`nodes/lib/localccu.js` asks the kernel instead of parsing lighttpd's
|
|
34
|
+
configuration: a listener on rfd's direct port (32001, or the ReGa's 31999) is exactly the condition that makes using the direct ports
|
|
35
|
+
correct, and it cannot drift when eQ-3 reorganises the config files
|
|
36
|
+
again. `/proc/net/tcp` and `/proc/net/tcp6` are plain files, so the check
|
|
37
|
+
stays synchronous — the interface table is built in the constructor —
|
|
38
|
+
and on a host without `/proc` (Windows, macOS) it simply reports "not
|
|
39
|
+
local", which is the safe answer.
|
|
40
|
+
|
|
41
|
+
8 unit tests, including the real `/proc/net/tcp` line format from the
|
|
42
|
+
3.89.8 lab box.
|
|
43
|
+
|
|
44
|
+
Original item: | 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 |
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# B-5 — Ping checks, sysvar node properties and status
|
|
2
|
+
|
|
3
|
+
**✅ done 2026-09-04** (`4.3.0`) — issues #44, #54, #52, #124, #166, #96,
|
|
4
|
+
#56, #183.
|
|
5
|
+
|
|
6
|
+
A collection of small connection- and node-level items that had all been
|
|
7
|
+
open since 2019/2020.
|
|
8
|
+
|
|
9
|
+
- **#44 — configurable ping checks.** The connection node had a _ping
|
|
10
|
+
timeout_ field but no way to switch the check off: entering 0 fell
|
|
11
|
+
through `Number.parseInt(config.rpcPingTimeout, 10) || 60` back to 60
|
|
12
|
+
seconds. New _RPC ping_ checkbox (default on). Off means no periodic
|
|
13
|
+
ping and no timeout-triggered re-init for that connection — the honest
|
|
14
|
+
reading of "deactivate ping checks", with the consequence documented in
|
|
15
|
+
the dialog.
|
|
16
|
+
- **#54 / #52 — last value and its age under the node.** The connection
|
|
17
|
+
keeps `value`, `ts` and `lc` for every datapoint and system variable;
|
|
18
|
+
the nodes simply never showed them, and the sysvar node showed nothing
|
|
19
|
+
at all unless "emit value on start" was enabled.
|
|
20
|
+
`nodes/lib/valuestatus.js` renders `<value> (3m)` and re-renders on a timer whose
|
|
21
|
+
interval follows the resolution shown, so the line does not go stale
|
|
22
|
+
between events. Used by the sysvar node (which also seeds it from the
|
|
23
|
+
connection's cache when "emit value on start" is off) and the rpc-event
|
|
24
|
+
node (which shows the topic that last fired).
|
|
25
|
+
- **#96 — filter uncertain values.** The `uncertain` flag was already in
|
|
26
|
+
every message; there was no way to filter on it. `uncertain` is a
|
|
27
|
+
subscription filter property now, exposed as a _discard uncertain
|
|
28
|
+
values_ checkbox on the value and rpc-event nodes. It is only put into
|
|
29
|
+
the filter when the option is on, so existing subscriptions are
|
|
30
|
+
unaffected, and it is evaluated before `callCallback()`'s attribute
|
|
31
|
+
loop, which may break early for a whitelisted datapoint.
|
|
32
|
+
- **#166 — immediate sysvar echo lost under concurrency.** `setVariable()`
|
|
33
|
+
triggers a ReGa poll so the new value comes back without waiting for
|
|
34
|
+
the 30 s interval, but only `if (!this.regaPollPending)`, and
|
|
35
|
+
`regaPoll()` itself no-ops while one is in flight. Writing several
|
|
36
|
+
variables at once therefore left all but the first invisible for up to
|
|
37
|
+
a poll interval — exactly the reported symptom ("works for one
|
|
38
|
+
variable, not for several"). The request is remembered and exactly one
|
|
39
|
+
more poll runs when the current one finishes.
|
|
40
|
+
- **#183 — RSSI conversion guarded.** `dp.value -= 256` ran for every
|
|
41
|
+
RSSI_DEVICE/RSSI_PEER value from the ReGa poll, so a value that was
|
|
42
|
+
already signed, or the 0 that means "never received", became -318 or
|
|
43
|
+
-256. Now only for values above 127, matching hm2mqtt's guard. (The
|
|
44
|
+
XML-RPC event path needs no conversion.)
|
|
45
|
+
- **#124 — re-read variable descriptions on poll** was already fixed in
|
|
46
|
+
2020 (commit 453f2b2, v3.2.1) and the issue merely never closed; the
|
|
47
|
+
remaining gap (`info` not selectable as a property) is noted below.
|
|
48
|
+
- **#56** — the sysvar node's configurable source property landed with
|
|
49
|
+
B-2, which owns the dialog change.
|
|
50
|
+
|
|
51
|
+
## Not done
|
|
52
|
+
|
|
53
|
+
- `info` (a variable's description) is still not selectable as a single
|
|
54
|
+
property in the get-value/sysvar nodes; it is reachable through the
|
|
55
|
+
whole message. Left for whoever touches those property lists next.
|
|
56
|
+
|
|
57
|
+
Original item: | B-5 | Configurable ping checks (#44), sysvar node property/status improvements (#54, #56, #52 last-event status, #124 re-read descriptions on poll, #166 immediate sysvar echo, #96 uncertain-filter option) | tracker |
|
|
@@ -18,6 +18,17 @@ the roadmap's contents index (marked ✅ there, linking here).
|
|
|
18
18
|
|
|
19
19
|
**Backlog items**
|
|
20
20
|
|
|
21
|
+
- [B-5.md](B-5.md) — ping toggle, value/age status lines, uncertain
|
|
22
|
+
filter, trailing sysvar re-poll, RSSI guard ✅ 2026-09-04 (4.3.0;
|
|
23
|
+
#44/#54/#52/#96/#166/#183/#124).
|
|
24
|
+
- [B-4.md](B-4.md) — local-CCU detection via a /proc/net/tcp listener
|
|
25
|
+
probe instead of the lighttpd config grep that had stopped matching ✅
|
|
26
|
+
2026-09-04 (4.3.0).
|
|
27
|
+
- [B-3.md](B-3.md) — ccu-mqtt fixes plus the `get` and `rpc` commands and
|
|
28
|
+
the VALUE_LIST enum names ✅ 2026-09-04 (4.3.0; #115/#22/#167 and the
|
|
29
|
+
§8.2 findings).
|
|
30
|
+
- [B-2.md](B-2.md) — dynamic node configuration via `msg.config` ✅
|
|
31
|
+
2026-09-04 (4.3.0; #172/#71/#103/#80/#56/#148/#185/#133/#158).
|
|
21
32
|
- [B-14.md](B-14.md) — COMBINED_PARAMETER mapping for HmIP slat writes ✅
|
|
22
33
|
2026-09-02 (#136/#154/#175, pending hardware confirmation).
|
|
23
34
|
- [B-6.md](B-6.md) — binrpc rewrite without abandoned deps ✅ 2026-09-02
|