node-red-contrib-knx-ultimate 3.3.17 → 3.3.19

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,14 @@
6
6
 
7
7
  # CHANGELOG
8
8
 
9
+ **Version 3.3.19** - March 2025<br/>
10
+ - HUE light nodes now have the colored status icon that follows the light status on/off. Blue fill dot is ON, blue ring is OFF<br/>
11
+
12
+ **Version 3.3.18** - March 2025<br/>
13
+ - For all HUE nodes, added both the HUE and KNX status in the node's status text.<br/>
14
+ - HUE engine: fixed a reconnection issue occurring sometimes, in some circumstances.<br/>
15
+ - KNX engine: speed up the connection, from 30 to 10 seconds.<br/>
16
+
9
17
  **Version 3.3.16** - February 2025<br/>
10
18
  - HUE config node: moved the connect directive after events declarations.<br/>
11
19
  - HUE engine: optimized the disconnection detection procedure.<br/>
@@ -76,15 +76,18 @@ module.exports = (RED) => {
76
76
  const serverId = RED.nodes.getNode(req.query.serverId); // Retrieve node.id of the config node.
77
77
  if (serverId.hueAllResources === null || serverId.hueAllResources === undefined) {
78
78
  (async function main() {
79
- await serverId.loadResourcesFromHUEBridge();
79
+ try {
80
+ await serverId.loadResourcesFromHUEBridge();
81
+ } catch (error) {
82
+ RED.log.error(`Errore RED.httpAdmin.get('/knxultimateCheckHueConnected' ${error.stack}`);
83
+ }
80
84
  res.json({ ready: false });
81
85
  }()).catch();
82
86
  } else {
83
87
  res.json({ ready: true });
84
88
  }
85
89
  } catch (error) {
86
- RED.log.error(`Errore RED.httpAdmin.get('/knxultimateCheckHueConnected' ${error.message}`);
87
-
90
+ RED.log.error(`Errore RED.httpAdmin.get('/knxultimateCheckHueConnected' ${error.stack}`);
88
91
  res.json({ ready: false });
89
92
  }
90
93
  });
