node-red-contrib-knx-ultimate 2.2.3 → 2.2.5

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.
@@ -54,233 +54,233 @@ module.exports = function (RED) {
54
54
  dpt = (typeof dpt === 'undefined' || dpt == '') ? '' : ' DPT' + dpt
55
55
  payload = typeof payload === 'object' ? JSON.stringify(payload) : payload
56
56
  node.status({ fill, shape, text: GA + payload + (node.listenallga === true ? ' ' + devicename : '') + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ' ' + text })
57
- } catch (error) {
58
- }
57
+ } catch (error) {
59
58
  }
59
+ }
60
60
 
61
61
  // Used to call the status update from the config node.
62
62
  node.setLocalStatus = ({ fill, shape, text, payload, GA, dpt, devicename }) => {
63
- const dDate = new Date()
64
- // 30/08/2019 Display only the things selected in the config
65
- GA = (typeof GA === 'undefined' || GA == '') ? '' : '(' + GA + ') '
66
- devicename = devicename || ''
67
- dpt = (typeof dpt === 'undefined' || dpt == '') ? '' : ' DPT' + dpt
68
- try {
69
- node.status({ fill, shape, text: GA + payload + (node.listenallga === true ? ' ' + devicename : '') + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ' ' + text })
70
- } catch (error) {
71
- }
63
+ const dDate = new Date()
64
+ // 30/08/2019 Display only the things selected in the config
65
+ GA = (typeof GA === 'undefined' || GA == '') ? '' : '(' + GA + ') '
66
+ devicename = devicename || ''
67
+ dpt = (typeof dpt === 'undefined' || dpt == '') ? '' : ' DPT' + dpt
68
+ try {
69
+ node.status({ fill, shape, text: GA + payload + (node.listenallga === true ? ' ' + devicename : '') + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ' ' + text })
70
+ } catch (error) {
72
71
  }
72
+ }
73
73
 
