node-red-contrib-velbus-2026 0.8.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/CHANGELOG_FORUM.md +784 -0
- package/LICENSE +21 -0
- package/README.md +140 -0
- package/examples/velbus-basic-relay-dimmer.json +328 -0
- package/index.js +3 -0
- package/lib/blind-types-20.js +26 -0
- package/lib/blind-types-s.js +46 -0
- package/lib/blind-types.js +38 -0
- package/lib/dimmer-types-20.js +120 -0
- package/lib/dimmer-types.js +34 -0
- package/lib/glass-panel-types.js +296 -0
- package/lib/pir-types-20.js +51 -0
- package/lib/pir-types.js +61 -0
- package/lib/relay-types-20.js +43 -0
- package/lib/relay-types.js +39 -0
- package/lib/sensor-types-20.js +29 -0
- package/lib/sensor-types.js +49 -0
- package/lib/velbus-utils.js +80 -0
- package/nodes/velbus-blind/velbus-blind.html +165 -0
- package/nodes/velbus-blind/velbus-blind.js +251 -0
- package/nodes/velbus-blind-20/velbus-blind-20.html +179 -0
- package/nodes/velbus-blind-20/velbus-blind-20.js +300 -0
- package/nodes/velbus-blind-s/velbus-blind-s.html +181 -0
- package/nodes/velbus-blind-s/velbus-blind-s.js +282 -0
- package/nodes/velbus-bridge/velbus-bridge.html +72 -0
- package/nodes/velbus-bridge/velbus-bridge.js +304 -0
- package/nodes/velbus-button/velbus-button.html +172 -0
- package/nodes/velbus-button/velbus-button.js +117 -0
- package/nodes/velbus-clock/velbus-clock.html +198 -0
- package/nodes/velbus-clock/velbus-clock.js +273 -0
- package/nodes/velbus-dimmer/velbus-dimmer.html +174 -0
- package/nodes/velbus-dimmer/velbus-dimmer.js +457 -0
- package/nodes/velbus-dimmer-20/velbus-dimmer-20.html +271 -0
- package/nodes/velbus-dimmer-20/velbus-dimmer-20.js +602 -0
- package/nodes/velbus-glass-panel/velbus-glass-panel.html +337 -0
- package/nodes/velbus-glass-panel/velbus-glass-panel.js +492 -0
- package/nodes/velbus-meteo/velbus-meteo.html +120 -0
- package/nodes/velbus-meteo/velbus-meteo.js +279 -0
- package/nodes/velbus-pir/velbus-pir.html +187 -0
- package/nodes/velbus-pir/velbus-pir.js +269 -0
- package/nodes/velbus-pir-20/velbus-pir-20.html +186 -0
- package/nodes/velbus-pir-20/velbus-pir-20.js +352 -0
- package/nodes/velbus-relay/velbus-relay.html +215 -0
- package/nodes/velbus-relay/velbus-relay.js +404 -0
- package/nodes/velbus-relay-20/velbus-relay-20.html +123 -0
- package/nodes/velbus-relay-20/velbus-relay-20.js +434 -0
- package/nodes/velbus-scan/velbus-scan.html +87 -0
- package/nodes/velbus-scan/velbus-scan.js +313 -0
- package/nodes/velbus-sensor/velbus-sensor.html +154 -0
- package/nodes/velbus-sensor/velbus-sensor.js +259 -0
- package/nodes/velbus-sensor-20/velbus-sensor-20.html +158 -0
- package/nodes/velbus-sensor-20/velbus-sensor-20.js +314 -0
- package/nodes/velbus-thermostat/velbus-thermostat.html +191 -0
- package/nodes/velbus-thermostat/velbus-thermostat.js +322 -0
- package/package.json +55 -0
- package/velbus-2026-repo.bundle +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Stuart Hanlon, MDAR Limited (https://mdar.co.uk)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# node-red-contrib-velbus-2026
|
|
2
|
+
|
|
3
|
+
A Node-RED palette for [Velbus](https://www.velbus.eu) building automation systems.
|
|
4
|
+
|
|
5
|
+
> **⚠ Testing status:** This palette was generated with Claude.ai and is in need of
|
|
6
|
+
> extensive field testing before being deployed into a commercial project. It is presented
|
|
7
|
+
> "as is" — any use beyond testing is entirely at your own risk and liability.
|
|
8
|
+
> Constructive feedback is welcomed, accompanied by as many examples and debug captures
|
|
9
|
+
> as possible. Please
|
|
10
|
+
> [file an issue on GitHub](https://github.com/MDAR/node-red-contrib-velbus-2026/issues).
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## About
|
|
15
|
+
|
|
16
|
+
Velbus is a CAN-bus building automation system manufactured in Belgium. This palette
|
|
17
|
+
provides Node-RED nodes for all major Velbus module families — both the original series
|
|
18
|
+
and the current V2 (-20 series) modules.
|
|
19
|
+
|
|
20
|
+
Developed and maintained by [MDAR Limited](https://mdar.co.uk), the UK distributor
|
|
21
|
+
for Velbus building automation systems.
|
|
22
|
+
|
|
23
|
+
This is a ground-up rewrite replacing the abandoned
|
|
24
|
+
[node-red-contrib-velbus](https://github.com/gertst/node-red-contrib-velbus) palette
|
|
25
|
+
(last updated 2020).
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Requirements
|
|
30
|
+
|
|
31
|
+
- Node-RED v3.0 or later (tested on v5.0)
|
|
32
|
+
- A Velbus TCP gateway:
|
|
33
|
+
- [velbus-tcp snap](https://snapcraft.io/velbus-tcp) (default port 6000)
|
|
34
|
+
- [python-velbustcp](https://github.com/velbus/python-velbustcp) (default port 27015)
|
|
35
|
+
- Node.js 18+
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
Via palette manager: search for `velbus-2026`.
|
|
42
|
+
|
|
43
|
+
Via npm:
|
|
44
|
+
```bash
|
|
45
|
+
cd ~/.node-red
|
|
46
|
+
npm install node-red-contrib-velbus-2026
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Via local tarball:
|
|
50
|
+
```bash
|
|
51
|
+
cd ~/.node-red
|
|
52
|
+
npm install /path/to/node-red-contrib-velbus-2026_v0.8.1.tar.gz
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Nodes
|
|
58
|
+
|
|
59
|
+
### Infrastructure
|
|
60
|
+
| Node | Description |
|
|
61
|
+
|---|---|
|
|
62
|
+
| `velbus-bridge` | Config node. TCP/TLS connection to gateway. Handles packet routing, subaddress mapping, scan locking. |
|
|
63
|
+
| `velbus-scan` | Bus scanner. Sends RTR to all addresses 0xFE→0x01, collects 0xFF responses. Populates address dropdowns in all other nodes. |
|
|
64
|
+
|
|
65
|
+
### Inputs (teal)
|
|
66
|
+
| Node | Modules |
|
|
67
|
+
|---|---|
|
|
68
|
+
| `velbus-glass-panel` | All VMBEL and VMBGP variants — 26 types including OLED, PIR, and original series. Thermostat, LED control, open collector. |
|
|
69
|
+
| `velbus-thermostat` | Dedicated thermostat node for all glass panel modules. |
|
|
70
|
+
| `velbus-button` | VMB8PB, VMB8PBU, VMB6PBN, VMB2PBN, VMB4PB, VMB6PB-20 |
|
|
71
|
+
| `velbus-pir` | VMBPIRM, VMBPIRC, VMBPIRO, VMBPIRO-10 |
|
|
72
|
+
| `velbus-pir-20` | VMBPIR-20, VMBPIRO-20 |
|
|
73
|
+
| `velbus-meteo` | VMBMETEO — wind, rain, light, temperature, alarm outputs |
|
|
74
|
+
| `velbus-sensor` | VMB7IN (8 digital inputs + 4 pulse counters), VMB4AN (16-channel analogue/alarm) |
|
|
75
|
+
| `velbus-sensor-20` | VMB8IN-20 (8 digital + 24 alarm channels via subaddresses, energy counters) |
|
|
76
|
+
|
|
77
|
+
### Outputs (blue)
|
|
78
|
+
| Node | Modules |
|
|
79
|
+
|---|---|
|
|
80
|
+
| `velbus-relay` | VMB1RY, VMB4RY, VMB4RYLD, VMB4RYNO, VMB1RYNO, VMB1RYNOS, VMB1RYS, VMB4RYLD-10, VMB4RYNO-10 |
|
|
81
|
+
| `velbus-relay-20` | VMB1RYS-20, VMB4RYLD-20, VMB4RYNO-20 |
|
|
82
|
+
| `velbus-dimmer` | VMBDMI, VMBDMI-R, VMB4DC |
|
|
83
|
+
| `velbus-dimmer-20` | VMB2DC-20, VMB8DC-20, VMB4LEDPWM-20 |
|
|
84
|
+
| `velbus-blind` | VMB1BL, VMB2BL — original series, stop/up/down only |
|
|
85
|
+
| `velbus-blind-s` | VMB1BLS, VMB2BLE, VMB2BLE-10 — full position, lock, force, inhibit |
|
|
86
|
+
| `velbus-blind-20` | VMB2BLE-20 — V2 series with CAN FD support |
|
|
87
|
+
| `velbus-clock` | No fixed module — broadcasts time/date/DST to bus address `0x00`, plus global/local clock alarm (V2 series only) |
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Examples
|
|
92
|
+
|
|
93
|
+
After installation, example flows are available via **Import → Examples → node-red-contrib-velbus-2026**
|
|
94
|
+
in the Node-RED editor.
|
|
95
|
+
|
|
96
|
+
### velbus-basic-relay-dimmer
|
|
97
|
+
A minimal working example with:
|
|
98
|
+
- Bus scan (inject to discover modules)
|
|
99
|
+
- Relay toggle — Dashboard 2 switch → velbus-relay command, with state feedback
|
|
100
|
+
- Dimmer slider — Dashboard 2 slider (0-100%) → velbus-dimmer-20 command, with level readout
|
|
101
|
+
|
|
102
|
+
**To use:** configure the velbus-bridge node, scan the bus, open the relay and dimmer
|
|
103
|
+
nodes and select your module addresses from the dropdowns, then deploy. Dashboard UI
|
|
104
|
+
at `/velbus`.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Quick start
|
|
109
|
+
|
|
110
|
+
1. Add a **velbus-bridge** config node pointing at your gateway (default: `127.0.0.1:6000`)
|
|
111
|
+
2. Add a **velbus-scan** node, connect to the bridge, deploy and inject to scan
|
|
112
|
+
3. All other nodes will have address dropdowns populated from the scan results
|
|
113
|
+
4. Add the node for your module type, select the address, deploy
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Confirmed hardware
|
|
118
|
+
|
|
119
|
+
Tested on a live 18-module installation including VMBEL4, VMBELO, VMBELPIR,
|
|
120
|
+
VMBPIR-20, VMB1RYS, and VMB8DC-20. CAN FD modules confirmed working.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Contributing
|
|
125
|
+
|
|
126
|
+
Issues and pull requests welcome at the
|
|
127
|
+
[GitHub repository](https://github.com/MDAR/node-red-contrib-velbus-2026).
|
|
128
|
+
|
|
129
|
+
Please include Node-RED version, gateway type, module model and firmware build,
|
|
130
|
+
and a packet capture where possible.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Licence
|
|
135
|
+
|
|
136
|
+
MIT — see [LICENSE](LICENSE)
|
|
137
|
+
|
|
138
|
+
## Author
|
|
139
|
+
|
|
140
|
+
Stuart Hanlon, [MDAR Limited](https://mdar.co.uk)
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "tab-velbus-example",
|
|
4
|
+
"type": "tab",
|
|
5
|
+
"label": "Velbus Basic Example",
|
|
6
|
+
"disabled": false,
|
|
7
|
+
"info": "Basic Velbus example — relay toggle and dimmer control.\n\nBefore using:\n1. Configure the velbus-bridge node with your gateway address.\n2. Deploy and inject the 'Scan bus' node to discover modules.\n3. Open each velbus-relay and velbus-dimmer node and select the correct address from the dropdown.\n4. Re-deploy.\n\nThe Dashboard 2 UI will be available at /dashboard"
|
|
8
|
+
},
|
|
9
|
+
|
|
10
|
+
{
|
|
11
|
+
"id": "bridge-example",
|
|
12
|
+
"type": "velbus-bridge",
|
|
13
|
+
"name": "Velbus Gateway",
|
|
14
|
+
"host": "127.0.0.1",
|
|
15
|
+
"port": "6000",
|
|
16
|
+
"tls": false,
|
|
17
|
+
"authKey": ""
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
{
|
|
21
|
+
"id": "comment-scan",
|
|
22
|
+
"type": "comment",
|
|
23
|
+
"z": "tab-velbus-example",
|
|
24
|
+
"name": "STEP 1 — Scan the bus first",
|
|
25
|
+
"info": "Inject once to discover all modules. Address dropdowns in relay/dimmer nodes are populated from scan results.",
|
|
26
|
+
"x": 200,
|
|
27
|
+
"y": 60,
|
|
28
|
+
"wires": []
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
{
|
|
32
|
+
"id": "inject-scan",
|
|
33
|
+
"type": "inject",
|
|
34
|
+
"z": "tab-velbus-example",
|
|
35
|
+
"name": "Scan bus",
|
|
36
|
+
"props": [{"p": "payload"}],
|
|
37
|
+
"repeat": "",
|
|
38
|
+
"crontab": "",
|
|
39
|
+
"once": false,
|
|
40
|
+
"onceDelay": 0.1,
|
|
41
|
+
"topic": "",
|
|
42
|
+
"payload": "{}",
|
|
43
|
+
"payloadType": "json",
|
|
44
|
+
"x": 160,
|
|
45
|
+
"y": 120,
|
|
46
|
+
"wires": [["scan-example"]]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "scan-example",
|
|
50
|
+
"type": "velbus-scan",
|
|
51
|
+
"z": "tab-velbus-example",
|
|
52
|
+
"name": "Bus scan",
|
|
53
|
+
"bridge": "bridge-example",
|
|
54
|
+
"x": 340,
|
|
55
|
+
"y": 120,
|
|
56
|
+
"wires": [["debug-scan"]]
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"id": "debug-scan",
|
|
60
|
+
"type": "debug",
|
|
61
|
+
"z": "tab-velbus-example",
|
|
62
|
+
"name": "Scan results",
|
|
63
|
+
"active": true,
|
|
64
|
+
"tosidebar": true,
|
|
65
|
+
"console": false,
|
|
66
|
+
"tostatus": false,
|
|
67
|
+
"complete": "payload",
|
|
68
|
+
"targetType": "msg",
|
|
69
|
+
"x": 540,
|
|
70
|
+
"y": 120,
|
|
71
|
+
"wires": []
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
{
|
|
75
|
+
"id": "comment-relay",
|
|
76
|
+
"type": "comment",
|
|
77
|
+
"z": "tab-velbus-example",
|
|
78
|
+
"name": "STEP 2 — Relay control",
|
|
79
|
+
"info": "Dashboard toggle → relay on/off command.\nRelay status events → Dashboard state indicator.\n\nOpen velbus-relay and select your relay module address and channel.",
|
|
80
|
+
"x": 200,
|
|
81
|
+
"y": 220,
|
|
82
|
+
"wires": []
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
{
|
|
86
|
+
"id": "ui-relay-toggle",
|
|
87
|
+
"type": "ui-switch",
|
|
88
|
+
"z": "tab-velbus-example",
|
|
89
|
+
"name": "Relay toggle",
|
|
90
|
+
"label": "Relay",
|
|
91
|
+
"group": "ui-group-main",
|
|
92
|
+
"order": 1,
|
|
93
|
+
"width": 3,
|
|
94
|
+
"height": 1,
|
|
95
|
+
"passthru": false,
|
|
96
|
+
"decouple": true,
|
|
97
|
+
"topic": "relay",
|
|
98
|
+
"topicType": "str",
|
|
99
|
+
"style": "",
|
|
100
|
+
"className": "",
|
|
101
|
+
"onvalue": "true",
|
|
102
|
+
"onvalueType": "bool",
|
|
103
|
+
"onicon": "",
|
|
104
|
+
"oncolor": "#00897B",
|
|
105
|
+
"onlabel": "ON",
|
|
106
|
+
"offvalue": "false",
|
|
107
|
+
"offvalueType": "bool",
|
|
108
|
+
"officon": "",
|
|
109
|
+
"offcolor": "",
|
|
110
|
+
"offlabel": "OFF",
|
|
111
|
+
"x": 160,
|
|
112
|
+
"y": 280,
|
|
113
|
+
"wires": [["fn-relay-command"]]
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"id": "fn-relay-command",
|
|
117
|
+
"type": "function",
|
|
118
|
+
"z": "tab-velbus-example",
|
|
119
|
+
"name": "Toggle → relay cmd",
|
|
120
|
+
"func": "// Convert Dashboard 2 switch to velbus-relay command\nmsg.payload = { cmd: msg.payload ? 'on' : 'off' };\nreturn msg;",
|
|
121
|
+
"outputs": 1,
|
|
122
|
+
"noerr": 0,
|
|
123
|
+
"initialize": "",
|
|
124
|
+
"finalize": "",
|
|
125
|
+
"x": 360,
|
|
126
|
+
"y": 280,
|
|
127
|
+
"wires": [["relay-example"]]
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"id": "relay-example",
|
|
131
|
+
"type": "velbus-relay",
|
|
132
|
+
"z": "tab-velbus-example",
|
|
133
|
+
"name": "Relay ch1",
|
|
134
|
+
"bridge": "bridge-example",
|
|
135
|
+
"address": "",
|
|
136
|
+
"channel": "1",
|
|
137
|
+
"x": 580,
|
|
138
|
+
"y": 280,
|
|
139
|
+
"wires": [["fn-relay-status"]]
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"id": "fn-relay-status",
|
|
143
|
+
"type": "function",
|
|
144
|
+
"z": "tab-velbus-example",
|
|
145
|
+
"name": "Relay status → switch",
|
|
146
|
+
"func": "// Feed relay state back to Dashboard switch\nif (msg.payload && msg.payload.hasOwnProperty('on')) {\n msg.payload = msg.payload.on;\n return msg;\n}\nreturn null;",
|
|
147
|
+
"outputs": 1,
|
|
148
|
+
"noerr": 0,
|
|
149
|
+
"initialize": "",
|
|
150
|
+
"finalize": "",
|
|
151
|
+
"x": 780,
|
|
152
|
+
"y": 280,
|
|
153
|
+
"wires": [["ui-relay-toggle"]]
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
{
|
|
157
|
+
"id": "comment-dimmer",
|
|
158
|
+
"type": "comment",
|
|
159
|
+
"z": "tab-velbus-example",
|
|
160
|
+
"name": "STEP 3 — Dimmer control",
|
|
161
|
+
"info": "Dashboard slider (0-100%) → dimmer level command.\nDimmer status events → slider and text readout.\n\nOpen velbus-dimmer-20 and select your dimmer module address and channel.",
|
|
162
|
+
"x": 200,
|
|
163
|
+
"y": 380,
|
|
164
|
+
"wires": []
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
{
|
|
168
|
+
"id": "ui-dimmer-slider",
|
|
169
|
+
"type": "ui-slider",
|
|
170
|
+
"z": "tab-velbus-example",
|
|
171
|
+
"name": "Dimmer slider",
|
|
172
|
+
"label": "Dimmer level",
|
|
173
|
+
"group": "ui-group-main",
|
|
174
|
+
"order": 2,
|
|
175
|
+
"width": 6,
|
|
176
|
+
"height": 1,
|
|
177
|
+
"passthru": false,
|
|
178
|
+
"outs": "end",
|
|
179
|
+
"topic": "dimmer",
|
|
180
|
+
"topicType": "str",
|
|
181
|
+
"min": 0,
|
|
182
|
+
"max": 100,
|
|
183
|
+
"step": 1,
|
|
184
|
+
"className": "",
|
|
185
|
+
"x": 160,
|
|
186
|
+
"y": 440,
|
|
187
|
+
"wires": [["fn-dimmer-command"]]
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"id": "fn-dimmer-command",
|
|
191
|
+
"type": "function",
|
|
192
|
+
"z": "tab-velbus-example",
|
|
193
|
+
"name": "Slider → dimmer cmd",
|
|
194
|
+
"func": "// Convert Dashboard 2 slider value to velbus-dimmer command\nconst level = Math.round(msg.payload);\nmsg.payload = { cmd: level > 0 ? 'set' : 'off', level: level };\nreturn msg;",
|
|
195
|
+
"outputs": 1,
|
|
196
|
+
"noerr": 0,
|
|
197
|
+
"initialize": "",
|
|
198
|
+
"finalize": "",
|
|
199
|
+
"x": 360,
|
|
200
|
+
"y": 440,
|
|
201
|
+
"wires": [["dimmer-example"]]
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"id": "dimmer-example",
|
|
205
|
+
"type": "velbus-dimmer-20",
|
|
206
|
+
"z": "tab-velbus-example",
|
|
207
|
+
"name": "Dimmer ch1",
|
|
208
|
+
"bridge": "bridge-example",
|
|
209
|
+
"address": "",
|
|
210
|
+
"channel": "1",
|
|
211
|
+
"x": 580,
|
|
212
|
+
"y": 440,
|
|
213
|
+
"wires": [["fn-dimmer-status"]]
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"id": "fn-dimmer-status",
|
|
217
|
+
"type": "function",
|
|
218
|
+
"z": "tab-velbus-example",
|
|
219
|
+
"name": "Dimmer status → slider + text",
|
|
220
|
+
"func": "// Feed dimmer level back to Dashboard slider\nif (msg.payload && msg.payload.hasOwnProperty('percent')) {\n const level = Math.round(msg.payload.percent);\n // Update slider\n const sliderMsg = { payload: level, topic: 'dimmer' };\n // Update text label\n const textMsg = { payload: level + '%', topic: 'dimmer' };\n return [sliderMsg, textMsg];\n}\nreturn [null, null];",
|
|
221
|
+
"outputs": 2,
|
|
222
|
+
"noerr": 0,
|
|
223
|
+
"initialize": "",
|
|
224
|
+
"finalize": "",
|
|
225
|
+
"x": 800,
|
|
226
|
+
"y": 440,
|
|
227
|
+
"wires": [["ui-dimmer-slider"], ["ui-dimmer-text"]]
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
"id": "ui-dimmer-text",
|
|
231
|
+
"type": "ui-text",
|
|
232
|
+
"z": "tab-velbus-example",
|
|
233
|
+
"name": "Dimmer level readout",
|
|
234
|
+
"label": "Current level",
|
|
235
|
+
"group": "ui-group-main",
|
|
236
|
+
"order": 3,
|
|
237
|
+
"width": 3,
|
|
238
|
+
"height": 1,
|
|
239
|
+
"format": "{{msg.payload}}",
|
|
240
|
+
"layout": "row-spread",
|
|
241
|
+
"style": false,
|
|
242
|
+
"className": "",
|
|
243
|
+
"x": 1060,
|
|
244
|
+
"y": 440,
|
|
245
|
+
"wires": []
|
|
246
|
+
},
|
|
247
|
+
|
|
248
|
+
{
|
|
249
|
+
"id": "comment-debug",
|
|
250
|
+
"type": "comment",
|
|
251
|
+
"z": "tab-velbus-example",
|
|
252
|
+
"name": "STEP 4 — Debug all events",
|
|
253
|
+
"info": "Wire any node output here to see raw payloads in the debug panel.",
|
|
254
|
+
"x": 200,
|
|
255
|
+
"y": 560,
|
|
256
|
+
"wires": []
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
"id": "debug-all",
|
|
260
|
+
"type": "debug",
|
|
261
|
+
"z": "tab-velbus-example",
|
|
262
|
+
"name": "All Velbus events",
|
|
263
|
+
"active": true,
|
|
264
|
+
"tosidebar": true,
|
|
265
|
+
"console": false,
|
|
266
|
+
"tostatus": false,
|
|
267
|
+
"complete": "payload",
|
|
268
|
+
"targetType": "msg",
|
|
269
|
+
"x": 360,
|
|
270
|
+
"y": 600,
|
|
271
|
+
"wires": []
|
|
272
|
+
},
|
|
273
|
+
|
|
274
|
+
{
|
|
275
|
+
"id": "ui-group-main",
|
|
276
|
+
"type": "ui-group",
|
|
277
|
+
"name": "Velbus Control",
|
|
278
|
+
"page": "ui-page-main",
|
|
279
|
+
"width": 6,
|
|
280
|
+
"height": 1,
|
|
281
|
+
"order": 1,
|
|
282
|
+
"showTitle": true,
|
|
283
|
+
"className": "",
|
|
284
|
+
"visible": true,
|
|
285
|
+
"disabled": false
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
"id": "ui-page-main",
|
|
289
|
+
"type": "ui-page",
|
|
290
|
+
"name": "Velbus",
|
|
291
|
+
"ui": "ui-main",
|
|
292
|
+
"path": "/velbus",
|
|
293
|
+
"icon": "mdi-home-lightning-bolt",
|
|
294
|
+
"layout": "grid",
|
|
295
|
+
"theme": "ui-theme-default",
|
|
296
|
+
"order": 1,
|
|
297
|
+
"className": "",
|
|
298
|
+
"visible": true,
|
|
299
|
+
"disabled": false
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
"id": "ui-main",
|
|
303
|
+
"type": "ui-base",
|
|
304
|
+
"acceptsClientConfig": ["ui-page", "ui-control"],
|
|
305
|
+
"dialogCloseIcon": "mdi-close",
|
|
306
|
+
"showPathInSidebar": false,
|
|
307
|
+
"navigationStyle": "default",
|
|
308
|
+
"titleBarStyle": "default"
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
"id": "ui-theme-default",
|
|
312
|
+
"type": "ui-theme",
|
|
313
|
+
"name": "Default Theme",
|
|
314
|
+
"colors": {
|
|
315
|
+
"surface": "#ffffff",
|
|
316
|
+
"primary": "#0d7eb8",
|
|
317
|
+
"bgPage": "#eeeeee",
|
|
318
|
+
"groupBg": "#ffffff",
|
|
319
|
+
"groupOutline": "#cccccc"
|
|
320
|
+
},
|
|
321
|
+
"sizes": {
|
|
322
|
+
"pagePadding": "12px",
|
|
323
|
+
"groupGap": "12px",
|
|
324
|
+
"groupBorderRadius": "4px",
|
|
325
|
+
"widgetGap": "6px"
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
]
|
package/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
4
|
+
// Blind/shutter module type registry — V2 (-20) series
|
|
5
|
+
// Covered by velbus-blind-20 node.
|
|
6
|
+
//
|
|
7
|
+
// VMB2BLE-20 (0x61): Full V2 redesign. 8-byte 0xFF with CAN FD properties.
|
|
8
|
+
// 0xEC status packet covers BOTH channels in one packet using nibble encoding.
|
|
9
|
+
// Channel identifier in commands: plain integer 1, 2, or 0xFF (all).
|
|
10
|
+
// Name request 0xEF: DB2 = channel number or 0xFF for all.
|
|
11
|
+
// No 0x00 relay event transmit — status comes via 0xEC only.
|
|
12
|
+
// 0xFFFFFF NOT allowed for up/down timeout (allowed for lock/force/inhibit).
|
|
13
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
14
|
+
|
|
15
|
+
const BLIND_TYPES_20 = {
|
|
16
|
+
0x61: {
|
|
17
|
+
name: 'VMB2BLE-20',
|
|
18
|
+
channels: 2,
|
|
19
|
+
minMapVer: null,
|
|
20
|
+
series: 'v2',
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const BLIND_TYPE_IDS_20 = new Set(Object.keys(BLIND_TYPES_20).map(k => parseInt(k)));
|
|
25
|
+
|
|
26
|
+
module.exports = { BLIND_TYPES_20, BLIND_TYPE_IDS_20 };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
4
|
+
// Blind/shutter module type registry — BLS/BLE series (VMB1BLS, VMB2BLE)
|
|
5
|
+
// Covered by velbus-blind-s node.
|
|
6
|
+
//
|
|
7
|
+
// Full-featured blind controllers with position feedback (0-100%),
|
|
8
|
+
// lock/unlock (0x1A/0x1B), forced up/down, inhibit variants, auto modes,
|
|
9
|
+
// sunrise/sunset, and real-time clock. 0xFF response is 7 bytes with serial.
|
|
10
|
+
//
|
|
11
|
+
// channels: number of blind channels
|
|
12
|
+
// channelBits: map of channel number to bit value used in commands
|
|
13
|
+
// Both modules use clean bit encoding: ch1=0x01, ch2=0x02
|
|
14
|
+
// hasLocalButtons: false — local button events NOT reported in 0x00
|
|
15
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
16
|
+
|
|
17
|
+
const BLIND_TYPES_S = {
|
|
18
|
+
0x2E: {
|
|
19
|
+
name: 'VMB1BLS',
|
|
20
|
+
channels: 1,
|
|
21
|
+
channelBits: { 1: 0x01 },
|
|
22
|
+
hasLocalButtons: false,
|
|
23
|
+
minMapVer: null,
|
|
24
|
+
series: 'bls',
|
|
25
|
+
},
|
|
26
|
+
0x1D: {
|
|
27
|
+
name: 'VMB2BLE',
|
|
28
|
+
channels: 2,
|
|
29
|
+
channelBits: { 1: 0x01, 2: 0x02 },
|
|
30
|
+
hasLocalButtons: false,
|
|
31
|
+
minMapVer: null,
|
|
32
|
+
series: 'ble',
|
|
33
|
+
},
|
|
34
|
+
0x4A: {
|
|
35
|
+
name: 'VMB2BLE-10',
|
|
36
|
+
channels: 2,
|
|
37
|
+
channelBits: { 1: 0x01, 2: 0x02 },
|
|
38
|
+
hasLocalButtons: false,
|
|
39
|
+
minMapVer: null,
|
|
40
|
+
series: 'ble-10',
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const BLIND_TYPE_IDS_S = new Set(Object.keys(BLIND_TYPES_S).map(k => parseInt(k)));
|
|
45
|
+
|
|
46
|
+
module.exports = { BLIND_TYPES_S, BLIND_TYPE_IDS_S };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
4
|
+
// Blind/shutter module type registry — original series (VMB1BL, VMB2BL)
|
|
5
|
+
// Covered by velbus-blind node.
|
|
6
|
+
//
|
|
7
|
+
// These are early modules with no position feedback, no lock/force/inhibit,
|
|
8
|
+
// and dip-switch-based timeout. 0xFF response is 5 bytes (no serial number).
|
|
9
|
+
//
|
|
10
|
+
// channels: number of blind channels
|
|
11
|
+
// channelMasks: map of channel number to bitmask used in 0xEC and commands
|
|
12
|
+
// VMB1BL uses 0x03 for its single channel (historical oddity)
|
|
13
|
+
// VMB2BL uses packed 2-bit pairs: ch1=0x03, ch2=0x0C
|
|
14
|
+
// hasLocalButtons: module reports local push button events mixed into 0x00
|
|
15
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
16
|
+
|
|
17
|
+
const BLIND_TYPES = {
|
|
18
|
+
0x03: {
|
|
19
|
+
name: 'VMB1BL',
|
|
20
|
+
channels: 1,
|
|
21
|
+
channelMasks: { 1: 0x03 },
|
|
22
|
+
hasLocalButtons: true,
|
|
23
|
+
minMapVer: null,
|
|
24
|
+
series: 'original',
|
|
25
|
+
},
|
|
26
|
+
0x09: {
|
|
27
|
+
name: 'VMB2BL',
|
|
28
|
+
channels: 2,
|
|
29
|
+
channelMasks: { 1: 0x03, 2: 0x0C },
|
|
30
|
+
hasLocalButtons: true,
|
|
31
|
+
minMapVer: null,
|
|
32
|
+
series: 'original',
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const BLIND_TYPE_IDS = new Set(Object.keys(BLIND_TYPES).map(k => parseInt(k)));
|
|
37
|
+
|
|
38
|
+
module.exports = { BLIND_TYPES, BLIND_TYPE_IDS };
|