node-red-contrib-knx-ultimate 2.4.5-beta.1 → 2.4.5-beta.3

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,13 @@
6
6
 
7
7
  # CHANGELOG
8
8
 
9
+ **Version 2.4.5-beta.3 PUBLIC BETA** - Feb 2024<br/>
10
+ - HUE: Fixed "read at startup" option, not working for some HUE nodes.<br/>
11
+ - NEW: HUE: added node Zigbee Connectivity.<br/>
12
+
13
+ **Version 2.4.5-beta.2 PUBLIC BETA** - Feb 2024<br/>
14
+ - Fix the listing of ethernet interfaces in the gateway config window.<br/>
15
+
9
16
  **Version 2.4.5-beta.1 PUBLIC BETA** - Feb 2024<br/>
10
17
  - WARNING: this version uses the Node-Red plugin system; the Node-Red version must be **equals or major than 3.1.1**<br/>
11
18
  - HUE: Optimized color translation between xyBri and RGB.<br/>
@@ -237,9 +237,9 @@ module.exports = (RED) => {
237
237
 
238
238
  // 14/08/2019 Endpoint for retrieving the ethernet interfaces
239
239
  RED.httpAdmin.get("/knxUltimateETHInterfaces", (req, res) => {
240
+ const jListInterfaces = [];
240
241
  try {
241
242
  const oiFaces = oOS.networkInterfaces();
242
- const jListInterfaces = [];
243
243
  Object.keys(oiFaces).forEach((ifname) => {
244
244
  // Interface with single IP
245
245
  if (Object.keys(oiFaces[ifname]).length === 1) {
@@ -1,3 +1,4 @@
1
+ /* eslint-disable camelcase */
1
2
  /* eslint-disable no-underscore-dangle */
2
3
  /* eslint-disable no-lonely-if */
3
4
  /* eslint-disable no-param-reassign */
@@ -120,24 +121,6 @@ module.exports = (RED) => {
120
121
  // °°°°°° Load ALL resources
121
122
  try {
122
123
  node.hueAllResources = await node.hueManager.hueApiV2.get("/resource");
123
-
124
- // // DEBUG
125
- // try {
126
- // const fs = require('fs');
127
- // const { resolve } = require('path');
128
- // const content = JSON.stringify(node.hueAllResources);
129
- // try {
130
- // fs.writeFileSync('resources.json', content);
131
- // RED.log.info("******************************* FILE WROTE IN resources.json " + resolve("resources.json"))
132
- // // file written successfully
133
- // } catch (error) {
134
- // RED.log.error("********************************************* const content = JSON.stringify(node.hueAllResources)2222: " + error.message)
135
- // }
136
- // } catch (error) {
137
- // RED.log.error("********************************************* const content = JSON.stringify(node.hueAllResources): " + error.message)
138
- // }
139
-
140
-
141
124
  if (node.hueAllResources !== undefined) {
142
125
  node.hueAllRooms = node.hueAllResources.filter((a) => a.type === "room");
143
126
  // Update all KNX State of the nodes with the new hue device values
@@ -149,10 +132,12 @@ module.exports = (RED) => {
149
132
  _node.setNodeStatusHue({
150
133
  fill: "green",
151
134
  shape: "ring",
152
- text: "Ready :-)",
135
+ text: "Ready",
153
136
  });
154
137
  _node.currentHUEDevice = cloneDeep(oHUEDevice); // Copy by Value and not by ref
155
- if (_node.initializingAtStart === true) _node.handleSendHUE(oHUEDevice); // Pass by value
138
+ if (_node.initializingAtStart === true) {
139
+ _node.handleSendHUE(oHUEDevice); // Pass by value
140
+ }
156
141
  }
157
142
  }
158
143
  });
@@ -317,6 +302,21 @@ module.exports = (RED) => {
317
302
  id: resource.id,
318
303
  });
319
304
  }
305
+ if (_rtype === "zigbee_connectivity") {
306
+ const Room = node.hueAllRooms.find((room) => room.children.find((child) => child.rid === resource.owner.rid));
307
+ const linkedDevName = node.hueAllResources.find((dev) => dev.type === "device" && dev.services.find((serv) => serv.rid === resource.id)).metadata.name || "";
308
+ retArray.push({
309
+ name: `Zigbee Connectivity: ${linkedDevName}${Room !== undefined ? `, room ${Room.metadata.name}` : ""}`,
310
+ id: resource.id,
311
+ });
312
+ // Get zigbee_connectivituy
313
+ // const bridgeId = node.hueAllResources.filter((a) => a.bridge_id === config.bridgeid).owner.rid;
314
+ // const zigbee_ConnectivityID = node.hueAllResources.filter((a) => a.id === bridgeId).services.filter((a) => a.rtype === "zigbee_connectivity").rid;
315
+ // // connected, disconnected, connectivity_issue, unidirectional_incoming
316
+ // const oZigbeeConnectivityStatus = node.hueAllResources.filter((a) => a.id === zigbee_ConnectivityID).status;
317
+ //const zigbee = node.hueAllResources.filter((a) => a.services !== undefined).find((a) => a.services.rtype === "zigbee_connectivity");
318
+ //const devs = zigbee.filter((a) => a.rtype === "zigbee_connectivity");
319
+ }
320
320
  } catch (error) {
321
321
  retArray.push({
322
322
  name: `${_rtype}: ERROR ${error.message}`,
@@ -23,7 +23,7 @@ module.exports = function (RED) {
23
23
  node.formatnegativevalue = 'leave';
24
24
  node.formatdecimalsvalue = 2;
25
25
  node.hueDevice = config.hueDevice;
26
- node.initializingAtStart = !((config.readStatusAtStartup === undefined || config.readStatusAtStartup === "yes"));
26
+ node.initializingAtStart = (config.readStatusAtStartup === undefined || config.readStatusAtStartup === "yes");
27
27
  node.currentDeviceValue = 0;
28
28
 
29
29
  // Used to call the status update from the config node.
@@ -1498,7 +1498,8 @@ Start typing in the GA field, the name or group address of your KNX device, the
1498
1498
  | Status H %| Status of the HSV chromatic circle.|
1499
1499
  | Control S dim | Changes the light's color saturation, using DPT 3.007 dimming. You can set the dimming speed in the **_Behaviour_** tab.|
1500
1500
  | Status S %| The light color saturation status group address.|
1501
- | Dim Speed (ms) | The dimming speed, in Milliseconds, from bottom to top scale. |
1501
+ | Dim Speed (ms) | The dimming speed, in Milliseconds, from bottom to top scale. |
1502
+
1502
1503
  For controlling the "V" (brightness) of the HSV, please use the standard controls of the **DIM** tab.
1503
1504
 
1504
1505
 
@@ -23,7 +23,7 @@ module.exports = function (RED) {
23
23
  node.formatnegativevalue = 'leave';
24
24
  node.formatdecimalsvalue = 2;
25
25
  node.hueDevice = config.hueDevice;
26
- node.initializingAtStart = !((config.readStatusAtStartup === undefined || config.readStatusAtStartup === "yes"));
26
+ node.initializingAtStart = (config.readStatusAtStartup === undefined || config.readStatusAtStartup === "yes");
27
27
  node.currentDeviceValue = 0;
28
28
 
29
29
  // Used to call the status update from the config node.
@@ -42,7 +42,7 @@
42
42
  if (Number(this.selectedModeTabNumber) === 0) return this.name;
43
43
  if (Number(this.selectedModeTabNumber) === 1) return this.namesceneMulti;
44
44
  },
45
- paletteLabel: "Hue Scene (Beta)",
45
+ paletteLabel: "Hue Scene",
46
46
  // button: {
47
47
  // enabled: function() {
48
48
  // // return whether or not the button is enabled, based on the current
@@ -23,7 +23,7 @@ module.exports = function (RED) {
23
23
  node.formatnegativevalue = 'leave';
24
24
  node.formatdecimalsvalue = 2;
25
25
  node.hueDevice = config.hueDevice;
26
- node.initializingAtStart = !((config.readStatusAtStartup === undefined || config.readStatusAtStartup === "yes"));
26
+ node.initializingAtStart = (config.readStatusAtStartup === undefined || config.readStatusAtStartup === "yes");
27
27
  node.currentDeviceValue = 0;
28
28
 
29
29
  // Used to call the status update from the config node.
@@ -0,0 +1,267 @@
1
+ <script type="text/javascript" src="resources/node-red-contrib-knx-ultimate/11f26b4500.js"></script>
2
+
3
+ <script type="text/javascript">
4
+ RED.nodes.registerType('knxUltimateHueZigbeeConnectivity', {
5
+ category: "KNX Ultimate",
6
+ color: '#C0C7E9',
7
+ defaults: {
8
+ //buttonState: {value: true},
9
+ server: { type: "knxUltimate-config", required: false },
10
+ serverHue: { type: "hue-config", required: true },
11
+ name: { value: "" },
12
+
13
+ namezigbeeconnectivity: { value: "" },
14
+ GAzigbeeconnectivity: { value: "" },
15
+ dptzigbeeconnectivity: { value: "" },
16
+ readStatusAtStartup: { value: "yes" },
17
+
18
+
19
+ hueDevice: { value: "" }
20
+ },
21
+ inputs: 0,
22
+ outputs: 1,
23
+ icon: "node-hue-icon.svg",
24
+ label: function () {
25
+ return (this.name);
26
+ },
27
+ paletteLabel: "Hue Zigbee Connectivity",
28
+ // button: {
29
+ // enabled: function() {
30
+ // // return whether or not the button is enabled, based on the current
31
+ // // configuration of the node
32
+ // return !this.changed
33
+ // },
34
+ // visible: function() {
35
+ // // return whether or not the button is visible, based on the current
36
+ // // configuration of the node
37
+ // return this.hasButton
38
+ // },
39
+ // //toggle: "buttonState",
40
+ // onclick: function() {}
41
+ // },
42
+ oneditprepare: function () {
43
+ var node = this;
44
+ var oNodeServer = RED.nodes.node($("#node-input-server").val()); // Store the config-node
45
+ var oNodeServerHue = RED.nodes.node($("#node-input-serverHue").val()); // Store the config-node
46
+
47
+ // 19/02/2020 Used to get the server sooner als deploy.
48
+ $("#node-input-server").change(function () {
49
+ try {
50
+ oNodeServer = RED.nodes.node($(this).val());
51
+ } catch (error) { }
52
+ });
53
+ // 19/02/2020 Used to get the server sooner als deploy.
54
+ $("#node-input-serverHue").change(function () {
55
+ try {
56
+ oNodeServerHue = RED.nodes.node($(this).val());
57
+ } catch (error) { }
58
+ });
59
+
60
+ // 31/03/2020 Search Helper
61
+ function fullSearch(sourceText, searchString) {
62
+ // This searches for all words in a string
63
+ var aSearchWords = searchString.toLowerCase().split(" ");
64
+ var i = 0;
65
+ for (let index = 0; index < aSearchWords.length; index++) {
66
+ if (sourceText.toLowerCase().indexOf(aSearchWords[index]) > -1) i += 1;
67
+ }
68
+ return i == aSearchWords.length;
69
+ }
70
+
71
+ // DPT
72
+ // ########################
73
+ $.getJSON('knxUltimateDpts?serverId=' + $("#node-input-server").val(), (data) => {
74
+ data.forEach(dpt => {
75
+ if (dpt.value.startsWith("1.")) {
76
+ $("#node-input-dptzigbeeconnectivity").append($("<option></option>")
77
+ .attr("value", dpt.value)
78
+ .text(dpt.text))
79
+ }
80
+ });
81
+ $("#node-input-dptzigbeeconnectivity").val(this.dptzigbeeconnectivity)
82
+ })
83
+
84
+ // Autocomplete suggestion with ETS csv File
85
+ $("#node-input-GAzigbeeconnectivity").autocomplete({
86
+ minLength: 1,
87
+ source: function (request, response) {
88
+ //$.getJSON("csv", request, function( data, status, xhr ) {
89
+ $.getJSON("knxUltimatecsv?nodeID=" + oNodeServer.id, (data) => {
90
+ response($.map(data, function (value, key) {
91
+ var sSearch = (value.ga + " (" + value.devicename + ") DPT" + value.dpt);
92
+ if (fullSearch(sSearch, request.term + " 1.")) {
93
+ return {
94
+ label: value.ga + " # " + value.devicename + " # " + value.dpt, // Label for Display
95
+ value: value.ga // Value
96
+ }
97
+ } else {
98
+ return null;
99
+ }
100
+ }));
101
+ });
102
+ }, select: function (event, ui) {
103
+ // Sets Datapoint and device name automatically
104
+ var sDevName = ui.item.label.split("#")[1].trim();
105
+ try {
106
+ sDevName = sDevName.substr(sDevName.indexOf(")") + 1).trim();
107
+ } catch (error) {
108
+ }
109
+ $('#node-input-namezigbeeconnectivity').val(sDevName);
110
+ var optVal = $("#node-input-dptzigbeeconnectivity option:contains('" + ui.item.label.split("#")[2].trim() + "')").attr('value');
111
+ // Select the option value
112
+ $("#node-input-dptzigbeeconnectivity").val(optVal);
113
+ }
114
+ });
115
+ // ########################
116
+
117
+
118
+
119
+
120
+ // Autocomplete suggestion with HUE
121
+ $("#node-input-name").autocomplete({
122
+ minLength: 1,
123
+ source: function (request, response) {
124
+ $.getJSON("KNXUltimateGetResourcesHUE?rtype=zigbee_connectivity&serverId=" + oNodeServerHue.id, (data) => {
125
+ response($.map(data.devices, function (value, key) {
126
+ //alert(JSON.stringify(value) + " "+ key)
127
+ var sSearch = (value.name);
128
+ if (fullSearch(sSearch, request.term)) {
129
+ return {
130
+ hueDevice: value.id, // Label for Display
131
+ value: value.name // Value
132
+ }
133
+ } else {
134
+ return null;
135
+ }
136
+ }));
137
+ });
138
+ }, select: function (event, ui) {
139
+ // Sets the fields
140
+ $('#node-input-hueDevice').val(ui.item.hueDevice);
141
+ }
142
+ });
143
+
144
+
145
+ // ########################
146
+
147
+
148
+ },
149
+ oneditsave: function () {
150
+
151
+
152
+ },
153
+ oneditcancel: function () {
154
+
155
+ }
156
+ })
157
+
158
+ </script>
159
+
160
+ <script type="text/html" data-template-name="knxUltimateHueZigbeeConnectivity">
161
+
162
+
163
+ <div class="form-row">
164
+ <b>HUE Zigbee Connectivity node</b>&nbsp&nbsp<span style="color:red"
165
+ &nbsp
166
+ &nbsp<i class="fa fa-youtube"></i></span>&nbsp<a target="_blank" href="https://youtu.be/jjEUI1J8bkA"><u>Youtube sample</u></a>
167
+ <br />
168
+ <br />
169
+ <p align="center">
170
+ <i class="fa-solid fa-tower-broadcast fa-beat fa-4x"></i>
171
+ </p>
172
+ <br />
173
+ <label for="node-input-server" >
174
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAKnRFWHRDcmVhdGlvbiBUaW1lAEZyIDYgQXVnIDIwMTAgMjE6NTI6MTkgKzAxMDD84aS8AAAAB3RJTUUH3gYYCicNV+4WIQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAARnQU1BAACxjwv8YQUAAACUSURBVHjaY2CgFZg5c+Z/ZEyWAZ8+f/6/ZsWs/xoamqMGkGrA6Wla/1+fVARjEBuGsSoGmY4eZSCNL59d/g8DIDbIAHR14OgFGQByKjIGKX5+6/T///8gGMQGiV1+/B0Fg70GIkD+RMYgxf/O5/7//2MSmAZhkBi6OrgB6Bg5DGB4ajr3f2xqsYYLSDE2THJUDg0AAAqyDVd4tp4YAAAAAElFTkSuQmCC"></img>
175
+ KNX GW
176
+ </label>
177
+ <input type="text" id="node-input-server" />
178
+ </div>
179
+
180
+ <div class="form-row">
181
+ <label for="node-input-serverHue">
182
+ <img src="data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAEKADAAQAAAABAAAAEAAAAAA0VXHyAAABFUlEQVQ4EZWSsWoCQRCG1yiENEFEi6QSkjqWWoqFoBYJ+Br6JHkMn8Iibd4ihQpaJIhWNkry/ZtdGZY78Qa+m39nZ+dm9s4550awglNBluS/gVtAX6KgDclf68w2OThgfR9iT/jnoEv4TtByDThWTCDKW4SSZTf/zj9/eZbN+izTDuKGimu0vPF8B/YN8aC8LmcOj/AAn9CFTEs70Js/oGqy79C69bqJ5XbQI2kGO5N8QL9D08S8zBtBF5ZaVsznpCMoqJnVdjTpb1Db0fwIWmQV6BLXzFOYgA6/gDVfQN9bBWp2J2hdWDPoBV5FrKnAJutHikk/CHHR8i7x4iG7qQ720IYvu3GFbpHjx3pFrOFYkA354z/5bkK826phyAAAAABJRU5ErkJggg=="/>
183
+ HUE Bridge
184
+ </label>
185
+ <input type="text" id="node-input-serverHue" />
186
+ </div>
187
+
188
+ <br/>
189
+ <p>
190
+ <b>Philips HUE</b>
191
+ </p>
192
+
193
+ <div class="form-row">
194
+ <label for="node-input-hueDevice" >
195
+ <i class="fa fa-play-circle"></i>&nbspHue Sensor</label>
196
+ <input type="text" id="node-input-name" placeholder="Enter your hue device name" />
197
+ <input type="hidden" id="node-input-hueDevice" />
198
+ </div>
199
+
200
+ <br/>
201
+
202
+ <p>
203
+ <b>KNX</b>
204
+ </p>
205
+
206
+ <div class="form-row">
207
+ <label for="node-input-namezigbeeconnectivity" style="width:100px;"><i class="fa fa-play-circle-o"></i> Status</span></label>
208
+
209
+ <label for="node-input-GAzigbeeconnectivity" style="width:20px;">GA</label>
210
+ <input type="text" id="node-input-GAzigbeeconnectivity" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
211
+
212
+ <label for="node-input-dptzigbeeconnectivity" style="width:40px; margin-left: 0px; text-align: right;">DPT</label>
213
+ <select id="node-input-dptzigbeeconnectivity" style="width:140px;"></select>
214
+
215
+ <label for="node-input-namezigbeeconnectivity" style="width:50px; margin-left: 0px; text-align: right;">Name</label>
216
+ <input type="text" id="node-input-namezigbeeconnectivity" style="width:200px;margin-left: 5px; text-align: left;">
217
+ </div>
218
+
219
+ <div class="form-row">
220
+ <label style="width:180px" for="node-input-readStatusAtStartup"><i class="fa fa-play-circle"></i> Read status at startup</label>
221
+ <select id="node-input-readStatusAtStartup">
222
+ <option value="no">No</option>
223
+ <option value="yes">Yes, and emit KNX telegrams.</option>
224
+ </select>
225
+ </div>
226
+ <br/>
227
+ <br/>
228
+ <br/>
229
+
230
+
231
+ </script>
232
+
233
+ <script type="text/markdown" data-help-name="knxUltimateHueZigbeeConnectivity">
234
+ This node lets you get the zigbee connectivity status from your HUE device.
235
+
236
+ Start typing the name or group address of your KNX device in the GA field, the avaiable devices start showing up while
237
+ you're typing.
238
+
239
+ **General**
240
+ |Property|Description|
241
+ |--|--|
242
+ | KNX GW | Select the KNX gateway to be used |
243
+ | HUE Bridge | Select the HUE Bridge to be used |
244
+ | Hue Sensor | HUE sensor to be used. The avaiable devices start showing up while you're typing.|
245
+
246
+ |Property|Description|
247
+ |--|--|
248
+ | Status | The zigbee connectivity status KNX group address. The status of this KNX group address, will change in *true* if connected, otherwise *false* |
249
+ | Read status at startup | Read the status at startup and emit the event to the KNX bus at startup/reconnection. (Default "yes")|
250
+
251
+ ### Outputs
252
+
253
+ 1. Standard output
254
+ : payload (boolean) : the standard output of the command.
255
+
256
+ ### Details
257
+
258
+ `msg.payload` is used as the payload of the published message (trus/false).
259
+ `msg.status` contains the text representing the status. It can be: **connected, disconnected, connectivity_issue, unidirectional_incoming**.
260
+
261
+ <br />
262
+
263
+ [Find it useful?](https://www.paypal.me/techtoday)
264
+
265
+ <br />
266
+
267
+ </script>
@@ -0,0 +1,134 @@
1
+ module.exports = function (RED) {
2
+ function knxUltimateHueZigbeeConnectivity(config) {
3
+ RED.nodes.createNode(this, config);
4
+ const node = this;
5
+ node.server = RED.nodes.getNode(config.server);
6
+ node.serverHue = RED.nodes.getNode(config.serverHue);
7
+ node.topic = node.name;
8
+ node.name = config.name === undefined ? 'Hue' : config.name;
9
+ node.dpt = '';
10
+ node.notifyreadrequest = true;
11
+ node.notifyreadrequestalsorespondtobus = 'false';
12
+ node.notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized = '';
13
+ node.notifyresponse = false;
14
+ node.notifywrite = true;
15
+ node.initialread = true;
16
+ node.listenallga = true; // Don't remove
17
+ node.outputtype = 'write';
18
+ node.outputRBE = false; // Apply or not RBE to the output (Messages coming from flow)
19
+ node.inputRBE = false; // Apply or not RBE to the input (Messages coming from BUS)
20
+ node.currentPayload = ''; // Current value for the RBE input and for the .previouspayload msg
21
+ node.passthrough = 'no';
22
+ node.formatmultiplyvalue = 1;
23
+ node.formatnegativevalue = 'leave';
24
+ node.formatdecimalsvalue = 2;
25
+ node.hueDevice = config.hueDevice;
26
+ node.initializingAtStart = (config.readStatusAtStartup === undefined || config.readStatusAtStartup === "yes");
27
+ node.currentDeviceValue = 0;
28
+
29
+ // Used to call the status update from the config node.
30
+ node.setNodeStatus = ({
31
+ fill, shape, text, payload,
32
+ }) => {
33
+
34
+ };
35
+ // Used to call the status update from the HUE config node.
36
+ node.setNodeStatusHue = ({
37
+ fill, shape, text, payload,
38
+ }) => {
39
+ if (payload === undefined) payload = '';
40
+ const dDate = new Date();
41
+ payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString();
42
+ node.status({ fill, shape, text: `${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})` });
43
+ };
44
+
45
+ // This function is called by the knx-ultimate config node, to output a msg.payload.
46
+ node.handleSend = (msg) => {
47
+ // Respond to KNX read telegram, by sending the current value as response telegram.
48
+ if (msg.knx.event === "GroupValue_Read") {
49
+ switch (msg.knx.destination) {
50
+ case config.GAzigbeeconnectivity:
51
+ // To the KNX bus wires
52
+ node.sendResponseToKNX(node.currentDeviceValue);
53
+ break;
54
+ default:
55
+ break;
56
+ }
57
+ }
58
+ };
59
+
60
+ node.handleSendHUE = (_event) => {
61
+ try {
62
+ // Event status: one of connected, disconnected, connectivity_issue, unidirectional_incoming
63
+ if (_event.id === config.hueDevice) {
64
+ if (!_event.hasOwnProperty("status") || _event.status === undefined) return;
65
+
66
+ const knxMsgPayload = {};
67
+ knxMsgPayload.topic = config.GAzigbeeconnectivity;
68
+ knxMsgPayload.dpt = config.dptzigbeeconnectivity;
69
+
70
+ knxMsgPayload.payload = (_event.status === "connected");
71
+ // Send to KNX bus
72
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
73
+ node.server.writeQueueAdd({
74
+ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id,
75
+ });
76
+ }
77
+ node.currentDeviceValue = knxMsgPayload.payload;
78
+ // Setup the output msg
79
+ knxMsgPayload.name = node.name;
80
+ knxMsgPayload.status = _event.status;
81
+ knxMsgPayload.event = 'zigbee_connectivity';
82
+ // Send payload
83
+ knxMsgPayload.rawEvent = _event;
84
+ node.send(knxMsgPayload);
85
+ node.setNodeStatusHue({
86
+ fill: 'blue', shape: 'ring', text: 'HUE->KNX', payload: knxMsgPayload.payload,
87
+ });
88
+ }
89
+ } catch (error) {
90
+ node.status({ fill: 'red', shape: 'dot', text: `HUE->KNX error ${error.message} (${new Date().getDate()}, ${new Date().toLocaleTimeString()})` });
91
+ }
92
+ };
93
+
94
+
95
+ node.sendResponseToKNX = (_level) => {
96
+ const knxMsgPayload = {};
97
+ knxMsgPayload.topic = config.GAzigbeeconnectivity;
98
+ knxMsgPayload.dpt = config.dptzigbeeconnectivity;
99
+
100
+ knxMsgPayload.payload = _level;
101
+ // Send to KNX bus
102
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
103
+ node.server.writeQueueAdd({
104
+ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'response', nodecallerid: node.id,
105
+ });
106
+ }
107
+ };
108
+
109
+ // On each deploy, unsubscribe+resubscribe
110
+ if (node.server) {
111
+ node.server.removeClient(node);
112
+ node.server.addClient(node);
113
+ }
114
+ if (node.serverHue) {
115
+ node.serverHue.removeClient(node);
116
+ node.serverHue.addClient(node);
117
+ }
118
+
119
+ node.on('input', (msg) => {
120
+
121
+ });
122
+
123
+ node.on('close', (done) => {
124
+ if (node.server) {
125
+ node.server.removeClient(node);
126
+ }
127
+ if (node.serverHue) {
128
+ node.serverHue.removeClient(node);
129
+ }
130
+ done();
131
+ });
132
+ }
133
+ RED.nodes.registerType('knxUltimateHueZigbeeConnectivity', knxUltimateHueZigbeeConnectivity);
134
+ };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "engines": {
4
4
  "node": ">=16.0.0"
5
5
  },
6
- "version": "2.4.5-beta.1",
6
+ "version": "2.4.5-beta.3",
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",
@@ -43,7 +43,8 @@
43
43
  "knxUltimateHueLightSensor": "/nodes/knxUltimateHueLightSensor.js",
44
44
  "knxUltimateHueTemperatureSensor": "/nodes/knxUltimateHueTemperatureSensor.js",
45
45
  "knxUltimateHueScene": "/nodes/knxUltimateHueScene.js",
46
- "knxUltimateHueBattery": "/nodes/knxUltimateHueBattery.js"
46
+ "knxUltimateHueBattery": "/nodes/knxUltimateHueBattery.js",
47
+ "knxUltimateHueZigbeeConnectivity": "/nodes/knxUltimateHueZigbeeConnectivity.js"
47
48
  }
48
49
  },
49
50
  "repository": {