74
- // This function is called by the knx-ultimate config node, to output a msg.payload.
75
- node.handleSend = msg => {
76
- try {
77
- if (!msg.knx.dpt.startsWith('1.')) return
78
- } catch (error) {
79
- return
80
- }
81
- let bFound = false // 24/04/2021 true if the cycle below found a match, otherwise false
74
+ // This function is called by the knx-ultimate config node, to output a msg.payload.
75
+ node.handleSend = msg => {
76
+ try {
77
+ if (!msg.knx.dpt.startsWith('1.')) return
78
+ } catch (error) {
79
+ return
80
+ }
81
+ let bFound = false // 24/04/2021 true if the cycle below found a match, otherwise false
82
82
 
83
- // Update the node.rules with the values taken from the file, if any, otherwise leave the default value
84
- for (let i = 0; i < node.rules.length; i++) {
85
- // rule is { topic: rowRuleTopic, devicename: rowRuleDeviceName, longdevicename: rowRuleLongDeviceName}
86
- var rule = node.rules[i]
87
- if (msg.topic === rule.topic) {
88
- if (msg.payload == true) {
89
- bFound = true
90
- // Add the device to the array of alertedDevices
91
- const oTrovato = node.alertedDevices.find(a => a.topic === rule.topic)
92
- if (oTrovato === undefined) {
93
- node.alertedDevices.unshift({ topic: rule.topic, devicename: rule.devicename, longdevicename: rule.longdevicename }) // Add to the begin of array
94
- if (node.whentostart === 'ifnewalert') node.send([null, null, node.getThirdPinMSG()])
95
- }
96
- node.setLocalStatus({ fill: 'red', shape: 'dot', text: 'Alert', payload: '', GA: msg.topic, dpt: '', devicename: rule.devicename })
97
- } else {
98
- // Remove the device from the array
99
- node.alertedDevices = node.alertedDevices.filter(a => a.topic !== msg.topic)
100
- node.setLocalStatus({ fill: 'green', shape: 'dot', text: 'Restore', payload: '', GA: msg.topic, dpt: '', devicename: rule.devicename })
83
+ // Update the node.rules with the values taken from the file, if any, otherwise leave the default value
84
+ for (let i = 0; i < node.rules.length; i++) {
85
+ // rule is { topic: rowRuleTopic, devicename: rowRuleDeviceName, longdevicename: rowRuleLongDeviceName}
86
+ var rule = node.rules[i]
87
+ if (msg.topic === rule.topic) {
88
+ if (msg.payload == true) {
89
+ bFound = true
90
+ // Add the device to the array of alertedDevices
91
+ const oTrovato = node.alertedDevices.find(a => a.topic === rule.topic)
92
+ if (oTrovato === undefined) {
93
+ node.alertedDevices.unshift({ topic: rule.topic, devicename: rule.devicename, longdevicename: rule.longdevicename }) // Add to the begin of array
94
+ if (node.whentostart === 'ifnewalert') node.send([null, null, node.getThirdPinMSG()])
101
95
  }
96
+ node.setLocalStatus({ fill: 'red', shape: 'dot', text: 'Alert', payload: '', GA: msg.topic, dpt: '', devicename: rule.devicename })
97
+ } else {
98
+ // Remove the device from the array
99
+ node.alertedDevices = node.alertedDevices.filter(a => a.topic !== msg.topic)
100
+ node.setLocalStatus({ fill: 'green', shape: 'dot', text: 'Restore', payload: '', GA: msg.topic, dpt: '', devicename: rule.devicename })
102
101
  }
103
102
  }
104
-
105
- // If there's some device to alert, stop current timer and restart
106
- // This allow the last alerted device to be outputted immediately
107
- if (bFound && node.whentostart === 'ifnewalert' && node.alertedDevices.length > 0) {
108
- clearTimeout(node.timerSend)
109
- // Send directly the second and third message PIN
110
- node.send([null, node.getSecondPinMSG(), null])
111
- node.curIndexAlertedDevice = 0 // Restart form the beginning
112
- node.startTimer()
113
- }
114
103
  }
115
104
 
116
- // Get the msg to be outputted on second PIN
117
- node.getSecondPinMSG = () => {
118
- if (node.alertedDevices.length > 0) {
119
- const msg = {}
120
- let sRet = ''
121
- let sRetLong = ''
122
- let sTopic = ''
123
- node.alertedDevices.forEach(function (item) {
124
- sTopic += item.topic + ', '
125
- if (item.devicename !== undefined && item.devicename !== '') sRet += item.devicename + ', '
126
- if (item.longdevicename !== undefined && item.longdevicename !== '') sRetLong += item.longdevicename + ', '
127
- })
128
- sTopic = sTopic.slice(0, -2)
129
- if (sRet.length > 2) sRet = sRet.slice(0, -2)
130
- if (sRetLong.length > 2) sRetLong = sRetLong.slice(0, -2)
131
- msg.topic = sTopic
132
- msg.devicename = sRet
133
- msg.longdevicename = sRetLong
134
- msg.count = node.alertedDevices.length
135
- msg.payload = true
136
- return msg
137
- }
105
+ // If there's some device to alert, stop current timer and restart
106
+ // This allow the last alerted device to be outputted immediately
107
+ if (bFound && node.whentostart === 'ifnewalert' && node.alertedDevices.length > 0) {
108
+ clearTimeout(node.timerSend)
109
+ // Send directly the second and third message PIN
110
+ node.send([null, node.getSecondPinMSG(), null])
111
+ node.curIndexAlertedDevice = 0 // Restart form the beginning
112
+ node.startTimer()
138
113
  }
114
+ }
139
115
 
140
- // Get the msg to be outputted on third PIN
141
- node.getThirdPinMSG = () => {
142
- if (node.alertedDevices.length > 0) {
143
- const msg = {}
144
- let sRet = ''
145
- let sRetLong = ''
146
- let sTopic = ''
147
- const item = node.alertedDevices[0] // Pick the last alerted device
148
- sTopic = item.topic
149
- if (item.devicename !== undefined && item.devicename !== '') sRet = item.devicename
150
- if (item.longdevicename !== undefined && item.longdevicename !== '') sRetLong = item.longdevicename
151
- msg.topic = sTopic
152
- msg.devicename = sRet
153
- msg.longdevicename = sRetLong
154
- msg.count = node.alertedDevices.length
155
- msg.payload = true
156
- return msg
157
- }
116
+ // Get the msg to be outputted on second PIN
117
+ node.getSecondPinMSG = () => {
118
+ if (node.alertedDevices.length > 0) {
119
+ const msg = {}
120
+ let sRet = ''
121
+ let sRetLong = ''
122
+ let sTopic = ''
123
+ node.alertedDevices.forEach(function (item) {
124
+ sTopic += item.topic + ', '
125
+ if (item.devicename !== undefined && item.devicename !== '') sRet += item.devicename + ', '
126
+ if (item.longdevicename !== undefined && item.longdevicename !== '') sRetLong += item.longdevicename + ', '
127
+ })
128
+ sTopic = sTopic.slice(0, -2)
129
+ if (sRet.length > 2) sRet = sRet.slice(0, -2)
130
+ if (sRetLong.length > 2) sRetLong = sRetLong.slice(0, -2)
131
+ msg.topic = sTopic
132
+ msg.devicename = sRet
133
+ msg.longdevicename = sRetLong
134
+ msg.count = node.alertedDevices.length
135
+ msg.payload = true
136
+ return msg
158
137
  }
138
+ }
159
139
 
160
- // 24/04/2021 perform a read on all GA in the rule list. Called both from node.on("input") and knxUltimate-config
161
- node.initialReadAllDevicesInRules = () => {
162
- if (node.server) {
163
- let grpaddr = ''
164
- for (let i = 0; i < node.rules.length; i++) {
165
- // rule is { topic: rowRuleTopic, devicename: rowRuleDeviceName, longdevicename: rowRuleLongDeviceName}
166
- const rule = node.rules[i]
167
- // READ: Send a Read request to the bus
168
- grpaddr = rule.topic
169
- try {
170
- // Check if it's a group address
171
- // const ret = Address.KNXAddress.createFromString(grpaddr, Address.KNXAddress.TYPE_GROUP)
172
- 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 })
174
- } catch (error) {
175
- node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'Not a KNX GA ' + error.message, payload: '', GA: grpaddr, dpt: '', devicename: rule.devicename })
176
- }
177
- }
178
- } else {
179
- node.setLocalStatus({ fill: 'red', shape: 'ring', text: 'No gateway selected. Unable to read from KNX bus', payload: '', GA: '', dpt: '', devicename: '' })
180
- }
140
+ // Get the msg to be outputted on third PIN
141
+ node.getThirdPinMSG = () => {
142
+ if (node.alertedDevices.length > 0) {
143
+ const msg = {}
144
+ let sRet = ''
145
+ let sRetLong = ''
146
+ let sTopic = ''
147
+ const item = node.alertedDevices[0] // Pick the last alerted device
148
+ sTopic = item.topic
149
+ if (item.devicename !== undefined && item.devicename !== '') sRet = item.devicename
150
+ if (item.longdevicename !== undefined && item.longdevicename !== '') sRetLong = item.longdevicename
151
+ msg.topic = sTopic
152
+ msg.devicename = sRet
153
+ msg.longdevicename = sRetLong
154
+ msg.count = node.alertedDevices.length
155
+ msg.payload = true
156
+ return msg
181
157
  }
158
+ }
182
159
 
183
- node.on('input', function (msg) {
184
- if (typeof msg === 'undefined') return
185
- if (msg.hasOwnProperty('start')) {
186
- clearTimeout(node.timerSend)
187
- node.curIndexAlertedDevice = 0 // Restart form the beginning
188
- if (node.alertedDevices.length > 0) {
189
- node.send([null, node.getSecondPinMSG(), node.getThirdPinMSG()])
190
- node.startTimer()
191
- } else {
192
- // Nothing more to output
193
- node.sendNoMoreDevices()
160
+ // 24/04/2021 perform a read on all GA in the rule list. Called both from node.on("input") and knxUltimate-config
161
+ node.initialReadAllDevicesInRules = () => {
162
+ if (node.server) {
163
+ let grpaddr = ''
164
+ for (let i = 0; i < node.rules.length; i++) {
165
+ // rule is { topic: rowRuleTopic, devicename: rowRuleDeviceName, longdevicename: rowRuleLongDeviceName}
166
+ const rule = node.rules[i]
167
+ // READ: Send a Read request to the bus
168
+ grpaddr = rule.topic
169
+ try {
170
+ // Check if it's a group address
171
+ // const ret = Address.KNXAddress.createFromString(grpaddr, Address.KNXAddress.TYPE_GROUP)
172
+ 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 })
174
+ } catch (error) {
175
+ node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'Not a KNX GA ' + error.message, payload: '', GA: grpaddr, dpt: '', devicename: rule.devicename })
194
176
  }
195
- return
196
- }
197
-
198
- // 24/04/2021 if payload is read or the output type is set to "read", do a read
199
- if ((msg.hasOwnProperty('readstatus') && msg.readstatus === true)) {
200
- node.initialReadAllDevicesInRules()
201
- return
202
- }
203
-
204
- if (msg.topic === undefined) {
205
- node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'ERROR: You must provide a msg.topic', payload: '', GA: '', dpt: '', devicename: '' })
206
- return
207
177
  }
208
- if (msg.payload === undefined) {
209
- node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'ERROR: You must provide payload (true/false)', payload: '', GA: '', dpt: '', devicename: '' })
210
- return
211
- }
212
- msg.knx = { dpt: '1.001' }
213
- node.handleSend(msg)
214
- })
178
+ } else {
179
+ node.setLocalStatus({ fill: 'red', shape: 'ring', text: 'No gateway selected. Unable to read from KNX bus', payload: '', GA: '', dpt: '', devicename: '' })
180
+ }
181
+ }
215
182
 
