node-red-contrib-knx-ultimate 3.0.0-beta2 → 3.0.0-beta3
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
|
@@ -6,6 +6,11 @@
|
|
|
6
6
|
|
|
7
7
|
# CHANGELOG
|
|
8
8
|
|
|
9
|
+
**Version 3.0.0-beta3** - Juni 2024<br/>
|
|
10
|
+
- Warning: Node-Red version **equals or major than 3.1.1** is needed to run this node.<br/>
|
|
11
|
+
- Chore: "betterized" the description for some captions in the KNX Device node. </br>
|
|
12
|
+
- NEW: KNX Viewer node: added an output PIN (third) you can use to monitor the KNX BUS congestion.</br>
|
|
13
|
+
|
|
9
14
|
**Version 3.0.0-beta2** - Juni 2024<br/>
|
|
10
15
|
- Warning: Node-Red version **equals or major than 3.1.1** is needed to run this node.<br/>
|
|
11
16
|
- NEW: Hue Node Software Update Status for the HUE devices. <br/>
|
package/nodes/knxUltimate.html
CHANGED
|
@@ -498,7 +498,7 @@
|
|
|
498
498
|
<div class="form-row" style="padding:10px">
|
|
499
499
|
<div class="form-row">
|
|
500
500
|
<dt>
|
|
501
|
-
<i class="fa fa-arrow-right"></i>
|
|
501
|
+
<i class="fa fa-arrow-right"></i> SEND msg to KNX BUS
|
|
502
502
|
</dt>
|
|
503
503
|
</div>
|
|
504
504
|
<div class="form-row">
|
|
@@ -524,7 +524,7 @@
|
|
|
524
524
|
<br />
|
|
525
525
|
<div class="form-row">
|
|
526
526
|
<dt>
|
|
527
|
-
|<i class="fa fa-arrow-right"></i>
|
|
527
|
+
|<i class="fa fa-arrow-right"></i> RECEIVE msg from KNX BUS
|
|
528
528
|
</dt>
|
|
529
529
|
</div>
|
|
530
530
|
<div class="form-row" id="divNode-input-initialread">
|
|
@@ -685,10 +685,10 @@
|
|
|
685
685
|
**Advanced options**
|
|
686
686
|
|Property|Description|
|
|
687
687
|
|--|--|
|
|
688
|
-
||**
|
|
688
|
+
||**SEND msg to KNX BUS**|
|
|
689
689
|
| Telegram type | *write* to send write telegram (usually, you want that), otherwise you can choose the telegram's type to react to. |
|
|
690
690
|
| RBE filter (in the CONTROL section) | *Report by change* filter. If set, only the msg input (from the Flow) having different values each time, will be sent to the KNX bus. If you intend to send everytime the same value, turn it off. |
|
|
691
|
-
||**
|
|
691
|
+
||**RECEIVE msg from KNX BUS**|
|
|
692
692
|
| Read status on start | Read group address status, every time Node-Red starts and at every reconnection to the KNX Gateway. The node stores all group address values to a file, so you can choose wether to read from file or from the KNX bus. |
|
|
693
693
|
| RBE filter (in the STATUS section)| *Report by change* filter. If set, only the msg output (to KNX bus) having different values each time, will be sent to the msg output's flow. If you intend to send everytime the same value, leave it off. |
|
|
694
694
|
| React to write telegrams | The node will react (will send a msg to the flow) each time it receives a *write* telegram from the KNX bus. Usually, you want that. |
|
|
@@ -10,14 +10,17 @@
|
|
|
10
10
|
name: { value: "KNXViewer", required: false }
|
|
11
11
|
},
|
|
12
12
|
inputs: 0,
|
|
13
|
-
outputs:
|
|
13
|
+
outputs: 3,
|
|
14
14
|
outputLabels: function (i) {
|
|
15
15
|
switch (i) {
|
|
16
16
|
case 0:
|
|
17
|
-
return "
|
|
17
|
+
return "Dashboard Group Addresses";
|
|
18
18
|
break;
|
|
19
19
|
case 1:
|
|
20
|
-
return "Simple Array";
|
|
20
|
+
return "Simple Array Json for data recording";
|
|
21
|
+
break;
|
|
22
|
+
case 2:
|
|
23
|
+
return "Dashboard Telegrams queue";
|
|
21
24
|
break;
|
|
22
25
|
default:
|
|
23
26
|
break;
|
|
@@ -85,10 +88,10 @@
|
|
|
85
88
|
</script>
|
|
86
89
|
|
|
87
90
|
<script type="text/markdown" data-help-name="knxUltimateViewer">
|
|
88
|
-
View all group addresses and their values in a Dashboard widget.
|
|
91
|
+
View all group addresses and their values in a Dashboard widget, as well as JSON Oblect output and KNX transmission queue congestion.
|
|
92
|
+
|
|
93
|
+
For all output pins marked as "Dashboard.. ", the node works in conjunction with the Node-Red dashboard UI Template node.
|
|
89
94
|
|
|
90
|
-
This node works in conjunction with the Node-Red dashboard UI Template node.
|
|
91
|
-
View all group addresses and their values in a Dashboard widget.
|
|
92
95
|
|
|
93
96
|
**General**
|
|
94
97
|
|Property|Description|
|
|
@@ -98,12 +101,28 @@ View all group addresses and their values in a Dashboard widget.
|
|
|
98
101
|
|
|
|
99
102
|
<br/>
|
|
100
103
|
|
|
101
|
-
### Outputs
|
|
104
|
+
### Outputs PINS
|
|
102
105
|
|
|
103
|
-
1.
|
|
104
|
-
: payload (
|
|
105
|
-
2. Array
|
|
106
|
+
1. Dashboard Group Addresses
|
|
107
|
+
: payload (html) : Connect it directly with the Template UI node. It creates a table with all Group Addresses and their values.
|
|
108
|
+
2. Simple Array JSON for data recording
|
|
106
109
|
: payload (array) : An array containing all the GA. You can use the array to do your own format and reordering.
|
|
110
|
+
2. Dashboard telegrams queue
|
|
111
|
+
: payload (html) : Connect it directly with the Template UI node. It creates a table with the KNX transmission queue for monitoring BUS congestion.
|
|
112
|
+
|
|
113
|
+
<br/>
|
|
114
|
+
<br/>
|
|
115
|
+
|
|
116
|
+
## SAMPLE
|
|
117
|
+
|
|
118
|
+
<img src="https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/wiki/viewer2.png" width="90%"><br/>
|
|
119
|
+
|
|
120
|
+
In this example, you can see how the Viewer works.<br/>
|
|
121
|
+
Just put a Viewer node in your flow and attach a Template UI node behind it.<br/>
|
|
122
|
+
The **template** node (Dashboard's Template UI) contains the default text:<br/>
|
|
123
|
+
The Output is something as follows:<br/>
|
|
124
|
+
|
|
125
|
+
<img src="https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/wiki/viewer1.png" width="90%"><br/>
|
|
107
126
|
|
|
108
127
|
<br/>
|
|
109
128
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const KNXAddress = require('knxultimate').KNXAddress;
|
|
2
|
+
const _ = require("lodash");
|
|
2
3
|
|
|
3
4
|
module.exports = function (RED) {
|
|
4
5
|
function knxUltimateViewer(config) {
|
|
@@ -24,7 +25,7 @@ module.exports = function (RED) {
|
|
|
24
25
|
node.formatmultiplyvalue = 1;
|
|
25
26
|
node.formatnegativevalue = 'leave';
|
|
26
27
|
node.formatdecimalsvalue = 2;
|
|
27
|
-
|
|
28
|
+
node.timerPIN3 = null;
|
|
28
29
|
node.exposedGAs = [];
|
|
29
30
|
|
|
30
31
|
// Used to call the status update from the config node.
|
|
@@ -59,11 +60,24 @@ module.exports = function (RED) {
|
|
|
59
60
|
oGa.payloadmeasureunit = (msg.payloadmeasureunit !== 'unknown' ? ' ' + msg.payloadmeasureunit : '');
|
|
60
61
|
}
|
|
61
62
|
// Output the payload
|
|
62
|
-
node.
|
|
63
|
+
let PIN1 = node.createPayloadPIN1();
|
|
64
|
+
let PIN2 = node.createPayloadPIN2();
|
|
65
|
+
let PIN3 = node.createPayloadPIN3();
|
|
66
|
+
node.send([PIN1, PIN2, PIN3]);
|
|
63
67
|
};
|
|
64
68
|
|
|
65
|
-
node.
|
|
66
|
-
|
|
69
|
+
node.createPayloadPIN1 = () => {
|
|
70
|
+
|
|
71
|
+
const aSorted = node.exposedGAs.sort((a, b) => {
|
|
72
|
+
if (a.addressRAW !== undefined && b.addressRAW !== undefined) {
|
|
73
|
+
return a.addressRAW > b.addressRAW ? 1 : -1;
|
|
74
|
+
} else {
|
|
75
|
+
return a.addressRAW !== undefined ? 1 : -1;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
let sPayload = '';
|
|
79
|
+
|
|
80
|
+
const sHead = `<div class="main"><table><caption>Current received KNX Group address values</caption>
|
|
67
81
|
<thead>
|
|
68
82
|
<tr>
|
|
69
83
|
<th> GA </th>
|
|
@@ -74,17 +88,14 @@ module.exports = function (RED) {
|
|
|
74
88
|
</tr>
|
|
75
89
|
</thead>
|
|
76
90
|
<tbody>`;
|
|
77
|
-
const sFooter = `</tbody>
|
|
78
|
-
|
|
79
|
-
|
|
91
|
+
const sFooter = `</tbody><tfoot>
|
|
92
|
+
<tr>
|
|
93
|
+
<th scope="row">Count</th>
|
|
94
|
+
<td>` + aSorted.length + `</td>
|
|
95
|
+
</tr>
|
|
96
|
+
</tfoot>
|
|
97
|
+
</table></div>`;
|
|
80
98
|
|
|
81
|
-
const aSorted = node.exposedGAs.sort((a, b) => {
|
|
82
|
-
if (a.addressRAW !== undefined && b.addressRAW !== undefined) {
|
|
83
|
-
return a.addressRAW > b.addressRAW ? 1 : -1;
|
|
84
|
-
} else {
|
|
85
|
-
return a.addressRAW !== undefined ? 1 : -1;
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
99
|
try {
|
|
89
100
|
for (let index = 0; index < aSorted.length; index++) {
|
|
90
101
|
const element = aSorted[index];
|
|
@@ -114,15 +125,87 @@ module.exports = function (RED) {
|
|
|
114
125
|
} catch (error) {
|
|
115
126
|
|
|
116
127
|
}
|
|
128
|
+
return { topic: node.name, payload: sHead + sPayload + sFooter };
|
|
129
|
+
};
|
|
130
|
+
node.createPayloadPIN2 = () => {
|
|
131
|
+
return { topic: node.name, payload: node.exposedGAs }
|
|
132
|
+
};
|
|
133
|
+
node.createPayloadPIN3 = () => {
|
|
134
|
+
|
|
135
|
+
// Object containing the telegram in the queue
|
|
136
|
+
// node.writeQueueAdd({
|
|
137
|
+
// grpaddr: _oClient.topic,
|
|
138
|
+
// payload: "",
|
|
139
|
+
// dpt: "",
|
|
140
|
+
// outputtype: "read",
|
|
141
|
+
// nodecallerid: _oClient.id,
|
|
142
|
+
// });
|
|
143
|
+
const aItems = _.clone(node.server.telegramsQueue);
|
|
144
|
+
let sPayload = '';
|
|
117
145
|
|
|
118
|
-
|
|
146
|
+
const sHead = `<div class="main"><table><caption>Queue of outgoing telegrams to the KNX BUS. The more the count,</br>the more congested is the KNX BUS.</caption>
|
|
147
|
+
<thead>
|
|
148
|
+
<tr>
|
|
149
|
+
<th> GA </th>
|
|
150
|
+
<th> Value </th>
|
|
151
|
+
<th> DPT </th>
|
|
152
|
+
<th> Output Type </th>
|
|
153
|
+
<th> Caller Node (id) </th>
|
|
154
|
+
</tr>
|
|
155
|
+
</thead>
|
|
156
|
+
<tbody>`;
|
|
157
|
+
const sFooter = `</tbody><tfoot>
|
|
158
|
+
<tr>
|
|
159
|
+
<th scope="row">Count</th>
|
|
160
|
+
<td>` + aItems.length + `</td>
|
|
161
|
+
</tr>
|
|
162
|
+
</tfoot>
|
|
163
|
+
</table></div>`;
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
for (let index = 0; index < aItems.length; index++) {
|
|
167
|
+
const element = aItems[index];
|
|
168
|
+
sPayload += '<tr><td>' + element.grpaddr + '</td>';
|
|
169
|
+
if (typeof element.payload === 'boolean' && element.payload === true) {
|
|
170
|
+
sPayload += '<td><b><font color=green>True</font></b></td>';
|
|
171
|
+
} else if (typeof element.payload === 'boolean' && element.payload === false) {
|
|
172
|
+
sPayload += '<td><font color=red>False</font></td>';
|
|
173
|
+
} else if (typeof element.payload === 'object' && !isNaN(Date.parse(element.payload))) {
|
|
174
|
+
// The payload is a datetime
|
|
175
|
+
sPayload += '<td>' + element.payload.toLocaleString() + '</td>';
|
|
176
|
+
} else if (typeof element.payload === 'object') {
|
|
177
|
+
// Is maybe a JSON?
|
|
178
|
+
try {
|
|
179
|
+
// sPayload += '<td>' + JSON.stringify(element.payload) + '</td>'
|
|
180
|
+
sPayload += '<td><i>' + element.rawPayload + '</i></td>';
|
|
181
|
+
} catch (error) {
|
|
182
|
+
sPayload += '<td>' + element.payload + '</td>';
|
|
183
|
+
}
|
|
184
|
+
} else {
|
|
185
|
+
sPayload += '<td>' + element.payload + element.payloadmeasureunit + '</td>';
|
|
186
|
+
}
|
|
187
|
+
sPayload += '<td>' + element.dpt + '</td>';
|
|
188
|
+
sPayload += '<td>' + element.outputtype + '</td>';
|
|
189
|
+
sPayload += '<td><font style="font-size: smaller;">' + element.nodecallerid + '</font></td></tr>';
|
|
190
|
+
}
|
|
191
|
+
} catch (error) {
|
|
192
|
+
|
|
193
|
+
}
|
|
194
|
+
return { topic: node.name, payload: sHead + sPayload + sFooter };
|
|
119
195
|
};
|
|
120
196
|
|
|
197
|
+
// if (timerPIN3 !== null) clearInterval(timerPIN3);
|
|
198
|
+
// timerPIN3 = setInterval(() => {
|
|
199
|
+
// let PIN3 = node.createPayloadPIN3();
|
|
200
|
+
// node.send([null, null, PIN3]);
|
|
201
|
+
// }, 200);
|
|
202
|
+
|
|
121
203
|
node.on('input', function (msg) {
|
|
122
204
|
|
|
123
205
|
});
|
|
124
206
|
|
|
125
207
|
node.on('close', function (done) {
|
|
208
|
+
if (timerPIN3 !== null) clearInterval(timerPIN3);
|
|
126
209
|
if (node.server) {
|
|
127
210
|
node.server.removeClient(node);
|
|
128
211
|
}
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"Advancedoptions": "Advanced options",
|
|
37
37
|
"Formatting": "Format INPUT (datagram coming from the KNX BUS)",
|
|
38
38
|
"Operations": "NUMERIC VALUES (operations are performed in order)",
|
|
39
|
-
"OUTPUT": "
|
|
40
|
-
"INPUT": "
|
|
39
|
+
"OUTPUT": "SEND msg to KNX bus",
|
|
40
|
+
"INPUT": "RECEIVE msg from KNX BUS",
|
|
41
41
|
"NUMERICVALUES": "NUMERIC VALUES (operations are performed in order)",
|
|
42
42
|
"noETSWarning": "You haven't imported the ETS csv file. <br/> The node will work as blind transmitter/receiver. <a href=\"https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/2.-Node-Configuration\" target='_blank'>Click here for help about that</a>.",
|
|
43
43
|
"notify-DPT3007": "You selected a relative DIM. Please <a target='_blank' href='https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/-Sample---Dimming'>click here to view this sample</a> and learn how to handle such payload.",
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"engines": {
|
|
4
4
|
"node": ">=16.0.0"
|
|
5
5
|
},
|
|
6
|
-
"version": "3.0.0-
|
|
6
|
+
"version": "3.0.0-beta3",
|
|
7
7
|
"description": "Control your KNX intallation via Node-Red! A bunch of KNX nodes, with integrated Philips HUE control and ETS group address importer. Easy to use and highly configurable.",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"binary-parser": "2.2.1",
|