node-red-contrib-knx-ultimate 2.0.6 → 2.0.8

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,15 @@
6
6
 
7
7
  # CHANGELOG
8
8
 
9
+ <p>
10
+ <b>Version 2.0.7</b> - June 2023<br/>
11
+ - NEW: HUE Motion node<br/>
12
+ </p>
13
+ <p>
14
+ <b>Version 2.0.7</b> - June 2023<br/>
15
+ - HUE Button node: added an output PIN<br/>
16
+ - HUE Button node: added an option to emit a simplified msg
17
+ </p>
9
18
  <p>
10
19
  <b>Version 2.0.6</b> - June 2023<br/>
11
20
  - NEW: HUE Button node. All HUE integrations are in BETA.<br/>
package/img/hueButton.png CHANGED
Binary file
Binary file
@@ -38,14 +38,14 @@
38
38
  this.disabled = true;
39
39
  return;
40
40
  }
41
-
41
+
42
42
  // Expected { bridge: bridgeConfig, user: createdUser }
43
43
  $("#node-config-input-name").val(data.bridge.data.name);
44
44
  $("#node-config-input-host").val(data.bridge.data.ipaddress);
45
45
  $("#node-config-input-username").val(data.user.username);
46
46
  $("#node-config-input-clientkey").val(data.user.clientkey);
47
47
  $("#node-config-input-bridgeid").val(data.bridge.data.bridgeid);
