node-red-contrib-knx-ultimate 2.4.5-beta.0 → 2.4.5-beta.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.md CHANGED
@@ -6,6 +6,17 @@
6
6
 
7
7
  # CHANGELOG
8
8
 
9
+ **Version 2.4.5-beta.2 PUBLIC BETA** - Feb 2024<br/>
10
+ - Fix the listing of ethernet interfaces in the gateway config window.<br/>
11
+
12
+ **Version 2.4.5-beta.1 PUBLIC BETA** - Feb 2024<br/>
13
+ - WARNING: this version uses the Node-Red plugin system; the Node-Red version must be **equals or major than 3.1.1**<br/>
14
+ - HUE: Optimized color translation between xyBri and RGB.<br/>
15
+ - NEW: HUE Light node: added the HSV controls.<br/>
16
+ - HUE Light node: stopping the dim sequence, now clears also the HUE bridge queue commands, to allow stopping the dimmer quickly.<br/>
17
+ - HUE Light node: smoother dimming.<br/>
18
+ - PLEASE TRY THIS VERSION AND GIVE ME ANY FEEDBACK ABOUT ISSUES YOU FIND. THANKS.<br/>
19
+
9
20
  **Version 2.4.5-beta.0** - Jan 2024<br/>
10
21
  - WARNING: this version uses the Node-Red plugin system; the Node-Red version must be **equals or major than 3.1.1**<br/>
11
22
  - NEW: Added KNX Datapoint 275.100<br/>
@@ -7,7 +7,7 @@
7
7
  # CHANGELOG
8
8
 
9
9
  <p>
10
- <b>Version 1.0.46</b> - January 2024<br/>
10
+ <b>Version 1.0.47</b> - January 2024<br/>
11
11
  - NEW: added DPT 275.100.<br/>
12
12
  </p>
13
13
  <p>