216
- node.on('close', function (done) {
183
+ node.on('input', function (msg) {
184
+ if (typeof msg === 'undefined') return
185
+ if (msg.hasOwnProperty('start')) {
217
186
  clearTimeout(node.timerSend)
218
- if (node.server) {
219
- node.server.removeClient(node)
220
- }
221
- done()
222
- })
223
-
224
- node.handleTimer = () => {
187
+ node.curIndexAlertedDevice = 0 // Restart form the beginning
225
188
  if (node.alertedDevices.length > 0) {
226
- const count = node.alertedDevices.length
227
- if (node.curIndexAlertedDevice > count - 1) {
228
- node.curIndexAlertedDevice = 0
229
- if (node.whentostart === 'manualstart') {
230
- node.curIndexAlertedDevice = 0 // Restart form the beginning
231
- return
232
- }
233
- }
234
- // Create output message
235
- try {
236
- const curDev = node.alertedDevices[node.curIndexAlertedDevice] // is { topic: rule.topic, devicename: rule.devicename }
237
- const msg = {}
238
- msg.topic = curDev.topic
239
- msg.count = count
240
- msg.devicename = curDev.devicename
241
- msg.longdevicename = curDev.longdevicename
242
- msg.payload = true
243
- node.send([msg, null, null])
244
- } catch (error) {
245
- }
246
- node.curIndexAlertedDevice += 1
247
- // Restart timer
189
+ node.send([null, node.getSecondPinMSG(), node.getThirdPinMSG()])
248
190
  node.startTimer()
249
191
  } else {
250
192
  // Nothing more to output
251
193
  node.sendNoMoreDevices()
252
194
  }
195
+ return
253
196
  }
254
197
 
255
- // Start timer
256
- node.startTimer = () => {
257
- clearTimeout(node.timerSend)
258
- node.timerSend = setTimeout(() => {
259
- node.handleTimer()
260
- }, node.timerinterval * 1000)
198
+ // 24/04/2021 if payload is read or the Telegram type is set to "read", do a read
199
+ if ((msg.hasOwnProperty('readstatus') && msg.readstatus === true)) {
200
+ node.initialReadAllDevicesInRules()
201
+ return
261
202
  }
262
203
 
263
- // As soon as there no more devices..
264
- node.sendNoMoreDevices = () => {
265
- const msg = {}
266
- msg.topic = ''
267
- msg.count = 0
268
- msg.devicename = ''
269
- msg.longdevicename = ''
270
- msg.payload = false
271
- node.send([msg, msg, msg])
204
+ if (msg.topic === undefined) {
205
+ node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'ERROR: You must provide a msg.topic', payload: '', GA: '', dpt: '', devicename: '' })
206
+ return
272
207
  }
208
+ if (msg.payload === undefined) {
209
+ node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'ERROR: You must provide payload (true/false)', payload: '', GA: '', dpt: '', devicename: '' })
210
+ return
211
+ }
212
+ msg.knx = { dpt: '1.001' }
213
+ node.handleSend(msg)
214
+ })
273
215
 
