node-red-contrib-knx-ultimate 2.1.18 → 2.1.19

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,11 +6,14 @@
6
6
 
7
7
  # CHANGELOG
8
8
 
9
+ <p>
10
+ <b>Version 2.1.19</b> - July 2023<br/>
11
+ - Hue light and Hue button optimization.<br/>
12
+ </p>
13
+ <p>
9
14
  <p>
10
15
  <b>Version 2.1.18</b> - July 2023<br/>
11
16
  - Quick fix for MDT and Wienzler interfaces.<br/>
12
- - HUE light: added "invert" option to the Day/Night sensor.<br/>
13
- - More verbose status for all nodes.<br/>
14
17
  </p>
15
18
  <p>
16
19
  <b>Version 2.1.17</b> - July 2023<br/>
@@ -139,7 +139,7 @@ class KNXClient extends EventEmitter {
139
139
  this._clientSocket.bind({ port: null, address: this._options.localIPAddress }, function () {
140
140
  try {
141
141
  conn._clientSocket.setTTL(250)
142
- if (conn._options.localSocketAddress === undefined) conn._options.localSocketAddress = conn._clientSocket.address()
142
+ if (conn._options.localSocketAddress === undefined) conn._options.localSocketAddress = conn._clientSocket.address()
143
143
  } catch (error) {
144
144
  if (conn.sysLogger !== undefined && conn.sysLogger !== null) conn.sysLogger.error('UDP: Error setting SetTTL ' + error.message || '')
145
145
  }
@@ -325,7 +325,7 @@ class KNXClient extends EventEmitter {
325
325
  cEMIMessage.control.broadcast = 1
326
326
  cEMIMessage.control.priority = 3
327
327
  cEMIMessage.control.addressType = 1
328
- cEMIMessage.control.hopCount = 6 // i telegrammi multicast vengono inviati con numero di hop = 6
328
+ cEMIMessage.control.hopCount = 6
329
329
  const knxPacketRequest = KNXProtocol.KNXProtocol.newKNXRoutingIndication(cEMIMessage)
330
330
  this.send(knxPacketRequest)
331
331
  // 06/12/2021 Multivast automaticalli echoes telegrams
@@ -337,7 +337,7 @@ class KNXClient extends EventEmitter {
337
337
  cEMIMessage.control.broadcast = 1
338
338
  cEMIMessage.control.priority = 3
339
339
  cEMIMessage.control.addressType = 1
340
- cEMIMessage.control.hopCount = 7 // i telegrammi unicast e broadcast vengono inviati con numero di hop = 7
340
+ cEMIMessage.control.hopCount = 6
341
341
  const seqNum = this._incSeqNumber() // 26/12/2021
342
342
  const knxPacketRequest = KNXProtocol.KNXProtocol.newKNXTunnelingRequest(this._channelID, seqNum, cEMIMessage)
343
343
  if (!this._options.suppress_ack_ldatareq) this._setTimerWaitingForACK(knxPacketRequest)
@@ -1003,11 +1003,11 @@ class KNXClient extends EventEmitter {
1003
1003
  _sendConnectRequestMessage(cri) {
1004
1004
  // try {
1005
1005
  // const oHPAI = new HPAI.HPAI(this._options.localSocketAddress.address, this._options.localSocketAddress.port, this._options.hostProtocol === 'TunnelTCP' ? KNXConstants.KNX_CONSTANTS.IPV4_TCP : KNXConstants.KNX_CONSTANTS.IPV4_UDP)
1006
- // this.send(KNXProtocol.KNXProtocol.newKNXConnectRequest(cri, oHPAI, oHPAI))
1006
+ // this.send(KNXProtocol.KNXProtocol.newKNXConnectRequest(cri, null, oHPAI))
1007
1007
  // } catch (error) {
1008
1008
  // this.send(KNXProtocol.KNXProtocol.newKNXConnectRequest(cri))
1009
1009
  // }
1010
- this.send(KNXProtocol.KNXProtocol.newKNXConnectRequest(cri))
1010
+ this.send(KNXProtocol.KNXProtocol.newKNXConnectRequest(cri))
1011
1011
  }
1012
1012
 
1013
1013
  _sendConnectionStateRequestMessage(channelID) {
@@ -171,9 +171,14 @@ return msg;`,
171
171
 
172
172
  node.setAllClientsStatus = (_status, _color, _text) => {
173
173
  function nextStatus(_oClient) {
174
- let oClient = RED.nodes.getNode(_oClient.id)
175
- oClient.setNodeStatus({ fill: _color, shape: 'dot', text: _status + ' ' + _text, payload: '', GA: oClient.topic, dpt: '', devicename: '' })
176
- oClient = null
174
+ try {
175
+ let oClient = RED.nodes.getNode(_oClient.id)
176
+ oClient.setNodeStatus({ fill: _color, shape: 'dot', text: _status + ' ' + _text, payload: '', GA: oClient.topic, dpt: '', devicename: '' })
177
+ oClient = null
178
+ } catch (error) {
179
+ if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.warn('Wow setAllClientsStatus error ' + error.message)
180
+ }
181
+
177
182
  }
178
183
  node.nodeClients.map(nextStatus)
179
184
  }
@@ -33,9 +33,10 @@ module.exports = function (RED) {
33
33
  }
34
34
  // Used to call the status update from the HUE config node.
35
35
  node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
36
+ if (payload === undefined) return
36
37
  const dDate = new Date()
37
- payload = typeof payload === 'object' ? JSON.stringify(payload) : payload
38
- node.status({ fill, shape, text: text + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
38
+ payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString()
39
+ node.status({ fill, shape, text: text + ' ' + payload + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
39
40
  }
40
41
 
41
42
  // This function is called by the knx-ultimate config node, to output a msg.payload.
@@ -46,24 +47,18 @@ module.exports = function (RED) {
46
47
  case config.GAshort_releaseStatus:
47
48
  msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptshort_release))
48
49
  node.short_releaseValue = msg.payload
49
- setTimeout(() => {
50
- node.status({ fill: 'blue', shape: 'dot', text: 'Updated Switch ' + msg.knx.destination + ' ' + JSON.stringify(msg.payload) + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
51
- }, 500)
52
- node.setNodeStatusHue({ fill: 'green', shape: 'dot', text: 'KNX->HUE', payload: msg.payload })
50
+ node.setNodeStatusHue({ fill: 'blue', shape: 'dot', text: 'KNX->HUE Short Release Status', payload: msg.payload })
53
51
  break
54
52
  case config.GArepeatStatus:
55
53
  msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptrepeat))
56
54
  node.toggleGArepeat = msg.payload.decr_incr === 1
57
- setTimeout(() => {
58
- node.status({ fill: 'blue', shape: 'dot', text: 'Updated Dim ' + msg.knx.destination + ' ' + JSON.stringify(msg.payload) + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
59
- }, 500)
60
- node.setNodeStatusHue({ fill: 'green', shape: 'dot', text: 'KNX->HUE', payload: msg.payload })
55
+ node.setNodeStatusHue({ fill: 'blue', shape: 'dot', text: 'KNX->HUE Repeat Status', payload: msg.payload })
61
56
  break
62
57
  default:
63
58
  break
64
59
  }
65
60
  } catch (error) {
66
- node.status({ fill: 'red', shape: 'dot', text: 'KNX->HUE error ' + error.message + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
61
+ node.setNodeStatusHue({ fill: 'red', shape: 'dot', text: 'KNX->HUE error ' + error.message, payload: '' })
67
62
  }
68
63
  }
69
64
 
@@ -84,6 +79,12 @@ module.exports = function (RED) {
84
79
  break
85
80
  case 'long_release':
86
81
  flowMsgPayload = node.long_pressValue
82
+ // if the dimmer was running, send the STOP telegram to the KNX bus wires, using the GArepeat Group address and dpt.
83
+ if (node.isTimerDimStopRunning) {
84
+ knxMsgPayload.topic = config.GArepeat
85
+ knxMsgPayload.dpt = config.dptrepeat
86
+ node.stopDIM(knxMsgPayload)
87
+ }
87
88
  break
88
89
  case 'double_short_release':
89
90
  if (node.double_short_releaseValue === undefined) node.double_short_releaseValue = false
@@ -98,25 +99,29 @@ module.exports = function (RED) {
98
99
  case 'short_release':
99
100
  node.short_releaseValue = config.toggleValues ? !node.short_releaseValue : true
100
101
  flowMsgPayload = node.short_releaseValue
101
- knxMsgPayload.topic = config.GAshort_release
102
- knxMsgPayload.dpt = config.dptshort_release
103
- knxMsgPayload.payload = node.short_releaseValue
104
- // Send to KNX bus
105
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
106
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.status({ fill: 'green', shape: 'dot', text: 'HUE->KNX ' + _event.button.last_event + ' ' + JSON.stringify(knxMsgPayload.payload) + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
102
+ if (config.GAshort_release !== undefined && config.GAshort_release !== '') {
103
+ knxMsgPayload.topic = config.GAshort_release
104
+ knxMsgPayload.dpt = config.dptshort_release
105
+ knxMsgPayload.payload = node.short_releaseValue
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
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.setNodeStatusHue({ fill: 'green', shape: 'dot', text: 'HUE->KNX ' + _event.button.last_event, payload: knxMsgPayload.payload })
109
+ }
107
110
  break
108
111
  case 'repeat':
109
112
  flowMsgPayload = true
110
- if (node.isTimerDimStopRunning === false) {
111
- // Set KNX Dim up/down start
112
- knxMsgPayload.topic = config.GArepeat
113
- knxMsgPayload.dpt = config.dptrepeat
114
- knxMsgPayload.payload = node.long_pressValue ? { decr_incr: 0, data: 3 } : { decr_incr: 1, data: 3 } // If the light is turned on, the initial DIM direction must be down, otherwise, up
115
- // Send to KNX bus
116
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
117
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.status({ fill: 'green', shape: 'dot', text: 'HUE->KNX start Dim' + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
113
+ if (config.GArepeat !== undefined && config.GArepeat !== '') {
114
+ if (node.isTimerDimStopRunning === false) {
115
+ // Set KNX Dim up/down start
116
+ knxMsgPayload.topic = config.GArepeat
117
+ knxMsgPayload.dpt = config.dptrepeat
118
+ knxMsgPayload.payload = node.long_pressValue ? { decr_incr: 0, data: 3 } : { decr_incr: 1, data: 3 } // If the light is turned on, the initial DIM direction must be down, otherwise, up
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 })
121
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.setNodeStatusHue({ fill: 'green', shape: 'dot', text: 'HUE->KNX START DIM', payload: '' })
122
+ }
123
+ node.startDimStopper(knxMsgPayload)
118
124
  }
119
- node.startDimStopper(knxMsgPayload)
120
125
  break
121
126
  default:
122
127
  break
@@ -129,25 +134,30 @@ module.exports = function (RED) {
129
134
  flowMsg.rawEvent = _event
130
135
  flowMsg.payload = flowMsgPayload
131
136
  node.send(flowMsg)
132
- node.setNodeStatusHue({ fill: 'blue', shape: 'ring', text: 'HUE->KNX', payload: flowMsg.payload })
137
+ node.setNodeStatusHue({ fill: 'blue', shape: 'ring', text: 'HUE->KNX', payload: flowMsg.rawEvent + ' ' + flowMsg.payload })
133
138
  }
134
139
  } catch (error) {
135
- node.status({ fill: 'red', shape: 'dot', text: 'HUE->KNX error ' + error.message + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
140
+ node.setNodeStatusHue({ fill: 'red', shape: 'dot', text: 'HUE->KNX error ' + error.message, payload: '' })
136
141
  }
137
142
  }
138
143
 
139
144
  // Timer to stop the dimming sequence
140
145
  node.startDimStopper = function (knxMsgPayload) {
141
- if (node.timerDimStop !== undefined) clearInterval(node.timerDimStop)
146
+ if (node.timerDimStop !== undefined) clearTimeout(node.timerDimStop)
142
147
  node.isTimerDimStopRunning = true
143
148
  node.timerDimStop = setTimeout(() => {
144
- // KNX Stop DIM
145
- knxMsgPayload.payload = { decr_incr: 0, data: 0 } // Payload for the output msg
146
- // Send to KNX bus
147
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
148
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.status({ fill: 'green', shape: 'dot', text: 'HUE->KNX Stop DIM' + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
149
- node.isTimerDimStopRunning = false
150
- }, 700)
149
+ node.stopDIM(knxMsgPayload)
150
+ }, 2000)
151
+ }
152
+
153
+ node.stopDIM = function (knxMsgPayload) {
154
+ // KNX Stop DIM
155
+ if (node.timerDimStop !== undefined) clearTimeout(node.timerDimStop)
156
+ node.isTimerDimStopRunning = false
157
+ knxMsgPayload.payload = { decr_incr: 0, data: 0 } // Payload for the output msg
158
+ // Send to KNX bus
159
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
160
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.setNodeStatusHue({ fill: 'grey', shape: 'ring', text: 'HUE->KNX STOP DIM', payload: knxMsgPayload.payload })
151
161
  }
152
162
 
153
163
  // On each deploy, unsubscribe+resubscribe
@@ -35,8 +35,9 @@ module.exports = function (RED) {
35
35
  }
36
36
  // Used to call the status update from the HUE config node.
37
37
  node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
38
+ if (payload === undefined) return
38
39
  const dDate = new Date()
39
- payload = typeof payload === 'object' ? JSON.stringify(payload) : payload
40
+ payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString()
40
41
  node.status({ fill, shape, text: text + ' ' + payload + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
41
42
  }
42
43
 
@@ -171,8 +172,11 @@ module.exports = function (RED) {
171
172
  node.dimDirection = {}
172
173
  node.timeoutDim = 0
173
174
  node.startDimStopper = function (_direction) {
175
+ node.timeoutDim = 0
174
176
  if (node.timerDim !== undefined) clearInterval(node.timerDim)
175
- if (_direction === 'stop') return
177
+ if (_direction === 'stop') {
178
+ return
179
+ }
176
180
  switch (_direction) {
177
181
  case 'up':
178
182
  node.dimDirection = { dimming_delta: { action: 'up', brightness_delta: 10 } }
@@ -185,16 +189,18 @@ module.exports = function (RED) {
185
189
  }
186
190
  node.timerDim = setInterval(() => {
187
191
  node.timeoutDim += 1
188
- if (node.timeoutDim > 100) { node.timeoutDim = 0; clearInterval(node.timerDim) }
192
+ if (node.timeoutDim > 150) { node.timeoutDim = 0; clearInterval(node.timerDim) }
189
193
  node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, node.dimDirection, 'setLight')
190
- }, 300)
194
+ }, 700)
191
195
  }
192
196
 
193
197
  // Start dimming tunable white
194
198
  // mirek: required(integer – minimum: 153 – maximum: 500)
195
199
  node.timerDimTunableWhite = undefined
196
200
  node.dimDirectionTunableWhite = {}
201
+ node.timeoutDimTunableWhite = 0
197
202
  node.startDimStopperTunableWhite = function (_direction) {
203
+ node.timeoutDimTunableWhite = 0
198
204
  if (node.timerDimTunableWhite !== undefined) clearInterval(node.timerDimTunableWhite)
199
205
  if (_direction === 'stop') return
200
206
  switch (_direction) {
@@ -208,9 +214,10 @@ module.exports = function (RED) {
208
214
  break
209
215
  }
210
216
  node.timerDimTunableWhite = setInterval(() => {
217
+ node.timeoutDimTunableWhite += 1
218
+ if (node.timeoutDimTunableWhite > 150) { node.timeoutDimTunableWhite = 0; clearInterval(node.timerDimTunableWhite) }
211
219
  node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, node.dimDirectionTunableWhite, 'setLight')
212
- }, 300)
213
-
220
+ }, 700)
214
221
  }
215
222
 
216
223
  node.handleSendHUE = _event => {
@@ -218,49 +225,55 @@ module.exports = function (RED) {
218
225
  if (_event.id === config.hueDevice) {
219
226
  const knxMsgPayload = {}
220
227
  if (_event.hasOwnProperty('on')) {
221
- knxMsgPayload.topic = config.GALightState
222
- knxMsgPayload.dpt = config.dptLightState
223
- knxMsgPayload.payload = _event.on.on
224
- // Send to KNX bus
225
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
226
- // ISE Connect Hue emulation, send brightness
227
- knxMsgPayload.topic = config.GALightBrightnessState
228
- knxMsgPayload.dpt = config.dptLightBrightnessState
229
- knxMsgPayload.payload = _event.on.on === true ? 100 : 0
230
- // Send to KNX bus
231
- //if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
228
+ if (config.GALightState !== undefined && config.GALightState !== '') {
229
+ knxMsgPayload.topic = config.GALightState
230
+ knxMsgPayload.dpt = config.dptLightState
231
+ knxMsgPayload.payload = _event.on.on
232
+ // Send to KNX bus
233
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
234
+ // ISE Connect Hue emulation, send brightness
235
+ knxMsgPayload.topic = config.GALightBrightnessState
236
+ knxMsgPayload.dpt = config.dptLightBrightnessState
237
+ knxMsgPayload.payload = _event.on.on === true ? 100 : 0
238
+ // Send to KNX bus
239
+ //if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
240
+ }
232
241
  }
233
242
  if (_event.hasOwnProperty('color')) {
234
- knxMsgPayload.topic = config.GALightColorState
235
- knxMsgPayload.dpt = config.dptLightColorState
236
- knxMsgPayload.payload = hueColorConverter.ColorConverter.xyBriToRgb(_event.color.xy.x, _event.color.xy.y, (node.currentHUEDevice !== undefined ? node.currentHUEDevice.dimming.brightness : 100))
237
- // Send to KNX bus
238
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
243
+ if (config.GALightColorState !== undefined && config.GALightColorState !== '') {
244
+ knxMsgPayload.topic = config.GALightColorState
245
+ knxMsgPayload.dpt = config.dptLightColorState
246
+ knxMsgPayload.payload = hueColorConverter.ColorConverter.xyBriToRgb(_event.color.xy.x, _event.color.xy.y, (node.currentHUEDevice !== undefined ? node.currentHUEDevice.dimming.brightness : 100))
247
+ // Send to KNX bus
248
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
249
+ }
239
250
  }
240
251
  if (_event.hasOwnProperty('dimming')) {
241
- knxMsgPayload.topic = config.GALightBrightnessState
242
- knxMsgPayload.dpt = config.dptLightBrightnessState
243
- knxMsgPayload.payload = _event.dimming.brightness
244
- // Send to KNX bus
245
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
246
- // ISE Connect Hue emulation, send true/false to switch state
247
- knxMsgPayload.topic = config.GALightState
248
- knxMsgPayload.dpt = config.dptLightState
249
- knxMsgPayload.payload = _event.dimming.brightness > 0
250
- // Send to KNX bus
251
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
252
+ if (config.GALightBrightnessState !== undefined && config.GALightBrightnessState !== '') {
253
+ knxMsgPayload.topic = config.GALightBrightnessState
254
+ knxMsgPayload.dpt = config.dptLightBrightnessState
255
+ knxMsgPayload.payload = _event.dimming.brightness
256
+ // Send to KNX bus
257
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
258
+ // ISE Connect Hue emulation, send true/false to switch state
259
+ knxMsgPayload.topic = config.GALightState
260
+ knxMsgPayload.dpt = config.dptLightState
261
+ knxMsgPayload.payload = _event.dimming.brightness > 0
262
+ // Send to KNX bus
263
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
264
+ }
252
265
  }
253
266
  if (_event.hasOwnProperty('color_temperature')) {
254
- knxMsgPayload.topic = config.GALightHSVState
255
- knxMsgPayload.dpt = config.dptLightHSVState
256
- if (config.dptLightHSVState === '5.001') {
257
- const retPercent = hueColorConverter.ColorConverter.scale(_event.color_temperature.mirek, [153, 500], [0, 100])
258
- //NewValue = (((OldValue - OldMin) * (NewMax - NewMin)) / (OldMax - OldMin)) + NewMin
259
- //let NewValue = 100 - ((((_event.color_temperature.mirek - 153) * (100 - 0)) / (500 - 153)) + 0)
260
- knxMsgPayload.payload = 100 - retPercent
267
+ if (config.GALightHSVState !== undefined && config.GALightHSVState !== '') {
268
+ knxMsgPayload.topic = config.GALightHSVState
269
+ knxMsgPayload.dpt = config.dptLightHSVState
270
+ if (config.dptLightHSVState === '5.001') {
271
+ const retPercent = hueColorConverter.ColorConverter.scale(_event.color_temperature.mirek, [153, 500], [0, 100])
272
+ knxMsgPayload.payload = 100 - retPercent
273
+ }
274
+ // Send to KNX bus
275
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
261
276
  }
262
- // Send to KNX bus
263
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
264
277
  }
265
278
  node.setNodeStatusHue({ fill: 'blue', shape: 'ring', text: 'HUE->KNX State', payload: knxMsgPayload.payload })
266
279
  }
@@ -29,9 +29,10 @@ module.exports = function (RED) {
29
29
  }
30
30
  // Used to call the status update from the HUE config node.
31
31
  node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
32
+ if (payload === undefined) return
32
33
  const dDate = new Date()
33
- payload = typeof payload === 'object' ? JSON.stringify(payload) : payload
34
- node.status({ fill, shape, text: text + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
34
+ payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString()
35
+ node.status({ fill, shape, text: text + ' ' + payload + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
35
36
  }
36
37
 
37
38
  // This function is called by the knx-ultimate config node, to output a msg.payload.
@@ -29,9 +29,10 @@ module.exports = function (RED) {
29
29
  }
30
30
  // Used to call the status update from the HUE config node.
31
31
  node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
32
+ if (payload === undefined) return
32
33
  const dDate = new Date()
33
- payload = typeof payload === 'object' ? JSON.stringify(payload) : payload
34
- node.status({ fill, shape, text: text + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
34
+ payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString()
35
+ node.status({ fill, shape, text: text + ' ' + payload + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
35
36
  }
36
37
 
37
38
  // This function is called by the knx-ultimate config node, to output a msg.payload.
@@ -31,9 +31,10 @@ module.exports = function (RED) {
31
31
  }
32
32
  // Used to call the status update from the HUE config node.
33
33
  node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
34
+ if (payload === undefined) return
34
35
  const dDate = new Date()
35
- payload = typeof payload === 'object' ? JSON.stringify(payload) : payload
36
- node.status({ fill, shape, text: text + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
36
+ payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString()
37
+ node.status({ fill, shape, text: text + ' ' + payload + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
37
38
  }
38
39
 
39
40
  // This function is called by the knx-hue config node
@@ -31,9 +31,10 @@ module.exports = function (RED) {
31
31
  }
32
32
  // Used to call the status update from the HUE config node.
33
33
  node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
34
+ if (payload === undefined) return
34
35
  const dDate = new Date()
35
- payload = typeof payload === 'object' ? JSON.stringify(payload) : payload
36
- node.status({ fill, shape, text: text + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
36
+ payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString()
37
+ node.status({ fill, shape, text: text + ' ' + payload + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
37
38
  }
38
39
 
39
40
  // This function is called by the knx-ultimate config node, to output a msg.payload.
@@ -102,7 +103,7 @@ module.exports = function (RED) {
102
103
  knxMsgPayload.event = 'rotation ' + _event.relative_rotary.last_event.rotation.direction
103
104
  knxMsgPayload.payload = _event
104
105
  node.send(knxMsgPayload)
105
- node.setNodeStatusHue({ fill: 'blue', shape: 'rong', text: 'HUE->KNX', payload: knxMsgPayload.payload })
106
+ node.setNodeStatusHue({ fill: 'blue', shape: 'ring', text: 'HUE->KNX', payload: knxMsgPayload.payload })
106
107
  }
107
108
  } catch (error) {
108
109
  node.status({ fill: 'red', shape: 'dot', text: 'HUE->KNX error ' + error.message + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
@@ -29,9 +29,10 @@ module.exports = function (RED) {
29
29
  }
30
30
  // Used to call the status update from the HUE config node.
31
31
  node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
32
+ if (payload === undefined) return
32
33
  const dDate = new Date()
33
- payload = typeof payload === 'object' ? JSON.stringify(payload) : payload
34
- node.status({ fill, shape, text: text + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
34
+ payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString()
35
+ node.status({ fill, shape, text: text + ' ' + payload + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
35
36
  }
36
37
 
37
38
  // This function is called by the knx-ultimate config node, to output a msg.payload.
@@ -58,7 +59,7 @@ module.exports = function (RED) {
58
59
  // Send payload
59
60
  knxMsgPayload.rawEvent = _event
60
61
  node.send(knxMsgPayload)
61
- node.setNodeStatusHue({ fill: 'blue', shape: 'rong', text: 'HUE->KNX', payload: knxMsgPayload.payload })
62
+ node.setNodeStatusHue({ fill: 'blue', shape: 'ring', text: 'HUE->KNX', payload: knxMsgPayload.payload })
62
63
  }
63
64
  }
64
65
  } catch (error) {
@@ -203,7 +203,7 @@ class classHUE extends EventEmitter {
203
203
  const linkedLight = allResources.find(res => res.id === jScene.group.rid).children || ''
204
204
  linkedLight.forEach(light => {
205
205
  this.writeHueQueueAdd(light.rid, jRet._state, 'setLight')
206
- });
206
+ });
207
207
  } catch (error) {
208
208
  console.log('KNXUltimateHUEConfig: classHUE: handleQueue: stopScene: ' + error.message)
209
209
  }
@@ -213,10 +213,11 @@ class classHUE extends EventEmitter {
213
213
  }
214
214
  }
215
215
  // The Hue bridge allows about 10 telegram per second, so i need to make a queue manager
216
- setTimeout(this.handleQueue, 150)
216
+ setTimeout(this.handleQueue, 100)
217
217
  }
218
218
 
219
219
  writeHueQueueAdd = async (_lightID, _state, _operation, _callback) => {
220
+ // Add the new item
220
221
  this.commandQueue.push({ _lightID, _state, _operation, _callback })
221
222
  }
222
223
  // ######################################
@@ -284,7 +285,7 @@ class classHUE extends EventEmitter {
284
285
  this.es = null;
285
286
  setTimeout(() => {
286
287
  resolve(true)
287
- }, 1000)
288
+ }, 500)
288
289
  } catch (error) {
289
290
  reject(error)
290
291
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "engines": {
4
4
  "node": ">=16.0.0"
5
5
  },
6
- "version": "2.1.18",
6
+ "version": "2.1.19",
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": "3.0.1",