node-red-contrib-knx-ultimate 3.2.0 → 3.2.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.
Files changed (33) hide show
  1. package/CHANGELOG.md +7 -1
  2. package/nodes/commonFunctions.js +0 -1
  3. package/nodes/hue-config.js +12 -6
  4. package/nodes/knxUltimate-config copy.html +456 -0
  5. package/nodes/knxUltimate-config copy.js +1939 -0
  6. package/nodes/knxUltimate-config.html +4 -9
  7. package/nodes/knxUltimate-config.js +128 -213
  8. package/nodes/knxUltimate.js +41 -32
  9. package/nodes/knxUltimateAlerter.js +11 -15
  10. package/nodes/knxUltimateAutoResponder.js +21 -13
  11. package/nodes/knxUltimateGarageDoorBarrierOpener.js +16 -8
  12. package/nodes/knxUltimateGlobalContext.js +10 -10
  13. package/nodes/knxUltimateHueBattery.js +8 -8
  14. package/nodes/knxUltimateHueButton.js +9 -9
  15. package/nodes/knxUltimateHueContactSensor.js +7 -7
  16. package/nodes/knxUltimateHueLight.js +26 -26
  17. package/nodes/knxUltimateHueLightSensor.js +8 -8
  18. package/nodes/knxUltimateHueMotion.js +7 -7
  19. package/nodes/knxUltimateHueScene.js +17 -9
  20. package/nodes/knxUltimateHueTapDial.js +13 -13
  21. package/nodes/knxUltimateHueTemperatureSensor.js +8 -8
  22. package/nodes/knxUltimateHueZigbeeConnectivity.js +8 -8
  23. package/nodes/knxUltimateHuedevice_software_update.js +8 -8
  24. package/nodes/knxUltimateLoadControl.js +24 -21
  25. package/nodes/knxUltimateLogger.js +8 -8
  26. package/nodes/knxUltimateSceneController.js +20 -13
  27. package/nodes/knxUltimateViewer.js +8 -8
  28. package/nodes/knxUltimateWatchDog.js +14 -14
  29. package/nodes/utils/http.js +0 -1
  30. package/nodes/utils/hueEngine.js +13 -6
  31. package/nodes/utils/payloadManipulation.js +2 -2
  32. package/nodes/utils/sysLogger.js +23 -60
  33. package/package.json +3 -3
@@ -1,4 +1,13 @@
1
1
 
2
+ // 10/09/2024 Setup the color logger
3
+ loggerSetup = (options) => {
4
+ let clog = require("node-color-log").createNamedLogger(options.setPrefix);
5
+ clog.setLevel(options.loglevel);
6
+ clog.setDate(() => (new Date()).toLocaleString());
7
+ return clog;
8
+ }
9
+
10
+
2
11
  /* eslint-disable max-len */
