node-red-contrib-velbus-2026 0.10.1 → 0.10.2
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_FORUM.md
CHANGED
|
@@ -29,6 +29,53 @@ separate duplicate-table bugs took to fully resolve.
|
|
|
29
29
|
|
|
30
30
|
---
|
|
31
31
|
|
|
32
|
+
## v0.10.2 — 09/07/2026
|
|
33
|
+
|
|
34
|
+
### velbus-sensor — VMB4AN generic analogue reading (channels 9-12)
|
|
35
|
+
|
|
36
|
+
- **Prompted by Stuart noticing `isVMB4AN` was defined but never used** —
|
|
37
|
+
confirmed the sensor-input channels (Group 2 of VMB4AN's three functional
|
|
38
|
+
groups) produced literally no output at all beforehand; the packet
|
|
39
|
+
carrying that data wasn't handled anywhere in the file.
|
|
40
|
+
- **Real trap found and avoided:** the obviously-named `0xEA`
|
|
41
|
+
("sensor status") packet does **not** carry a value at all — it's
|
|
42
|
+
operating-mode/sleep-timer/auto-send configuration only. The actual
|
|
43
|
+
reading lives in a separate, easy-to-miss packet earlier in the protocol
|
|
44
|
+
document: `0xA9` (`COMMAND_SENSOR_RAW_DATA`, "Transmit the sensor raw
|
|
45
|
+
value"), genuinely standalone with no need to cross-reference anything
|
|
46
|
+
else. Also confirmed `0xE8`/`0xE9` ("sensor settings") is preset
|
|
47
|
+
*configuration* storage, not a live value either — three different
|
|
48
|
+
packets that could each plausibly have been mistaken for "the reading."
|
|
49
|
+
- Deliberately generic, per explicit preference: emits `{ type: "analogue",
|
|
50
|
+
channel, mode, raw }` with no engineering-unit conversion attempted —
|
|
51
|
+
`mode` (voltage/current/resistance/period) and the PDF's resolution
|
|
52
|
+
table are exposed in the node's help so conversion can happen in the flow
|
|
53
|
+
instead.
|
|
54
|
+
- New `get_analogue` input command (`0xE5`, request-a-reading-now) — uses
|
|
55
|
+
the protocol's own "auto-send config byte = 0" option to request a value
|
|
56
|
+
without side-effecting the module's existing auto-send schedule.
|
|
57
|
+
**Priority byte corrected during verification:** the protocol PDF
|
|
58
|
+
explicitly states "SID10-SID9 = 11 (lowest priority)" for this specific
|
|
59
|
+
command — `0xFB`, not the `0xF8` most other commands in this file use.
|
|
60
|
+
Checked directly rather than assumed, since this is the one place it
|
|
61
|
+
genuinely differs from the file's established convention.
|
|
62
|
+
- Both confirmed absent from `VMB7IN`'s own protocol PDF before wiring
|
|
63
|
+
in — this file's switch statement handles both module types together,
|
|
64
|
+
so a collision would misfire for `VMB7IN` modules if either byte had
|
|
65
|
+
been reused there.
|
|
66
|
+
- **Full Group 2 configuration (presets, mode-switching, sleep time,
|
|
67
|
+
offset, auto-send interval config) and all of Group 3 (analog outputs)
|
|
68
|
+
remain parked** — see `coverage-roadmap.md` section 6. This is
|
|
69
|
+
deliberately just the minimal reading piece, not the full feature.
|
|
70
|
+
|
|
71
|
+
Verified via the mock-RED harness: voltage/period modes, both period
|
|
72
|
+
special-value cases (`0x000000` short-circuit, `0xFFFFFF` open-circuit),
|
|
73
|
+
`VMB7IN` isolation confirmed (same bytes produce no output on that type),
|
|
74
|
+
`get_analogue` checksum hand-verified, correctly rejected on non-VMB4AN
|
|
75
|
+
types. Not yet sent to a real bus.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
32
79
|
## v0.10.1 — 09/07/2026
|
|
33
80
|
|
|
34
81
|
### Two critical bugs found on real hardware — velbus-dimmer and velbus-glass-panel
|
package/HANDOVER.md
CHANGED
|
@@ -6,7 +6,7 @@ you're a new contributor, a new maintainer, or an AI assistant starting a fresh
|
|
|
6
6
|
with no memory of previous work — this document should be sufficient on its own, together
|
|
7
7
|
with the source code in this repository, to continue development competently.
|
|
8
8
|
|
|
9
|
-
Current state at time of writing: **v0.10.
|
|
9
|
+
Current state at time of writing: **v0.10.2, 19 nodes, published on npm.**
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
@@ -306,7 +306,7 @@ or a string before assuming the parsing logic itself is wrong.
|
|
|
306
306
|
| `velbus-pir` | Velbus (inputs) | Original-series PIR: VMBPIRO-10, VMBPIRM, VMBPIRC, VMBPIRO |
|
|
307
307
|
| `velbus-pir-20` | Velbus (inputs) | V2 PIR: VMBPIR-20, VMBPIRO-20 |
|
|
308
308
|
| `velbus-meteo` | Velbus (inputs) | Weather station: VMBMETEO |
|
|
309
|
-
| `velbus-sensor` | Velbus (inputs) | Original-series input/analogue: VMB7IN, VMB4AN, VMB6IN |
|
|
309
|
+
| `velbus-sensor` | Velbus (inputs) | Original-series input/analogue: VMB7IN, VMB4AN (channels 1-8 alarm outputs + generic analogue reading on channels 9-12; full sensor/preset config and analog outputs on channels 13-16 remain parked), VMB6IN |
|
|
310
310
|
| `velbus-sensor-20` | Velbus (inputs) | V2 input: VMB8IN-20 |
|
|
311
311
|
| `velbus-blind` | Velbus (outputs) | VMB1BL, VMB2BL |
|
|
312
312
|
| `velbus-blind-s` | Velbus (outputs) | VMB1BLS, VMB2BLE, VMB2BLE-10 |
|
|
@@ -589,6 +589,23 @@ Address assignment: allow 500ms, then rescan to confirm the new address took eff
|
|
|
589
589
|
not the right trigger for an automatic write-back, both for the EEPROM-wear reason above
|
|
590
590
|
and because it risks a feedback loop. Reads have no such constraint and are always safe.
|
|
591
591
|
|
|
592
|
+
### 7.8a `VMB4AN` — three similar-sounding packets, only one has the actual value
|
|
593
|
+
|
|
594
|
+
A real trap, worth remembering for any future work on this module's
|
|
595
|
+
sensor channels (9-12): `0xEA` ("sensor status") sounds like it should be
|
|
596
|
+
the reading, but it's operating-mode/sleep-timer/auto-send configuration
|
|
597
|
+
only — no value field at all. `0xE8`/`0xE9` ("sensor settings") sounds
|
|
598
|
+
promising too, but that's stored preset *configuration*, not a live
|
|
599
|
+
reading. The actual value lives in `0xA9` (`COMMAND_SENSOR_RAW_DATA`,
|
|
600
|
+
labelled "Transmit the sensor raw value" in the PDF) — a completely
|
|
601
|
+
standalone packet with no need to cross-reference either of the other two.
|
|
602
|
+
```
|
|
603
|
+
body[0] = 0xA9, body[1] = channel (9-12)
|
|
604
|
+
body[2] = operating mode (00=voltage, 01=current, 10=resistance, 11=period)
|
|
605
|
+
body[3-5] = 24-bit raw value, MSB first
|
|
606
|
+
(period mode: 0x000000 = short-circuited, 0xFFFFFF = open-circuit)
|
|
607
|
+
```
|
|
608
|
+
|
|
592
609
|
### 7.9 Thermostat commands — always to the primary address
|
|
593
610
|
```
|
|
594
611
|
0xDB = comfort mode, 0xDC = day mode, 0xDD = night mode, 0xDE = safe mode
|
|
@@ -137,12 +137,24 @@
|
|
|
137
137
|
"enabled": [1,2,3,4,5,6,7,8], "locked": [], "progDisabled": [],
|
|
138
138
|
"program": "summer", "alarms": { "alarm1Active": false, "alarm2Active": false } }</pre>
|
|
139
139
|
|
|
140
|
-
<h3>Output 2 — Counter data (VMB7IN
|
|
140
|
+
<h3>Output 2 — Counter data (VMB7IN) / Analogue readings (VMB4AN)</h3>
|
|
141
141
|
<pre>{ "type": "counter", "channel": 1, "count": 12345,
|
|
142
142
|
"pulsesPerUnit": 1000, "periodMs": 3600, "overflow": false }</pre>
|
|
143
143
|
<p>Engineering units: calculate in flow using pulsesPerUnit and periodMs.</p>
|
|
144
144
|
<p>Power (W) = 3,600,000,000 / (periodMs × pulsesPerUnit)</p>
|
|
145
145
|
|
|
146
|
+
<p>VMB4AN sensor channels (9-12) — deliberately generic, no engineering-unit
|
|
147
|
+
conversion attempted here (mode-aware scaling, presets, and sleep-timer
|
|
148
|
+
configuration are a larger, separately-scoped piece of work — see
|
|
149
|
+
<code>coverage-roadmap.md</code>):</p>
|
|
150
|
+
<pre>{ "type": "analogue", "channel": 9, "mode": "voltage", "raw": 12345 }</pre>
|
|
151
|
+
<p><code>mode</code> is <code>"voltage"</code> (0-10V, 0.25mV/count),
|
|
152
|
+
<code>"current"</code> (4-20mA, 5µA/count), <code>"resistance"</code>
|
|
153
|
+
(PT100/PT1000/Ni1000, 0.25Ω/count), or <code>"period"</code> (0.5µs/count —
|
|
154
|
+
<code>raw</code> of <code>0</code> means short-circuited, <code>16777215</code>
|
|
155
|
+
means open-circuit). Apply the resolution yourself in the flow, e.g.
|
|
156
|
+
<code>volts = raw * 0.00025</code> for voltage mode.</p>
|
|
157
|
+
|
|
146
158
|
<h3>Input commands</h3>
|
|
147
159
|
<dl>
|
|
148
160
|
<dt><code>{ "cmd": "get_status" }</code></dt><dd>Request module status.</dd>
|
|
@@ -150,6 +162,10 @@
|
|
|
150
162
|
<dd>Request counter (VMB7IN). channels=bitmask of ch1-4 (default 15=all). interval=0 no change.</dd>
|
|
151
163
|
<dt><code>{ "cmd": "reset_counter", "channel": 1 }</code></dt><dd>Reset pulse counter to zero.</dd>
|
|
152
164
|
<dt><code>{ "cmd": "load_counter", "channel": 1, "value": 12345 }</code></dt><dd>Load counter with preset value (build 1426+).</dd>
|
|
165
|
+
<dt><code>{ "cmd": "get_analogue", "channel": 9 }</code></dt>
|
|
166
|
+
<dd>Request an analogue reading now (VMB4AN, channel 9-12). Doesn't change
|
|
167
|
+
the module's own auto-send interval configuration — it already sends
|
|
168
|
+
readings on its own schedule; this just asks for one immediately.</dd>
|
|
153
169
|
<dt><code>{ "cmd": "get_name", "channel": 1 }</code></dt><dd>Request channel name from VelbusLink.</dd>
|
|
154
170
|
</dl>
|
|
155
171
|
</script>
|
|
@@ -172,6 +172,34 @@ module.exports = function(RED) {
|
|
|
172
172
|
break;
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
+
// ── 0xA9 Sensor raw value (VMB4AN channels 9-12 only) ────────────
|
|
176
|
+
// Confirmed from protocol_vmb4an.pdf, "Transmit the sensor raw
|
|
177
|
+
// value" — a genuinely standalone packet (COMMAND_SENSOR_RAW_DATA),
|
|
178
|
+
// not to be confused with 0xEA "sensor status" (that one carries
|
|
179
|
+
// operating mode / sleep timer / auto-send config, no actual value
|
|
180
|
+
// at all — a real trap if you assume "status" means "reading").
|
|
181
|
+
// body[0]=0xA9, body[1]=channel(9-12), body[2]=operating mode,
|
|
182
|
+
// body[3-5]=24-bit raw value (upper/high/low, MSB first).
|
|
183
|
+
// Deliberately generic per Stuart's own preference — engineering-
|
|
184
|
+
// unit conversion (voltage/current/resistance/period) is left to
|
|
185
|
+
// the flow, not attempted here. The PDF's resolution table (e.g.
|
|
186
|
+
// 0.25mV/count for voltage) is available in this node's help if
|
|
187
|
+
// conversion is ever wanted downstream.
|
|
188
|
+
case 0xA9: {
|
|
189
|
+
if (!isVMB4AN) return;
|
|
190
|
+
if (body.length < 6) return;
|
|
191
|
+
|
|
192
|
+
const channel = body[1];
|
|
193
|
+
const modeCode = body[2] & 0x03;
|
|
194
|
+
const mode = ['voltage', 'current', 'resistance', 'period'][modeCode];
|
|
195
|
+
const raw = (body[3] << 16) | (body[4] << 8) | body[5];
|
|
196
|
+
|
|
197
|
+
const payload = { type: 'analogue', channel, mode, raw };
|
|
198
|
+
|
|
199
|
+
node.send([null, { payload }]);
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
|
|
175
203
|
// ── 0xF0/F1/F2 Channel name parts ───────────────────────────────
|
|
176
204
|
case 0xF0:
|
|
177
205
|
case 0xF1:
|
|
@@ -222,6 +250,25 @@ module.exports = function(RED) {
|
|
|
222
250
|
return;
|
|
223
251
|
}
|
|
224
252
|
|
|
253
|
+
// Request an analogue reading now — VMB4AN channels 9-12 only.
|
|
254
|
+
// DATABYTE3=0 explicitly means "don't change the auto-send interval
|
|
255
|
+
// config" per the protocol PDF — this just asks for a value without
|
|
256
|
+
// side effects on the module's existing auto-send behaviour.
|
|
257
|
+
// Priority: protocol PDF explicitly states "SID10-SID9 = 11 (lowest
|
|
258
|
+
// priority)" for this specific command — 0xFB, not the 0xF8 used by
|
|
259
|
+
// most other commands in this file. Checked directly rather than
|
|
260
|
+
// assumed, since this is the one place it genuinely differs.
|
|
261
|
+
if (cmd === 'get_analogue') {
|
|
262
|
+
if (!isVMB4AN) { node.warn('velbus-sensor: this module has no analogue sensor channels'); return; }
|
|
263
|
+
const ch = parseInt(msg.payload.channel);
|
|
264
|
+
if (!ch || ch < 9 || ch > 12) {
|
|
265
|
+
node.warn('velbus-sensor: get_analogue requires "channel": 9-12');
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
node.bridge.send(pkt(0xFB, node.address, [0xE5, ch, 0x00]));
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
|
|
225
272
|
// Load counter — DB2=channel number (0-3), DB3=don't care, DB4-7=32-bit value
|
|
226
273
|
if (cmd === 'load_counter') {
|
|
227
274
|
if (!hasCounter) { node.warn('velbus-sensor: this module has no pulse counter'); return; }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-velbus-2026",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.2",
|
|
4
4
|
"description": "Node-RED palette for Velbus building automation \u2014 relay, dimmer, glass panel, PIR, blind, sensor, meteo, clock nodes. Original and V2 (-20) series.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"node-red",
|
package/velbus-2026-repo.bundle
CHANGED
|
Binary file
|