48
-
48
+
49
49
  }).error(function (jqXHR, textStatus, errorThrown) {
50
50
  RED.notify("Something went wrong. Please create at least a KNX Gateway node first.",
51
51
  {
@@ -88,10 +88,9 @@
88
88
 
89
89
  <p align='center'> <img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/huehub.jpg' width='40%'></p>
90
90
 
91
-
92
91
 
93
- <div class="form-row">
94
- <label><i class="fa fa-sign-in"></i>&nbsp&nbsp<span data-i18n="hue-config.properties.getinfocam"</span></label>
92
+ <div class="form-row">
93
+ <label><i class="fa fa-sign-in"></i>&nbspRegister</label>
95
94
  <input type="button" id="getinfocam" class="ui-button ui-corner-all ui-widget" style="background-color:#AEE1FF;width:150px" value="CONNECT">
96
95
  </div>
97
96
 
@@ -129,4 +128,14 @@
129
128
 
130
129
 
131
130
 
131
+ </script>
132
+ <script type="text/x-red" data-help-name="hue-config">
133
+ <p> This node registes to the Hue Bridge.<br/>
134
+
135
+ Just click **Connect** button.
136
+
137
+ [Find it useful?](https://www.paypal.me/techtoday)
138
+
139
+ <br/>
140
+
132
141
  </script>
@@ -90,41 +90,23 @@ module.exports = (RED) => {
90
90
  })
91
91
  })
92
92
 
93
- // Endpoint frontend
94
- RED.httpAdmin.get('/KNXUltimateGetAllLightsHUE', RED.auth.needsPermission('hue-config.read'), function (req, res) {
95
- try {
96
- (async () => {
97
- try {
98
- // °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
99
- const jRet = await node.hueManager.getAllLights()
100
- res.json(jRet)
101
- // °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
102
- } catch (err) {
103
- RED.log.error('Errore KNXUltimateGetAllLightsHUE non gestito ' + err.message)
104
- res.json({ error: err.message })
105
- }
106
- })()
107
- } catch (err) {
108
- RED.log.error('Errore KNXUltimateGetAllLightsHUE bsonto ' + err.message)
109
- res.json({ error: err.message })
110
- }
111
- })
112
93
 
113
94
  RED.httpAdmin.get('/KNXUltimateGetDevicesHUE', RED.auth.needsPermission('hue-config.read'), function (req, res) {
114
95
  try {
115
96
  (async () => {
116
97
  try {
117
98
  // °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
118
- const jRet = await node.hueManager.getDevices(req.query.rtype)
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)
119
101
  res.json(jRet)
120
102
  // °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
121
103
  } catch (err) {
122
- RED.log.error('Errore KNXUltimategetButtonsHUE non gestito ' + err.message)
104
+ RED.log.error('Errore KNXUltimateGetDevicesHUE non gestito ' + err.message)
123
105
  res.json({ error: err.message })
124
106
  }
125
107
  })()
126
108
  } catch (err) {
127
- RED.log.error('Errore KNXUltimategetButtons bsonto ' + err.message)
109
+ RED.log.error('Errore KNXUltimateGetDevicesHUE bsonto ' + err.message)
128
110
  res.json({ error: err.message })
129
111
  }
130
112
  })
@@ -4,9 +4,9 @@
4
4
  color: '#C7E9C0',
5
5
  defaults: {
6
6
  //buttonState: {value: true},
7
- server: { type: "knxUltimate-config", required: true },
7
+ server: { type: "knxUltimate-config", required: false },
8
8
  serverHue: { type: "hue-config", required: true },
9
- name: { value: "Hue Button (beta)" },
9
+ name: { value: "" },
10
10
 
11
11
  nameinitial_press: { value: "" },
12
12
  GAinitial_press: { value: "" },
@@ -32,11 +32,12 @@
32
32
  GAlong_press: { value: "" },
33
33
  dptlong_press: { value: "" },
34
34
 
35
+ outputSimpleMode: { value: true },
35
36
  toggleValues: { value: true },
36
37
  hueDevice: { value: "" }
37
38
  },
38
39
  inputs: 0,
39
- outputs: 0,
40
+ outputs: 1,
40
41
  icon: "node-hue-icon.svg",
41
42
  label: function () {
42
43
  return (this.name);
@@ -362,7 +363,7 @@
362
363
 
363
364
 
364
365
 
365
- // Autocomplete suggestion with HUE Lights
366
+ // Autocomplete suggestion with HUE
366
367
  $("#node-input-name").autocomplete({
367
368
  minLength: 1,
368
369
  source: function (request, response) {
@@ -533,7 +534,11 @@
533
534
  Toggle values
534
535
  </label>
535
536
  </div>
536
-
537
+ <div class="form-row">
538
+ <input type="checkbox" id="node-input-outputSimpleMode" style="display:inline-block; width:auto; vertical-align:top;" />
539
+ <label style="width:auto" for="node-input-outputSimpleMode"><i class="fa fa-filter">Simple output mode</i></label>
540
+ </div>
541
+
537
542
  </div>
538
543
 
539
544
 
@@ -550,14 +555,12 @@
550
555
  </script>
551
556
 
552
557
  <script type="text/markdown" data-help-name="knxUltimateHueButton">
558
+ <p> This node lets you get the events from your HUE button.<br/>
553
559
 
554
- [Find it useful?](https://www.paypal.me/techtoday)
555
-
556
- This node lets you get the events of your HUE button.<br/>
557
560
  There are many event you can choose from. The relevants one are *short release* and *repeat*.<br/>
558
561
  In *short release* you can send true/false to your KNX group address to, for example, toggle a light.<br/>
559
562
  In *repeat* event, you can DIM a KNX light.<br/>
560
- The **toggle values** option is enabled by default. This option toggles the value of each KNX group address (*true/false, increase/decrease dim*))
563
+ The **toggle values** option is enabled by default. This option toggles the value of each KNX group address (*true/false, increase/decrease dim*)
561
564
 
562
565
  **General**
563
566
  |Property|Description|
@@ -579,8 +582,21 @@ Start typing in the GA field, the name or group address of your KNX device, the
579
582
  | Short release | Rapid push of the button, fired as soon as you release your finger from the button. Usually used to toggle a KNX light true/false |
580
583
  | Long release | Long press of the button, fired as soon as you release your finger from the button |
581
584
  | Long press | Long press of the button, fired as soon as you long press the button |
582
- | Toggle values | Enable or disable toggling values. If enabled, all values toggles, otherwise, all values are sent as *true* or *increase dim*, to the selected KNX group address. |
585
+ | Toggle values | Enable or disable toggling values. If enabled, all values toggles, otherwise, all values are sent as *true* or *increase dim*, to the selected KNX group address |
586
+ | Simple output mode | Enables an RBE output on the payload *true/false*, independently from the HUE Button events type. *Repeat* messages are always repeated. When disabled, the node outputs a msg for every different HUE Button events |
583
587
 
588
+ ### Outputs
589
+
590
+ 1. Standard output
591
+ : payload (string|object) : the standard output of the command.
592
+
593
+ ### Details
594
+
595
+ `msg.payload` is used as the payload of the published message.
596
+ If it contains an Object it will be converted to a JSON string before being sent.
597
+
598
+ [Find it useful?](https://www.paypal.me/techtoday)
584
599
 
585
600
  <br/>
601
+
586
602
  </script>
@@ -1,7 +1,4 @@
1
1
  module.exports = function (RED) {
2
- const dptlib = require('./../KNXEngine/dptlib')
3
- const hueColorConverter = require('./utils/hueColorConverter')
4
-
5
2
 
6
3
  async function getLightState(node, _lightID) {
7
4
  return new Promise((resolve, reject) => {
@@ -25,7 +22,6 @@ module.exports = function (RED) {
25
22
  node.serverHue = RED.nodes.getNode(config.serverHue)
26
23
  node.topic = node.name
27
24
  node.name = config.name === undefined ? 'Hue' : config.name
28
- node.outputtopic = node.name
29
25
  node.dpt = ''
30
26
  node.notifyreadrequest = false
31
27
  node.notifyreadrequestalsorespondtobus = 'false'
@@ -49,7 +45,7 @@ module.exports = function (RED) {
49
45
  node.toggle4 = false
50
46
  node.toggle5 = false
51
47
  node.toggle5 = false
52
-
48
+ node.rbeOutputPayload = undefined
53
49
 
54
50
  // Read the state of the light and store it in the holding object
55
51
  try {
@@ -122,6 +118,18 @@ module.exports = function (RED) {
122
118
  node.status({ fill: 'green', shape: 'dot', text: 'HUE->KNX ' + _event.button.last_event + ' ' + JSON.stringify(knxMsgPayload.payload) + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
123
119
  if (knxMsgPayload.ga !== '' && knxMsgPayload.ga !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.ga, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
124
120
  }
121
+ // Setup the output msg
122
+ knxMsgPayload.topic = knxMsgPayload.ga
123
+ delete knxMsgPayload.ga
124
+ knxMsgPayload.name = node.name
125
+ knxMsgPayload.event = _event.button.last_event
126
+
127
+ // Applying rbe filter
128
+ if (config.outputSimpleMode && knxMsgPayload.payload !== node.rbeOutputPayload) {
129
+ node.rbeOutputPayload = knxMsgPayload.payload
130
+ } else {
131
+ node.send(knxMsgPayload)
132
+ }
125
133
  }
126
134
  } catch (error) {
127
135
  node.status({ fill: 'red', shape: 'dot', text: 'HUE->KNX error ' + error.message + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
@@ -6,7 +6,7 @@
6
6
  //buttonState: {value: true},
7
7
  server: { type: "knxUltimate-config", required: true },
8
8
  serverHue: { type: "hue-config", required: true },
9
- name: { value: "Hue Light (beta)" },
9
+ name: { value: "" },
10
10
 
11
11
  nameLightSwitch: { value: "" },
12
12
  GALightSwitch: { value: "" },
@@ -442,8 +442,8 @@
442
442
 
443
443
  <div class="form-row">
444
444
  <b>HUE Light</b>&nbsp&nbsp<span style="color:red"
445
- &nbsp<i class="fa fa-question-circle"></i></span>
446
- &nbsp<a target="_blank" href="https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/en-hue-configuration"><u>Configuration</u></a>
445
+ &nbsp
446
+ &nbsp<i class="fa fa-youtube"></i></span>&nbsp<a target="_blank" href="https://youtu.be/3M02Du2gero"><u>Youtube sample</u></a>
447
447
  <br />
448
448
  <p align="center"><img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/hueLight.png'></p>
449
449
  <br />
@@ -599,10 +599,7 @@
599
599
 
600
600
 
601
601
  <script type="text/markdown" data-help-name="knxUltimateHueLight">
602
-
603
- [Find it useful?](https://www.paypal.me/techtoday)
604
-
605
- This node lets you control your Philips HUE light and also get the states of this lights.
602
+ <p>This node lets you control your Philips HUE light and also get the states of this lights.
606
603
 
607
604
  **General**
608
605
  |Property|Description|
@@ -636,5 +633,7 @@ Start typing in the GA field, the name or group address of your KNX device, the
636
633
  | Color | This state is used to send changes of the HUE light's color. Accepted datapoint is RGB triplet (r,g,b)|
637
634
  | Brightness | This state is used to send changes of your absolute HUE light's brightness, to a KNX group address |
638
635
 
636
+ [Find it useful?](https://www.paypal.me/techtoday)
637
+
639
638
  <br/>
640
639
  </script>
@@ -0,0 +1,251 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('knxUltimateHueMotion', {
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
+ namemotion: { value: "" },
12
+ GAmotion: { value: "" },
13
+ dptmotion: { 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 Motion (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("1.")) {
72
+ $("#node-input-dptmotion").append($("<option></option>")
73
+ .attr("value", dpt.value)
74
+ .text(dpt.text))
75
+ }
76
+ });
77
+ $("#node-input-dptmotion").val(this.dptmotion)
78
+ })
79
+
80
+ // Autocomplete suggestion with ETS csv File
81
+ $("#node-input-GAmotion").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 + " 1.")) {
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-namemotion').val(sDevName);
106
+ var optVal = $("#node-input-dptmotion option:contains('" + ui.item.label.split("#")[2].trim() + "')").attr('value');
107
+ // Select the option value
108
+ $("#node-input-dptmotion").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("KNXUltimateGetDevicesHUE?rtype=motion&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="knxUltimateHueMotion">
157
+
158
+
159
+ <div class="form-row">
160
+ <b>HUE Light</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 Button</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 MOTION EVENTS -> TO KNX</b>
197
+ </p>
198
+
199
+ <div class="form-row">
200
+ <label for="node-input-namemotion" style="width:100px;"><i class="fa fa-play-circle-o"></i> Motion</span></label>
201
+
202
+ <label for="node-input-GAmotion" style="width:20px;">GA</label>
203
+ <input type="text" id="node-input-GAmotion" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
204
+
205
+ <label for="node-input-dptmotion" style="width:40px; margin-left: 0px; text-align: right;">dpt</label>
206
+ <select id="node-input-dptmotion" style="width:140px;"></select>
207
+
208
+ <label for="node-input-namemotion" style="width:50px; margin-left: 0px; text-align: right;">Name</label>
209
+ <input type="text" id="node-input-namemotion" style="width:200px;margin-left: 5px; text-align: left;">
210
+ </div>
211
+
212
+ </div>
213
+
214
+
215
+ <br/>
216
+ <br/>
217
+ <br/>
218
+ <br/>
219
+ <br/>
220
+ <br/>
221
+ <br/>
222
+ <br/>
223
+
224
+
225
+ </script>
226
+
227
+ <script type="text/markdown" data-help-name="knxUltimateHueMotion">
228
+ <p> This node lets you get the events from your HUE motion device.<br/>
229
+
230
+ **PHILIPS HUE MOTION EVENTS -> TO KNX**
231
+ Here you can get the HUE motion events.<br/>
232
+ 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.
233
+
234
+ |Property|Description|
235
+ |--|--|
236
+ | Motion | As soon as someone moves in the motion device's range |
237
+
238
+ ### Outputs
239
+
240
+ 1. Standard output
241
+ : payload (boolean) : the standard output of the command. **true** for motion | **false** for motion end.
242
+
243
+ ### Details
244
+
245
+ `msg.payload` is used as the payload of the published message.
246
+
247
+ [Find it useful?](https://www.paypal.me/techtoday)
248
+
249
+ <br/>
250
+
251
+ </script>
@@ -0,0 +1,93 @@
1
+ module.exports = function (RED) {
2
+
3
+
4
+ function knxUltimateHueMotion(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.ga = config.GAmotion
44
+ knxMsgPayload.dpt = config.dptmotion
45
+ knxMsgPayload.payload = _event.motion.motion
46
+
47
+ // Send to KNX bus
48
+ node.status({ fill: 'green', shape: 'dot', text: 'HUE->KNX ' + JSON.stringify(knxMsgPayload.payload) + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
49
+ if (knxMsgPayload.ga !== '' && knxMsgPayload.ga !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.ga, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
50
+
51
+ // Setup the output msg
52
+ knxMsgPayload.topic = knxMsgPayload.ga
53
+ delete knxMsgPayload.ga
54
+ knxMsgPayload.name = node.name
55
+ knxMsgPayload.event = 'motion'
56
+
57
+ // Applying rbe filter
58
+ node.send(knxMsgPayload)
59
+ }
60
+ } catch (error) {
61
+ node.status({ fill: 'red', shape: 'dot', text: 'HUE->KNX error ' + error.message + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
62
+ }
63
+ }
64
+
65
+ // On each deploy, unsubscribe+resubscribe
66
+ if (node.server) {
67
+ node.server.removeClient(node)
68
+ node.server.addClient(node)
69
+ }
70
+ if (node.serverHue) {
71
+ node.serverHue.removeClient(node)
72
+ node.serverHue.addClient(node)
73
+ }
74
+
75
+ node.on('input', function (msg) {
76
+
77
+ })
78
+
79
+ node.on('close', function (done) {
80
+ if (node.server) {
81
+ node.server.removeClient(node)
82
+ }
83
+ done()
84
+ })
85
+
86
+ // On each deploy, unsubscribe+resubscribe
87
+ if (node.server) {
88
+ node.server.removeClient(node)
89
+ node.server.addClient(node)
90
+ }
91
+ }
92
+ RED.nodes.registerType('knxUltimateHueMotion', knxUltimateHueMotion)
93
+ }
@@ -17,10 +17,10 @@ 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) => {
20
+ getDevices = async (_rtype, _host, _username) => {
21
21
  try {
22
22
  // V2
23
- const hue = hueApiV2.connect({ host: this.HUEBridgeIP, key: this.username })
23
+ const hue = hueApiV2.connect({ host: _host, key: _username })
24
24
  const retArray = []
25
25
  const allResources = await hue.getResources()
26
26
  const allRooms = await hue.getRooms()
@@ -39,6 +39,9 @@ class classHUE extends EventEmitter {
39
39
  if (_rtype === 'light') {
40
40
  retArray.push({ name: linkedDevName + (Room !== undefined ? ', room ' + Room.metadata.name : ''), id: device.id })
41
41
  }
42
+ if (_rtype === 'motion') {
43
+ retArray.push({ name: linkedDevName + (Room !== undefined ? ', room ' + Room.metadata.name : ''), id: device.id })
44
+ }
42
45
  })
43
46
  return { devices: retArray }
44
47
  } catch (error) {
@@ -101,6 +104,13 @@ class classHUE extends EventEmitter {
101
104
  startPushEvents = async () => {
102
105
  try {
103
106
  this.hue = await hueApiV2.connect({
107
+ log: {
108
+ trace: (msg) => { },
109
+ debug: (msg) => { },
110
+ info: (msg) => { },
111
+ warn: (msg) => { },
112
+ error: (msg) => { }
113
+ },
104
114
  host: this.HUEBridgeIP,
105
115
  key: this.username,
106
116
  eventListener: this.listener // The eventlistener is given as option
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "engines": {
4
4
  "node": ">=14.0.0"
5
5
  },
6
- "version": "2.0.6",
6
+ "version": "2.0.8",
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",
@@ -17,7 +17,7 @@
17
17
  "xml2js": "0.5.0",
18
18
  "dns-sync": "0.2.1",
19
19
  "node-hue-api": "5.0.0-beta.16",
20
- "node-hue": "1.0.3",
20
+ "node-hue": "1.0.4",
21
21
  "color-convert": "2.0.1"
22
22
  },
23
23
  "node-red": {
@@ -34,7 +34,8 @@
34
34
  "knxUltimateViewer": "/nodes/knxUltimateViewer.js",
35
35
  "hueConfig": "/nodes/hue-config.js",
36
36
  "knxUltimateHueLight": "/nodes/knxUltimateHueLight.js",
37
- "knxUltimateHueButton": "/nodes/knxUltimateHueButton.js"
37
+ "knxUltimateHueButton": "/nodes/knxUltimateHueButton.js",
38
+ "knxUltimateHueMotion": "/nodes/knxUltimateHueMotion.js"
38
39
  }
39
40
  },
40
41
  "repository": {
@@ -1,11 +0,0 @@
1
- <script type="text/x-red" data-help-name="hue-config">
2
- <h1>KNX Ultimate - HUE config node</h1>
3
-
4
- <p>
5
- <a href="https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/en-hue-configuration" target="_blank"><i class="fa fa-info-circle"></i>&nbsp Help configuring</a>
6
- </p>
7
-
8
- <p>
9
- <a href="https://www.paypal.me/techtoday" target="_blank"><img src='https://img.shields.io/badge/Donate-PayPal-blue.svg?style=flat-square' width='30%'></a>
10
- </p>
11
- </script>