3
12
  module.exports = function (RED) {
4
13
  const _ = require('lodash');
@@ -9,9 +18,9 @@ module.exports = function (RED) {
9
18
  function knxUltimate(config) {
10
19
  RED.nodes.createNode(this, config);
11
20
  const node = this;
12
- node.server = RED.nodes.getNode(config.server);
21
+ node.serverKNX = RED.nodes.getNode(config.server);
13
22
  // 11/11/2021 Is the node server disabled by the flow "disable" command?
14
- if (node.server === null) {
23
+ if (node.serverKNX === null) {
15
24
  node.status({ fill: 'red', shape: 'dot', text: '[THE GATEWAY NODE HAS BEEN DISABLED]' });
16
25
  return;
17
26
  }
@@ -21,7 +30,7 @@ module.exports = function (RED) {
21
30
  fill, shape, text, payload, GA, dpt, devicename,
22
31
  }) => {
23
32
  try {
24
- if (node.server == null) { node.status({ fill: 'red', shape: 'dot', text: '[NO GATEWAY SELECTED]' }); return; }
33
+ if (node.serverKNX === null) { node.status({ fill: 'red', shape: 'dot', text: '[NO GATEWAY SELECTED]' }); return; }
25
34
  if (node.icountMessageInWindow == -999) return; // Locked out, doesn't change status.
26
35
  const dDate = new Date();
27
36
  // 30/08/2019 Display only the things selected in the config
@@ -32,11 +41,11 @@ module.exports = function (RED) {
32
41
  node.status({ fill, shape, text: `${GA + payload + (node.listenallga === true ? ` ${devicename}` : '')} (${dDate.getDate()}, ${dDate.toLocaleTimeString()} ${text}` });
33
42
  // 16/02/2020 signal errors to the server
34
43
  if (fill.toUpperCase() === 'RED') {
35
- if (node.server) {
44
+ if (node.serverKNX) {
36
45
  const oError = {
37
46
  nodeid: node.id, topic: node.outputtopic, devicename, GA, text,
38
47
  };
39
- node.server.reportToWatchdogCalledByKNXUltimateNode(oError);
48
+ node.serverKNX.reportToWatchdogCalledByKNXUltimateNode(oError);
40
49
  }
41
50
  }
42
51
  // Validate the Address to advise the user. The address can be undefined, because the
@@ -119,7 +128,7 @@ module.exports = function (RED) {
119
128
  node.passthrough = (typeof config.passthrough === 'undefined' ? 'no' : config.passthrough);
120
129
  node.inputmessage = {}; // Stores the input message to be passed through
121
130
  node.timerTTLInputMessage = null; // The stored node.inputmessage has a ttl.
122
- node.sysLogger = require('./utils/sysLogger.js').get({ loglevel: node.server.loglevel || 'error' }); // 08/04/2021 new logger to adhere to the loglevel selected in the config-window
131
+ node.sysLogger = loggerSetup({ loglevel: node.serverKNX.loglevel, setPrefix: "knxUltimate.js" }); // 08/04/2021 new logger to adhere to the loglevel selected in the config-window
123
132
  node.sendMsgToKNXCode = config.sendMsgToKNXCode || undefined;
124
133
  node.receiveMsgFromKNXCode = config.receiveMsgFromKNXCode || undefined;
125
134
  if (node.sendMsgToKNXCode === '') node.sendMsgToKNXCode = undefined
@@ -144,7 +153,7 @@ module.exports = function (RED) {
144
153
  const blankSpacePosition = _ga.indexOf(" ");
145
154
  if (blankSpacePosition > -1) _ga = _ga.substring(0, blankSpacePosition);
146
155
  // Is there a GA in the server's exposedGAs?
147
- const found = node.server.exposedGAs.find(a => a.ga === _ga);
156
+ const found = node.serverKNX.exposedGAs.find(a => a.ga === _ga);
148
157
  if (found !== undefined) {
149
158
  if (_dpt === undefined && found.dpt === undefined) {
150
159
  const errM = 'knxUltimate: getGaValue: node ID:' + node.id + ' ' + 'No CSV file imported. Please provide the dpt manually';
@@ -175,7 +184,7 @@ module.exports = function (RED) {
175
184
  if (blankSpacePosition > -1) _ga = _ga.substring(0, blankSpacePosition);
176
185
  if (_dpt === undefined) {
177
186
  // Try getting dpt from ETS CSV
178
- const found = node.server.exposedGAs.find(a => a.ga === _ga);
187
+ const found = node.serverKNX.exposedGAs.find(a => a.ga === _ga);
179
188
  if (found === undefined || found.dpt === undefined) {
180
189
  const errM = 'knxUltimate: setGAValue: node ID:' + node.id + ' ' + 'No CSV file imported. Please provide the dpt manually';
181
190
  RED.log.error(errM);
@@ -183,7 +192,7 @@ module.exports = function (RED) {
183
192
  return;
184
193
  }
185
194
  }
186
- node.server.writeQueueAdd({
195
+ node.serverKNX.sendKNXTelegramToKNXEngine({
187
196
  grpaddr: _ga, payload: _value, dpt: _dpt, outputtype: 'write', nodecallerid: node.id,
188
197
  });
189
198
  } catch (error) {
@@ -195,7 +204,7 @@ module.exports = function (RED) {
195
204
  // Used in the KNX Function TAB
196
205
  let self = function self(_value) {
197
206
  try {
198
- node.server.writeQueueAdd({
207
+ node.serverKNX.sendKNXTelegramToKNXEngine({
199
208
  grpaddr: node.topic, payload: _value, dpt: node.dpt, outputtype: 'write', nodecallerid: node.id,
200
209
  });
201
210
  } catch (error) {
@@ -208,7 +217,7 @@ module.exports = function (RED) {
208
217
  let toggle = function toggle() {
209
218
  if (node.currentPayload === true || node.currentPayload === false) {
210
219
  try {
211
- node.server.writeQueueAdd({
220
+ node.serverKNX.sendKNXTelegramToKNXEngine({
212
221
  grpaddr: node.topic, payload: !node.currentPayload, dpt: node.dpt, outputtype: 'write', nodecallerid: node.id,
213
222
  });
214
223
  } catch (error) {
@@ -257,7 +266,7 @@ module.exports = function (RED) {
257
266
 
258
267
  node.on('input', (msg) => {
259
268
  if (typeof msg === 'undefined') return;
260
- if (!node.server) return; // 29/08/2019 Server not instantiate
269
+ if (!node.serverKNX) return; // 29/08/2019 Server not instantiate
261
270
 
262
271
  // 11/01/2021 Accept properties change from msg
263
272
  // *********************************
@@ -339,7 +348,7 @@ module.exports = function (RED) {
339
348
  node.setNodeStatus({
340
349
  fill: 'grey', shape: 'dot', text: 'Read', payload: '', GA: grpaddr, dpt: '', devicename: '',
341
350
  });
342
- node.server.writeQueueAdd({
351
+ node.serverKNX.sendKNXTelegramToKNXEngine({
343
352
  grpaddr, payload: '', dpt: '', outputtype: 'read', nodecallerid: node.id,
344
353
  });
345
354
  } else { // Listen all GAs
@@ -358,16 +367,16 @@ module.exports = function (RED) {
358
367
  return;
359
368
  }
360
369
  }
361
- node.server.writeQueueAdd({
370
+ node.serverKNX.sendKNXTelegramToKNXEngine({
362
371
  grpaddr, payload: '', dpt: '', outputtype: 'read', nodecallerid: node.id,
363
372
  });
364
373
  } else {
365
374
  // Issue read to all group addresses
366
375
  // 25/10/2019 the user is able not import the csv, so i need to check for it. This option should be unckecked by the knxUltimate html config, but..
367
- if (typeof node.server.csv !== 'undefined') {
376
+ if (typeof node.serverKNX.csv !== 'undefined') {
368
377
  let delay = 0;
369
- for (let index = 0; index < node.server.csv.length; index++) {
370
- const element = node.server.csv[index];
378
+ for (let index = 0; index < node.serverKNX.csv.length; index++) {
379
+ const element = node.serverKNX.csv[index];
371
380
  const grpaddr = element.ga;
372
381
  // 29/12/2020 Protection over circular references (for example, if you link two Ultimate Nodes toghether with the same group address), to prevent infinite loops
373
382
  if (msg.hasOwnProperty('knx')) {
@@ -378,7 +387,7 @@ module.exports = function (RED) {
378
387
  });
379
388
  }
380
389
  } else {
381
- node.server.writeQueueAdd({
390
+ node.serverKNX.sendKNXTelegramToKNXEngine({
382
391
  grpaddr, payload: '', dpt: '', outputtype: 'read', nodecallerid: node.id,
383
392
  });
384
393
  const t = setTimeout(() => { // 21/03/2022 fixed possible memory leak. Previously was setTimeout without "let t = ".
@@ -437,7 +446,7 @@ module.exports = function (RED) {
437
446
  node.icountMessageInWindow += 1;
438
447
 
439
448
  // OUTPUT: Send message to the bus (write/response)
440
- if (node.server.knxConnection) {
449
+ if (node.serverKNX.knxConnection) {
441
450
  let { outputtype } = node;
442
451
  let grpaddr = '';
443
452
  let dpt = '';
@@ -465,8 +474,8 @@ module.exports = function (RED) {
465
474
  // No datapoint set. If the CSV is loaded, try to get it from there.
466
475
  if (!msg.hasOwnProperty('writeraw')) { // In raw mode, Datapoint is useless
467
476
  // Get the datapoint from the CSV
468
- if (typeof node.server.csv !== 'undefined') {
469
- const oGA = node.server.csv.filter((sga) => sga.ga == grpaddr)[0];
477
+ if (typeof node.serverKNX.csv !== 'undefined') {
478
+ const oGA = node.serverKNX.csv.filter((sga) => sga.ga == grpaddr)[0];
470
479
  if (oGA !== undefined) {
471
480
  dpt = oGA.dpt;
472
481
  } else {
@@ -513,9 +522,9 @@ module.exports = function (RED) {
513
522
  if (msg.hasOwnProperty('writeraw') && msg.hasOwnProperty('writeraw') !== null) {
514
523
  try {
515
524
  if (msg.hasOwnProperty('bitlenght') && msg.bitlenght !== null) {
516
- node.server.knxConnection.writeRaw(grpaddr, msg.writeraw, msg.bitlenght);
525
+ node.serverKNX.knxConnection.writeRaw(grpaddr, msg.writeraw, msg.bitlenght);
517
526
  } else {
518
- node.server.knxConnection.writeRaw(grpaddr, msg.writeraw);
527
+ node.serverKNX.knxConnection.writeRaw(grpaddr, msg.writeraw);
519
528
  }
520
529
  node.setNodeStatus({
521
530
  fill: 'green', shape: 'dot', text: 'RAW Write', payload: '', GA: grpaddr, dpt: '', devicename: '',
@@ -531,7 +540,7 @@ module.exports = function (RED) {
531
540
  if (outputtype == 'response') {
532
541
  try {
533
542
  node.currentPayload = msg.payload;// 31/12/2019 Set the current value (because, if the node is a virtual device, then it'll never fire "GroupValue_Write" in the server node, causing the currentPayload to never update)
534
- node.server.writeQueueAdd({
543
+ node.serverKNX.sendKNXTelegramToKNXEngine({
535
544
  grpaddr, payload: msg.payload, dpt, outputtype, nodecallerid: node.id,
536
545
  });
537
546
  node.setNodeStatus({
@@ -542,7 +551,7 @@ module.exports = function (RED) {
542
551
  // 05/01/2021 Updates only the internal currentPayload value.
543
552
  try {
544
553
  node.currentPayload = msg.payload;
545
- node.server.writeQueueAdd({
554
+ node.serverKNX.sendKNXTelegramToKNXEngine({
546
555
  grpaddr, payload: msg.payload, dpt, outputtype, nodecallerid: node.id,
547
556
  });
548
557
  node.setNodeStatus({
@@ -552,8 +561,8 @@ module.exports = function (RED) {
552
561
  } else {
553
562
  try {
554
563
  node.currentPayload = msg.payload;// 31/12/2019 Set the current value (because, if the node is a virtual device, then it'll never fire "GroupValue_Write" in the server node, causing the currentPayload to never update)
555
- // if (node.server.linkStatus === "connected") {
556
- node.server.writeQueueAdd({
564
+ // if (node.serverKNX.linkStatus === "connected") {
565
+ node.serverKNX.sendKNXTelegramToKNXEngine({
557
566
  grpaddr, payload: msg.payload, dpt, outputtype, nodecallerid: node.id,
558
567
  });
559
568
  node.setNodeStatus({
@@ -571,8 +580,8 @@ module.exports = function (RED) {
571
580
  node.on('close', (done) => {
572
581
  if (node.timerTTLInputMessage !== null) clearTimeout(node.timerTTLInputMessage);
573
582
  node.inputmessage = {};
574
- if (node.server) {
575
- node.server.removeClient(node);
583
+ if (node.serverKNX) {
584
+ node.serverKNX.removeClient(node);
576
585
  try {
577
586
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.info(`knxUltimate: Close: node id ${node.id} with topic ${node.topic || ''} has been removed from the server.`);
578
587
  } catch (error) { }
@@ -581,15 +590,15 @@ module.exports = function (RED) {
581
590
  });
582
591
 
583
592
  // On each deploy, add the node to the server list
584
- if (node.server) {
585
- node.server.addClient(node);
593
+ if (node.serverKNX) {
594
+ node.serverKNX.addClient(node);
586
595
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.info(`knxUltimate: addClient: node id ${node.id}` || '' + ` with topic ${node.topic || ''} has been added to the server.`);
587
596
  // 05/11/2021 if the node is set to read from bus, issue a read.
588
597
  // "node-input-initialread0": "No",
589
598
  // "node-input-initialread1": "Leggi dal BUS KNX",
590
599
  // "node-input-initialread2": "Leggi l'ultimo valore salvato su file prima della disconnessione.",
591
600
  // "node-input-initialread3": "Leggi l'ultimo valore salvato su file prima della disconnessione. Se inesistente, leggi dal BUS KNX",
592
- if (node.server.linkStatus === 'connected' && node.initialread === 1 || node.initialread === 3) {
601
+ if (node.serverKNX.linkStatus === 'connected' && node.initialread === 1 || node.initialread === 3) {
593
602
  node.setNodeStatus({
594
603
  fill: 'yellow', shape: 'dot', text: 'Get value from BUS.', payload: '', GA: node.topic || '', dpt: '', devicename: '',
595
604
  });
@@ -1,4 +1,5 @@
1
1
 
2
+
2
3
  module.exports = function (RED) {
3
4
  function knxUltimateAlerter(config) {
4
5
  const fs = require('fs');
@@ -9,7 +10,7 @@ module.exports = function (RED) {
9
10
 
10
11
  RED.nodes.createNode(this, config);
11
12
  const node = this;
12
- node.server = RED.nodes.getNode(config.server);
13
+ node.serverKNX = RED.nodes.getNode(config.server);
13
14
  node.name = config.name || 'KNX Alerter';
14
15
  node.listenallga = true; // Dont' remove this.
15
16
  node.notifyreadrequest = false;
@@ -27,22 +28,17 @@ module.exports = function (RED) {
27
28
  node.timerSend = null;
28
29
  node.whentostart = config.whentostart === undefined ? 'ifnewalert' : config.whentostart;
29
30
  node.timerinterval = (config.timerinterval === undefined || config.timerinterval == '') ? '2' : config.timerinterval;
31
+
30
32
  if (config.initialreadGAInRules === undefined) {
31
33
  node.initialread = true;
32
34
  } else {
33
35
  node.initialread = config.initialreadGAInRules !== '0';
34
36
  }
35
37
 
36
- try {
37
- node.sysLogger = require('./utils/sysLogger.js').get({ loglevel: node.server.loglevel || 'error' }); // 08/04/2021 new logger to adhere to the loglevel selected in the config-window
38
- } catch (error) {
39
- node.sysLogger = 'error';
40
- }
41
-
42
38
  // Used to call the status update from the config node.
43
39
  node.setNodeStatus = ({ fill, shape, text, payload, GA, dpt, devicename }) => {
44
40
  try {
45
- if (node.server === null) return;
41
+ if (node.serverKNX === null) return;
46
42
  // Log only service statuses, not the GA values
47
43
  if (dpt !== undefined) return;
48
44
  if (dpt !== '') return;
@@ -159,7 +155,7 @@ module.exports = function (RED) {
159
155
 
160
156
  // 24/04/2021 perform a read on all GA in the rule list. Called both from node.on("input") and knxUltimate-config
161
157
  node.initialReadAllDevicesInRules = () => {
162
- if (node.server) {
158
+ if (node.serverKNX) {
163
159
  let grpaddr = '';
164
160
  for (let i = 0; i < node.rules.length; i++) {
165
161
  // rule is { topic: rowRuleTopic, devicename: rowRuleDeviceName, longdevicename: rowRuleLongDeviceName}
@@ -170,7 +166,7 @@ module.exports = function (RED) {
170
166
  // Check if it's a group address
171
167
  // const ret = Address.KNXAddress.createFromString(grpaddr, Address.KNXAddress.TYPE_GROUP)
172
168
  node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'Read', payload: '', GA: grpaddr, dpt: '', devicename: rule.devicename });
173
- node.server.writeQueueAdd({ grpaddr, payload: '', dpt: '', outputtype: 'read', nodecallerid: node.id });
169
+ node.serverKNX.sendKNXTelegramToKNXEngine({ grpaddr, payload: '', dpt: '', outputtype: 'read', nodecallerid: node.id });
174
170
  } catch (error) {
175
171
  node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'Not a KNX GA ' + error.message, payload: '', GA: grpaddr, dpt: '', devicename: rule.devicename });
176
172
  }
@@ -216,8 +212,8 @@ module.exports = function (RED) {
216
212
 
217
213
  node.on('close', function (done) {
218
214
  clearTimeout(node.timerSend);
219
- if (node.server) {
220
- node.server.removeClient(node);
215
+ if (node.serverKNX) {
216
+ node.serverKNX.removeClient(node);
221
217
  }
222
218
  done();
223
219
  });
@@ -276,10 +272,10 @@ module.exports = function (RED) {
276
272
  node.sendNoMoreDevices();
277
273
 
278
274
  // On each deploy, unsubscribe+resubscribe
279
- if (node.server) {
280
- node.server.removeClient(node);
275
+ if (node.serverKNX) {
276
+ node.serverKNX.removeClient(node);
281
277
  if (node.topic !== '' || node.topicSave !== '') {
282
- node.server.addClient(node);
278
+ node.serverKNX.addClient(node);
283
279
  }
284
280
  }
285
281
  }
@@ -1,3 +1,11 @@
1
+ // 10/09/2024 Setup the color logger
2
+ loggerSetup = (options) => {
3
+ let clog = require("node-color-log").createNamedLogger(options.setPrefix);
4
+ clog.setLevel(options.loglevel);
5
+ clog.setDate(() => (new Date()).toLocaleString());
6
+ return clog;
7
+ }
8
+
1
9
  module.exports = function (RED) {
2
10
  const dptlib = require('knxultimate').dptlib;
3
11
  const fs = require("fs");
@@ -33,7 +41,7 @@ module.exports = function (RED) {
33
41
  function knxUltimateAutoResponder(config) {
34
42
  RED.nodes.createNode(this, config)
35
43
  const node = this
36
- node.server = RED.nodes.getNode(config.server)
44
+ node.serverKNX = RED.nodes.getNode(config.server)
37
45
  node.topic = node.name
38
46
  node.name = config.name === undefined ? 'Auto responder' : config.name
39
47
  node.outputtopic = node.name
@@ -48,12 +56,12 @@ module.exports = function (RED) {
48
56
  node.inputRBE = 'false' // Apply or not RBE to the input (Messages coming from BUS)
49
57
  node.exposedGAs = [];
50
58
  node.commandText = []; // Raw list Respond To
51
- node.sysLogger = require('./utils/sysLogger.js').get({ loglevel: node.server.loglevel || 'error' }); // 08/04/2021 new logger to adhere to the loglevel selected in the config-window
59
+ node.sysLogger = loggerSetup({ loglevel: node.serverKNX.loglevel, setPrefix: "knxUltimateAutoResponder.js" }); // 08/04/2021 new logger to adhere to the loglevel selected in the config-window
52
60
 
53
61
  // Used to call the status update from the config node.
54
62
  node.setNodeStatus = ({ fill, shape, text, payload, GA, dpt, devicename }) => {
55
63
  // try {
56
- // if (node.server == null) { node.status({ fill: 'red', shape: 'dot', text: '[NO GATEWAY SELECTED]' }); return }
64
+ // if (node.serverKNX === null) { node.status({ fill: 'red', shape: 'dot', text: '[NO GATEWAY SELECTED]' }); return }
57
65
  // GA = GA === undefined ? '' : GA
58
66
  // payload = payload === undefined ? '' : payload
59
67
  // payload = typeof payload === 'object' ? JSON.stringify(payload) : payload
@@ -64,7 +72,7 @@ module.exports = function (RED) {
64
72
  }
65
73
 
66
74
  node.saveExposedGAs = () => {
67
- const sFile = path.join(node.server.userDir, "knxpersistvalues", "knxpersist" + node.id + ".json");
75
+ const sFile = path.join(node.serverKNX.userDir, "knxpersistvalues", "knxpersist" + node.id + ".json");
68
76
  try {
69
77
  if (node.exposedGAs.length > 0) {
70
78
  fs.writeFileSync(sFile, JSON.stringify(node.exposedGAs));
@@ -75,7 +83,7 @@ module.exports = function (RED) {
75
83
  }
76
84
  }
77
85
  node.loadExposedGAs = () => {
78
- const sFile = path.join(node.server.userDir, "knxpersistvalues", "knxpersist" + node.id + ".json");
86
+ const sFile = path.join(node.serverKNX.userDir, "knxpersistvalues", "knxpersist" + node.id + ".json");
79
87
  try {
80
88
  node.exposedGAs = JSON.parse(fs.readFileSync(sFile, "utf8"));
81
89
  } catch (err) {
@@ -96,11 +104,11 @@ module.exports = function (RED) {
96
104
 
97
105
 
98
106
  // Add the ETS CSV file list to exposedGAs
99
- if (node.server.csv === undefined || node.server.csv === '' || node.server.csv.length === 0) {
107
+ if (node.serverKNX.csv === undefined || node.serverKNX.csv === '' || node.serverKNX.csv.length === 0) {
100
108
  node.status({ fill: 'grey', shape: 'ring', text: 'No ETS file imported', payload: '', dpt: '', devicename: '' });
101
109
  //return;
102
110
  } else {
103
- node.server.csv.forEach(element => {
111
+ node.serverKNX.csv.forEach(element => {
104
112
  const curGa = node.exposedGAs.find(a => a.address === element.ga);
105
113
  if (curGa === undefined) {
106
114
  node.exposedGAs.push({ address: element.ga, dpt: element.dpt, default: undefined, payload: undefined, enabled: false }); // "enabled" will be used to filter only the node.commandText directiver
@@ -198,7 +206,7 @@ module.exports = function (RED) {
198
206
  if (retVal !== undefined) {
199
207
  const dDate = new Date()
200
208
  if (oFoundGA.address !== undefined && oFoundGA.dpt !== undefined && retVal !== undefined) {
201
- node.server.writeQueueAdd({ grpaddr: oFoundGA.address, payload: retVal, dpt: oFoundGA.dpt, outputtype: 'response', nodecallerid: node.id });
209
+ node.serverKNX.sendKNXTelegramToKNXEngine({ grpaddr: oFoundGA.address, payload: retVal, dpt: oFoundGA.dpt, outputtype: 'response', nodecallerid: node.id });
202
210
  node.status({ fill: 'blue', shape: 'dot', text: 'Respond ' + oFoundGA.address + ' => ' + retVal + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
203
211
  } else {
204
212
  node.status({ fill: 'yellow', shape: 'ring', text: 'Issue responding ' + oFoundGA.address + ' => ' + retVal + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
@@ -221,16 +229,16 @@ module.exports = function (RED) {
221
229
  }
222
230
 
223
231
  node.exposedGAs = [];
224
- if (node.server) {
225
- node.server.removeClient(node)
232
+ if (node.serverKNX) {
233
+ node.serverKNX.removeClient(node)
226
234
  }
227
235
  done()
228
236
  })
229
237
 
230
238
  // On each deploy, unsubscribe+resubscribe
231
- if (node.server) {
232
- node.server.removeClient(node)
233
- node.server.addClient(node)
239
+ if (node.serverKNX) {
240
+ node.serverKNX.removeClient(node)
241
+ node.serverKNX.addClient(node)
234
242
  }
235
243
  }
236
244
  RED.nodes.registerType('knxUltimateAutoResponder', knxUltimateAutoResponder)
@@ -4,14 +4,22 @@ const _ = require('lodash');
4
4
  const KNXUtils = require('knxultimate').KNXUtils;
5
5
  const payloadRounder = require('./utils/payloadManipulation');
6
6
 
7
+ // 10/09/2024 Setup the color logger
8
+ loggerSetup = (options) => {
9
+ let clog = require("node-color-log").createNamedLogger(options.setPrefix);
10
+ clog.setLevel(options.loglevel);
11
+ clog.setDate(() => (new Date()).toLocaleString());
12
+ return clog;
13
+ }
14
+
7
15
  module.exports = function (RED) {
8
16
 
9
17
  function knxUltimateGarageDoorBarrierOpener(config) {
10
18
  RED.nodes.createNode(this, config);
11
19
  const node = this;
12
- node.server = RED.nodes.getNode(config.server);
20
+ node.serverKNX = RED.nodes.getNode(config.server);
13
21
  // 11/11/2021 Is the node server disabled by the flow "disable" command?
14
- if (node.server === null) {
22
+ if (node.serverKNX === null) {
15
23
  node.status({ fill: 'red', shape: 'dot', text: '[THE GATEWAY NODE HAS BEEN DISABLED]' });
16
24
  return;
17
25
  }
@@ -26,7 +34,7 @@ module.exports = function (RED) {
26
34
  node.initialread = false;
27
35
  node.listenallga = true; // Don't remove
28
36
  node.outputtype = 'write';
29
- node.sysLogger = require('./utils/sysLogger.js').get({ loglevel: node.server.loglevel || 'error' }); // 08/04/2021 new logger to adhere to the loglevel selected in the config-window
37
+ node.sysLogger = loggerSetup({ loglevel: node.serverKNX.loglevel, setPrefix: "knxUltimateGarageDoorOpener.js" }); // 08/04/2021 new logger to adhere to the loglevel selected in the config-window
30
38
 
31
39
  // From KNX to the node
32
40
  node.GACommand = config.GACommand === undefined ? "" : config.GACommand;
@@ -70,7 +78,7 @@ module.exports = function (RED) {
70
78
  fill, shape, text, payload, GA, dpt, devicename,
71
79
  }) => {
72
80
  try {
73
- if (node.server == null) { node.status({ fill: 'red', shape: 'dot', text: '[NO GATEWAY SELECTED]' }); return; }
81
+ if (node.serverKNX === null) { node.status({ fill: 'red', shape: 'dot', text: '[NO GATEWAY SELECTED]' }); return; }
74
82
  const dDate = new Date();
75
83
  // 30/08/2019 Display only the things selected in the config
76
84
  GA = (typeof GA === 'undefined' || GA === '') ? '' : `(${GA}) `;
@@ -97,7 +105,7 @@ module.exports = function (RED) {
97
105
  node.setNodeStatus({
98
106
  fill: 'yellow', shape: 'dot', text: status, payload: '',
99
107
  });
100
- node.server.writeQueueAdd({
108
+ node.serverKNX.sendKNXTelegramToKNXEngine({
101
109
  grpaddr: node.GAImpulse, payload: true, dpt: '1.001', outputtype: 'write', nodecallerid: node.id
102
110
  });
103
111
  if (node.timerMovement !== null) clearTimeout(node.timerMovement);
@@ -127,12 +135,12 @@ module.exports = function (RED) {
127
135
 
128
136
  node.on('input', (msg) => {
129
137
  if (typeof msg === 'undefined') return;
130
- if (!node.server) return; // 29/08/2019 Server not instantiate
138
+ if (!node.serverKNX) return; // 29/08/2019 Server not instantiate
131
139
  });
132
140
 
133
141
  node.on('close', (done) => {
134
- if (node.server) {
135
- node.server.removeClient(node);
142
+ if (node.serverKNX) {
143
+ node.serverKNX.removeClient(node);
136
144
  try {
137
145
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.info(`knxUltimateGarageDoorBarrierOpener: Close: node id ${node.id} with topic ${node.topic || ''} has been removed from the server.`);
138
146
  } catch (error) { }
@@ -29,7 +29,7 @@ module.exports = function (RED) {
29
29
  function knxUltimateGlobalContext(config) {
30
30
  RED.nodes.createNode(this, config)
31
31
  const node = this
32
- node.server = RED.nodes.getNode(config.server)
32
+ node.serverKNX = RED.nodes.getNode(config.server)
33
33
  node.topic = node.name
34
34
  node.name = config.name === undefined ? 'KNXGlobalContext' : config.name
35
35
  node.outputtopic = node.name
@@ -58,7 +58,7 @@ module.exports = function (RED) {
58
58
  // Used to call the status update from the config node.
59
59
  node.setNodeStatus = ({ fill, shape, text, payload, GA, dpt, devicename }) => {
60
60
  try {
61
- if (node.server == null) { node.status({ fill: 'red', shape: 'dot', text: '[NO GATEWAY SELECTED]' }); return }
61
+ if (node.serverKNX === null) { node.status({ fill: 'red', shape: 'dot', text: '[NO GATEWAY SELECTED]' }); return }
62
62
  GA = GA === undefined ? '' : GA
63
63
  payload = payload === undefined ? '' : payload
64
64
  payload = typeof payload === 'object' ? JSON.stringify(payload) : payload
@@ -71,7 +71,7 @@ module.exports = function (RED) {
71
71
  // 02/12/2022 Expose the complete ETS CSV as well
72
72
  if (node.exposeAsVariable !== 'exposeAsVariableNO') {
73
73
  try {
74
- node.server.csv.forEach(element => {
74
+ node.serverKNX.csv.forEach(element => {
75
75
  node.exposedGAs.push({ address: element.ga, dpt: element.dpt, devicename: element.devicename, payload: undefined })
76
76
  })
77
77
  } catch (error) {
@@ -105,7 +105,7 @@ module.exports = function (RED) {
105
105
  // 13/09/2021 retrieve the datapoint if not specified
106
106
  if (element.hasOwnProperty('dpt') === false || element.dpt === undefined || element.dpt === '') {
107
107
  try {
108
- const sDPT = node.server.csv.find(item => item.ga === element.address).dpt
108
+ const sDPT = node.serverKNX.csv.find(item => item.ga === element.address).dpt
109
109
  element.dpt = sDPT
110
110
  } catch (error) {
111
111
  node.setNodeStatus({ fill: 'RED', shape: 'dot', text: 'Datapoint not found in CSV for ' + element.address, payload: '', GA: '', dpt: '', devicename: '' })
@@ -117,7 +117,7 @@ module.exports = function (RED) {
117
117
  }
118
118
 
119
119
  node.setNodeStatus({ fill: 'green', shape: 'dot', text: 'Write', payload: element.payload, GA: element.address, dpt: element.dpt || '', devicename: '' })
120
- node.server.writeQueueAdd({ grpaddr: element.address, payload: element.payload, dpt: element.dpt || '', outputtype: 'write', nodecallerid: node.id })
120
+ node.serverKNX.sendKNXTelegramToKNXEngine({ grpaddr: element.address, payload: element.payload, dpt: element.dpt || '', outputtype: 'write', nodecallerid: node.id })
121
121
  }
122
122
  oContext = null // 21/03/2022
123
123
  node.goTimerGo()
@@ -167,16 +167,16 @@ module.exports = function (RED) {
167
167
  node.on('close', function (done) {
168
168
  if (node.timerExposedGAs !== null) clearTimeout(node.timerExposedGAs)
169
169
  node.exposedGAs = []
170
- if (node.server) {
171
- node.server.removeClient(node)
170
+ if (node.serverKNX) {
171
+ node.serverKNX.removeClient(node)
172
172
  }
173
173
  done()
174
174
  })
175
175
 
176
176
  // On each deploy, unsubscribe+resubscribe
177
- if (node.server) {
178
- node.server.removeClient(node)
179
- node.server.addClient(node)
177
+ if (node.serverKNX) {
178
+ node.serverKNX.removeClient(node)
179
+ node.serverKNX.addClient(node)
180
180
  }
181
181
  }
182
182
  RED.nodes.registerType('knxUltimateGlobalContext', knxUltimateGlobalContext)
@@ -2,7 +2,7 @@ module.exports = function (RED) {
2
2
  function knxUltimateHueBattery(config) {
3
3
  RED.nodes.createNode(this, config);
4
4
  const node = this;
5
- node.server = RED.nodes.getNode(config.server);
5
+ node.serverKNX = RED.nodes.getNode(config.server);
6
6
  node.serverHue = RED.nodes.getNode(config.serverHue);
7
7
  node.topic = node.name;
8
8
  node.name = config.name === undefined ? 'Hue' : config.name;
@@ -69,7 +69,7 @@ module.exports = function (RED) {
69
69
  knxMsgPayload.payload = _event.power_state.battery_level;
70
70
  // Send to KNX bus
71
71
  if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
72
- node.server.writeQueueAdd({
72
+ node.serverKNX.sendKNXTelegramToKNXEngine({
73
73
  grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id,
74
74
  });
75
75
  }
@@ -100,16 +100,16 @@ module.exports = function (RED) {
100
100
  knxMsgPayload.payload = _level;
101
101
  // Send to KNX bus
102
102
  if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
103
- node.server.writeQueueAdd({
103
+ node.serverKNX.sendKNXTelegramToKNXEngine({
104
104
  grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'response', nodecallerid: node.id,
105
105
  });
106
106
  }
107
107
  };
108
108
 
109
109
  // On each deploy, unsubscribe+resubscribe
110
- if (node.server) {
111
- node.server.removeClient(node);
112
- node.server.addClient(node);
110
+ if (node.serverKNX) {
111
+ node.serverKNX.removeClient(node);
112
+ node.serverKNX.addClient(node);
113
113
  }
114
114
  if (node.serverHue) {
115
115
  node.serverHue.removeClient(node);
@@ -121,8 +121,8 @@ module.exports = function (RED) {
121
121
  });
122
122
 
123
123
  node.on('close', (done) => {
124
- if (node.server) {
125
- node.server.removeClient(node);
124
+ if (node.serverKNX) {
125
+ node.serverKNX.removeClient(node);
126
126
  }
127
127
  if (node.serverHue) {
128
128
  node.serverHue.removeClient(node);