node-red-contrib-knx-ultimate 2.0.13 → 2.0.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,9 +6,15 @@
6
6
 
7
7
  # CHANGELOG
8
8
 
9
+ <p>
10
+ <b>Version 2.0.15</b> - June 2023<br/>
11
+ - HUE: CAUTION POSSIBLE BREAKING CHANGES TO THE HUE NODES. PLEASE BE AWARE THAT HUE NODES ARE STILL IN BETA<br/>
12
+ - NEW: Temperature sensor.<br/>
13
+ - Changes to HUE Light node, to mime the ISE KNX CONNECT HUE beavior.<br/>
14
+ </p>
9
15
  <p>
10
16
  <b>Version 2.0.13</b> - June 2023<br/>
11
- - HUE: CAUTION BREAKING CHANGES TO THE HUE NODES. PLEASE BE AWARE THAT HUE NODES ARE STILL IN BETA<br/>
17
+ - HUE: CAUTION POSSIBLE BREAKING CHANGES TO THE HUE NODES. PLEASE BE AWARE THAT HUE NODES ARE STILL IN BETA<br/>
12
18
  - Hue Button node: fixed missing events in output msg.<br/>
13
19
  </p>
14
20
  <p>
@@ -91,22 +91,22 @@ module.exports = (RED) => {
91
91
  })
92
92
 
93
93
 