274
- // Init
275
- node.sendNoMoreDevices()
276
-
277
- // On each deploy, unsubscribe+resubscribe
216
+ node.on('close', function (done) {
217
+ clearTimeout(node.timerSend)
278
218
  if (node.server) {
279
219
  node.server.removeClient(node)
280
- if (node.topic !== '' || node.topicSave !== '') {
281
- node.server.addClient(node)
220
+ }
221
+ done()
222
+ })
223
+
224
+ node.handleTimer = () => {
225
+ if (node.alertedDevices.length > 0) {
226
+ const count = node.alertedDevices.length
227
+ if (node.curIndexAlertedDevice > count - 1) {
228
+ node.curIndexAlertedDevice = 0
229
+ if (node.whentostart === 'manualstart') {
230
+ node.curIndexAlertedDevice = 0 // Restart form the beginning
231
+ return
232
+ }
233
+ }
234
+ // Create output message
235
+ try {
236
+ const curDev = node.alertedDevices[node.curIndexAlertedDevice] // is { topic: rule.topic, devicename: rule.devicename }
237
+ const msg = {}
238
+ msg.topic = curDev.topic
239
+ msg.count = count
240
+ msg.devicename = curDev.devicename
241
+ msg.longdevicename = curDev.longdevicename
242
+ msg.payload = true
243
+ node.send([msg, null, null])
244
+ } catch (error) {
282
245
  }
246
+ node.curIndexAlertedDevice += 1
247
+ // Restart timer
248
+ node.startTimer()
249
+ } else {
250
+ // Nothing more to output
251
+ node.sendNoMoreDevices()
252
+ }
253
+ }
254
+
255
+ // Start timer
256
+ node.startTimer = () => {
257
+ clearTimeout(node.timerSend)
258
+ node.timerSend = setTimeout(() => {
259
+ node.handleTimer()
260
+ }, node.timerinterval * 1000)
261
+ }
262
+
263
+ // As soon as there no more devices..
264
+ node.sendNoMoreDevices = () => {
265
+ const msg = {}
266
+ msg.topic = ''
267
+ msg.count = 0
268
+ msg.devicename = ''
269
+ msg.longdevicename = ''
270
+ msg.payload = false
271
+ node.send([msg, msg, msg])
272
+ }
273
+
274
+ // Init
275
+ node.sendNoMoreDevices()
276
+
277
+ // On each deploy, unsubscribe+resubscribe
278
+ if (node.server) {
279
+ node.server.removeClient(node)
280
+ if (node.topic !== '' || node.topicSave !== '') {
281
+ node.server.addClient(node)
283
282
  }
284
283
  }
285
- RED.nodes.registerType('knxUltimateAlerter', knxUltimateAlerter)
286
284
  }