@@ -28,12 +28,19 @@ module.exports = (RED) => {
28
28
  node.sysLogger = null;
29
29
  node.hueAllResources = undefined;
30
30
  node.timerHUEConfigCheckState = null; // Timer that check the connection to the hue bridge every xx seconds
31
- node.linkStatus = "disconnected";
32
31
  try {
33
32
  node.sysLogger = loggerSetup({ loglevel: node.loglevel, setPrefix: "hue-config.js" });
34
33
  } catch (error) { console.log(error.stack) }
35
34
  node.name = config.name === undefined || config.name === "" ? node.host : config.name;
36
35
 
36
+ // Helper not to write everytime the "node.hueManager === null || node.hueManager === "undefined" || node.hueManager.HUEBridgeConnectionStatus === undefined"
37
+ Object.defineProperty(node, "linkStatus", {
38
+ get: function () {
39
+ return node.hueManager?.HUEBridgeConnectionStatus ?? "disconnected";
40
+ }
41
+ });
42
+
43
+
37
44
  // Connect to Bridge and get the resources
38
45
  node.initHUEConnection = async () => {
39
46
  try {
@@ -44,13 +51,11 @@ module.exports = (RED) => {
44
51
  } catch (error) { /* empty */ }
45
52
  // Handle events
46
53
  try {
47
- try {
48
- // Init HUE Utility
49
- node.hueManager = new HueClass(node.host, node.credentials.username, node.credentials.clientkey, config.bridgeid, node.sysLogger);
50
- } catch (error) { /* empty */ }
54
+ // Init HUE Utility
55
+ node.hueManager = new HueClass(node.host, node.credentials.username, node.credentials.clientkey, config.bridgeid, node.sysLogger);
51
56
  } catch (error) {
52
57
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`Errore hue-config: node.initHUEConnection: ${error.message}`);
53
- node.linkStatus = "disconnected";
58
+ throw (error)
54
59
  }
55
60
  node.hueManager.on("event", (_event) => {
56
61
  node.nodeClients.forEach((_oClient) => {
@@ -65,7 +70,6 @@ module.exports = (RED) => {
65
70
  // Connected
66
71
  node.hueManager.on("connected", () => {
67
72
  if (node.linkStatus === "disconnected") {
68
- node.linkStatus = "connected";
69
73
  // Start the timer to do initial read.
70
74
  if (node.timerDoInitialRead !== null) clearTimeout(node.timerDoInitialRead);
71
75
  node.timerDoInitialRead = setTimeout(() => {
@@ -75,7 +79,6 @@ module.exports = (RED) => {
75
79
  await node.loadResourcesFromHUEBridge();
76
80
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.info(`Total HUE resources count : ${node.hueAllResources.length}`);
77
81
  } catch (error) {
78
- node.linkStatus = "disconnected";
79
82
  node.nodeClients.forEach((_oClient) => {
80
83
  setTimeout(() => {
81
84
  _oClient.setNodeStatusHue({
@@ -93,7 +96,6 @@ module.exports = (RED) => {
93
96
  });
94
97
 
95
98
  node.hueManager.on("disconnected", () => {
96
- node.linkStatus = "disconnected";
97
99
  node.nodeClients.forEach((_oClient) => {
98
100
  _oClient.setNodeStatusHue({
99
101
  fill: "red",
@@ -114,10 +116,11 @@ module.exports = (RED) => {
114
116
  node.timerHUEConfigCheckState = setTimeout(() => {
115
117
  (async () => {
116
118
  if (node.linkStatus === "disconnected") {
119
+ // The hueEngine is already connected to the HUE Bridge
117
120
  try {
118
121
  await node.initHUEConnection();
119
122
  } catch (error) {
120
- node.linkStatus = "disconnected";
123
+ if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`Errore hue-config: node.startWatchdogTimer: ${error.message}`);
121
124
  }
122
125
  }
123
126
  node.startWatchdogTimer();
@@ -126,6 +129,7 @@ module.exports = (RED) => {
126
129
  };
127
130
  node.startWatchdogTimer();
128
131
 
132
+
129
133
  // Functions called from the nodes ----------------------------------------------------------------
130
134
  // Query the HUE Bridge to return the resources
131
135
  node.loadResourcesFromHUEBridge = async () => {
@@ -457,7 +461,6 @@ module.exports = (RED) => {
457
461
  });
458
462
  }
459
463
  } else {
460
- node.linkStatus = "disconnected";
461
464
  // Add _Node to the clients array
462
465
  _Node.setNodeStatusHue({
463
466
  fill: "grey",
@@ -1836,7 +1836,7 @@ module.exports = (RED) => {
1836
1836
  );
1837
1837
  // node.initKNXConnection();
1838
1838
  }
1839
- }, 30000);
1839
+ }, 10000);
1840
1840
 
1841
1841
  node.Disconnect = async (_sNodeStatus = "", _sColor = "grey") => {
1842
1842
  if (node.linkStatus === "disconnected") {
@@ -30,16 +30,23 @@ module.exports = function (RED) {
30
30
  node.setNodeStatus = ({
31
31
  fill, shape, text, payload,
32
32
  }) => {
33
-
33
+ try {
34
+ if (payload === undefined) payload = '';
35
+ const dDate = new Date();
36
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
37
+ node.sKNXNodeStatusText = `|KNX: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
38
+ node.status({ fill, shape, text: (node.sHUENodeStatusText || '') + ' ' + (node.sKNXNodeStatusText || '') });
39
+ } catch (error) { }
34
40
  };
35
41
  // 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()})` });
42
+ node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
43
+ try {
44
+ if (payload === undefined) payload = '';
45
+ const dDate = new Date();
46
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
47
+ node.sHUENodeStatusText = `|HUE: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
48
+ node.status({ fill, shape, text: node.sHUENodeStatusText + ' ' + (node.sKNXNodeStatusText || '') });
49
+ } catch (error) { }
43
50
  };
44
51
 
45
52
  // This function is called by the knx-ultimate config node, to output a msg.payload.
@@ -41,16 +41,23 @@ module.exports = function (RED) {
41
41
  node.setNodeStatus = ({
42
42
  fill, shape, text, payload,
43
43
  }) => {
44
-
44
+ try {
45
+ if (payload === undefined) payload = '';
46
+ const dDate = new Date();
47
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
48
+ node.sKNXNodeStatusText = `|KNX: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
49
+ node.status({ fill, shape, text: (node.sHUENodeStatusText || '') + ' ' + (node.sKNXNodeStatusText || '') });
50
+ } catch (error) { }
45
51
  };
46
52
  // Used to call the status update from the HUE config node.
47
- node.setNodeStatusHue = ({
48
- fill, shape, text, payload,
49
- }) => {
50
- if (payload === undefined) payload = '';
51
- const dDate = new Date();
52
- payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString();
53
- node.status({ fill, shape, text: `${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})` });
53
+ node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
54
+ try {
55
+ if (payload === undefined) payload = '';
56
+ const dDate = new Date();
57
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
58
+ node.sHUENodeStatusText = `|HUE: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
59
+ node.status({ fill, shape, text: node.sHUENodeStatusText + ' ' + (node.sKNXNodeStatusText || '') });
60
+ } catch (error) { }
54
61
  };
55
62
 
56
63
  // This function is called by the knx-ultimate config node, to output a msg.payload.
@@ -26,19 +26,27 @@ module.exports = function (RED) {
26
26
  node.initializingAtStart = false
27
27
 
28
28
  // Used to call the status update from the config node.
29
- node.setNodeStatus = ({ fill, shape, text, payload }) => {
30
- }
29
+ node.setNodeStatus = ({
30
+ fill, shape, text, payload,
31
+ }) => {
32
+ try {
33
+ if (payload === undefined) payload = '';
34
+ const dDate = new Date();
35
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
36
+ node.sKNXNodeStatusText = `|KNX: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
37
+ node.status({ fill, shape, text: (node.sHUENodeStatusText || '') + ' ' + (node.sKNXNodeStatusText || '') });
38
+ } catch (error) { }
39
+ };
31
40
  // Used to call the status update from the HUE config node.
32
41
  node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
33
- if (payload === undefined) payload = ''
34
- const dDate = new Date()
35
- payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString()
36
- node.status({
37
- fill,
38
- shape,
39
- text: `${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`,
40
- })
41
- }
42
+ try {
43
+ if (payload === undefined) payload = '';
44
+ const dDate = new Date();
45
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
46
+ node.sHUENodeStatusText = `|HUE: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
47
+ node.status({ fill, shape, text: node.sHUENodeStatusText + ' ' + (node.sKNXNodeStatusText || '') });
48
+ } catch (error) { }
49
+ };
42
50
 
43
51
  // This function is called by the knx-ultimate config node, to output a msg.payload.
44
52
  node.handleSend = (msg) => {
@@ -104,13 +104,26 @@ module.exports = function (RED) {
104
104
  // Used to call the status update from the config node.
105
105
  node.setNodeStatus = ({
106
106
  fill, shape, text, payload,
107
- }) => { };
107
+ }) => {
108
+ try {
109
+ if (node.currentHUEDevice?.on?.on === true) { fill = "blue"; shape = "dot" } else { fill = "blue"; shape = "ring" };
110
+ if (payload === undefined) payload = '';
111
+ const dDate = new Date();
112
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
113
+ node.sKNXNodeStatusText = `|KNX: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
114
+ node.status({ fill, shape, text: (node.sHUENodeStatusText || '') + ' ' + (node.sKNXNodeStatusText || '') });
115
+ } catch (error) { }
116
+ };
108
117
  // Used to call the status update from the HUE config node.
109
118
  node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
110
- if (payload === undefined) payload = '';
111
- const dDate = new Date();
112
- payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
113
- node.status({ fill, shape, text: `${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})` });
119
+ try {
120
+ if (node.currentHUEDevice?.on?.on === true) { fill = "blue"; shape = "dot" } else { fill = "blue"; shape = "ring" };
121
+ if (payload === undefined) payload = '';
122
+ const dDate = new Date();
123
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
124
+ node.sHUENodeStatusText = `|HUE: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
125
+ node.status({ fill, shape, text: node.sHUENodeStatusText + ' ' + (node.sKNXNodeStatusText || '') });
126
+ } catch (error) { }
114
127
  };
115
128
 
116
129
  function getRandomIntInclusive(min, max) {
@@ -27,15 +27,26 @@ module.exports = function (RED) {
27
27
  node.currentDeviceValue = 0;
28
28
 
29
29
  // Used to call the status update from the config node.
30
- node.setNodeStatus = ({ fill, shape, text, payload }) => {
31
-
30
+ node.setNodeStatus = ({
31
+ fill, shape, text, payload,
32
+ }) => {
33
+ try {
34
+ if (payload === undefined) payload = '';
35
+ const dDate = new Date();
36
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
37
+ node.sKNXNodeStatusText = `|KNX: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
38
+ node.status({ fill, shape, text: (node.sHUENodeStatusText || '') + ' ' + (node.sKNXNodeStatusText || '') });
39
+ } catch (error) { }
32
40
  };
33
41
  // Used to call the status update from the HUE config node.
34
42
  node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
35
- if (payload === undefined) payload = '';
36
- const dDate = new Date();
37
- payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString();
38
- node.status({ fill, shape, text: text + ' ' + payload + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' });
43
+ try {
44
+ if (payload === undefined) payload = '';
45
+ const dDate = new Date();
46
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
47
+ node.sHUENodeStatusText = `|HUE: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
48
+ node.status({ fill, shape, text: node.sHUENodeStatusText + ' ' + (node.sKNXNodeStatusText || '') });
49
+ } catch (error) { }
39
50
  };
40
51
 
41
52
  // This function is called by the knx-ultimate config node, to output a msg.payload.
@@ -26,13 +26,26 @@ module.exports = function (RED) {
26
26
  node.initializingAtStart = false;
27
27
 
28
28
  // Used to call the status update from the config node.
29
- node.setNodeStatus = ({ fill, shape, text, payload }) => { };
29
+ node.setNodeStatus = ({
30
+ fill, shape, text, payload,
31
+ }) => {
32
+ try {
33
+ if (payload === undefined) payload = '';
34
+ const dDate = new Date();
35
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
36
+ node.sKNXNodeStatusText = `|KNX: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
37
+ node.status({ fill, shape, text: (node.sHUENodeStatusText || '') + ' ' + (node.sKNXNodeStatusText || '') });
38
+ } catch (error) { }
39
+ };
30
40
  // Used to call the status update from the HUE config node.
31
41
  node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
32
- if (payload === undefined) payload = '';
33
- const dDate = new Date();
34
- payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
35
- node.status({ fill, shape, text: `${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})` });
42
+ try {
43
+ if (payload === undefined) payload = '';
44
+ const dDate = new Date();
45
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
46
+ node.sHUENodeStatusText = `|HUE: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
47
+ node.status({ fill, shape, text: node.sHUENodeStatusText + ' ' + (node.sKNXNodeStatusText || '') });
48
+ } catch (error) { }
36
49
  };
37
50
 
38
51
  // This function is called by the knx-ultimate config node, to output a msg.payload.
@@ -39,15 +39,26 @@ module.exports = function (RED) {
39
39
  config.selectedModeTabNumber = config.selectedModeTabNumber === undefined ? 0 : Number(config.selectedModeTabNumber); // Transform as number
40
40
 
41
41
  // Used to call the status update from the config node.
42
- node.setNodeStatus = ({ fill, shape, text, payload }) => {
43
-
42
+ node.setNodeStatus = ({
43
+ fill, shape, text, payload,
44
+ }) => {
45
+ try {
46
+ if (payload === undefined) payload = '';
47
+ const dDate = new Date();
48
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
49
+ node.sKNXNodeStatusText = `|KNX: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
50
+ node.status({ fill, shape, text: (node.sHUENodeStatusText || '') + ' ' + (node.sKNXNodeStatusText || '') });
51
+ } catch (error) { }
44
52
  };
45
53
  // Used to call the status update from the HUE config node.
46
54
  node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
47
- if (payload === undefined) payload = '';
48
- const dDate = new Date();
49
- payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString();
50
- node.status({ fill, shape, text: text + ' ' + payload + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' });
55
+ try {
56
+ if (payload === undefined) payload = '';
57
+ const dDate = new Date();
58
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
59
+ node.sHUENodeStatusText = `|HUE: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
60
+ node.status({ fill, shape, text: node.sHUENodeStatusText + ' ' + (node.sKNXNodeStatusText || '') });
61
+ } catch (error) { }
51
62
  };
52
63
 
53
64
  // This function is called by the knx-hue config node
@@ -32,15 +32,23 @@ module.exports = function (RED) {
32
32
  node.setNodeStatus = ({
33
33
  fill, shape, text, payload,
34
34
  }) => {
35
+ try {
36
+ if (payload === undefined) payload = '';
37
+ const dDate = new Date();
38
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
39
+ node.sKNXNodeStatusText = `|KNX: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
40
+ node.status({ fill, shape, text: (node.sHUENodeStatusText || '') + ' ' + (node.sKNXNodeStatusText || '') });
41
+ } catch (error) { }
35
42
  };
36
43
  // Used to call the status update from the HUE config node.
37
- node.setNodeStatusHue = ({
38
- fill, shape, text, payload,
39
- }) => {
40
- if (payload === undefined) payload = '';
41
- const dDate = new Date();
42
- payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString();
43
- node.status({ fill, shape, text: `${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})` });
44
+ node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
45
+ try {
46
+ if (payload === undefined) payload = '';
47
+ const dDate = new Date();
48
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
49
+ node.sHUENodeStatusText = `|HUE: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
50
+ node.status({ fill, shape, text: node.sHUENodeStatusText + ' ' + (node.sKNXNodeStatusText || '') });
51
+ } catch (error) { }
44
52
  };
45
53
 
46
54
  // This function is called by the knx-ultimate config node, to output a msg.payload.
@@ -30,16 +30,23 @@ module.exports = function (RED) {
30
30
  node.setNodeStatus = ({
31
31
  fill, shape, text, payload,
32
32
  }) => {
33
-
33
+ try {
34
+ if (payload === undefined) payload = '';
35
+ const dDate = new Date();
36
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
37
+ node.sKNXNodeStatusText = `|KNX: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
38
+ node.status({ fill, shape, text: (node.sHUENodeStatusText || '') + ' ' + (node.sKNXNodeStatusText || '') });
39
+ } catch (error) { }
34
40
  };
35
41
  // 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()})` });
42
+ node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
43
+ try {
44
+ if (payload === undefined) payload = '';
45
+ const dDate = new Date();
46
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
47
+ node.sHUENodeStatusText = `|HUE: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
48
+ node.status({ fill, shape, text: node.sHUENodeStatusText + ' ' + (node.sKNXNodeStatusText || '') });
49
+ } catch (error) { }
43
50
  };
44
51
 
45
52
  // This function is called by the knx-ultimate config node, to output a msg.payload.
@@ -30,16 +30,23 @@ module.exports = function (RED) {
30
30
  node.setNodeStatus = ({
31
31
  fill, shape, text, payload,
32
32
  }) => {
33
-
33
+ try {
34
+ if (payload === undefined) payload = '';
35
+ const dDate = new Date();
36
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
37
+ node.sKNXNodeStatusText = `|KNX: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
38
+ node.status({ fill, shape, text: (node.sHUENodeStatusText || '') + ' ' + (node.sKNXNodeStatusText || '') });
39
+ } catch (error) { }
34
40
  };
35
41
  // 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()})` });
42
+ node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
43
+ try {
44
+ if (payload === undefined) payload = '';
45
+ const dDate = new Date();
46
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
47
+ node.sHUENodeStatusText = `|HUE: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
48
+ node.status({ fill, shape, text: node.sHUENodeStatusText + ' ' + (node.sKNXNodeStatusText || '') });
49
+ } catch (error) { }
43
50
  };
44
51
 
45
52
  // This function is called by the knx-ultimate config node, to output a msg.payload.
@@ -30,16 +30,23 @@ module.exports = function (RED) {
30
30
  node.setNodeStatus = ({
31
31
  fill, shape, text, payload,
32
32
  }) => {
33
-
33
+ try {
34
+ if (payload === undefined) payload = '';
35
+ const dDate = new Date();
36
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
37
+ node.sKNXNodeStatusText = `|KNX: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
38
+ node.status({ fill, shape, text: (node.sHUENodeStatusText || '') + ' ' + (node.sKNXNodeStatusText || '') });
39
+ } catch (error) { }
34
40
  };
35
41
  // 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()})` });
42
+ node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
43
+ try {
44
+ if (payload === undefined) payload = '';
45
+ const dDate = new Date();
46
+ payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
47
+ node.sHUENodeStatusText = `|HUE: ${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})`;
48
+ node.status({ fill, shape, text: node.sHUENodeStatusText + ' ' + (node.sKNXNodeStatusText || '') });
49
+ } catch (error) { }
43
50
  };
44
51
 
45
52
  // This function is called by the knx-ultimate config node, to output a msg.payload.
@@ -11,12 +11,13 @@ class classHUE extends EventEmitter {
11
11
 
12
12
  constructor(_hueBridgeIP, _username, _clientkey, _bridgeid, _sysLogger) {
13
13
  super();
14
+ this.HUEBridgeConnectionStatus = "disconnected";
15
+ this.exitAllQueues = false;
14
16
  this.hueBridgeIP = _hueBridgeIP;
15
17
  this.username = _username;
16
18
  this.clientkey = _clientkey;
17
19
  this.bridgeid = _bridgeid;
18
20
  this.commandQueue = [];
19
- this.closePushEventStream = false;
20
21
  // eslint-disable-next-line max-len
21
22
  setTimeout(this.handleQueue, 10000); // First start. Allow the KNX to connect
22
23
  this.sysLogger = _sysLogger;
@@ -24,6 +25,9 @@ class classHUE extends EventEmitter {
24
25
  }
25
26
 
26
27
  Connect = () => {
28
+ if (this.timerCheckConnected !== null) clearInterval(this.timerCheckConnected);
29
+ this.HUEBridgeConnectionStatus = "disconnected";
30
+ this.exitAllQueues = false;
27
31
 
28
32
  const options = {
29
33
  headers: {
@@ -80,12 +84,29 @@ class classHUE extends EventEmitter {
80
84
  this.es.onopen = () => {
81
85
  // if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.error('KNXUltimatehueEngine: classHUE: SSE-Connected')
82
86
  this.emit("connected");
87
+ this.HUEBridgeConnectionStatus = "connected";
83
88
  if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.info(`KNXUltimatehueEngine: classHUE: this.es.onopen: connected`);
84
89
  // Check wether the hue bridge is connected or not
85
90
  if (this.timerCheckConnected !== null) clearInterval(this.timerCheckConnected);
86
91
  this.timerCheckConnected = setInterval(() => {
87
- this.writeHueQueueAdd(null, null, "Ping");
88
- }, 30000);
92
+ (async () => {
93
+ try {
94
+ if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.debug(`KNXUltimatehueEngine: classHUE: processQueueItem: Pinging...`);
95
+ const jReturn = await this.hueApiV2.get('/resource/bridge');
96
+ if (!Array.isArray(jReturn) || jReturn.length < 1) throw new Error("jReturn: not an array or array empty")
97
+ this.HUEBridgeConnectionStatus = "connected";
98
+ if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.debug(`KNXUltimatehueEngine: classHUE: processQueueItem: Ping OK`);
99
+ } catch (error) {
100
+ if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.error(`KNXUltimatehueEngine: classHUE: processQueueItem: Ping ERROR: ${error.message}`);
101
+ if (this.timerCheckConnected !== null) clearInterval(this.timerCheckConnected);
102
+ this.commandQueue = [];
103
+ this.emit("disconnected");
104
+ try {
105
+ this.close();
106
+ } catch (error) { }
107
+ }
108
+ })();
109
+ }, 20000);
89
110
  };
90
111
 
91
112
  this.es.onerror = (error) => {
@@ -149,20 +170,6 @@ class classHUE extends EventEmitter {
149
170
  if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.error(`KNXUltimatehueEngine: classHUE: processQueueItem: stopScene: ${error.message}`);
150
171
  }
151
172
  break;
152
- case "Ping":
153
- try {
154
- const jReturn = await this.hueApiV2.get('/resource/bridge');
155
- if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.debug(`KNXUltimatehueEngine: classHUE: processQueueItem: Ping OK: Bridge id:${jReturn[0].bridge_id}`);
156
- } catch (error) {
157
- if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.error(`KNXUltimatehueEngine: classHUE: processQueueItem: Ping ERROR: ${error.message}`);
158
- if (this.timerCheckConnected !== null) clearInterval(this.timerCheckConnected);
159
- this.commandQueue = [];
160
- try {
161
- this.close();
162
- } catch (error) { }
163
- this.emit("disconnected");
164
- }
165
- break;
166
173
  default:
167
174
  break;
168
175
  }
@@ -190,7 +197,7 @@ class classHUE extends EventEmitter {
190
197
  //}
191
198
  }
192
199
  await pleaseWait(150);
193
- } while (this.closePushEventStream === false);
200
+ } while (!this.exitAllQueues);
194
201
  //console.log("\x1b[42m End processing commandQueue \x1b[0m " + new Date().toTimeString(), this.commandQueue.length);
195
202
  };
196
203
 
@@ -212,8 +219,10 @@ class classHUE extends EventEmitter {
212
219
 
213
220
  close = async () =>
214
221
  new Promise((resolve, reject) => {
222
+ if (this.timerCheckConnected !== null) clearInterval(this.timerCheckConnected);
215
223
  try {
216
- this.closePushEventStream = true; // Signal to exit all loops
224
+ this.HUEBridgeConnectionStatus = "disconnected";
225
+ this.exitAllQueues = true;
217
226
  setTimeout(() => {
218
227
  try {
219
228
  if (this.es !== null && this.es !== undefined) this.es.close();
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "engines": {
4
4
  "node": ">=16.0.0"
5
5
  },
6
- "version": "3.3.17",
6
+ "version": "3.3.19",
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",