94
- RED.httpAdmin.get('/KNXUltimateGetDevicesHUE', RED.auth.needsPermission('hue-config.read'), function (req, res) {
94
+ RED.httpAdmin.get('/KNXUltimateGetResourcesHUE', RED.auth.needsPermission('hue-config.read'), function (req, res) {
95
95
  try {
96
96
  (async () => {
97
97
  try {
98
98
  // °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
99
99
  const _node = RED.nodes.getNode(req.query.nodeID)// Retrieve node.id of the config node.
100
- const jRet = await node.hueManager.getDevices(req.query.rtype, _node.host, _node.credentials.username)
100
+ const jRet = await node.hueManager.getResources(req.query.rtype, _node.host, _node.credentials.username)
101
101
  res.json(jRet)
102
102
  // °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
103
103
  } catch (err) {
104
- RED.log.error('Errore KNXUltimateGetDevicesHUE non gestito ' + err.message)
104
+ RED.log.error('Errore KNXUltimateGetResourcesHUE non gestito ' + err.message)
105
105
  res.json({ error: err.message })
106
106
  }
107
107
  })()
108
108
  } catch (err) {
109
- RED.log.error('Errore KNXUltimateGetDevicesHUE bsonto ' + err.message)
109
+ RED.log.error('Errore KNXUltimateGetResourcesHUE bsonto ' + err.message)
110
110
  res.json({ error: err.message })
111
111
  }
112
112
  })
@@ -265,7 +265,7 @@
265
265
  $("#node-input-name").autocomplete({
266
266
  minLength: 1,
267
267
  source: function (request, response) {
268
- $.getJSON("KNXUltimateGetDevicesHUE?rtype=button&nodeID=" + oNodeServerHue.id, (data) => {
268
+ $.getJSON("KNXUltimateGetResourcesHUE?rtype=button&nodeID=" + oNodeServerHue.id, (data) => {
269
269
  response($.map(data.devices, function (value, key) {
270
270
  //alert(JSON.stringify(value) + " "+ key)
271
271
  var sSearch = (value.name);
@@ -401,7 +401,7 @@
401
401
  $("#node-input-name").autocomplete({
402
402
  minLength: 1,
403
403
  source: function (request, response) {
404
- $.getJSON("KNXUltimateGetDevicesHUE?rtype=light&nodeID=" + oNodeServerHue.id, (data) => {
404
+ $.getJSON("KNXUltimateGetResourcesHUE?rtype=light&nodeID=" + oNodeServerHue.id, (data) => {
405
405
  response($.map(data.devices, function (value, key) {
406
406
  //alert(JSON.stringify(value) + " "+ key)
407
407
  var sSearch = (value.name);
@@ -480,7 +480,7 @@
480
480
  <!-- <p> <img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/knx.png' width='32px'> -> <img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/hue.png' width='32px'></p> -->
481
481
 
482
482
  <p>
483
- <b>KNX COMMANDS -> TO PHILIPS HUE</b>
483
+ <b>KNX LINK</b>
484
484
  </p>
485
485
  <div class="form-row">
486
486
  <label for="node-input-nameLightSwitch" style="width:100px;"><i class="fa fa-play-circle-o"></i> <span data-i18n="knxUltimateHueLight.node-input-nameLightSwitch"></span></label>
@@ -494,6 +494,19 @@
494
494
  <label for="node-input-nameLightSwitch" style="width:50px; margin-left: 0px; text-align: right;"><span data-i18n="knxUltimateHueLight.node-input-name"></span></label>
495
495
  <input type="text" id="node-input-nameLightSwitch" style="width:200px;margin-left: 5px; text-align: left;">
496
496
  </div>
497
+ <div class="form-row">
498
+ <label for="node-input-nameLightState" style="width:100px;"><i class="fa fa-play-circle-o"></i> Switch Status</label>
499
+
500
+ <label for="node-input-GALightState" style="width:20px;">GA</label>
501
+ <input type="text" id="node-input-GALightState" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
502
+
503
+ <label for="node-input-dptLightState" style="width:40px; margin-left: 0px; text-align: right;">DPT</label>
504
+ <select id="node-input-dptLightState" style="width:140px;"></select>
505
+
506
+ <label for="node-input-nameLightState" style="width:50px; margin-left: 0px; text-align: right;"><span data-i18n="knxUltimateHueLight.node-input-name"></span></label>
507
+ <input type="text" id="node-input-nameLightState" style="width:200px;margin-left: 5px; text-align: left;">
508
+ </div>
509
+ <br/>
497
510
  </div>
498
511
  <div class="form-row">
499
512
  <label for="node-input-nameLightDIM" style="width:100px;"><i class="fa fa-play-circle-o"></i>&nbspDimming</label>
@@ -507,6 +520,7 @@
507
520
  <label for="node-input-nameLightDIM" style="width:50px; margin-left: 0px; text-align: right;"><span data-i18n="knxUltimateHueLight.node-input-name"></span></label>
508
521
  <input type="text" id="node-input-nameLightDIM" style="width:200px;margin-left: 5px; text-align: left;">
509
522
  </div>
523
+ <br/>
510
524
  </div>
511
525
  <div class="form-row">
512
526
  <label for="node-input-nameLightColor" style="width:100px;"><i class="fa fa-play-circle-o"></i>&nbspColor</label>
@@ -520,6 +534,19 @@
520
534
  <label for="node-input-nameLightColor" style="width:50px; margin-left: 0px; text-align: right;"><span data-i18n="knxUltimateHueLight.node-input-name"></span></label>
521
535
  <input type="text" id="node-input-nameLightColor" style="width:200px;margin-left: 5px; text-align: left;">
522
536
  </div>
537
+ <div class="form-row">
538
+ <label for="node-input-nameLightColorState" style="width:100px;"><i class="fa fa-play-circle-o"></i> Color Status</label>
539
+
540
+ <label for="node-input-GALightColorState" style="width:20px;"><span data-i18n="knxUltimateHueLight.node-input-GALightState"></span></label>
541
+ <input type="text" id="node-input-GALightColorState" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
542
+
543
+ <label for="node-input-dptLightColorState" style="width:40px; margin-left: 0px; text-align: right;">DPT</label>
544
+ <select id="node-input-dptLightColorState" style="width:140px;"></select>
545
+
546
+ <label for="node-input-nameLightColorState" style="width:50px; margin-left: 0px; text-align: right;"><span data-i18n="knxUltimateHueLight.node-input-name"></span></label>
547
+ <input type="text" id="node-input-nameLightColorState" style="width:200px;margin-left: 5px; text-align: left;">
548
+ </div>
549
+ <br/>
523
550
  </div>
524
551
  </div>
525
552
  <div class="form-row">
@@ -534,37 +561,7 @@
534
561
  <label for="node-input-nameLightBrightness" style="width:50px; margin-left: 0px; text-align: right;"><span data-i18n="knxUltimateHueLight.node-input-name"></span></label>
535
562
  <input type="text" id="node-input-nameLightBrightness" style="width:200px;margin-left: 5px; text-align: left;">
536
563
  </div>
537
-
538
- <br/>
539
- <p>
540
- <b>PHILIPS HUE LIGHT STATE -> TO KNX</b>
541
- </p>
542
-
543
- <div class="form-row">
544
- <label for="node-input-nameLightState" style="width:100px;"><i class="fa fa-play-circle-o"></i> Switch Status</label>
545
-
546
- <label for="node-input-GALightState" style="width:20px;">GA</label>
547
- <input type="text" id="node-input-GALightState" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
548
-
549
- <label for="node-input-dptLightState" style="width:40px; margin-left: 0px; text-align: right;">DPT</label>
550
- <select id="node-input-dptLightState" style="width:140px;"></select>
551
-
552
- <label for="node-input-nameLightState" style="width:50px; margin-left: 0px; text-align: right;"><span data-i18n="knxUltimateHueLight.node-input-name"></span></label>
553
- <input type="text" id="node-input-nameLightState" style="width:200px;margin-left: 5px; text-align: left;">
554
- </div>
555
- <div class="form-row">
556
- <label for="node-input-nameLightColorState" style="width:100px;"><i class="fa fa-play-circle-o"></i> Color Status</label>
557
-
558
- <label for="node-input-GALightColorState" style="width:20px;"><span data-i18n="knxUltimateHueLight.node-input-GALightState"></span></label>
559
- <input type="text" id="node-input-GALightColorState" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
560
-
561
- <label for="node-input-dptLightColorState" style="width:40px; margin-left: 0px; text-align: right;">DPT</label>
562
- <select id="node-input-dptLightColorState" style="width:140px;"></select>
563
-
564
- <label for="node-input-nameLightColorState" style="width:50px; margin-left: 0px; text-align: right;"><span data-i18n="knxUltimateHueLight.node-input-name"></span></label>
565
- <input type="text" id="node-input-nameLightColorState" style="width:200px;margin-left: 5px; text-align: left;">
566
- </div>
567
- </div>
564
+ </div>
568
565
  <div class="form-row">
569
566
  <label for="node-input-nameLightBrightnessState" style="width:100px;"><i class="fa fa-play-circle-o"></i>Brightness Status</label>
570
567
 
@@ -585,7 +582,7 @@
585
582
 
586
583
 
587
584
  <script type="text/markdown" data-help-name="knxUltimateHueLight">
588
- <p>This node lets you control your Philips HUE light and also get the states of this lights.
585
+ <p>This node lets you control your Philips HUE light and also get the states of this lights, to be sent to the KNX bus.
589
586
 
590
587
  **General**
591
588
  |Property|Description|
@@ -596,28 +593,20 @@
596
593
 
597
594
  <br/>
598
595
 
599
- **KNX COMMANDS -> TO PHILIPS HUE**
600
- Here you can choose the KNX addresses to be linked to the avaiable HUE light commands.<br/>
596
+ **KNX LINK**
597
+
598
+ Here you can choose the KNX addresses to be linked to the avaiable HUE light commands/states.<br/>
601
599
  Start typing in the GA field, the name or group address of your KNX device, the avaiable devices start showing up while you're typing.
602
600
 
603
601
  |Property|Description|
604
602
  |--|--|
605
- | Switch | This command is used to turn on/off the HUE light via a boolean KNX value true/false|
606
- | Dimming | This command is used to DIM the HUE light via a KNX relative DIM datapoint |
603
+ | Switch | This GA is used to turn on/off the HUE light via a boolean KNX value true/false|
604
+ | Switch Status| Link this to the light's switch status group address|
605
+ | Dimming | Relative DIM the HUE light |
607
606
  | Color | This command is used to change the HUE light's color. Accepted datapoint is RGB triplet (r,g,b). The node handles the gamut color correction. As soon as you send a color KNX telegran, the light turns on and sets color and brightness, derived from the brightness human perception. As soon as you send a KNX telegram with r,g,b set to zero, the light turns off |
607
+ | Color Status | Link this to the light's color status group address. Accepted datapoint is RGB triplet (r,g,b)|
608
608
  | Brightness | This command is used to change the absolute HUE light's brightness |
609
-
610
- <br/>
611
-
612
- **PHILIPS HUE LIGHT STATE -> TO KNX**
613
- Here you can link the state changes of your HUE light, to any KNX group address you want.<br/>
614
- Start typing in the GA field, the name or group address of your KNX device, the avaiable devices start showing up while you're typing.
615
-
616
- |Property|Description|
617
- |--|--|
618
- | Switch Status| This state is used to send on/off value to the selected KNX group address |
619
- | Color Status | This state is used to send changes of the HUE light's color. Accepted datapoint is RGB triplet (r,g,b)|
620
- | Brightness Status| This state is used to send changes of your absolute HUE light's brightness, to a KNX group address |
609
+ | Brightness Status| Link this to the light's brightness status group address |
621
610
 
622
611
  <br/>
623
612
 
@@ -103,21 +103,37 @@ module.exports = function (RED) {
103
103
  knxMsgPayload.topic = config.GALightState
104
104
  knxMsgPayload.dpt = config.dptLightState
105
105
  knxMsgPayload.payload = _event.on.on
106
+ // Send to KNX bus
107
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
108
+ // ISE Connect Hue emulation, send brightness
109
+ knxMsgPayload.topic = config.GALightBrightnessState
110
+ knxMsgPayload.dpt = config.dptLightBrightnessState
111
+ _event.on.on === true ? knxMsgPayload.payload = 100 : 0
112
+ // Send to KNX bus
113
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
106
114
  }
107
115
  if (_event.hasOwnProperty('color')) {
108
116
  knxMsgPayload.topic = config.GALightColorState
109
117
  knxMsgPayload.dpt = config.dptLightColorState
110
118
  knxMsgPayload.payload = hueColorConverter.ColorConverter.xyBriToRgb(_event.color.xy.x, _event.color.xy.y, node.currentHUEDevice.dimming.brightness)
119
+ // Send to KNX bus
120
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
111
121
  }
112
122
  if (_event.hasOwnProperty('dimming')) {
113
123
  knxMsgPayload.topic = config.GALightBrightnessState
114
124
  knxMsgPayload.dpt = config.dptLightBrightnessState
115
125
  knxMsgPayload.payload = _event.dimming.brightness
126
+ // Send to KNX bus
127
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
128
+ // ISE Connect Hue emulation, send true/false to switch state
129
+ knxMsgPayload.topic = config.GALightState
130
+ knxMsgPayload.dpt = config.dptLightState
131
+ _event.dimming.brightness > 0 ? knxMsgPayload.payload = true : false
132
+ // Send to KNX bus
133
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
134
+
116
135
  }
117
- // Send to KNX bus
118
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
119
136
  node.status({ fill: 'green', shape: 'dot', text: 'HUE->KNX State ' + JSON.stringify(knxMsgPayload.payload) + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
120
-
121
137
  }
122
138
  } catch (error) {
123
139
  node.status({ fill: 'red', shape: 'dot', text: 'HUE->KNX error ' + error.message + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
@@ -117,7 +117,7 @@
117
117
  $("#node-input-name").autocomplete({
118
118
  minLength: 1,
119
119
  source: function (request, response) {
120
- $.getJSON("KNXUltimateGetDevicesHUE?rtype=light_level&nodeID=" + oNodeServerHue.id, (data) => {
120
+ $.getJSON("KNXUltimateGetResourcesHUE?rtype=light_level&nodeID=" + oNodeServerHue.id, (data) => {
121
121
  response($.map(data.devices, function (value, key) {
122
122
  //alert(JSON.stringify(value) + " "+ key)
123
123
  var sSearch = (value.name);
@@ -117,7 +117,7 @@
117
117
  $("#node-input-name").autocomplete({
118
118
  minLength: 1,
119
119
  source: function (request, response) {
120
- $.getJSON("KNXUltimateGetDevicesHUE?rtype=motion&nodeID=" + oNodeServerHue.id, (data) => {
120
+ $.getJSON("KNXUltimateGetResourcesHUE?rtype=motion&nodeID=" + oNodeServerHue.id, (data) => {
121
121
  response($.map(data.devices, function (value, key) {
122
122
  //alert(JSON.stringify(value) + " "+ key)
123
123
  var sSearch = (value.name);
@@ -119,7 +119,7 @@
119
119
  $("#node-input-name").autocomplete({
120
120
  minLength: 1,
121
121
  source: function (request, response) {
122
- $.getJSON("KNXUltimateGetDevicesHUE?rtype=relative_rotary&nodeID=" + oNodeServerHue.id, (data) => {
122
+ $.getJSON("KNXUltimateGetResourcesHUE?rtype=relative_rotary&nodeID=" + oNodeServerHue.id, (data) => {
123
123
  response($.map(data.devices, function (value, key) {
124
124
  //alert(JSON.stringify(value) + " "+ key)
125
125
  var sSearch = (value.name);
@@ -0,0 +1,256 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('knxUltimateHueTemperatureSensor', {
3
+ category: "KNX Ultimate",
4
+ color: '#C7E9C0',
5
+ defaults: {
6
+ //buttonState: {value: true},
7
+ server: { type: "knxUltimate-config", required: false },
8
+ serverHue: { type: "hue-config", required: true },
9
+ name: { value: "" },
10
+
11
+ nametemperaturesensor: { value: "" },
12
+ GAtemperaturesensor: { value: "" },
13
+ dpttemperaturesensor: { value: "" },
14
+
15
+ hueDevice: { value: "" }
16
+ },
17
+ inputs: 0,
18
+ outputs: 1,
19
+ icon: "node-hue-icon.svg",
20
+ label: function () {
21
+ return (this.name);
22
+ },
23
+ paletteLabel: "Hue Temperature Sensor (beta)",
24
+ // button: {
25
+ // enabled: function() {
26
+ // // return whether or not the button is enabled, based on the current
27
+ // // configuration of the node
28
+ // return !this.changed
29
+ // },
30
+ // visible: function() {
31
+ // // return whether or not the button is visible, based on the current
32
+ // // configuration of the node
33
+ // return this.hasButton
34
+ // },
35
+ // //toggle: "buttonState",
36
+ // onclick: function() {}
37
+ // },
38
+ oneditprepare: function () {
39
+ var node = this;
40
+ var oNodeServer = RED.nodes.node($("#node-input-server").val()); // Store the config-node
41
+ var oNodeServerHue = RED.nodes.node($("#node-input-serverHue").val()); // Store the config-node
42
+
43
+ // 19/02/2020 Used to get the server sooner als deploy.
44
+ $("#node-input-server").change(function () {
45
+ try {
46
+ oNodeServer = RED.nodes.node($(this).val());
47
+ } catch (error) { }
48
+ });
49
+ // 19/02/2020 Used to get the server sooner als deploy.
50
+ $("#node-input-serverHue").change(function () {
51
+ try {
52
+ oNodeServerHue = RED.nodes.node($(this).val());
53
+ } catch (error) { }
54
+ });
55
+
56
+ // 31/03/2020 Search Helper
57
+ function fullSearch(sourceText, searchString) {
58
+ // This searches for all words in a string
59
+ var aSearchWords = searchString.toLowerCase().split(" ");
60
+ var i = 0;
61
+ for (let index = 0; index < aSearchWords.length; index++) {
62
+ if (sourceText.toLowerCase().indexOf(aSearchWords[index]) > -1) i += 1;
63
+ }
64
+ return i == aSearchWords.length;
65
+ }
66
+
67
+ // DPT
68
+ // ########################
69
+ $.getJSON('knxUltimateDpts', (data) => {
70
+ data.forEach(dpt => {
71
+ if (dpt.value.startsWith("9.001")) {
72
+ $("#node-input-dpttemperaturesensor").append($("<option></option>")
73
+ .attr("value", dpt.value)
74
+ .text(dpt.text))
75
+ }
76
+ });
77
+ $("#node-input-dpttemperaturesensor").val(this.dpttemperaturesensor)
78
+ })
79
+
80
+ // Autocomplete suggestion with ETS csv File
81
+ $("#node-input-GAtemperaturesensor").autocomplete({
82
+ minLength: 1,
83
+ source: function (request, response) {
84
+ //$.getJSON("csv", request, function( data, status, xhr ) {
85
+ $.getJSON("knxUltimatecsv?nodeID=" + oNodeServer.id, (data) => {
86
+ response($.map(data, function (value, key) {
87
+ var sSearch = (value.ga + " (" + value.devicename + ") DPT" + value.dpt);
88
+ if (fullSearch(sSearch, request.term + " 9.001")) {
89
+ return {
90
+ label: value.ga + " # " + value.devicename + " # " + value.dpt, // Label for Display
91
+ value: value.ga // Value
92
+ }
93
+ } else {
94
+ return null;
95
+ }
96
+ }));
97
+ });
98
+ }, select: function (event, ui) {
99
+ // Sets Datapoint and device name automatically
100
+ var sDevName = ui.item.label.split("#")[1].trim();
101
+ try {
102
+ sDevName = sDevName.substr(sDevName.indexOf(")") + 1).trim();
103
+ } catch (error) {
104
+ }
105
+ $('#node-input-nametemperaturesensor').val(sDevName);
106
+ var optVal = $("#node-input-dpttemperaturesensor option:contains('" + ui.item.label.split("#")[2].trim() + "')").attr('value');
107
+ // Select the option value
108
+ $("#node-input-dpttemperaturesensor").val(optVal);
109
+ }
110
+ });
111
+ // ########################
112
+
113
+
114
+
115
+
116
+ // Autocomplete suggestion with HUE
117
+ $("#node-input-name").autocomplete({
118
+ minLength: 1,
119
+ source: function (request, response) {
120
+ $.getJSON("KNXUltimateGetResourcesHUE?rtype=temperature&nodeID=" + oNodeServerHue.id, (data) => {
121
+ response($.map(data.devices, function (value, key) {
122
+ //alert(JSON.stringify(value) + " "+ key)
123
+ var sSearch = (value.name);
124
+ if (fullSearch(sSearch, request.term)) {
125
+ return {
126
+ hueDevice: value.id, // Label for Display
127
+ value: value.name // Value
128
+ }
129
+ } else {
130
+ return null;
131
+ }
132
+ }));
133
+ });
134
+ }, select: function (event, ui) {
135
+ // Sets the fields
136
+ $('#node-input-hueDevice').val(ui.item.hueDevice);
137
+ }
138
+ });
139
+
140
+
141
+ // ########################
142
+
143
+
144
+ },
145
+ oneditsave: function () {
146
+
147
+
148
+ },
149
+ oneditcancel: function () {
150
+
151
+ }
152
+ })
153
+
154
+ </script>
155
+
156
+ <script type="text/x-red" data-template-name="knxUltimateHueTemperatureSensor">
157
+
158
+
159
+ <div class="form-row">
160
+ <b>HUE Light Sensor node</b>&nbsp&nbsp<span style="color:red"
161
+ &nbsp<i class="fa fa-question-circle"></i></span>
162
+ &nbsp<a target="_blank" href="https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/en-hue-configuration"><u>Configuration</u></a>
163
+ <br />
164
+ <p align="center"><img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/hueMotion.png'></p>
165
+ <br />
166
+ <label for="node-input-server" >
167
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAKnRFWHRDcmVhdGlvbiBUaW1lAEZyIDYgQXVnIDIwMTAgMjE6NTI6MTkgKzAxMDD84aS8AAAAB3RJTUUH3gYYCicNV+4WIQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAARnQU1BAACxjwv8YQUAAACUSURBVHjaY2CgFZg5c+Z/ZEyWAZ8+f/6/ZsWs/xoamqMGkGrA6Wla/1+fVARjEBuGsSoGmY4eZSCNL59d/g8DIDbIAHR14OgFGQByKjIGKX5+6/T///8gGMQGiV1+/B0Fg70GIkD+RMYgxf/O5/7//2MSmAZhkBi6OrgB6Bg5DGB4ajr3f2xqsYYLSDE2THJUDg0AAAqyDVd4tp4YAAAAAElFTkSuQmCC"></img>
168
+ KNX GW
169
+ </label>
170
+ <input type="text" id="node-input-server" />
171
+ </div>
172
+
173
+ <div class="form-row">
174
+ <label for="node-input-serverHue">
175
+ <img src="data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAEKADAAQAAAABAAAAEAAAAAA0VXHyAAABFUlEQVQ4EZWSsWoCQRCG1yiENEFEi6QSkjqWWoqFoBYJ+Br6JHkMn8Iibd4ihQpaJIhWNkry/ZtdGZY78Qa+m39nZ+dm9s4550awglNBluS/gVtAX6KgDclf68w2OThgfR9iT/jnoEv4TtByDThWTCDKW4SSZTf/zj9/eZbN+izTDuKGimu0vPF8B/YN8aC8LmcOj/AAn9CFTEs70Js/oGqy79C69bqJ5XbQI2kGO5N8QL9D08S8zBtBF5ZaVsznpCMoqJnVdjTpb1Db0fwIWmQV6BLXzFOYgA6/gDVfQN9bBWp2J2hdWDPoBV5FrKnAJutHikk/CHHR8i7x4iG7qQ720IYvu3GFbpHjx3pFrOFYkA354z/5bkK826phyAAAAABJRU5ErkJggg=="/>
176
+ HUE Bridge
177
+ </label>
178
+ <input type="text" id="node-input-serverHue" />
179
+ </div>
180
+
181
+ <br/>
182
+ <p>
183
+ <b>Philips HUE</b>
184
+ </p>
185
+
186
+ <div class="form-row">
187
+ <label for="node-input-hueDevice" >
188
+ <i class="fa fa-play-circle"></i>&nbspHue Sensor</label>
189
+ <input type="text" id="node-input-name" placeholder="Enter your hue device name" />
190
+ <input type="hidden" id="node-input-hueDevice" />
191
+ </div>
192
+
193
+ <br/>
194
+
195
+ <p>
196
+ <b>PHILIPS HUE LIGHT EVENTS -> TO KNX</b>
197
+ </p>
198
+
199
+ <div class="form-row">
200
+ <label for="node-input-nametemperaturesensor" style="width:100px;"><i class="fa fa-play-circle-o"></i> Temp °C</span></label>
201
+
202
+ <label for="node-input-GAtemperaturesensor" style="width:20px;">GA</label>
203
+ <input type="text" id="node-input-GAtemperaturesensor" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
204
+
205
+ <label for="node-input-dpttemperaturesensor" style="width:40px; margin-left: 0px; text-align: right;">DPT</label>
206
+ <select id="node-input-dpttemperaturesensor" style="width:140px;"></select>
207
+
208
+ <label for="node-input-nametemperaturesensor" style="width:50px; margin-left: 0px; text-align: right;">Name</label>
209
+ <input type="text" id="node-input-nametemperaturesensor" style="width:200px;margin-left: 5px; text-align: left;">
210
+ </div>
211
+
212
+ </div>
213
+
214
+
215
+ <br/>
216
+ <br/>
217
+ <br/>
218
+
219
+
220
+ </script>
221
+
222
+ <script type="text/markdown" data-help-name="knxUltimateHueTemperatureSensor">
223
+ <p> This node lets you get the events from your HUE temperature device.<br/>
224
+
225
+ Here you can get the HUE temperature events, that represents a celsius value, evetytime the ambient temp changes.<br/>
226
+ Start typing in the GA field, the name or group address of your KNX device, the avaiable devices start showing up while you're typing.
227
+
228
+ **General**
229
+ |Property|Description|
230
+ |--|--|
231
+ | KNX GW | Select the KNX gateway to be used |
232
+ | HUE Bridge | Select the HUE Bridge to be used |
233
+ | Hue Sensor | HUE sensor to be used. The avaiable buttons start showing up while you're typing.|
234
+
235
+ **PHILIPS HUE LIGHT EVENTS -> TO KNX**
236
+ |Property|Description|
237
+ |--|--|
238
+ | Temp | temperature value, in Celsius degrees |
239
+
240
+ ### Outputs
241
+
242
+ 1. Standard output
243
+ : payload (integer) : the standard output of the command.
244
+
245
+ ### Details
246
+
247
+ `msg.payload` is used as the payload of the published message.
248
+ It contains the detailed event sent by your Hue devicem so you can use it for whatever you want.
249
+
250
+ <br/>
251
+
252
+ [Find it useful?](https://www.paypal.me/techtoday)
253
+
254
+ <br/>
255
+
256
+ </script>
@@ -0,0 +1,88 @@
1
+ module.exports = function (RED) {
2
+
3
+
4
+ function knxUltimateHueTemperatureSensor(config) {
5
+ RED.nodes.createNode(this, config)
6
+ const node = this
7
+ node.server = RED.nodes.getNode(config.server)
8
+ node.serverHue = RED.nodes.getNode(config.serverHue)
9
+ node.topic = node.name
10
+ node.name = config.name === undefined ? 'Hue' : config.name
11
+ node.dpt = ''
12
+ node.notifyreadrequest = false
13
+ node.notifyreadrequestalsorespondtobus = 'false'
14
+ node.notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized = ''
15
+ node.notifyresponse = false
16
+ node.notifywrite = true
17
+ node.initialread = true
18
+ node.listenallga = true // Don't remove
19
+ node.outputtype = 'write'
20
+ node.outputRBE = false // Apply or not RBE to the output (Messages coming from flow)
21
+ node.inputRBE = false // Apply or not RBE to the input (Messages coming from BUS)
22
+ node.currentPayload = '' // Current value for the RBE input and for the .previouspayload msg
23
+ node.passthrough = 'no'
24
+ node.formatmultiplyvalue = 1
25
+ node.formatnegativevalue = 'leave'
26
+ node.formatdecimalsvalue = 2
27
+
28
+
29
+
30
+ // Used to call the status update from the config node.
31
+ node.setNodeStatus = ({ fill, shape, text, payload }) => {
32
+
33
+ }
34
+
35
+ // This function is called by the knx-ultimate config node, to output a msg.payload.
36
+ node.handleSend = msg => {
37
+ }
38
+
39
+ node.handleSendHUE = _event => {
40
+ try {
41
+ if (_event.id === config.hueDevice) {
42
+ const knxMsgPayload = {}
43
+ knxMsgPayload.topic = config.GAtemperaturesensor
44
+ knxMsgPayload.dpt = config.dpttemperaturesensor
45
+
46
+ if (_event.hasOwnProperty('temperature') && _event.temperature.hasOwnProperty('temperature')) {
47
+ knxMsgPayload.payload = _event.temperature.temperature
48
+ // Send to KNX bus
49
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
50
+ node.status({ fill: 'green', shape: 'dot', text: 'HUE->KNX ' + JSON.stringify(knxMsgPayload.payload) + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
51
+
52
+ // Setup the output msg
53
+ knxMsgPayload.name = node.name
54
+ knxMsgPayload.event = 'temperature'
55
+
56
+ // Send payload
57
+ knxMsgPayload.rawEvent = _event
58
+ node.send(knxMsgPayload)
59
+ }
60
+ }
61
+ } catch (error) {
62
+ node.status({ fill: 'red', shape: 'dot', text: 'HUE->KNX error ' + error.message + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
63
+ }
64
+ }
65
+
66
+ // On each deploy, unsubscribe+resubscribe
67
+ if (node.server) {
68
+ node.server.removeClient(node)
69
+ node.server.addClient(node)
70
+ }
71
+ if (node.serverHue) {
72
+ node.serverHue.removeClient(node)
73
+ node.serverHue.addClient(node)
74
+ }
75
+
76
+ node.on('input', function (msg) {
77
+
78
+ })
79
+
80
+ node.on('close', function (done) {
81
+ if (node.server) {
82
+ node.server.removeClient(node)
83
+ }
84
+ done()
85
+ })
86
+ }
87
+ RED.nodes.registerType('knxUltimateHueTemperatureSensor', knxUltimateHueTemperatureSensor)
88
+ }
@@ -17,7 +17,7 @@ class classHUE extends EventEmitter {
17
17
  }
18
18
 
19
19
  // Get all devices and join it with relative rooms, by adding the room name to the device name
20
- getDevices = async (_rtype, _host, _username) => {
20
+ getResources = async (_rtype, _host, _username) => {
21
21
  try {
22
22
  // V2
23
23
  const hue = hueApiV2.connect({ host: _host, key: _username })
@@ -48,7 +48,13 @@ class classHUE extends EventEmitter {
48
48
  if (_rtype === 'light_level') {
49
49
  retArray.push({ name: 'Light Level: ' + linkedDevName + (Room !== undefined ? ', room ' + Room.metadata.name : ''), id: device.id })
50
50
  }
51
-
51
+ if (_rtype === 'temperature') {
52
+ retArray.push({ name: 'Temp: ' + linkedDevName + (Room !== undefined ? ', room ' + Room.metadata.name : ''), id: device.id })
53
+ }
54
+ if (_rtype === 'scene') {
55
+ retArray.push({ name: 'Temp: ' + linkedDevName + (Room !== undefined ? ', room ' + Room.metadata.name : ''), id: device.id })
56
+ }
57
+
52
58
  })
53
59
  return { devices: retArray }
54
60
  } catch (error) {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "engines": {
4
4
  "node": ">=14.0.0"
5
5
  },
6
- "version": "2.0.13",
6
+ "version": "2.0.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",
@@ -37,7 +37,8 @@
37
37
  "knxUltimateHueButton": "/nodes/knxUltimateHueButton.js",
38
38
  "knxUltimateHueMotion": "/nodes/knxUltimateHueMotion.js",
39
39
  "knxUltimateHueTapDial": "/nodes/knxUltimateHueTapDial.js",
40
- "knxUltimateHueLightSensor": "/nodes/knxUltimateHueLightSensor.js"
40
+ "knxUltimateHueLightSensor": "/nodes/knxUltimateHueLightSensor.js",
41
+ "knxUltimateHueTemperatureSensor": "/nodes/knxUltimateHueTemperatureSensor.js"
41
42
  }
42
43
  },
43
44
  "repository": {