285
+ RED.nodes.registerType('knxUltimateAlerter', knxUltimateAlerter)
286
+ }
@@ -22,6 +22,7 @@ module.exports = function (RED) {
22
22
  node.formatmultiplyvalue = 1;
23
23
  node.formatnegativevalue = 'leave';
24
24
  node.formatdecimalsvalue = 2;
25
+ node.hueDevice = config.hueDevice;
25
26
 
26
27
  // Used to call the status update from the config node.
27
28
  node.setNodeStatus = ({
@@ -33,7 +34,7 @@ module.exports = function (RED) {
33
34
  node.setNodeStatusHue = ({
34
35
  fill, shape, text, payload,
35
36
  }) => {
36
- if (payload === undefined) return;
37
+ if (payload === undefined) payload = '';
37
38
  const dDate = new Date();
38
39
  payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString();
39
40
  node.status({ fill, shape, text: `${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})` });
@@ -83,11 +84,7 @@ module.exports = function (RED) {
83
84
  }
84
85
  if (node.serverHue) {
85
86
  node.serverHue.removeClient(node);
86
- // I must get the object, to store read the battery status
87
- // I queue the state request, by passing the callback to call whenever the HUE bridge send me the light status async
88
- if (node.serverHue !== null && node.serverHue.hueManager !== null) {
89
- node.serverHue.addClient(node);
90
- }
87
+ node.serverHue.addClient(node);
91
88
  }
92
89
 
93
90
  node.on('input', (msg) => {
@@ -26,6 +26,7 @@ module.exports = function (RED) {
26
26
  node.formatdecimalsvalue = 2;
27
27
  node.short_releaseValue = false;
28
28
  node.isTimerDimStopRunning = false;
29
+ node.hueDevice = config.hueDevice;
29
30
 
30
31
  // Used to call the status update from the config node.
31
32
  node.setNodeStatus = ({
@@ -37,7 +38,7 @@ module.exports = function (RED) {
37
38
  node.setNodeStatusHue = ({
38
39
  fill, shape, text, payload,
39
40
  }) => {
40
- if (payload === undefined) return;
41
+ if (payload === undefined) payload = '';
41
42
  const dDate = new Date();
42
43
  payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString();
43
44
  node.status({ fill, shape, text: `${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})` });
@@ -1,4 +1,24 @@
1
1
  <script type="text/javascript">
2
+ RED.events.on('nodes:add', function (node) {
3
+ if (node.type === 'uibuilder') {
4
+ // Keep a list of uib nodes in the editor
5
+ // may be different to the deployed list
6
+ editorInstances[node.id] = node.url
7
+ // -- IF uibuilderInstances <> editorInstances THEN there are undeployed instances. --
8
+ }
9
+ })
10
+ RED.events.on('nodes:change', function (node) {
11
+ if (node.type === 'uibuilder') {
12
+ mylog('nodes:change:', node)
13
+ editorInstances[node.id] = node.url
14
+ }
15
+ })
16
+ RED.events.on('nodes:remove', function (node) {
17
+ if (node.type === 'uibuilder') {
18
+ mylog('>> nodes:remove >>', node)
19
+ delete editorInstances[node.id]
20
+ }
21
+ })
2
22
  RED.nodes.registerType("knxUltimateHueLight", {
3
23
  category: "KNX Ultimate",
4
24
  color: "#C0C7E9",
@@ -486,15 +506,15 @@
486
506
  $("#getColorAtSwitchOnNightTimeButton").text("Get current");
487
507
  });
488
508
  });
489
-
509
+
490
510
  // Fill options for minDimLevel and maxDimLevel
491
511
  for (let index = 0; index <= 90; index++) {
492
- if (index === 0){
512
+ if (index === 0) {
493
513
  $("#node-input-minDimLevelLight").append($("<option>").val(index).text(index.toString() + "% (Switch Off)"));
494
- }else{
514
+ } else {
495
515
  $("#node-input-minDimLevelLight").append($("<option>").val(index).text(index.toString() + "%"));
496
516
  }
497
-
517
+
498
518
  }
499
519
  $("#node-input-minDimLevelLight").val(node.minDimLevelLight);
500
520
  for (let index = 100; index >= 10; index--) {
@@ -41,22 +41,13 @@ module.exports = function (RED) {
41
41
  fill, shape, text, payload,
42
42
  }) => { };
43
43
  // Used to call the status update from the HUE config node.
44
- node.setNodeStatusHue = ({
45
- fill, shape, text, payload,
46
- }) => {
47
- if (payload === undefined) return;
44
+ node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
45
+ if (payload === undefined) payload = '';
48
46
  const dDate = new Date();
49
47
  payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
50
48
  node.status({ fill, shape, text: `${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})` });
51
49
  };
52
50
 
53
- node.setNodeStatusHue({
54
- fill: "grey",
55
- shape: "ring",
56
- text: "Connecting to the Bridge...",
57
- payload: "",
58
- });
59
-
60
51
  function getRandomIntInclusive(min, max) {
61
52
  min = Math.ceil(min);
62
53
  max = Math.floor(max);
@@ -69,7 +60,7 @@ module.exports = function (RED) {
69
60
  node.setNodeStatusHue({
70
61
  fill: "red",
71
62
  shape: "ring",
72
- text: "Rejected KNX message. I'm connecting to the Bridge...",
63
+ text: "Currently not ready.",
73
64
  payload: "",
74
65
  });
75
66
  return;
@@ -448,26 +439,32 @@ module.exports = function (RED) {
448
439
  node.currentHUEDevice.on.on = _event.on.on;
449
440
  }
450
441
  if (_event.hasOwnProperty("color")) {
451
- node.updateKNXLightColorState(_event.color);
452
- node.currentHUEDevice.color = _event.color;
442
+ if (_event.type !== 'grouped_light') {
443
+ // In grouped lights, there is group color, but each light has it's own color.
444
+ node.updateKNXLightColorState(_event.color);
445
+ node.currentHUEDevice.color = _event.color;
446
+ }
453
447
  }
454
448
  if (_event.hasOwnProperty("dimming") && _event.dimming.brightness !== undefined) {
455
449
  // Every once on a time, the light transmit the brightness value of 0.39.
456
450
  // To avoid wrongly turn light state on, exit
457
451
  if (_event.dimming.brightness < 1) _event.dimming.brightness = 0;
458
- if (node.currentHUEDevice.hasOwnProperty("on") && node.currentHUEDevice.on.on === false && _event.dimming.brightness === 0) return;
459
- if (node.currentHUEDevice.on.on === false) node.updateKNXLightState(_event.dimming.brightness > 0);
460
- node.updateKNXBrightnessState(_event.dimming.brightness);
461
- // If the brightness reaches zero, the hue lamp "on" property must be set to zero as well
462
- if (_event.dimming.brightness === 0) {
463
- node.serverHue.hueManager.writeHueQueueAdd(
464
- node.hueDevice,
465
- { on: { on: false } },
466
- node.isGrouped_light === false ? "setLight" : "setGroupedLight",
467
- );
468
- node.currentHUEDevice.on.on = false;
452
+ if (node.currentHUEDevice.hasOwnProperty("on") && node.currentHUEDevice.on.on === false && _event.dimming.brightness === 0) {
453
+ // Do nothing, because the light is off and the dimming also is 0
454
+ } else {
455
+ if (node.currentHUEDevice.on.on === false) node.updateKNXLightState(_event.dimming.brightness > 0);
456
+ node.updateKNXBrightnessState(_event.dimming.brightness);
457
+ // If the brightness reaches zero, the hue lamp "on" property must be set to zero as well
458
+ if (_event.dimming.brightness === 0) {
459
+ node.serverHue.hueManager.writeHueQueueAdd(
460
+ node.hueDevice,
461
+ { on: { on: false } },
462
+ node.isGrouped_light === false ? "setLight" : "setGroupedLight",
463
+ );
464
+ node.currentHUEDevice.on.on = false;
465
+ }
466
+ node.currentHUEDevice.dimming.brightness = _event.dimming.brightness;
469
467
  }
470
- node.currentHUEDevice.dimming.brightness = _event.dimming.brightness;
471
468
  }
472
469
  if (_event.hasOwnProperty("color_temperature") && _event.color_temperature.mirek !== undefined) {
473
470
  node.updateKNXLightHSVState(_event.color_temperature.mirek);
@@ -615,6 +612,8 @@ module.exports = function (RED) {
615
612
  }
616
613
  };
617
614
 
615
+
616
+
618
617
  // On each deploy, unsubscribe+resubscribe
619
618
  if (node.server) {
620
619
  node.server.removeClient(node);
@@ -622,13 +621,7 @@ module.exports = function (RED) {
622
621
  }
623
622
  if (node.serverHue) {
624
623
  node.serverHue.removeClient(node);
625
- if (node.serverHue !== null && node.serverHue.hueManager !== null) {
626
- try {
627
- node.serverHue.addClient(node);
628
- } catch (err) {
629
- RED.log.error(`Errore knxUltimateHueLight node.currentHUEDevice ${err.message}`);
630
- }
631
- }
624
+ node.serverHue.addClient(node);
632
625
  }
633
626
 
634
627
  node.on("input", (msg) => { });
@@ -22,6 +22,7 @@ module.exports = function (RED) {
22
22
  node.formatmultiplyvalue = 1;
23
23
  node.formatnegativevalue = 'leave';
24
24
  node.formatdecimalsvalue = 2;
25
+ node.hueDevice = config.hueDevice;
25
26
 
26
27
  // Used to call the status update from the config node.
27
28
  node.setNodeStatus = ({ fill, shape, text, payload }) => {
@@ -29,7 +30,7 @@ module.exports = function (RED) {
29
30
  };
30
31
  // Used to call the status update from the HUE config node.
31
32
  node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
32
- if (payload === undefined) return;
33
+ if (payload === undefined) payload = '';
33
34
  const dDate = new Date();
34
35
  payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString();
35
36
  node.status({ fill, shape, text: text + ' ' + payload + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' });
@@ -76,11 +77,7 @@ module.exports = function (RED) {
76
77
  }
77
78
  if (node.serverHue) {
78
79
  node.serverHue.removeClient(node);
79
- // I must get the object, to store read the status
80
- // I queue the state request, by passing the callback to call whenever the HUE bridge send me the light status async
81
- if (node.serverHue !== null && node.serverHue.hueManager !== null) {
82
- node.serverHue.addClient(node);
83
- }
80
+ node.serverHue.addClient(node);
84
81
  }
85
82
 
86
83
  node.on('input', function (msg) {