@@ -161,16 +161,24 @@ knxUltimateClient.on(knx.KNXClient.KNXClientEvents.indication, function (_datagr
161
161
  let _dst = _datagram.cEMIMessage.dstAddress.toString()
162
162
  // Get the RAW Value
163
163
  let _Rawvalue = _datagram.cEMIMessage.npdu.dataValue;
164
-
164
+
165
165
  // Decode the telegram.
166
166
  if (_dst === "0/1/1") {
167
- // We know that 0/1/1 is a boolean DPT 1.001
167
+ // We know, for example, that 0/1/1 is a boolean DPT 1.001
168
168
  dpt = dptlib.resolve("1.001");
169
169
  jsValue = dptlib.fromBuffer(_Rawvalue, dpt)
170
170
  } else if (_dst === "0/1/2") {
171
- // We know that 0/1/2 is a boolean DPT 232.600 Color RGB
171
+ // We know , for example, that 0/1/2 is a DPT 232.600 Color RGB
172
172
  dpt = dptlib.resolve("232.600");
173
173
  jsValue = dptlib.fromBuffer(_Rawvalue, dpt)
174
+ } else {
175
+ // All others... assume they are boolean
176
+ dpt = dptlib.resolve("1.001");
177
+ jsValue = dptlib.fromBuffer(_Rawvalue, dpt)
178
+ if (jsValue === null) {
179
+ // Opppsss, it's null. It means that the datapoint isn't 1.001
180
+ // Raise whatever error you want.
181
+ }
174
182
  }
175
183
  console.log("src: " + _src + " dest: " + _dst, " event: " + _evt, " value: " + jsValue);
176
184
 
@@ -184,6 +192,10 @@ knxUltimateClient.on(knx.KNXClient.KNXClientEvents.connected, info => {
184
192
  });
185
193
 
186
194
  // Connect
195
+ try {
196
+ knxUltimateClient.removeAllListeners();
197
+ } catch (error) {
198
+ }
187
199
  knxUltimateClient.Connect();
188
200
  ```
189
201
 
@@ -280,8 +292,18 @@ let knxUltimateClientProperties = {
280
292
  KNXEthInterface: "Auto", // Bind to the first avaiable local interfavce. "Manual" if you wish to specify the interface (for example eth1); in this case, set the property interface to the interface name (interface:"eth1")
281
293
  };
282
294
 
295
+ var knxUltimateClient;
296
+
297
+ // If you're reinstantiating a new knxUltimateClient object, you must remove all listeners.
298
+ // If this is the first time you instantiate tne knxUltimateClient object, this part of code throws an error into the try...catch.
299
+ try {
300
+ if (knxUltimateClient !== null) knxUltimateClient.removeAllListeners();
301
+ } catch (error) {
302
+ // New connection, do nothing.
303
+ }
304
+
283
305
  // Let's go
284
- var knxUltimateClient = new knx.KNXClient(knxUltimateClientProperties);
306
+ knxUltimateClient = new knx.KNXClient(knxUltimateClientProperties);
285
307
 
286
308
  // Setting handlers
287
309
  // ######################################
@@ -368,6 +390,15 @@ function handleBusEvents(_datagram, _echoed) {
368
390
  // We know that 0/1/2 is a boolean DPT 232.600 Color RGB
369
391
  dpt = dptlib.resolve("232.600");
370
392
  jsValue = dptlib.fromBuffer(_Rawvalue, dpt)
393
+ } else {
394
+ // All others... assume they are boolean
395
+ dpt = dptlib.resolve("1.001");
396
+ jsValue = dptlib.fromBuffer(_Rawvalue, dpt)
397
+ if (jsValue === null) {
398
+ // Is null, try if it's a numerical value
399
+ dpt = dptlib.resolve("5.001");
400
+ jsValue = dptlib.fromBuffer(_Rawvalue, dpt)
401
+ }
371
402
  }
372
403
  console.log("src: " + _src + " dest: " + _dst, " event: " + _evt, " value: " + jsValue);
373
404
 
@@ -390,7 +421,6 @@ Loading, decrypting and validating Keyring file has been done.<br/>
390
421
  I'm working on the first secure handshake now.<br/>
391
422
 
392
423
  ```javascript
393
-
394
424
  const knx = require("./index.js");
395
425
  const KNXsecureKeyring = require("./src/KNXsecureKeyring.js");
396
426
  const dptlib = require('./src/dptlib');
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "knxultimate",
3
3
  "description": "KNX IP protocol implementation for Node. This is the ENGINE of Node-Red KNX-Ultimate node.",
4
- "version": "1.0.46",
4
+ "version": "1.0.47",
5
5
  "engines": {
6
6
  "node": ">=14"
7
7
  },
@@ -84,9 +84,18 @@ let knxUltimateClientProperties = {
84
84
  KNXEthInterface: "Auto", // Bind to the first avaiable local interfavce. "Manual" if you wish to specify the interface (for example eth1); in this case, set the property interface to the interface name (interface:"eth1")
85
85
  };
86
86
 
87
+ var knxUltimateClient;
88
+
89
+ // If you're reinstantiating a new knxUltimateClient object, you must remove all listeners.
90
+ // If this is the first time you instantiate tne knxUltimateClient object, this part of code throws an error into the try...catch.
91
+ try {
92
+ if (knxUltimateClient !== null) knxUltimateClient.removeAllListeners();
93
+ } catch (error) {
94
+ // New connection, do nothing.
95
+ }
87
96
 
88
97
  // Let's go
89
- var knxUltimateClient = new knx.KNXClient(knxUltimateClientProperties);
98
+ knxUltimateClient = new knx.KNXClient(knxUltimateClientProperties);
90
99
 
91
100
  // Setting handlers
92
101
  // ######################################
@@ -40,11 +40,11 @@ knxUltimateClient.on(knx.KNXClient.KNXClientEvents.indication, function (_datagr
40
40
 
41
41
  // Decode the telegram.
42
42
  if (_dst === "0/1/1") {
43
- // We know that 0/1/1 is a boolean DPT 1.001
43
+ // We know, for example, that 0/1/1 is a boolean DPT 1.001
44
44
  dpt = dptlib.resolve("1.001");
45
45
  jsValue = dptlib.fromBuffer(_Rawvalue, dpt)
46
46
  } else if (_dst === "0/1/2") {
47
- // We know that 0/1/2 is a boolean DPT 232.600 Color RGB
47
+ // We know , for example, that 0/1/2 is a DPT 232.600 Color RGB
48
48
  dpt = dptlib.resolve("232.600");
49
49
  jsValue = dptlib.fromBuffer(_Rawvalue, dpt)
50
50
  } else {
@@ -52,9 +52,8 @@ knxUltimateClient.on(knx.KNXClient.KNXClientEvents.indication, function (_datagr
52
52
  dpt = dptlib.resolve("1.001");
53
53
  jsValue = dptlib.fromBuffer(_Rawvalue, dpt)
54
54
  if (jsValue === null) {
55
- // Is null, try if it's a numerical value
56
- dpt = dptlib.resolve("5.001");
57
- jsValue = dptlib.fromBuffer(_Rawvalue, dpt)
55
+ // Opppsss, it's null. It means that the datapoint isn't 1.001
56
+ // Raise whatever error you want.
58
57
  }
59
58
  }
60
59
  console.log("src: " + _src + " dest: " + _dst, " event: " + _evt, " value: " + jsValue);
@@ -69,5 +68,9 @@ knxUltimateClient.on(knx.KNXClient.KNXClientEvents.connected, info => {
69
68
  });
70
69
 
71
70
  // Connect
71
+ try {
72
+ knxUltimateClient.removeAllListeners();
73
+ } catch (error) {
74
+ }
72
75
  knxUltimateClient.Connect();
73
76
 
@@ -53,7 +53,7 @@ module.exports = (RED) => {
53
53
  type: "foo",
54
54
  onadd: function () {
55
55
  RED.events.on("registry:plugin-added", function (id) {
56
- console.log(`my-test-plugin: plugin-added event "${id}"`)
56
+ //console.log(`my-test-plugin: plugin-added event "${id}"`)
57
57
  commonFunctions();
58
58
  });
59
59
  }
@@ -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,55 +1,13 @@
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 */
4
5
  /* eslint-disable no-inner-declarations */
5
6
  /* eslint-disable max-len */
6
- const dptlib = require("../KNXEngine/src/dptlib");
7
+ const cloneDeep = require("lodash/cloneDeep");
7
8
  const HueClass = require("./utils/hueEngine").classHUE;
8
9
  const loggerEngine = require("./utils/sysLogger");
9
- const hueColorConverter = require("./utils/hueColorConverter");
10
- const cloneDeep = require("lodash/cloneDeep");
11
-
12
- function getRandomIntInclusive(min, max) {
13
- min = Math.ceil(min);
14
- max = Math.floor(max);
15
- return Math.floor(Math.random() * (max - min + 1) + min); // The maximum is inclusive and the minimum is inclusive
16
- }
17
-
18
- // Helpers
19
- const sortBy = (field) => (a, b) => {
20
- if (a[field] > b[field]) {
21
- return 1;
22
- }
23
- return -1;
24
- };
25
-
26
- const onlyDptKeys = (kv) => kv[0].startsWith("DPT");
27
-
28
- const extractBaseNo = (kv) => ({
29
- subtypes: kv[1].subtypes,
30
- base: parseInt(kv[1].id.replace("DPT", "")),
31
- });
32
-
33
- const convertSubtype = (baseType) => (kv) => {
34
- const value = `${baseType.base}.${kv[0]}`;
35
- // let sRet = value + " " + kv[1].name + (kv[1].unit === undefined ? "" : " (" + kv[1].unit + ")");
36
- const sRet = `${value} ${kv[1].name}`;
37
- return {
38
- value,
39
- text: sRet,
40
- };
41
- };
42
-
43
- const toConcattedSubtypes = (acc, baseType) => {
44
- const subtypes = Object.entries(baseType.subtypes).sort(sortBy(0)).map(convertSubtype(baseType));
45
- return acc.concat(subtypes);
46
- };
47
-
48
- function getRandomInt(min, max) {
49
- min = Math.ceil(min);
50
- max = Math.floor(max);
51
- return Math.floor(Math.random() * (max - min) + min); // The maximum is exclusive and the minimum is inclusive
52
- }
10
+ const hueColorConverter = require("./utils/colorManipulators/hueColorConverter");
53
11
 
54
12
  module.exports = (RED) => {
55
13
  function hueConfig(config) {
@@ -69,33 +27,20 @@ module.exports = (RED) => {
69
27
  }
70
28
  node.name = config.name === undefined || config.name === "" ? node.host : config.name;
71
29
 
72
- // Call the connect function of all hue-config nodes.
73
- // function callinitHUEConnectionOfAllHUEServers() {
74
- // RED.nodes.eachNode((_node) => {
75
- // if (_node.type === 'hue-config') {
76
- // try {
77
- // RED.nodes.getNode(_node.id).initHUEConnection();
78
- // } catch (error) {
79
- // if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error("callinitHUEConnectionOfAllHUEServers: Node " + _node.name + " " + error.message);
80
- // }
81
- // }
82
- // });
83
- // }
84
-
85
30
  // Connect to Bridge and get the resources
86
31
  node.initHUEConnection = async () => {
87
32
  try {
88
33
  if (node.hueManager !== undefined) node.hueManager.close();
89
- } catch (error) { }
34
+ } catch (error) { /* empty */ }
90
35
  try {
91
36
  if (node.hueManager !== undefined) node.hueManager.removeAllListeners();
92
- } catch (error) { }
37
+ } catch (error) { /* empty */ }
93
38
  // Handle events
94
39
  try {
95
40
  try {
96
41
  // Init HUE Utility
97
42
  node.hueManager = new HueClass(node.host, node.credentials.username, node.credentials.clientkey, config.bridgeid, node.sysLogger);
98
- } catch (error) { }
43
+ } catch (error) { /* empty */ }
99
44
  node.hueManager.Connect();
100
45
  } catch (error) {
101
46
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`Errore hue-config: node.initHUEConnection: ${error.message}`);
@@ -176,26 +121,15 @@ module.exports = (RED) => {
176
121
  // °°°°°° Load ALL resources
177
122
  try {
178
123
  node.hueAllResources = await node.hueManager.hueApiV2.get("/resource");
179
-
180
- // // DEBUG
181
- // try {
182
- // const fs = require('fs');
183
- // const { resolve } = require('path');
184
- // const content = JSON.stringify(node.hueAllResources);
185
- // try {
186
- // fs.writeFileSync('resources.json', content);
187
- // RED.log.info("******************************* FILE WROTE IN resources.json " + resolve("resources.json"))
188
- // // file written successfully
189
- // } catch (error) {
190
- // RED.log.error("********************************************* const content = JSON.stringify(node.hueAllResources)2222: " + error.message)
191
- // }
192
- // } catch (error) {
193
- // RED.log.error("********************************************* const content = JSON.stringify(node.hueAllResources): " + error.message)
194
- // }
195
-
196
-
197
124
  if (node.hueAllResources !== undefined) {
198
125
  node.hueAllRooms = node.hueAllResources.filter((a) => a.type === "room");
126
+
127
+ // Get zigbee_connectivituy
128
+ // const bridgeId = node.hueAllResources.filter((a) => a.bridge_id === config.bridgeid).owner.rid;
129
+ // const zigbee_ConnectivityID = node.hueAllResources.filter((a) => a.id === bridgeId).services.filter((a) => a.rtype === "zigbee_connectivity").rid;
130
+ // // connected, disconnected, connectivity_issue, unidirectional_incoming
131
+ // const oZigbeeConnectivityStatus = node.hueAllResources.filter((a) => a.id === zigbee_ConnectivityID).status;
132
+
199
133
  // Update all KNX State of the nodes with the new hue device values
200
134
  node.nodeClients.forEach((_node) => {
201
135
  if (_node.hueDevice !== undefined && node.hueAllResources !== undefined) {