node-red-contrib-knx-ultimate 2.1.13 → 2.1.15

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
+ <p>
10
+ <b>Version 2.1.15</b> - June 2023<br/>
11
+ - Fix an issue with auto discovery of not registered HUE bridges. Now you must first set the IP, then click CONNECT.<br/>
12
+ </p>
13
+ <p>
14
+ <b>Version 2.1.14</b> - June 2023<br/>
15
+ - Hue Light node: added day/night behaviour.<br/>
16
+ </p>
9
17
  <p>
10
18
  <b>Version 2.1.13</b> - June 2023<br/>
11
19
  - Hue Light node: fixed inversion in the color temp state.<br/>
@@ -11,8 +11,11 @@
11
11
  clientkey: { type: "password" }
12
12
  },
13
13
  oneditprepare: function () {
14
-
15
-
14
+ if (this.bridgeid === undefined || this.bridgeid === '') {
15
+ $("#divDetails").hide()
16
+ } else {
17
+ $("#divDetails").show()
18
+ }
16
19
  $("#getinfocam").click(function () {
17
20
 
18
21
  var myNotification = RED.notify("Please press the Link button on the HUE Bridge / Pre favore, premi il pulsante sul bridge HUE",
@@ -25,7 +28,7 @@
25
28
  text: "OK",
26
29
  click: function (e) {
27
30
  // Send the infos to Supergiovane
28
- $.getJSON("KNXUltimateRegisterToHueBridge", (data) => {
31
+ $.getJSON("KNXUltimateRegisterToHueBridge?IP=" + $("#node-config-input-host").val(), (data) => {
29
32
  this.value = "Connect";
30
33
  this.disabled = false;
31
34
  if (data.hasOwnProperty("error")) {
@@ -35,16 +38,18 @@
35
38
  fixed: false,
36
39
  type: 'error'
37
40
  });
38
- this.disabled = true;
41
+ this.disabled = false;
42
+ $("#divDetails").hide()
39
43
  return;
40
44
  }
41
45
 
42
46
  // Expected { bridge: bridgeConfig, user: createdUser }
43
47
  $("#node-config-input-name").val(data.bridge.data.name);
44
- $("#node-config-input-host").val(data.bridge.data.ipaddress);
48
+ // $("#node-config-input-host").val(data.bridge.data.ipaddress);
45
49
  $("#node-config-input-username").val(data.user.username);
46
50
  $("#node-config-input-clientkey").val(data.user.clientkey);
47
51
  $("#node-config-input-bridgeid").val(data.bridge.data.bridgeid);
52
+ $("#divDetails").show()
48
53
 
49
54
  }).error(function (jqXHR, textStatus, errorThrown) {
50
55
  RED.notify("Something went wrong. Please create at least a KNX Gateway node first.",
@@ -88,51 +93,54 @@
88
93
 
89
94
  <p align='center'> <img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/huehub.jpg' width='40%'></p>
90
95
 
91
-
92
- <div class="form-row">
93
- <label><i class="fa fa-sign-in"></i>&nbspRegister</label>
94
- <input type="button" id="getinfocam" class="ui-button ui-corner-all ui-widget" style="background-color:#AEE1FF;width:150px" value="CONNECT">
95
- </div>
96
-
97
- <div class="form-row">
98
- <label for="node-config-input-name">
99
- <i class="fa fa-tag"></i>
100
- <span data-i18n="hue-config.properties.node-config-input-name"</span>
101
- </label>
102
- <input type="text" id="node-config-input-name" ><data-i18n="[Title]hue-config.properties.node-config-input-name" style="margin-left:5px;">
103
- </div>
104
-
105
- <div class="form-row">
106
- <label for="node-config-input-bridgeid">
107
- <i class="fa fa-tag"></i>
108
- Bridge ID
109
- </label>
110
- <input type="text" id="node-config-input-bridgeid" disabled>
111
- </div>
112
-
96
+
113
97
  <div class="form-row">
114
98
  <label for="node-config-input-host">
115
99
  <i class="fa fa-server"></i>
116
- <span data-i18n="hue-config.properties.host"</span>
100
+ <span data-i18n="hue-config.properties.host" </span>
117
101
  </label>
118
- <input type="text" id="node-config-input-host"><data-i18n="[Title]hue-config.properties.host_info" style="margin-left:5px;">
102
+ <input type="text" id="node-config-input-host" placeholder="Write here the HUE bridge's IP, then click CONNECT">
119
103
  </div>
120
104
  <div class="form-row">
121
- <label for="node-config-input-username"> Username</label>
122
- <input type="password" id="node-config-input-username" placeholder="">
123
- </div>
124
- <div class="form-row">
125
- <label for="node-config-input-clientkey"> Bridge Key</label>
126
- <input type="password" id="node-config-input-clientkey" placeholder="">
105
+ <label><i class="fa fa-sign-in"></i>&nbspRegister</label>
106
+ <input type="button" id="getinfocam" class="ui-button ui-corner-all ui-widget"
107
+ style="background-color:#AEE1FF;width:150px" value="CONNECT">
127
108
  </div>
109
+
110
+ <div id="divDetails" hidden>
111
+ <div class="form-row">
112
+ <label for="node-config-input-name">
113
+ <i class="fa fa-tag"></i>
114
+ <span data-i18n="hue-config.properties.node-config-input-name" </span>
115
+ </label>
116
+ <input type="text" id="node-config-input-name"><data-i18n="[Title]hue-config.properties.node-config-input-name"
117
+ style="margin-left:5px;">
118
+ </div>
128
119
 
120
+ <div class="form-row">
121
+ <label for="node-config-input-bridgeid">
122
+ <i class="fa fa-tag"></i>
123
+ Bridge ID
124
+ </label>
125
+ <input type="text" id="node-config-input-bridgeid" disabled>
126
+ </div>
127
+
128
+ <div class="form-row">
129
+ <label for="node-config-input-username"> Username</label>
130
+ <input type="password" id="node-config-input-username" placeholder="">
131
+ </div>
132
+ <div class="form-row">
133
+ <label for="node-config-input-clientkey"> Bridge Key</label>
134
+ <input type="password" id="node-config-input-clientkey" placeholder="">
135
+ </div>
136
+ </div>
129
137
 
130
138
 
131
139
  </script>
132
140
  <script type="text/html" data-help-name="hue-config">
133
141
  <p> This node registers to the Hue Bridge.<br/>
134
142
 
135
- Just click **Connect** button.
143
+ Just set the Bridge's ip and click **CONNECT** button.
136
144
 
137
145
  [Find it useful?](https://www.paypal.me/techtoday)
138
146
 
@@ -51,7 +51,7 @@ module.exports = (RED) => {
51
51
  res.json(dpts)
52
52
  })
53
53
 
54
- function hueConfig (config) {
54
+ function hueConfig(config) {
55
55
  RED.nodes.createNode(this, config)
56
56
  const node = this
57
57
  node.host = config.host
@@ -124,9 +124,12 @@ module.exports = (RED) => {
124
124
  node.nodeClients = []
125
125
  node.hueManager.removeAllListeners();
126
126
  (async () => {
127
- await node.hueManager.close()
128
- node.hueManager = null
129
- delete node.hueManager
127
+ try {
128
+ await node.hueManager.close()
129
+ node.hueManager = null
130
+ delete node.hueManager
131
+ } catch (error) {
132
+ }
130
133
  done()
131
134
  })()
132
135
  } catch (error) {
@@ -99,7 +99,7 @@ return msg;`,
99
99
  res.json(jRet)
100
100
  })
101
101
 
102
- function knxUltimateConfigNode (config) {
102
+ function knxUltimateConfigNode(config) {
103
103
  RED.nodes.createNode(this, config)
104
104
  const node = this
105
105
  node.host = config.host
@@ -170,7 +170,7 @@ return msg;`,
170
170
  }
171
171
 
172
172
  node.setAllClientsStatus = (_status, _color, _text) => {
173
- function nextStatus (_oClient) {
173
+ function nextStatus(_oClient) {
174
174
  let oClient = RED.nodes.getNode(_oClient.id)
175
175
  oClient.setNodeStatus({ fill: _color, shape: 'dot', text: _status + ' ' + _text, payload: '', GA: oClient.topic, dpt: '', devicename: '' })
176
176
  oClient = null
@@ -216,7 +216,7 @@ return msg;`,
216
216
  // 04/04/2021 Supergiovane, creates the service paths where the persistent files are created.
217
217
  // The values file is stored only upon disconnection/close
218
218
  // ************************
219
- function setupDirectory (_aPath) {
219
+ function setupDirectory(_aPath) {
220
220
  if (!fs.existsSync(_aPath)) {
221
221
  // Create the path
222
222
  try {
@@ -236,7 +236,7 @@ return msg;`,
236
236
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.info('KNXUltimate-config: payload cache set to ' + path.join(node.userDir, 'knxpersistvalues'))
237
237
  }
238
238
 
239
- function saveExposedGAs () {
239
+ function saveExposedGAs() {
240
240
  const sFile = path.join(node.userDir, 'knxpersistvalues', 'knxpersist' + node.id + '.json')
241
241
  try {
242
242
  if (node.exposedGAs.length > 0) {
@@ -247,7 +247,7 @@ return msg;`,
247
247
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error('KNXUltimate-config: unable to write peristent values to the file ' + sFile + ' ' + err.message)
248
248
  }
249
249
  }
250
- function loadExposedGAs () {
250
+ function loadExposedGAs() {
251
251
  const sFile = path.join(node.userDir, 'knxpersistvalues', 'knxpersist' + node.id + '.json')
252
252
  try {
253
253
  node.exposedGAs = JSON.parse(fs.readFileSync(sFile, 'utf8'))
@@ -262,6 +262,10 @@ return msg;`,
262
262
  // Endpoint for connecting to HUE Bridge
263
263
  RED.httpAdmin.get('/KNXUltimateRegisterToHueBridge', RED.auth.needsPermission('knxUltimate-config.read'), function (req, res) {
264
264
  try {
265
+ if (typeof req.query.nodeID !== 'undefined' && req.query.nodeID !== null && req.query.nodeID !== '') {
266
+ const _node = RED.nodes.getNode(req.query.nodeID)// Retrieve node.id of the config node.
267
+ if (_node !== null) res.json(RED.nodes.getNode(_node.id).csv)
268
+ }
265
269
  (async () => {
266
270
  try {
267
271
  // °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
@@ -272,20 +276,21 @@ return msg;`,
272
276
  const appName = 'KNXUltimate'
273
277
  const deviceName = 'Node-Red'
274
278
 
275
- async function discoverBridge () {
276
- const discoveryResults = await discovery.nupnpSearch()
279
+ // async function discoverBridge() {
280
+ // const discoveryResults = await discovery.nupnpSearch()
277
281
 
278
- if (discoveryResults.length === 0) {
279
- if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error('Failed to resolve any Hue Bridges')
280
- return null
281
- } else {
282
- // Ignoring that you could have more than one Hue Bridge on a network as this is unlikely in 99.9% of users situations
283
- return discoveryResults[0].ipaddress
284
- }
285
- }
282
+ // if (discoveryResults.length === 0) {
283
+ // if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error('Failed to resolve any Hue Bridges')
284
+ // return null
285
+ // } else {
286
+ // // Ignoring that you could have more than one Hue Bridge on a network as this is unlikely in 99.9% of users situations
287
+ // return discoveryResults[0].ipaddress
288
+ // }
289
+ // }
286
290
 
287
- async function discoverAndCreateUser () {
288
- const ipAddress = await discoverBridge()
291
+ async function discoverAndCreateUser() {
292
+ // const ipAddress = await discoverBridge()
293
+ const ipAddress = req.query.IP
289
294
 
290
295
  // Create an unauthenticated instance of the Hue API so that we can create a new user
291
296
  const unauthenticatedApi = await hueApi.createLocal(ipAddress).connect()
@@ -533,7 +538,7 @@ return msg;`,
533
538
  }
534
539
 
535
540
  // 17/02/2020 Do initial read (called by node.timerDoInitialRead timer)
536
- function DoInitialReadFromKNXBusOrFile () {
541
+ function DoInitialReadFromKNXBusOrFile() {
537
542
  if (node.linkStatus !== 'connected') return // 29/08/2019 If not connected, exit
538
543
  loadExposedGAs() // 04/04/2021 load the current values of GA payload
539
544
  try {
@@ -893,7 +898,7 @@ return msg;`,
893
898
 
894
899
  // Handle BUS events
895
900
  // ---------------------------------------------------------------------------------------
896
- function handleBusEvents (_datagram, _echoed) {
901
+ function handleBusEvents(_datagram, _echoed) {
897
902
  // console.time('handleBusEvents');
898
903
 
899
904
  let _rawValue = null
@@ -1161,7 +1166,7 @@ return msg;`,
1161
1166
  node.telegramsQueue.unshift(_clonedMessage) // Add _clonedMessage as first in the queue pile
1162
1167
  }
1163
1168
 
1164
- function handleTelegramQueue () {
1169
+ function handleTelegramQueue() {
1165
1170
  if (node.knxConnection !== null || node.host.toUpperCase() === 'EMULATE') {
1166
1171
  if (node.lockHandleTelegramQueue === true) return // Exits if the funtion is busy
1167
1172
  node.lockHandleTelegramQueue = true // Lock the function. It cannot be called again until finished.
@@ -1310,14 +1315,14 @@ return msg;`,
1310
1315
  }
1311
1316
 
1312
1317
  // 14/08/2019 If the node has payload same as the received telegram, return false
1313
- function checkRBEInputFromKNXBusAllowSend (_node, _KNXTelegramPayload) {
1318
+ function checkRBEInputFromKNXBusAllowSend(_node, _KNXTelegramPayload) {
1314
1319
  if (_node.inputRBE !== true) return true
1315
1320
 
1316
1321
  return !_.isEqual(_node.currentPayload, _KNXTelegramPayload)
1317
1322
  }
1318
1323
 
1319
1324
  // 26/10/2019 Try to figure out the datapoint type from raw value
1320
- function tryToFigureOutDataPointFromRawValue (_rawValue) {
1325
+ function tryToFigureOutDataPointFromRawValue(_rawValue) {
1321
1326
  // 25/10/2019 Try some Datapoints
1322
1327
  if (_rawValue === null) return '1.001'
1323
1328
  if (_rawValue.length === 1) {
@@ -1363,7 +1368,7 @@ return msg;`,
1363
1368
  }
1364
1369
  }
1365
1370
 
1366
- function buildInputMessage ({ _srcGA, _destGA, _event, _Rawvalue, _inputDpt, _devicename, _outputtopic, _oNode }) {
1371
+ function buildInputMessage({ _srcGA, _destGA, _event, _Rawvalue, _inputDpt, _devicename, _outputtopic, _oNode }) {
1367
1372
  let sPayloadmeasureunit = 'unknown'
1368
1373
  let sDptdesc = 'unknown'
1369
1374
  let sPayloadsubtypevalue = 'unknown'
@@ -1470,7 +1475,7 @@ return msg;`,
1470
1475
  }
1471
1476
  };
1472
1477
 
1473
- function readCSV (_csvText) {
1478
+ function readCSV(_csvText) {
1474
1479
  // 26/05/2023 check if the text is a file path
1475
1480
  if (_csvText.toUpperCase().includes('.CSV') || _csvText.toUpperCase().includes('.ESF')) {
1476
1481
  // I'ts a file. Read it now and pass to the _csvText
@@ -1564,7 +1569,7 @@ return msg;`,
1564
1569
  }
1565
1570
  }
1566
1571
 
1567
- function readESF (_esfText) {
1572
+ function readESF(_esfText) {
1568
1573
  // 24/02/2020 must do an EIS to DPT conversion.
1569
1574
  // https://www.loxone.com/dede/kb/eibknx-datentypen/
1570
1575
  // Format: Attuatori luci.Luci primo piano.0/0/1 Luce camera da letto EIS 1 'Switching' (1 Bit) Low
@@ -1648,7 +1653,7 @@ return msg;`,
1648
1653
  }
1649
1654
 
1650
1655
  // 23/08/2019 Delete unwanted CRLF in the GA description
1651
- function correctCRLFInCSV (_csv) {
1656
+ function correctCRLFInCSV(_csv) {
1652
1657
  let sOut = '' // fixed output text to return
1653
1658
  let sChar = ''
1654
1659
  let bStart = false
@@ -1681,7 +1686,7 @@ return msg;`,
1681
1686
  }
1682
1687
 
1683
1688
  // 26/02/2021 Used to send the messages if the node gateway is in EMULATION mode
1684
- function sendEmulatedTelegram (_msg) {
1689
+ function sendEmulatedTelegram(_msg) {
1685
1690
  // INPUT IS
1686
1691
  // _msg = {
1687
1692
  // grpaddr: '5/0/1',
@@ -52,6 +52,13 @@
52
52
  GALightColorCycle: { value: "" },
53
53
  dptLightColorCycle: { value: "" },
54
54
 
55
+ colorAtSwitchOnDayTime: { value: '{"red":255, "green":255, "blue":255}' },
56
+ colorAtSwitchOnNightTime: { value: '{"red":23, "green":4, "blue":0}' },
57
+
58
+ nameDaylightSensor: { value: "" },
59
+ GADaylightSensor: { value: "" },
60
+ dptDaylightSensor: { value: "" },
61
+
55
62
  hueDevice: { value: "" }
56
63
  },
57
64
  inputs: 0,
@@ -607,6 +614,53 @@
607
614
  // ########################
608
615
 
609
616
 
617
+ // DPT Day/Time sensor
618
+ // ########################
619
+ $.getJSON('knxUltimateDpts', (data) => {
620
+ data.forEach(dpt => {
621
+ if (dpt.value.startsWith("1.")) {
622
+ $("#node-input-dptDaylightSensor").append($("<option></option>")
623
+ .attr("value", dpt.value)
624
+ .text(dpt.text))
625
+ }
626
+ });
627
+ $("#node-input-dptDaylightSensor").val(this.dptDaylightSensor)
628
+ })
629
+
630
+ // Autocomplete suggestion with ETS csv File
631
+ $("#node-input-GADaylightSensor").autocomplete({
632
+ minLength: 1,
633
+ source: function (request, response) {
634
+ //$.getJSON("csv", request, function( data, status, xhr ) {
635
+ $.getJSON("knxUltimatecsv?nodeID=" + oNodeServer.id, (data) => {
636
+ response($.map(data, function (value, key) {
637
+ var sSearch = (value.ga + " (" + value.devicename + ") DPT" + value.dpt);
638
+ if (fullSearch(sSearch, request.term + " 1.")) {
639
+ return {
640
+ label: value.ga + " # " + value.devicename + " # " + value.dpt, // Label for Display
641
+ value: value.ga // Value
642
+ }
643
+ } else {
644
+ return null;
645
+ }
646
+ }));
647
+ });
648
+ }, select: function (event, ui) {
649
+ // Sets Datapoint and device name automatically
650
+ var sDevName = ui.item.label.split("#")[1].trim();
651
+ try {
652
+ sDevName = sDevName.substr(sDevName.indexOf(")") + 1).trim();
653
+ } catch (error) {
654
+ }
655
+ $('#node-input-nameDaylightSensor').val(sDevName);
656
+ var optVal = $("#node-input-dptDaylightSensor option:contains('" + ui.item.label.split("#")[2].trim() + "')").attr('value');
657
+ // Select the option value
658
+ $("#node-input-dptDaylightSensor").val(optVal);
659
+ }
660
+ });
661
+ // ########################
662
+
663
+
610
664
 
611
665
  // Autocomplete suggestion with HUE Lights
612
666
  $("#node-input-name").autocomplete({
@@ -727,6 +781,33 @@
727
781
  <label for="node-input-nameLightState" style="width:50px; margin-left: 0px; text-align: right;"><span data-i18n="knxUltimateHueLight.node-input-name"></span></label>
728
782
  <input type="text" id="node-input-nameLightState" style="width:200px;margin-left: 5px; text-align: left;">
729
783
  </div>
784
+
785
+ <div class="form-row">
786
+ <label for="node-input-nameDaylightSensor" style="width:100px;"><i class="fa fa-clock-o"></i> Day/Night</label>
787
+
788
+ <label for="node-input-GADaylightSensor" style="width:20px;">GA</label>
789
+ <input type="text" id="node-input-GADaylightSensor" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
790
+
791
+ <label for="node-input-dptDaylightSensor" style="width:40px; margin-left: 0px; text-align: right;">DPT</label>
792
+ <select id="node-input-dptDaylightSensor" style="width:140px;"></select>
793
+
794
+ <label for="node-input-nameDaylightSensor" style="width:50px; margin-left: 0px; text-align: right;"><span data-i18n="knxUltimateHueLight.node-input-name"></span></label>
795
+ <input type="text" id="node-input-nameDaylightSensor" style="width:200px;margin-left: 5px; text-align: left;">
796
+ </div>
797
+
798
+ <div class="form-row">
799
+ <label for="node-input-colorAtSwitchOnDayTime" style="width:200px">
800
+ <i class="fa fa-sun-o"></i> Switch on color at Daytime
801
+ </label>
802
+ <input type="text" id="node-input-colorAtSwitchOnDayTime" placeholder='{"red":255, "green":255, "blue":255}' style="width:250px">
803
+ </div>
804
+ <div class="form-row">
805
+ <label for="node-input-colorAtSwitchOnNightTime" style="width:200px">
806
+ <i class="fa fa-moon-o"></i> Switch on color at Nighttime
807
+ </label>
808
+ <input type="text" id="node-input-colorAtSwitchOnNightTime" placeholder='{"red":100, "green":0, "blue":50}' style="width:250px">
809
+ </div>
810
+
730
811
  </p>
731
812
  </div>
732
813
  <div id="tabs-2">
@@ -891,7 +972,9 @@ Start typing in the GA field, the name or group address of your KNX device, the
891
972
  | Brightness Status| Link this to the light's brightness status group address |
892
973
  | Blink| *true* Blink the light, *false* Stop blinking. Blinks the light on and off. Useful for signalling. Works with all HUE lights. |
893
974
  | Color Cycle| *true* start cycle, *false* Stop cycle. Randomly changes the HUE light's color at regular interval. Works with all HUE lights having color capabilities. |
894
-
975
+ | Day/Night | *true* if daytime, *false* if nighttime. This GA is used to change some behaviours at day or night. |
976
+ | Switch on color at Daytime | You can choose the color/brightness of your light, at switch on, on night time. Set it as JSON object, like { "red": 255, "green": 255, "blue": 255 } |
977
+ | Switch on color at Nighttime | You can choose the color/brightness of your light, at switch on, on night time. Set it as JSON object, like { "red": 100, "green": 0, "blue": 0 } |
895
978
  <br/>
896
979
 
897
980
  [Find it useful?](https://www.paypal.me/techtoday)
@@ -27,6 +27,7 @@ module.exports = function (RED) {
27
27
  node.formatnegativevalue = 'leave'
28
28
  node.formatdecimalsvalue = 2
29
29
  node.currentHUEDevice = undefined
30
+ node.DayTime = true
30
31
 
31
32
  // Used to call the status update from the config node.
32
33
  node.setNodeStatus = ({ fill, shape, text, payload }) => {
@@ -45,7 +46,20 @@ module.exports = function (RED) {
45
46
  switch (msg.knx.destination) {
46
47
  case config.GALightSwitch:
47
48
  msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightSwitch))
48
- state = msg.payload === true ? { on: { on: true },dimming: { brightness: 100 } } : { on: { on: false }, dimming: { brightness: 0 }}
49
+ if (msg.payload) {
50
+ let jColorChoosen = { red: 255, green: 255, blue: 255 }
51
+ if (node.DayTime) {
52
+ jColorChoosen = JSON.parse(config.colorAtSwitchOnDayTime || '{ "red": 255, "green": 255, "blue": 255 }')
53
+ } else {
54
+ jColorChoosen = JSON.parse(config.colorAtSwitchOnNightTime || '{ "red": 255, "green": 255, "blue": 255 }')
55
+ }
56
+ let dgamut = node.currentHUEDevice !== undefined ? node.currentHUEDevice.color.gamut_type : null
57
+ let dretXY = hueColorConverter.ColorConverter.rgbToXy(jColorChoosen.red, jColorChoosen.green, jColorChoosen.blue, dgamut)
58
+ let dbright = hueColorConverter.ColorConverter.getBrightnessFromRGB(jColorChoosen.red, jColorChoosen.green, jColorChoosen.blue)
59
+ state = dbright > 0 ? { on: { on: true }, dimming: { brightness: dbright }, color: { xy: dretXY } } : { on: { on: false } }
60
+ } else {
61
+ state = { on: { on: false } }
62
+ }
49
63
  node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, state, 'setLight')
50
64
  break
51
65
  case config.GALightDIM:
@@ -59,6 +73,9 @@ module.exports = function (RED) {
59
73
  node.startDimStopper('stop')
60
74
  }
61
75
  break
76
+ case config.GADaylightSensor:
77
+ node.DayTime = Boolean(dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptDaylightSensor)))
78
+ break
62
79
  case config.GALightHSV:
63
80
  if (config.dptLightHSV === '3.007') {
64
81
  // MDT smartbutton will dim the color temperature
@@ -245,20 +245,20 @@ class classHUE extends EventEmitter {
245
245
  }
246
246
 
247
247
  // Get the light details
248
- getLightStatus = async (_rid) => {
248
+ getLightStatus = async (_rid) => {
249
249
  try {
250
250
  const hue = hueApiV2.connect({ host: this.hueBridgeIP, key: this.username })
251
251
  const oLight = await hue.getLight(_rid)
252
252
  return oLight[0]
253
- } catch (error) {
254
- }
253
+ } catch (error) {
254
+ }
255
255
  }
256
256
 
257
257
  close = async () => {
258
258
  return new Promise((resolve, reject) => {
259
259
  try {
260
260
  this.closePushEventStream = true
261
- this.es.close();
261
+ if (this.es !== null) this.es.close();
262
262
  this.es = null;
263
263
  setTimeout(() => {
264
264
  resolve(true)
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "engines": {
4
4
  "node": ">=16.0.0"
5
5
  },
6
- "version": "2.1.13",
6
+ "version": "2.1.15",
7
7
  "description": "Control your KNX intallation via Node-Red! Single Node KNX IN/OUT with optional ETS group address importer. Easy to use and highly configurable. With integrated Philips HUE devices handling.",
8
8
  "dependencies": {
9
9
  "mkdirp": "1.0.4",