node-red-contrib-knx-ultimate 4.3.1 → 4.3.3

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.
@@ -2,297 +2,297 @@
2
2
  /* eslint-disable camelcase */
3
3
  /* eslint-disable max-len */
4
4
  /* eslint-disable no-lonely-if */
5
- const cloneDeep = require("lodash/cloneDeep");
6
- const dptlib = require('knxultimate').dptlib;
7
- const hueColorConverter = require("./utils/colorManipulators/hueColorConverter");
5
+ const cloneDeep = require('lodash/cloneDeep')
6
+ const dptlib = require('knxultimate').dptlib
7
+ const hueColorConverter = require('./utils/colorManipulators/hueColorConverter')
8
8
 
9
9
  module.exports = function (RED) {
10
- function knxUltimateHueLight(config) {
11
- RED.nodes.createNode(this, config);
12
- const node = this;
13
- node.serverKNX = RED.nodes.getNode(config.server) || undefined;
14
- node.serverHue = RED.nodes.getNode(config.serverHue) || undefined;
10
+ function knxUltimateHueLight (config) {
11
+ RED.nodes.createNode(this, config)
12
+ const node = this
13
+ node.serverKNX = RED.nodes.getNode(config.server) || undefined
14
+ node.serverHue = RED.nodes.getNode(config.serverHue) || undefined
15
15
 
16
16
  // Convert for backward compatibility
17
17
  if (config.nameLightKelvinDIM === undefined) {
18
- config.nameLightKelvinDIM = config.nameLightHSV;
19
- config.GALightKelvinDIM = config.GALightHSV;
20
- config.dptLightKelvinDIM = config.dptLightHSV;
18
+ config.nameLightKelvinDIM = config.nameLightHSV
19
+ config.GALightKelvinDIM = config.GALightHSV
20
+ config.dptLightKelvinDIM = config.dptLightHSV
21
21
 
22
- config.nameLightKelvinPercentage = config.nameLightHSVPercentage;
23
- config.GALightKelvinPercentage = config.GALightHSVPercentage;
24
- config.dptLightKelvinPercentage = config.dptLightHSVPercentage;
22
+ config.nameLightKelvinPercentage = config.nameLightHSVPercentage
23
+ config.GALightKelvinPercentage = config.GALightHSVPercentage
24
+ config.dptLightKelvinPercentage = config.dptLightHSVPercentage
25
25
 
26
- config.nameLightKelvinPercentageState = config.nameLightHSVState;
27
- config.GALightKelvinPercentageState = config.GALightHSVState;
28
- config.dptLightKelvinPercentageState = config.dptLightHSVState;
26
+ config.nameLightKelvinPercentageState = config.nameLightHSVState
27
+ config.GALightKelvinPercentageState = config.GALightHSVState
28
+ config.dptLightKelvinPercentageState = config.dptLightHSVState
29
29
  }
30
30
 
31
- node.topic = node.name;
32
- node.name = config.name === undefined ? "Hue" : config.name;
33
- node.outputtopic = node.name;
34
- node.dpt = "";
35
- node.notifyreadrequest = true;
36
- node.notifyreadrequestalsorespondtobus = "false";
37
- node.notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized = "";
38
- node.notifyresponse = false;
39
- node.notifywrite = true;
40
- node.initialread = true;
41
- node.listenallga = true; // Don't remove
42
- node.outputtype = "write";
43
- node.outputRBE = 'false'; // Apply or not RBE to the output (Messages coming from flow)
44
- node.inputRBE = 'false'; // Apply or not RBE to the input (Messages coming from BUS)
45
- node.currentPayload = ""; // Current value for the RBE input and for the .previouspayload msg
46
- node.passthrough = "no";
47
- node.formatmultiplyvalue = 1;
48
- node.formatnegativevalue = "leave";
49
- node.formatdecimalsvalue = 2;
50
- node.currentHUEDevice = undefined; // At start, this value is filled by a call to HUE api. It stores a value representing the current light status.
51
- node.HUEDeviceWhileDaytime = null;// This retains the HUE device status while daytime, to be restored after nighttime elapsed.
52
- node.HUELightsBelongingToGroupWhileDaytime = null; // Array contains all light belonging to the grouped_light (if grouped_light is selected)
53
- node.DayTime = true;
54
- node.isGrouped_light = config.hueDevice.split("#")[1] === "grouped_light";
55
- node.hueDevice = config.hueDevice.split("#")[0];
56
- node.initializingAtStart = (config.readStatusAtStartup === undefined || config.readStatusAtStartup === "yes");
57
- config.specifySwitchOnBrightness = (config.specifySwitchOnBrightness === undefined || config.specifySwitchOnBrightness === '') ? "temperature" : config.specifySwitchOnBrightness;
58
- config.specifySwitchOnBrightnessNightTime = (config.specifySwitchOnBrightnessNightTime === undefined || config.specifySwitchOnBrightnessNightTime === '') ? "no" : config.specifySwitchOnBrightnessNightTime;
59
- config.colorAtSwitchOnDayTime = (config.colorAtSwitchOnDayTime === '' || config.colorAtSwitchOnDayTime === undefined) ? '{ "kelvin":3000, "brightness":100 }' : config.colorAtSwitchOnDayTime;
60
- config.colorAtSwitchOnNightTime = (config.colorAtSwitchOnNightTime === '' || config.colorAtSwitchOnNightTime === undefined) ? '{ "kelvin":2700, "brightness":20 }' : config.colorAtSwitchOnNightTime;
61
- config.colorAtSwitchOnDayTime = config.colorAtSwitchOnDayTime.replace("geen", "green");
62
- config.colorAtSwitchOnNightTime = config.colorAtSwitchOnNightTime.replace("geen", "green");
63
- config.dimSpeed = (config.dimSpeed === undefined || config.dimSpeed === '') ? 5000 : Number(config.dimSpeed);
64
- config.HSVDimSpeed = (config.HSVDimSpeed === undefined || config.HSVDimSpeed === '') ? 5000 : Number(config.HSVDimSpeed);
65
- config.invertDimTunableWhiteDirection = config.invertDimTunableWhiteDirection !== undefined;
66
- config.restoreDayMode = config.restoreDayMode === undefined ? "no" : config.restoreDayMode; // no or setDayByFastSwitchLightSingle or setDayByFastSwitchLightALL
67
- config.updateLocalStateFromKNXWrite = config.updateLocalStateFromKNXWrite === true || config.updateLocalStateFromKNXWrite === "true"; // Starting from v 4.1.31
68
- node.timerCheckForFastLightSwitch = null;
69
- config.invertDayNight = config.invertDayNight === undefined ? false : config.invertDayNight;
70
- node.HSVObject = null; //{ h, s, v };// Store the current light calculated HSV
31
+ node.topic = node.name
32
+ node.name = config.name === undefined ? 'Hue' : config.name
33
+ node.outputtopic = node.name
34
+ node.dpt = ''
35
+ node.notifyreadrequest = true
36
+ node.notifyreadrequestalsorespondtobus = 'false'
37
+ node.notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized = ''
38
+ node.notifyresponse = false
39
+ node.notifywrite = true
40
+ node.initialread = true
41
+ node.listenallga = true // Don't remove
42
+ node.outputtype = 'write'
43
+ node.outputRBE = 'false' // Apply or not RBE to the output (Messages coming from flow)
44
+ node.inputRBE = 'false' // Apply or not RBE to the input (Messages coming from BUS)
45
+ node.currentPayload = '' // Current value for the RBE input and for the .previouspayload msg
46
+ node.passthrough = 'no'
47
+ node.formatmultiplyvalue = 1
48
+ node.formatnegativevalue = 'leave'
49
+ node.formatdecimalsvalue = 2
50
+ node.currentHUEDevice = undefined // At start, this value is filled by a call to HUE api. It stores a value representing the current light status.
51
+ node.HUEDeviceWhileDaytime = null// This retains the HUE device status while daytime, to be restored after nighttime elapsed.
52
+ node.HUELightsBelongingToGroupWhileDaytime = null // Array contains all light belonging to the grouped_light (if grouped_light is selected)
53
+ node.DayTime = true
54
+ node.isGrouped_light = config.hueDevice.split('#')[1] === 'grouped_light'
55
+ node.hueDevice = config.hueDevice.split('#')[0]
56
+ node.initializingAtStart = (config.readStatusAtStartup === undefined || config.readStatusAtStartup === 'yes')
57
+ config.specifySwitchOnBrightness = (config.specifySwitchOnBrightness === undefined || config.specifySwitchOnBrightness === '') ? 'temperature' : config.specifySwitchOnBrightness
58
+ config.specifySwitchOnBrightnessNightTime = (config.specifySwitchOnBrightnessNightTime === undefined || config.specifySwitchOnBrightnessNightTime === '') ? 'no' : config.specifySwitchOnBrightnessNightTime
59
+ config.colorAtSwitchOnDayTime = (config.colorAtSwitchOnDayTime === '' || config.colorAtSwitchOnDayTime === undefined) ? '{ "kelvin":3000, "brightness":100 }' : config.colorAtSwitchOnDayTime
60
+ config.colorAtSwitchOnNightTime = (config.colorAtSwitchOnNightTime === '' || config.colorAtSwitchOnNightTime === undefined) ? '{ "kelvin":2700, "brightness":20 }' : config.colorAtSwitchOnNightTime
61
+ config.colorAtSwitchOnDayTime = config.colorAtSwitchOnDayTime.replace('geen', 'green')
62
+ config.colorAtSwitchOnNightTime = config.colorAtSwitchOnNightTime.replace('geen', 'green')
63
+ config.dimSpeed = (config.dimSpeed === undefined || config.dimSpeed === '') ? 5000 : Number(config.dimSpeed)
64
+ config.HSVDimSpeed = (config.HSVDimSpeed === undefined || config.HSVDimSpeed === '') ? 5000 : Number(config.HSVDimSpeed)
65
+ config.invertDimTunableWhiteDirection = config.invertDimTunableWhiteDirection !== undefined
66
+ config.restoreDayMode = config.restoreDayMode === undefined ? 'no' : config.restoreDayMode // no or setDayByFastSwitchLightSingle or setDayByFastSwitchLightALL
67
+ config.updateLocalStateFromKNXWrite = config.updateLocalStateFromKNXWrite === true || config.updateLocalStateFromKNXWrite === 'true' // Starting from v 4.1.31
68
+ node.timerCheckForFastLightSwitch = null
69
+ config.invertDayNight = config.invertDayNight === undefined ? false : config.invertDayNight
70
+ node.HSVObject = null // { h, s, v };// Store the current light calculated HSV
71
71
 
72
72
  // Transform HEX in RGB and stringified json in json oblects.
73
- if (config.colorAtSwitchOnDayTime.indexOf("#") !== -1) {
73
+ if (config.colorAtSwitchOnDayTime.indexOf('#') !== -1) {
74
74
  // Transform to rgb.
75
75
  try {
76
- config.colorAtSwitchOnDayTime = hueColorConverter.ColorConverter.hexRgb(config.colorAtSwitchOnDayTime.replace("#", ""));
76
+ config.colorAtSwitchOnDayTime = hueColorConverter.ColorConverter.hexRgb(config.colorAtSwitchOnDayTime.replace('#', ''))
77
77
  } catch (error) {
78
- config.colorAtSwitchOnDayTime = { kelvin: 3000, brightness: 100 };
78
+ config.colorAtSwitchOnDayTime = { kelvin: 3000, brightness: 100 }
79
79
  }
80
80
  } else {
81
81
  try {
82
- config.colorAtSwitchOnDayTime = JSON.parse(config.colorAtSwitchOnDayTime);
82
+ config.colorAtSwitchOnDayTime = JSON.parse(config.colorAtSwitchOnDayTime)
83
83
  } catch (error) {
84
- RED.log.error(`knxUltimateHueLight: config.colorAtSwitchOnDayTime = JSON.parse(config.colorAtSwitchOnDayTime): ${error.message} : ${error.stack || ""} `);
85
- config.colorAtSwitchOnDayTime = "";
84
+ RED.log.error(`knxUltimateHueLight: config.colorAtSwitchOnDayTime = JSON.parse(config.colorAtSwitchOnDayTime): ${error.message} : ${error.stack || ''} `)
85
+ config.colorAtSwitchOnDayTime = ''
86
86
  }
87
87
  }
88
88
  // Same thing, but with night color
89
- if (config.colorAtSwitchOnNightTime.indexOf("#") !== -1) {
89
+ if (config.colorAtSwitchOnNightTime.indexOf('#') !== -1) {
90
90
  // Transform to rgb.
91
91
  try {
92
- config.colorAtSwitchOnNightTime = hueColorConverter.ColorConverter.hexRgb(config.colorAtSwitchOnNightTime.replace("#", ""));
92
+ config.colorAtSwitchOnNightTime = hueColorConverter.ColorConverter.hexRgb(config.colorAtSwitchOnNightTime.replace('#', ''))
93
93
  } catch (error) {
94
- config.colorAtSwitchOnNightTime = { kelvin: 2700, brightness: 20 };
94
+ config.colorAtSwitchOnNightTime = { kelvin: 2700, brightness: 20 }
95
95
  }
96
96
  } else {
97
97
  try {
98
- config.colorAtSwitchOnNightTime = JSON.parse(config.colorAtSwitchOnNightTime);
98
+ config.colorAtSwitchOnNightTime = JSON.parse(config.colorAtSwitchOnNightTime)
99
99
  } catch (error) {
100
- RED.log.error(`knxUltimateHueLight: config.colorAtSwitchOnDayTime = JSON.parse(config.colorAtSwitchOnNightTime): ${error.message} : ${error.stack || ""} `);
101
- config.colorAtSwitchOnNightTime = "";
100
+ RED.log.error(`knxUltimateHueLight: config.colorAtSwitchOnDayTime = JSON.parse(config.colorAtSwitchOnNightTime): ${error.message} : ${error.stack || ''} `)
101
+ config.colorAtSwitchOnNightTime = ''
102
102
  }
103
103
  }
104
104
 
105
105
  const formatTs = (date) => {
106
- const d = date instanceof Date ? date : new Date(date);
107
- const provider = node.serverKNX;
108
- if (provider && typeof provider.formatStatusTimestamp === "function") return provider.formatStatusTimestamp(d);
109
- return `${d.getDate()}, ${d.toLocaleTimeString()}`;
110
- };
111
-
112
- node.syncCurrentHUEDeviceFromKNXState = function syncCurrentHUEDeviceFromKNXState(_state) { // Starting from v 4.1.31
113
- if (config.updateLocalStateFromKNXWrite !== true) return; // Starting from v 4.1.31
114
- if (_state === undefined || _state === null || typeof _state !== "object") return; // Starting from v 4.1.31
115
- if (node.currentHUEDevice === undefined || node.currentHUEDevice === null) return; // Starting from v 4.1.31
116
- if (_state.on !== undefined && typeof _state.on.on === "boolean") { // Starting from v 4.1.31
117
- if (node.currentHUEDevice.on === undefined || node.currentHUEDevice.on === null) node.currentHUEDevice.on = {}; // Starting from v 4.1.31
118
- node.currentHUEDevice.on.on = _state.on.on; // Starting from v 4.1.31
106
+ const d = date instanceof Date ? date : new Date(date)
107
+ const provider = node.serverKNX
108
+ if (provider && typeof provider.formatStatusTimestamp === 'function') return provider.formatStatusTimestamp(d)
109
+ return `${d.getDate()}, ${d.toLocaleTimeString()}`
110
+ }
111
+
112
+ node.syncCurrentHUEDeviceFromKNXState = function syncCurrentHUEDeviceFromKNXState (_state) { // Starting from v 4.1.31
113
+ if (config.updateLocalStateFromKNXWrite !== true) return // Starting from v 4.1.31
114
+ if (_state === undefined || _state === null || typeof _state !== 'object') return // Starting from v 4.1.31
115
+ if (node.currentHUEDevice === undefined || node.currentHUEDevice === null) return // Starting from v 4.1.31
116
+ if (_state.on !== undefined && typeof _state.on.on === 'boolean') { // Starting from v 4.1.31
117
+ if (node.currentHUEDevice.on === undefined || node.currentHUEDevice.on === null) node.currentHUEDevice.on = {} // Starting from v 4.1.31
118
+ node.currentHUEDevice.on.on = _state.on.on // Starting from v 4.1.31
119
119
  } // Starting from v 4.1.31
120
120
  if (_state.dimming !== undefined && _state.dimming !== null && _state.dimming.brightness !== undefined) { // Starting from v 4.1.31
121
- if (node.currentHUEDevice.dimming === undefined || node.currentHUEDevice.dimming === null) node.currentHUEDevice.dimming = {}; // Starting from v 4.1.31
122
- node.currentHUEDevice.dimming.brightness = _state.dimming.brightness; // Starting from v 4.1.31
121
+ if (node.currentHUEDevice.dimming === undefined || node.currentHUEDevice.dimming === null) node.currentHUEDevice.dimming = {} // Starting from v 4.1.31
122
+ node.currentHUEDevice.dimming.brightness = _state.dimming.brightness // Starting from v 4.1.31
123
123
  } // Starting from v 4.1.31
124
124
  if (_state.color !== undefined && _state.color !== null && _state.color.xy !== undefined) { // Starting from v 4.1.31
125
- if (node.currentHUEDevice.color === undefined || node.currentHUEDevice.color === null) node.currentHUEDevice.color = {}; // Starting from v 4.1.31
126
- node.currentHUEDevice.color.xy = cloneDeep(_state.color.xy); // Starting from v 4.1.31
125
+ if (node.currentHUEDevice.color === undefined || node.currentHUEDevice.color === null) node.currentHUEDevice.color = {} // Starting from v 4.1.31
126
+ node.currentHUEDevice.color.xy = cloneDeep(_state.color.xy) // Starting from v 4.1.31
127
127
  } // Starting from v 4.1.31
128
128
  if (_state.color_temperature !== undefined && _state.color_temperature !== null && _state.color_temperature.mirek !== undefined) { // Starting from v 4.1.31
129
- if (node.currentHUEDevice.color_temperature === undefined || node.currentHUEDevice.color_temperature === null) node.currentHUEDevice.color_temperature = {}; // Starting from v 4.1.31
130
- node.currentHUEDevice.color_temperature.mirek = _state.color_temperature.mirek; // Starting from v 4.1.31
129
+ if (node.currentHUEDevice.color_temperature === undefined || node.currentHUEDevice.color_temperature === null) node.currentHUEDevice.color_temperature = {} // Starting from v 4.1.31
130
+ node.currentHUEDevice.color_temperature.mirek = _state.color_temperature.mirek // Starting from v 4.1.31
131
131
  } // Starting from v 4.1.31
132
- }; // Starting from v 4.1.31
132
+ } // Starting from v 4.1.31
133
133
 
134
134
  // Used to call the status update from the config node.
135
135
  node.setNodeStatus = ({
136
- fill, shape, text, payload,
136
+ fill, shape, text, payload
137
137
  }) => {
138
138
  try {
139
- if (node.currentHUEDevice?.on?.on === true) { fill = "blue"; shape = "dot" } else { fill = "blue"; shape = "ring" };
140
- if (payload === undefined) payload = '';
141
- const dDate = new Date();
142
- payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
143
- node.sKNXNodeStatusText = `|KNX: ${text} ${payload} (${formatTs(dDate)})`;
144
- node.status({ fill, shape, text: (node.sHUENodeStatusText || '') + ' ' + (node.sKNXNodeStatusText || '') });
139
+ if (node.currentHUEDevice?.on?.on === true) { fill = 'blue'; shape = 'dot' } else { fill = 'blue'; shape = 'ring' };
140
+ if (payload === undefined) payload = ''
141
+ const dDate = new Date()
142
+ payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString()
143
+ node.sKNXNodeStatusText = `|KNX: ${text} ${payload} (${formatTs(dDate)})`
144
+ node.status({ fill, shape, text: (node.sHUENodeStatusText || '') + ' ' + (node.sKNXNodeStatusText || '') })
145
145
  } catch (error) { }
146
- };
146
+ }
147
147
  // Used to call the status update from the HUE config node.
148
148
  node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
149
149
  try {
150
- if (node.currentHUEDevice?.on?.on === true) { fill = "blue"; shape = "dot" } else { fill = "blue"; shape = "ring" };
151
- if (payload === undefined) payload = '';
152
- const dDate = new Date();
153
- payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
154
- node.sHUENodeStatusText = `|HUE: ${text} ${payload} (${formatTs(dDate)})`;
155
- node.status({ fill, shape, text: node.sHUENodeStatusText + ' ' + (node.sKNXNodeStatusText || '') });
150
+ if (node.currentHUEDevice?.on?.on === true) { fill = 'blue'; shape = 'dot' } else { fill = 'blue'; shape = 'ring' };
151
+ if (payload === undefined) payload = ''
152
+ const dDate = new Date()
153
+ payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString()
154
+ node.sHUENodeStatusText = `|HUE: ${text} ${payload} (${formatTs(dDate)})`
155
+ node.status({ fill, shape, text: node.sHUENodeStatusText + ' ' + (node.sKNXNodeStatusText || '') })
156
156
  } catch (error) { }
157
- };
158
-
159
- node.writeHueState = function writeHueState(_state) {
160
- const defaultOperation = node.isGrouped_light === false ? "setLight" : "setGroupedLight";
161
- const isGroupedLightOff = node.isGrouped_light === true && node.currentHUEDevice?.on?.on === false;
162
- const stateKeys = _state && typeof _state === "object" ? Object.keys(_state) : [];
163
- const presetKeys = ["dimming", "color", "color_temperature", "gradient"];
164
- const actionableKeys = ["dimming", ...presetKeys];
165
- const hasActionablePayload = stateKeys.some((key) => actionableKeys.includes(key));
166
- const mustPresetGroupedLightChildren = isGroupedLightOff
167
- && stateKeys.some((key) => presetKeys.includes(key));
157
+ }
158
+
159
+ node.writeHueState = function writeHueState (_state) {
160
+ const defaultOperation = node.isGrouped_light === false ? 'setLight' : 'setGroupedLight'
161
+ const isGroupedLightOff = node.isGrouped_light === true && node.currentHUEDevice?.on?.on === false
162
+ const stateKeys = _state && typeof _state === 'object' ? Object.keys(_state) : []
163
+ const presetKeys = ['dimming', 'color', 'color_temperature', 'gradient']
164
+ const actionableKeys = ['dimming', ...presetKeys]
165
+ const hasActionablePayload = stateKeys.some((key) => actionableKeys.includes(key))
166
+ const mustPresetGroupedLightChildren = isGroupedLightOff &&
167
+ stateKeys.some((key) => presetKeys.includes(key))
168
168
 
169
169
  if (!mustPresetGroupedLightChildren) {
170
- node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, _state, defaultOperation);
171
- return;
170
+ node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, _state, defaultOperation)
171
+ return
172
172
  }
173
173
 
174
174
  (async () => {
175
175
  try {
176
- const groupLights = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, false);
177
- RED.log.debug(`knxUltimateHueLight: preset grouped_light children before group on. Group=${node.hueDevice} lights=${Array.isArray(groupLights) ? groupLights.length : 0}`);
178
- let hasWrittenAtLeastOneLight = false;
176
+ const groupLights = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, false)
177
+ RED.log.debug(`knxUltimateHueLight: preset grouped_light children before group on. Group=${node.hueDevice} lights=${Array.isArray(groupLights) ? groupLights.length : 0}`)
178
+ let hasWrittenAtLeastOneLight = false
179
179
  for (let index = 0; index < groupLights.length; index++) {
180
- const light = groupLights[index];
181
- if (!light?.id) continue;
182
- const lightState = {};
183
- let hasActionableStateForLight = false;
180
+ const light = groupLights[index]
181
+ if (!light?.id) continue
182
+ const lightState = {}
183
+ let hasActionableStateForLight = false
184
184
 
185
185
  if (_state.dimming !== undefined && light.dimming !== undefined) {
186
- lightState.dimming = cloneDeep(_state.dimming);
187
- hasActionableStateForLight = true;
186
+ lightState.dimming = cloneDeep(_state.dimming)
187
+ hasActionableStateForLight = true
188
188
  }
189
189
  if (_state.color !== undefined && light.color !== undefined) {
190
- lightState.color = cloneDeep(_state.color);
191
- hasActionableStateForLight = true;
190
+ lightState.color = cloneDeep(_state.color)
191
+ hasActionableStateForLight = true
192
192
  }
193
193
  if (_state.color_temperature !== undefined && light.color_temperature !== undefined) {
194
- lightState.color_temperature = cloneDeep(_state.color_temperature);
195
- hasActionableStateForLight = true;
194
+ lightState.color_temperature = cloneDeep(_state.color_temperature)
195
+ hasActionableStateForLight = true
196
196
  }
197
197
  if (_state.gradient !== undefined && light.gradient !== undefined) {
198
- lightState.gradient = cloneDeep(_state.gradient);
199
- hasActionableStateForLight = true;
198
+ lightState.gradient = cloneDeep(_state.gradient)
199
+ hasActionableStateForLight = true
200
200
  }
201
201
 
202
- if (!hasActionableStateForLight) continue;
203
- node.serverHue.hueManager.writeHueQueueAdd(light.id, lightState, "setLight");
204
- hasWrittenAtLeastOneLight = true;
202
+ if (!hasActionableStateForLight) continue
203
+ node.serverHue.hueManager.writeHueQueueAdd(light.id, lightState, 'setLight')
204
+ hasWrittenAtLeastOneLight = true
205
205
  }
206
206
 
207
207
  if (!hasWrittenAtLeastOneLight || !hasActionablePayload) {
208
- node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, _state, defaultOperation);
209
- return;
208
+ node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, _state, defaultOperation)
209
+ return
210
210
  }
211
211
 
212
- if (_state?.on?.on !== true) return;
212
+ if (_state?.on?.on !== true) return
213
213
 
214
- const groupedLightState = { on: cloneDeep(_state.on) };
215
- if (_state.dynamics !== undefined) groupedLightState.dynamics = cloneDeep(_state.dynamics);
216
- RED.log.debug(`knxUltimateHueLight: turning on grouped_light after children preset. Group=${node.hueDevice}`);
217
- node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, groupedLightState, defaultOperation);
214
+ const groupedLightState = { on: cloneDeep(_state.on) }
215
+ if (_state.dynamics !== undefined) groupedLightState.dynamics = cloneDeep(_state.dynamics)
216
+ RED.log.debug(`knxUltimateHueLight: turning on grouped_light after children preset. Group=${node.hueDevice}`)
217
+ node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, groupedLightState, defaultOperation)
218
218
  } catch (error) {
219
- RED.log.debug(`knxUltimateHueLight: node.writeHueState fallback to grouped_light write: ${error.message}`);
220
- node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, _state, defaultOperation);
219
+ RED.log.debug(`knxUltimateHueLight: node.writeHueState fallback to grouped_light write: ${error.message}`)
220
+ node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, _state, defaultOperation)
221
221
  }
222
- })();
223
- };
222
+ })()
223
+ }
224
224
 
225
- node.deleteHueStateQueue = function deleteHueStateQueue() {
226
- node.serverHue.hueManager.deleteHueQueue(node.hueDevice);
225
+ node.deleteHueStateQueue = function deleteHueStateQueue () {
226
+ node.serverHue.hueManager.deleteHueQueue(node.hueDevice)
227
227
  if (node.isGrouped_light !== true) return;
228
228
 
229
229
  (async () => {
230
230
  try {
231
- const groupLights = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, false);
231
+ const groupLights = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, false)
232
232
  for (let index = 0; index < groupLights.length; index++) {
233
- const light = groupLights[index];
234
- if (!light?.id) continue;
235
- node.serverHue.hueManager.deleteHueQueue(light.id);
233
+ const light = groupLights[index]
234
+ if (!light?.id) continue
235
+ node.serverHue.hueManager.deleteHueQueue(light.id)
236
236
  }
237
237
  } catch (error) {
238
- RED.log.debug(`knxUltimateHueLight: node.deleteHueStateQueue: ${error.message}`);
238
+ RED.log.debug(`knxUltimateHueLight: node.deleteHueStateQueue: ${error.message}`)
239
239
  }
240
- })();
241
- };
240
+ })()
241
+ }
242
242
 
243
- function getRandomIntInclusive(min, max) {
244
- min = Math.ceil(min);
245
- max = Math.floor(max);
246
- return Math.floor(Math.random() * (max - min + 1) + min); // The maximum is inclusive and the minimum is inclusive
243
+ function getRandomIntInclusive (min, max) {
244
+ min = Math.ceil(min)
245
+ max = Math.floor(max)
246
+ return Math.floor(Math.random() * (max - min + 1) + min) // The maximum is inclusive and the minimum is inclusive
247
247
  }
248
248
 
249
249
  // This function is called by the hue-config.js
250
250
  node.handleSend = (msg) => {
251
- if (node.currentHUEDevice === undefined && node.serverHue.linkStatus === "connected") {
251
+ if (node.currentHUEDevice === undefined && node.serverHue.linkStatus === 'connected') {
252
252
  node.setNodeStatusHue({
253
- fill: "yellow",
254
- shape: "ring",
255
- text: "Initializing. Please wait.",
256
- payload: "",
257
- });
258
- return;
253
+ fill: 'yellow',
254
+ shape: 'ring',
255
+ text: 'Initializing. Please wait.',
256
+ payload: ''
257
+ })
258
+ return
259
259
  }
260
- if (msg.knx.event !== "GroupValue_Read" && node.currentHUEDevice !== undefined) {
261
- let state = {};
260
+ if (msg.knx.event !== 'GroupValue_Read' && node.currentHUEDevice !== undefined) {
261
+ let state = {}
262
262
  try {
263
263
  switch (msg.knx.destination) {
264
264
  case config.GALightSwitch:
265
- msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightSwitch));
265
+ msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightSwitch))
266
266
 
267
267
  // 15/05/2024 Supergiovane: check the Override to Day option
268
268
  // config.restoreDayMode can be: no or setDayByFastSwitchLightSingle or setDayByFastSwitchLightALL
269
269
  // ----------------------------------------------------------
270
- if (config.restoreDayMode === "setDayByFastSwitchLightSingle" || config.restoreDayMode === "setDayByFastSwitchLightALL") {
270
+ if (config.restoreDayMode === 'setDayByFastSwitchLightSingle' || config.restoreDayMode === 'setDayByFastSwitchLightALL') {
271
271
  if (node.DayTime === false) {
272
272
  if (msg.payload === true) {
273
273
  if (node.timerCheckForFastLightSwitch === null) {
274
274
  node.timerCheckForFastLightSwitch = setTimeout(() => {
275
- node.DayTime = false;
276
- RED.log.debug("knxUltimateHueLight: node.timerCheckForFastLightSwitch: set daytime to false after node.timerCheckForFastLightSwitch elapsed");
277
- node.timerCheckForFastLightSwitch = null;
278
- }, 10000); // 10 seconds
275
+ node.DayTime = false
276
+ RED.log.debug('knxUltimateHueLight: node.timerCheckForFastLightSwitch: set daytime to false after node.timerCheckForFastLightSwitch elapsed')
277
+ node.timerCheckForFastLightSwitch = null
278
+ }, 10000) // 10 seconds
279
279
  } else {
280
- if (config.restoreDayMode === "setDayByFastSwitchLightALL") {
280
+ if (config.restoreDayMode === 'setDayByFastSwitchLightALL') {
281
281
  // Turn off the Day/Night group address
282
- if (config.GADaylightSensor !== undefined && config.GADaylightSensor !== "") {
283
- if (node.timerCheckForFastLightSwitch !== null) { clearTimeout(node.timerCheckForFastLightSwitch); node.timerCheckForFastLightSwitch = null; }
284
- RED.log.debug(`knxUltimateHueLight: node.timerCheckForFastLightSwitch: set daytime the group address ${config.GADaylightSensor}`);
282
+ if (config.GADaylightSensor !== undefined && config.GADaylightSensor !== '') {
283
+ if (node.timerCheckForFastLightSwitch !== null) { clearTimeout(node.timerCheckForFastLightSwitch); node.timerCheckForFastLightSwitch = null }
284
+ RED.log.debug(`knxUltimateHueLight: node.timerCheckForFastLightSwitch: set daytime the group address ${config.GADaylightSensor}`)
285
285
  node.serverKNX.sendKNXTelegramToKNXEngine({
286
286
  grpaddr: config.GADaylightSensor,
287
287
  payload: config.invertDayNight === false,
288
288
  dpt: config.dptDaylightSensor,
289
- outputtype: "write",
290
- nodecallerid: node.id,
291
- });
289
+ outputtype: 'write',
290
+ nodecallerid: node.id
291
+ })
292
292
  }
293
293
  }
294
- node.DayTime = true;
295
- RED.log.debug("knxUltimateHueLight: node.timerCheckForFastLightSwitch: set daytime to true");
294
+ node.DayTime = true
295
+ RED.log.debug('knxUltimateHueLight: node.timerCheckForFastLightSwitch: set daytime to true')
296
296
  }
297
297
  }
298
298
  }
@@ -304,374 +304,374 @@ module.exports = function (RED) {
304
304
  // If you try and control multiple conflicting parameters at once e.g. {"color": {"xy": {"x":0.5,"y":0.5}}, "color_temperature": {"mirek": 250}}
305
305
  // the lights can only physically do one, for this we apply the rule that xy beats ct. Simple.
306
306
  // color_temperature.mirek: color temperature in mirek is null when the light color is not in the ct spectrum
307
- if ((node.DayTime === true && config.specifySwitchOnBrightness === "no") && ((node.isGrouped_light === false && node.HUEDeviceWhileDaytime !== null) || (node.isGrouped_light === true && node.HUELightsBelongingToGroupWhileDaytime !== null))) {
307
+ if ((node.DayTime === true && config.specifySwitchOnBrightness === 'no') && ((node.isGrouped_light === false && node.HUEDeviceWhileDaytime !== null) || (node.isGrouped_light === true && node.HUELightsBelongingToGroupWhileDaytime !== null))) {
308
308
  if (node.isGrouped_light === false && node.HUEDeviceWhileDaytime !== null) {
309
309
  // The DayNight has switched into day, so restore the previous light status
310
- state = { on: { on: true }, dimming: node.HUEDeviceWhileDaytime.dimming, color: node.HUEDeviceWhileDaytime.color, color_temperature: node.HUEDeviceWhileDaytime.color_temperature };
311
- if (node.HUEDeviceWhileDaytime.color_temperature !== undefined && node.HUEDeviceWhileDaytime.color_temperature.mirek === null) delete state.color_temperature; // Otherwise the lamp will not turn on due to an error. color_temperature.mirek: color temperature in mirek is null when the light color is not in the ct spectrum
312
- node.writeHueState(state);
310
+ state = { on: { on: true }, dimming: node.HUEDeviceWhileDaytime.dimming, color: node.HUEDeviceWhileDaytime.color, color_temperature: node.HUEDeviceWhileDaytime.color_temperature }
311
+ if (node.HUEDeviceWhileDaytime.color_temperature !== undefined && node.HUEDeviceWhileDaytime.color_temperature.mirek === null) delete state.color_temperature // Otherwise the lamp will not turn on due to an error. color_temperature.mirek: color temperature in mirek is null when the light color is not in the ct spectrum
312
+ node.writeHueState(state)
313
313
  node.setNodeStatusHue({
314
- fill: "green",
315
- shape: "dot",
316
- text: "KNX->HUE",
317
- payload: "Restore light status",
318
- });
319
- node.HUEDeviceWhileDaytime = null; // Nullize the object.
314
+ fill: 'green',
315
+ shape: 'dot',
316
+ text: 'KNX->HUE',
317
+ payload: 'Restore light status'
318
+ })
319
+ node.HUEDeviceWhileDaytime = null // Nullize the object.
320
320
  } else if (node.isGrouped_light === true && node.HUELightsBelongingToGroupWhileDaytime !== null) {
321
321
  // The DayNight has switched into day, so restore the previous light state, belonging to the group
322
- let bAtLeastOneIsOn = false;
322
+ let bAtLeastOneIsOn = false
323
323
  for (let index = 0; index < node.HUELightsBelongingToGroupWhileDaytime.length; index++) { // Ensure, at least 1 lamp was on, otherwise turn all lamps on
324
- const element = node.HUELightsBelongingToGroupWhileDaytime[index].light[0];
324
+ const element = node.HUELightsBelongingToGroupWhileDaytime[index].light[0]
325
325
  if (element.on.on === true) {
326
- bAtLeastOneIsOn = true;
327
- break;
326
+ bAtLeastOneIsOn = true
327
+ break
328
328
  }
329
329
  }
330
330
  for (let index = 0; index < node.HUELightsBelongingToGroupWhileDaytime.length; index++) {
331
- const element = node.HUELightsBelongingToGroupWhileDaytime[index].light[0];
331
+ const element = node.HUELightsBelongingToGroupWhileDaytime[index].light[0]
332
332
  if (bAtLeastOneIsOn === true) {
333
- state = { on: element.on, dimming: element.dimming, color: element.color, color_temperature: element.color_temperature };
333
+ state = { on: element.on, dimming: element.dimming, color: element.color, color_temperature: element.color_temperature }
334
334
  } else {
335
335
  // Failsafe all on
336
- state = { on: { on: true }, dimming: element.dimming, color: element.color, color_temperature: element.color_temperature };
336
+ state = { on: { on: true }, dimming: element.dimming, color: element.color, color_temperature: element.color_temperature }
337
337
  }
338
- if (element.color_temperature !== undefined && element.color_temperature.mirek === null) delete state.color_temperature; // Otherwise the lamp will not turn on due to an error. color_temperature.mirek: color temperature in mirek is null when the light color is not in the ct spectrum
339
- node.serverHue.hueManager.writeHueQueueAdd(element.id, state, "setLight");
338
+ if (element.color_temperature !== undefined && element.color_temperature.mirek === null) delete state.color_temperature // Otherwise the lamp will not turn on due to an error. color_temperature.mirek: color temperature in mirek is null when the light color is not in the ct spectrum
339
+ node.serverHue.hueManager.writeHueQueueAdd(element.id, state, 'setLight')
340
340
  }
341
341
  node.setNodeStatusHue({
342
- fill: "green",
343
- shape: "dot",
344
- text: "KNX->HUE",
345
- payload: "Resuming all group's light",
346
- });
347
- node.HUELightsBelongingToGroupWhileDaytime = null; // Nullize the object.
348
- return;
342
+ fill: 'green',
343
+ shape: 'dot',
344
+ text: 'KNX->HUE',
345
+ payload: "Resuming all group's light"
346
+ })
347
+ node.HUELightsBelongingToGroupWhileDaytime = null // Nullize the object.
348
+ return
349
349
  }
350
350
  } else {
351
- let colorChoosen;
352
- let temperatureChoosen;
353
- let brightnessChoosen;
351
+ let colorChoosen
352
+ let temperatureChoosen
353
+ let brightnessChoosen
354
354
  // The light must support the temperature (in this case, colorAtSwitchOnNightTime is an object {kelvin:xx, brightness:yy})
355
355
  if (node.currentHUEDevice.color_temperature !== undefined) {
356
- if (node.DayTime === true && config.specifySwitchOnBrightness === "temperature") {
357
- temperatureChoosen = config.colorAtSwitchOnDayTime.kelvin;
358
- } else if (node.DayTime === false && config.enableDayNightLighting === "temperature") {
359
- temperatureChoosen = config.colorAtSwitchOnNightTime.kelvin;
356
+ if (node.DayTime === true && config.specifySwitchOnBrightness === 'temperature') {
357
+ temperatureChoosen = config.colorAtSwitchOnDayTime.kelvin
358
+ } else if (node.DayTime === false && config.enableDayNightLighting === 'temperature') {
359
+ temperatureChoosen = config.colorAtSwitchOnNightTime.kelvin
360
360
  }
361
361
  }
362
362
  if (node.currentHUEDevice.dimming !== undefined) {
363
363
  // Check wether the user selected specific brightness at switch on (in this case, colorAtSwitchOnNightTime is an object {kelvin:xx, brightness:yy})
364
- if (node.DayTime === true && config.specifySwitchOnBrightness === "temperature") {
365
- brightnessChoosen = config.colorAtSwitchOnDayTime.brightness;
366
- } else if (node.DayTime === false && config.enableDayNightLighting === "temperature") {
367
- brightnessChoosen = config.colorAtSwitchOnNightTime.brightness;
364
+ if (node.DayTime === true && config.specifySwitchOnBrightness === 'temperature') {
365
+ brightnessChoosen = config.colorAtSwitchOnDayTime.brightness
366
+ } else if (node.DayTime === false && config.enableDayNightLighting === 'temperature') {
367
+ brightnessChoosen = config.colorAtSwitchOnNightTime.brightness
368
368
  }
369
369
  }
370
370
  if (node.currentHUEDevice.color !== undefined) {
371
371
  // Check wether the user selected specific color at switch on (in this case, colorAtSwitchOnDayTime is a text with HTML web color)
372
- if (node.DayTime === true && config.specifySwitchOnBrightness === "yes") {
373
- colorChoosen = config.colorAtSwitchOnDayTime;
374
- } else if (node.DayTime === false && config.enableDayNightLighting === "yes") {
375
- colorChoosen = config.colorAtSwitchOnNightTime;
372
+ if (node.DayTime === true && config.specifySwitchOnBrightness === 'yes') {
373
+ colorChoosen = config.colorAtSwitchOnDayTime
374
+ } else if (node.DayTime === false && config.enableDayNightLighting === 'yes') {
375
+ colorChoosen = config.colorAtSwitchOnNightTime
376
376
  }
377
377
  }
378
378
  // Create the HUE command
379
379
  if (colorChoosen !== undefined) {
380
380
  // Now we have a jColorChoosen. Proceed illuminating the light
381
- let gamut = null;
381
+ let gamut = null
382
382
  if (node.currentHUEDevice.color.gamut !== undefined) {
383
- gamut = node.currentHUEDevice.color.gamut;
383
+ gamut = node.currentHUEDevice.color.gamut
384
384
  }
385
- const dretXY = hueColorConverter.ColorConverter.calculateXYFromRGB(colorChoosen.red, colorChoosen.green, colorChoosen.blue, gamut);
386
- const dbright = hueColorConverter.ColorConverter.getBrightnessFromRGBOrHex(colorChoosen.red, colorChoosen.green, colorChoosen.blue);
387
- node.currentHUEDevice.dimming.brightness = Math.round(dbright, 0);
388
- if (node.currentHUEDevice.color !== undefined) node.currentHUEDevice.color.xy = dretXY; // 26/03/2024
389
- node.updateKNXBrightnessState(node.currentHUEDevice.dimming.brightness);
390
- state = dbright > 0 ? { on: { on: true }, dimming: { brightness: dbright }, color: { xy: dretXY } } : { on: { on: false } };
385
+ const dretXY = hueColorConverter.ColorConverter.calculateXYFromRGB(colorChoosen.red, colorChoosen.green, colorChoosen.blue, gamut)
386
+ const dbright = hueColorConverter.ColorConverter.getBrightnessFromRGBOrHex(colorChoosen.red, colorChoosen.green, colorChoosen.blue)
387
+ node.currentHUEDevice.dimming.brightness = Math.round(dbright, 0)
388
+ if (node.currentHUEDevice.color !== undefined) node.currentHUEDevice.color.xy = dretXY // 26/03/2024
389
+ node.updateKNXBrightnessState(node.currentHUEDevice.dimming.brightness)
390
+ state = dbright > 0 ? { on: { on: true }, dimming: { brightness: dbright }, color: { xy: dretXY } } : { on: { on: false } }
391
391
  // state = { on: { on: true }, dimming: { brightness: dbright }, color: { xy: dretXY } };
392
392
  } else if (temperatureChoosen !== undefined) {
393
393
  // Kelvin
394
- const mirek = hueColorConverter.ColorConverter.kelvinToMirek(temperatureChoosen);
395
- node.currentHUEDevice.color_temperature.mirek = mirek;
396
- node.currentHUEDevice.dimming.brightness = brightnessChoosen;
397
- node.updateKNXBrightnessState(node.currentHUEDevice.dimming.brightness);
394
+ const mirek = hueColorConverter.ColorConverter.kelvinToMirek(temperatureChoosen)
395
+ node.currentHUEDevice.color_temperature.mirek = mirek
396
+ node.currentHUEDevice.dimming.brightness = brightnessChoosen
397
+ node.updateKNXBrightnessState(node.currentHUEDevice.dimming.brightness)
398
398
  // Kelvin temp
399
- state = brightnessChoosen > 0 ? { on: { on: true }, dimming: { brightness: brightnessChoosen }, color_temperature: { mirek: mirek } } : { on: { on: false } };
399
+ state = brightnessChoosen > 0 ? { on: { on: true }, dimming: { brightness: brightnessChoosen }, color_temperature: { mirek } } : { on: { on: false } }
400
400
  // state = { on: { on: true }, dimming: { brightness: brightnessChoosen }, color_temperature: { mirek: mirek } };
401
401
  } else if (brightnessChoosen !== undefined) {
402
- state = brightnessChoosen > 0 ? { on: { on: true }, dimming: { brightness: brightnessChoosen } } : { on: { on: false } };
402
+ state = brightnessChoosen > 0 ? { on: { on: true }, dimming: { brightness: brightnessChoosen } } : { on: { on: false } }
403
403
  // state = { on: { on: true }, dimming: { brightness: brightnessChoosen } };
404
404
  } else {
405
- state = { on: { on: true } };
405
+ state = { on: { on: true } }
406
406
  }
407
407
  }
408
408
  } else {
409
409
  // Stop color cycle
410
- if (node.timerColorCycle !== undefined) clearInterval(node.timerColorCycle);
410
+ if (node.timerColorCycle !== undefined) clearInterval(node.timerColorCycle)
411
411
  // Stop Blinking
412
- if (node.timerBlink !== undefined) clearInterval(node.timerBlink);
413
- state = { on: { on: false } };
412
+ if (node.timerBlink !== undefined) clearInterval(node.timerBlink)
413
+ state = { on: { on: false } }
414
414
  }
415
415
 
416
- node.syncCurrentHUEDeviceFromKNXState(state); // Starting from v 4.1.31
417
- node.writeHueState(state);
416
+ node.syncCurrentHUEDeviceFromKNXState(state) // Starting from v 4.1.31
417
+ node.writeHueState(state)
418
418
  node.setNodeStatusHue({
419
- fill: "green",
420
- shape: "dot",
421
- text: "KNX->HUE",
422
- payload: state,
423
- });
424
- break;
419
+ fill: 'green',
420
+ shape: 'dot',
421
+ text: 'KNX->HUE',
422
+ payload: state
423
+ })
424
+ break
425
425
  case config.GALightDIM:
426
426
  // { decr_incr: 1, data: 1 } : Start increasing until { decr_incr: 0, data: 0 } is received.
427
427
  // { decr_incr: 0, data: 1 } : Start decreasing until { decr_incr: 0, data: 0 } is received.
428
- msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightDIM));
429
- node.hueDimming(msg.payload.decr_incr, msg.payload.data, config.dimSpeed);
428
+ msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightDIM))
429
+ node.hueDimming(msg.payload.decr_incr, msg.payload.data, config.dimSpeed)
430
430
  node.setNodeStatusHue({
431
- fill: "green", shape: "dot", text: "KNX->HUE", payload: JSON.stringify(msg.payload),
432
- });
433
- break;
431
+ fill: 'green', shape: 'dot', text: 'KNX->HUE', payload: JSON.stringify(msg.payload)
432
+ })
433
+ break
434
434
  case config.GALightHSV_H_DIM:
435
435
  // { decr_incr: 1, data: 1 } : Start increasing until { decr_incr: 0, data: 0 } is received.
436
436
  // { decr_incr: 0, data: 1 } : Start decreasing until { decr_incr: 0, data: 0 } is received.
437
- msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightDIM));
438
- node.hueDimmingHSV_H(msg.payload.decr_incr, msg.payload.data, config.HSVDimSpeed);
437
+ msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightDIM))
438
+ node.hueDimmingHSV_H(msg.payload.decr_incr, msg.payload.data, config.HSVDimSpeed)
439
439
  node.setNodeStatusHue({
440
- fill: "green", shape: "dot", text: "KNX->HUE", payload: JSON.stringify(msg.payload),
441
- });
442
- break;
440
+ fill: 'green', shape: 'dot', text: 'KNX->HUE', payload: JSON.stringify(msg.payload)
441
+ })
442
+ break
443
443
  case config.GALightHSV_S_DIM:
444
444
  // { decr_incr: 1, data: 1 } : Start increasing until { decr_incr: 0, data: 0 } is received.
445
445
  // { decr_incr: 0, data: 1 } : Start decreasing until { decr_incr: 0, data: 0 } is received.
446
- msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightDIM));
447
- node.hueDimmingHSV_S(msg.payload.decr_incr, msg.payload.data, config.HSVDimSpeed);
446
+ msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightDIM))
447
+ node.hueDimmingHSV_S(msg.payload.decr_incr, msg.payload.data, config.HSVDimSpeed)
448
448
  node.setNodeStatusHue({
449
- fill: "green", shape: "dot", text: "KNX->HUE", payload: JSON.stringify(msg.payload),
450
- });
451
- break;
449
+ fill: 'green', shape: 'dot', text: 'KNX->HUE', payload: JSON.stringify(msg.payload)
450
+ })
451
+ break
452
452
  case config.GALightKelvin:
453
- let retMirek;
454
- let kelvinValue = 0;
455
- msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightKelvin));
456
- if (config.dptLightKelvin === "7.600") {
457
- if (msg.payload > 6535) msg.payload = 6535;
458
- if (msg.payload < 2000) msg.payload = 2000;
459
- kelvinValue = msg.payload;//hueColorConverter.ColorConverter.scale(msg.payload, [0, 65535], [2000, 6535]);
460
- retMirek = hueColorConverter.ColorConverter.kelvinToMirek(kelvinValue);
461
- } else if (config.dptLightKelvin === "9.002") {
453
+ let retMirek
454
+ let kelvinValue = 0
455
+ msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightKelvin))
456
+ if (config.dptLightKelvin === '7.600') {
457
+ if (msg.payload > 6535) msg.payload = 6535
458
+ if (msg.payload < 2000) msg.payload = 2000
459
+ kelvinValue = msg.payload// hueColorConverter.ColorConverter.scale(msg.payload, [0, 65535], [2000, 6535]);
460
+ retMirek = hueColorConverter.ColorConverter.kelvinToMirek(kelvinValue)
461
+ } else if (config.dptLightKelvin === '9.002') {
462
462
  // Relative temperature in Kelvin. Use HUE scale.
463
- if (msg.payload > 6535) msg.payload = 6535;
464
- if (msg.payload < 2000) msg.payload = 2000;
465
- retMirek = hueColorConverter.ColorConverter.kelvinToMirek(msg.payload);
463
+ if (msg.payload > 6535) msg.payload = 6535
464
+ if (msg.payload < 2000) msg.payload = 2000
465
+ retMirek = hueColorConverter.ColorConverter.kelvinToMirek(msg.payload)
466
466
  }
467
- state = { color_temperature: { mirek: retMirek } };
468
- node.syncCurrentHUEDeviceFromKNXState(state); // Starting from v 4.1.31
469
- node.writeHueState(state);
467
+ state = { color_temperature: { mirek: retMirek } }
468
+ node.syncCurrentHUEDeviceFromKNXState(state) // Starting from v 4.1.31
469
+ node.writeHueState(state)
470
470
  node.setNodeStatusHue({
471
- fill: "green",
472
- shape: "dot",
473
- text: "KNX->HUE",
474
- payload: kelvinValue,
475
- });
476
- break;
471
+ fill: 'green',
472
+ shape: 'dot',
473
+ text: 'KNX->HUE',
474
+ payload: kelvinValue
475
+ })
476
+ break
477
477
  case config.GADaylightSensor:
478
- node.DayTime = Boolean(dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptDaylightSensor)));
479
- if (config.invertDayNight === true) node.DayTime = !node.DayTime;
480
- if (config.specifySwitchOnBrightness === "no") {
478
+ node.DayTime = Boolean(dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptDaylightSensor)))
479
+ if (config.invertDayNight === true) node.DayTime = !node.DayTime
480
+ if (config.specifySwitchOnBrightness === 'no') {
481
481
  // This retains the HUE device status while daytime, to be restored after nighttime elapsed. https://github.com/Supergiovane/node-red-contrib-knx-ultimate/issues/298
482
482
  if (node.DayTime === false) {
483
- if (node.isGrouped_light === false) node.HUEDeviceWhileDaytime = cloneDeep(node.currentHUEDevice); // DayTime has switched to false: save the currentHUEDevice into the HUEDeviceWhileDaytime
483
+ if (node.isGrouped_light === false) node.HUEDeviceWhileDaytime = cloneDeep(node.currentHUEDevice) // DayTime has switched to false: save the currentHUEDevice into the HUEDeviceWhileDaytime
484
484
  if (node.isGrouped_light === true) {
485
485
  (async () => {
486
486
  try {
487
- const retLights = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, false);
488
- node.HUELightsBelongingToGroupWhileDaytime = cloneDeep(retLights); // DayTime has switched to false: save the lights belonging to the group into the HUELightsBelongingToGroupWhileDaytime array
487
+ const retLights = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, false)
488
+ node.HUELightsBelongingToGroupWhileDaytime = cloneDeep(retLights) // DayTime has switched to false: save the lights belonging to the group into the HUELightsBelongingToGroupWhileDaytime array
489
489
  } catch (error) { /* empty */ }
490
- })();
490
+ })()
491
491
  }
492
492
  }
493
493
  } else {
494
- node.HUEDeviceWhileDaytime = null;
495
- node.HUELightsBelongingToGroupWhileDaytime = null;
494
+ node.HUEDeviceWhileDaytime = null
495
+ node.HUELightsBelongingToGroupWhileDaytime = null
496
496
  }
497
497
  node.setNodeStatusHue({
498
- fill: "green",
499
- shape: "dot",
500
- text: "KNX->HUE Daytime",
501
- payload: node.DayTime,
502
- });
498
+ fill: 'green',
499
+ shape: 'dot',
500
+ text: 'KNX->HUE Daytime',
501
+ payload: node.DayTime
502
+ })
503
503
 
504
- break;
504
+ break
505
505
  case config.GALightKelvinDIM:
506
- if (config.dptLightKelvinDIM === "3.007") {
506
+ if (config.dptLightKelvinDIM === '3.007') {
507
507
  // MDT smartbutton will dim the color temperature
508
508
  // { decr_incr: 1, data: 1 } : Start increasing until { decr_incr: 0, data: 0 } is received.
509
509
  // { decr_incr: 0, data: 1 } : Start decreasing until { decr_incr: 0, data: 0 } is received.
510
- msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightKelvinDIM));
511
- node.hueDimmingTunableWhite(msg.payload.decr_incr, msg.payload.data, 5000);
510
+ msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightKelvinDIM))
511
+ node.hueDimmingTunableWhite(msg.payload.decr_incr, msg.payload.data, 5000)
512
512
  node.setNodeStatusHue({
513
- fill: "green", shape: "dot", text: "KNX->HUE", payload: JSON.stringify(msg.payload),
514
- });
513
+ fill: 'green', shape: 'dot', text: 'KNX->HUE', payload: JSON.stringify(msg.payload)
514
+ })
515
515
  }
516
- break;
516
+ break
517
517
  case config.GALightKelvinPercentage:
518
- if (config.dptLightKelvinPercentage === "5.001") {
518
+ if (config.dptLightKelvinPercentage === '5.001') {
519
519
  // 0-100% tunable white
520
- msg.payload = 100 - dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightKelvinPercentage));
520
+ msg.payload = 100 - dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightKelvinPercentage))
521
521
  // msg.payload = msg.payload <= 0 ? 1 : msg.payload
522
- const retMirek = hueColorConverter.ColorConverter.scale(msg.payload, [0, 100], [153, 500]);
523
- msg.payload = retMirek;
524
- state = { color_temperature: { mirek: msg.payload } };
525
- node.syncCurrentHUEDeviceFromKNXState(state); // Starting from v 4.1.31
526
- node.writeHueState(state);
522
+ const retMirek = hueColorConverter.ColorConverter.scale(msg.payload, [0, 100], [153, 500])
523
+ msg.payload = retMirek
524
+ state = { color_temperature: { mirek: msg.payload } }
525
+ node.syncCurrentHUEDeviceFromKNXState(state) // Starting from v 4.1.31
526
+ node.writeHueState(state)
527
527
  node.setNodeStatusHue({
528
- fill: "green",
529
- shape: "dot",
530
- text: "KNX->HUE",
531
- payload: state,
532
- });
528
+ fill: 'green',
529
+ shape: 'dot',
530
+ text: 'KNX->HUE',
531
+ payload: state
532
+ })
533
533
  }
534
- break;
534
+ break
535
535
  case config.GALightBrightness:
536
- msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightBrightness));
537
- if (typeof msg.payload !== "number" || Number.isNaN(msg.payload)) throw new Error("Invalid KNX brightness payload");
538
- state = { dimming: { brightness: msg.payload } };
536
+ msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightBrightness))
537
+ if (typeof msg.payload !== 'number' || Number.isNaN(msg.payload)) throw new Error('Invalid KNX brightness payload')
538
+ state = { dimming: { brightness: msg.payload } }
539
539
  if (msg.payload === 0) {
540
- state.on = { on: false };
540
+ state.on = { on: false }
541
541
  } else if (node.currentHUEDevice !== undefined && node.currentHUEDevice.on?.on === true) {
542
- state.on = { on: true };
542
+ state.on = { on: true }
543
543
  }
544
- node.syncCurrentHUEDeviceFromKNXState(state); // Starting from v 4.1.31
545
- node.writeHueState(state);
544
+ node.syncCurrentHUEDeviceFromKNXState(state) // Starting from v 4.1.31
545
+ node.writeHueState(state)
546
546
  node.setNodeStatusHue({
547
- fill: "green",
548
- shape: "dot",
549
- text: "KNX->HUE",
550
- payload: state,
551
- });
552
- break;
547
+ fill: 'green',
548
+ shape: 'dot',
549
+ text: 'KNX->HUE',
550
+ payload: state
551
+ })
552
+ break
553
553
  case config.GALightColor:
554
- msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightColor));
555
- let gamut = null;
554
+ msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightColor))
555
+ let gamut = null
556
556
  if (
557
- node.currentHUEDevice !== undefined
558
- && node.currentHUEDevice.color !== undefined
559
- && node.currentHUEDevice.color.gamut !== undefined
557
+ node.currentHUEDevice !== undefined &&
558
+ node.currentHUEDevice.color !== undefined &&
559
+ node.currentHUEDevice.color.gamut !== undefined
560
560
  ) {
561
- gamut = node.currentHUEDevice.color.gamut;
561
+ gamut = node.currentHUEDevice.color.gamut
562
562
  }
563
- const retXY = hueColorConverter.ColorConverter.calculateXYFromRGB(msg.payload.red, msg.payload.green, msg.payload.blue, gamut);
564
- const bright = hueColorConverter.ColorConverter.getBrightnessFromRGBOrHex(msg.payload.red, msg.payload.green, msg.payload.blue);
565
- state = { dimming: { brightness: bright }, color: { xy: retXY } };
563
+ const retXY = hueColorConverter.ColorConverter.calculateXYFromRGB(msg.payload.red, msg.payload.green, msg.payload.blue, gamut)
564
+ const bright = hueColorConverter.ColorConverter.getBrightnessFromRGBOrHex(msg.payload.red, msg.payload.green, msg.payload.blue)
565
+ state = { dimming: { brightness: bright }, color: { xy: retXY } }
566
566
  if (node.currentHUEDevice === undefined) {
567
567
  // Grouped light
568
- state.on = { on: bright > 0 };
568
+ state.on = { on: bright > 0 }
569
569
  } else {
570
570
  // Light
571
- if (node.currentHUEDevice.on.on === false && bright > 0) state.on = { on: true };
572
- if (node.currentHUEDevice.on.on === true && bright === 0) state = { on: { on: false }, dimming: { brightness: bright } };
571
+ if (node.currentHUEDevice.on.on === false && bright > 0) state.on = { on: true }
572
+ if (node.currentHUEDevice.on.on === true && bright === 0) state = { on: { on: false }, dimming: { brightness: bright } }
573
573
  }
574
- node.syncCurrentHUEDeviceFromKNXState(state); // Starting from v 4.1.31
575
- node.writeHueState(state);
574
+ node.syncCurrentHUEDeviceFromKNXState(state) // Starting from v 4.1.31
575
+ node.writeHueState(state)
576
576
  node.setNodeStatusHue({
577
- fill: "green",
578
- shape: "dot",
579
- text: "KNX->HUE",
580
- payload: state,
581
- });
582
- break;
577
+ fill: 'green',
578
+ shape: 'dot',
579
+ text: 'KNX->HUE',
580
+ payload: state
581
+ })
582
+ break
583
583
  case config.GALightBlink:
584
- const gaVal = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightBlink));
584
+ const gaVal = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightBlink))
585
585
  if (gaVal) {
586
586
  node.timerBlink = setInterval(() => {
587
- if (node.blinkValue === undefined) node.blinkValue = true;
588
- node.blinkValue = !node.blinkValue;
589
- msg.payload = node.blinkValue;
587
+ if (node.blinkValue === undefined) node.blinkValue = true
588
+ node.blinkValue = !node.blinkValue
589
+ msg.payload = node.blinkValue
590
590
  // state = msg.payload === true ? { on: { on: true } } : { on: { on: false } }
591
591
  state = msg.payload === true
592
592
  ? { on: { on: true }, dimming: { brightness: 100 }, dynamics: { duration: 0 } }
593
- : { on: { on: false }, dimming: { brightness: 0 }, dynamics: { duration: 0 } };
594
- node.writeHueState(state);
595
- }, 1500);
593
+ : { on: { on: false }, dimming: { brightness: 0 }, dynamics: { duration: 0 } }
594
+ node.writeHueState(state)
595
+ }, 1500)
596
596
  } else {
597
- if (node.timerBlink !== undefined) clearInterval(node.timerBlink);
598
- node.writeHueState({ on: { on: false } });
597
+ if (node.timerBlink !== undefined) clearInterval(node.timerBlink)
598
+ node.writeHueState({ on: { on: false } })
599
599
  }
600
600
  node.setNodeStatusHue({
601
- fill: "green",
602
- shape: "dot",
603
- text: "KNX->HUE",
604
- payload: gaVal,
605
- });
606
- break;
601
+ fill: 'green',
602
+ shape: 'dot',
603
+ text: 'KNX->HUE',
604
+ payload: gaVal
605
+ })
606
+ break
607
607
  case config.GALightColorCycle:
608
608
  {
609
- if (node.timerColorCycle !== undefined) clearInterval(node.timerColorCycle);
610
- const gaValColorCycle = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightColorCycle));
609
+ if (node.timerColorCycle !== undefined) clearInterval(node.timerColorCycle)
610
+ const gaValColorCycle = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightColorCycle))
611
611
  if (gaValColorCycle === true) {
612
- node.writeHueState({ on: { on: true } });
612
+ node.writeHueState({ on: { on: true } })
613
613
  node.timerColorCycle = setInterval(() => {
614
614
  try {
615
- const red = getRandomIntInclusive(0, 255);
616
- const green = getRandomIntInclusive(0, 255);
617
- const blue = getRandomIntInclusive(0, 255);
618
- let gamut = null;
615
+ const red = getRandomIntInclusive(0, 255)
616
+ const green = getRandomIntInclusive(0, 255)
617
+ const blue = getRandomIntInclusive(0, 255)
618
+ let gamut = null
619
619
  if (
620
- node.currentHUEDevice !== undefined
621
- && node.currentHUEDevice.color !== undefined
622
- && node.currentHUEDevice.color.gamut !== undefined
620
+ node.currentHUEDevice !== undefined &&
621
+ node.currentHUEDevice.color !== undefined &&
622
+ node.currentHUEDevice.color.gamut !== undefined
623
623
  ) {
624
- gamut = node.currentHUEDevice.color.gamut;
624
+ gamut = node.currentHUEDevice.color.gamut
625
625
  }
626
- const retXY = hueColorConverter.ColorConverter.calculateXYFromRGB(red, green, blue, gamut);
627
- const bright = hueColorConverter.ColorConverter.getBrightnessFromRGBOrHex(red, green, blue);
628
- state = bright > 0 ? { on: { on: true }, dimming: { brightness: bright }, color: { xy: retXY } } : { on: { on: false } };
629
- node.writeHueState(state);
626
+ const retXY = hueColorConverter.ColorConverter.calculateXYFromRGB(red, green, blue, gamut)
627
+ const bright = hueColorConverter.ColorConverter.getBrightnessFromRGBOrHex(red, green, blue)
628
+ state = bright > 0 ? { on: { on: true }, dimming: { brightness: bright }, color: { xy: retXY } } : { on: { on: false } }
629
+ node.writeHueState(state)
630
630
  } catch (error) { }
631
- }, 10000);
631
+ }, 10000)
632
632
  } else {
633
- if (node.timerColorCycle !== undefined) clearInterval(node.timerColorCycle);
634
- node.writeHueState({ on: { on: false } });
633
+ if (node.timerColorCycle !== undefined) clearInterval(node.timerColorCycle)
634
+ node.writeHueState({ on: { on: false } })
635
635
  }
636
636
  node.setNodeStatusHue({
637
- fill: "green",
638
- shape: "dot",
639
- text: "KNX->HUE",
640
- payload: gaValColorCycle,
641
- });
637
+ fill: 'green',
638
+ shape: 'dot',
639
+ text: 'KNX->HUE',
640
+ payload: gaValColorCycle
641
+ })
642
642
  }
643
- break;
643
+ break
644
644
  default:
645
- break;
645
+ break
646
646
  }
647
647
  } catch (error) {
648
648
  node.status({
649
- fill: "red",
650
- shape: "dot",
651
- text: `KNX->HUE errorRead ${error.message} (${formatTs(new Date())})`,
652
- });
653
- RED.log.error(`knxUltimateHueLight: node.handleSend: if (msg.knx.event !== "GroupValue_Read"): ${error.message} : ${error.stack || ""} `);
649
+ fill: 'red',
650
+ shape: 'dot',
651
+ text: `KNX->HUE errorRead ${error.message} (${formatTs(new Date())})`
652
+ })
653
+ RED.log.error(`knxUltimateHueLight: node.handleSend: if (msg.knx.event !== "GroupValue_Read"): ${error.message} : ${error.stack || ''} `)
654
654
  }
655
655
  }
656
656
 
657
657
  // I must respond to query requests (read request) sent from the KNX BUS
658
658
  try {
659
- if (msg.knx.event === "GroupValue_Read" && node.currentHUEDevice !== undefined) {
660
- const zeroBrightnessWhenOff = (config.updateKNXBrightnessStatusOnHUEOnOff === undefined || config.updateKNXBrightnessStatusOnHUEOnOff === "onhueoff");
661
- let ret;
659
+ if (msg.knx.event === 'GroupValue_Read' && node.currentHUEDevice !== undefined) {
660
+ const zeroBrightnessWhenOff = (config.updateKNXBrightnessStatusOnHUEOnOff === undefined || config.updateKNXBrightnessStatusOnHUEOnOff === 'onhueoff')
661
+ let ret
662
662
  switch (msg.knx.destination) {
663
663
  case config.GALightState:
664
- ret = node.currentHUEDevice.on.on;
665
- if (ret !== undefined) node.updateKNXLightState(ret, "response");
666
- break;
664
+ ret = node.currentHUEDevice.on.on
665
+ if (ret !== undefined) node.updateKNXLightState(ret, 'response')
666
+ break
667
667
  case config.GALightColorState:
668
- ret = node.currentHUEDevice.color.xy;
669
- if (ret !== undefined) node.updateKNXLightColorState(node.currentHUEDevice.color, "response");
670
- break;
668
+ ret = node.currentHUEDevice.color.xy
669
+ if (ret !== undefined) node.updateKNXLightColorState(node.currentHUEDevice.color, 'response')
670
+ break
671
671
  case config.GALightKelvinPercentageState:
672
672
  // The kelvin level belongs to the group defice, so i don't need to get the first light in the collection (if the device is a grouped_light)
673
- ret = node.currentHUEDevice.color_temperature.mirek;
674
- if (ret !== undefined) node.updateKNXLightKelvinPercentageState(ret, "response");
673
+ ret = node.currentHUEDevice.color_temperature.mirek
674
+ if (ret !== undefined) node.updateKNXLightKelvinPercentageState(ret, 'response')
675
675
  // if (node.isGrouped_light === false) {
676
676
  // ret = node.currentHUEDevice.color_temperature.mirek;
677
677
  // if (ret !== undefined) node.updateKNXLightKelvinPercentageState(ret, "response");
@@ -691,21 +691,21 @@ module.exports = function (RED) {
691
691
  // } catch (error) { /* empty */ }
692
692
  // })();
693
693
  // }
694
- break;
694
+ break
695
695
  case config.GALightBrightnessState:
696
696
  // Hue keeps the last brightness even when the light is OFF. If the user enabled "brightness status -> 0 on HUE off",
697
697
  // keep returning 0 while OFF to avoid the KNX status jumping back to the last/start value after some time/read-requests.
698
698
  if (zeroBrightnessWhenOff === true && node.currentHUEDevice?.on?.on === false) {
699
- ret = 0;
699
+ ret = 0
700
700
  } else {
701
- ret = node.currentHUEDevice.dimming.brightness;
701
+ ret = node.currentHUEDevice.dimming.brightness
702
702
  }
703
- if (ret !== undefined) node.updateKNXBrightnessState(ret, "response");
704
- break;
703
+ if (ret !== undefined) node.updateKNXBrightnessState(ret, 'response')
704
+ break
705
705
  case config.GALightKelvinState:
706
706
  // The kelvin level belongs to the group defice, so i don't need to get the first light in the collection (if the device is a grouped_light)
707
- ret = node.currentHUEDevice.color_temperature.mirek;
708
- if (ret !== undefined) node.updateKNXLightKelvinState(ret, "response");
707
+ ret = node.currentHUEDevice.color_temperature.mirek
708
+ if (ret !== undefined) node.updateKNXLightKelvinState(ret, 'response')
709
709
  // if (node.isGrouped_light === false) {
710
710
  // ret = node.currentHUEDevice.color_temperature.mirek;
711
711
  // if (ret !== undefined) node.updateKNXLightKelvinState(ret, "response");
@@ -725,178 +725,177 @@ module.exports = function (RED) {
725
725
  // } catch (error) { /* empty */ }
726
726
  // })();
727
727
  // }
728
- break;
728
+ break
729
729
  default:
730
- break;
730
+ break
731
731
  }
732
732
  }
733
733
  } catch (error) {
734
734
  node.status({
735
- fill: "red",
736
- shape: "dot",
737
- text: `KNX->HUE error :-( ${error.message} (${formatTs(new Date())})`,
738
- });
739
- RED.log.error(`knxUltimateHueLight: node.handleSend: if (msg.knx.event === "GroupValue_Read" && node.currentHUEDevice !== undefined): ${error.message} : ${error.stack || ""} `);
735
+ fill: 'red',
736
+ shape: 'dot',
737
+ text: `KNX->HUE error :-( ${error.message} (${formatTs(new Date())})`
738
+ })
739
+ RED.log.error(`knxUltimateHueLight: node.handleSend: if (msg.knx.event === "GroupValue_Read" && node.currentHUEDevice !== undefined): ${error.message} : ${error.stack || ''} `)
740
740
  }
741
- };
741
+ }
742
742
 
743
743
  // Start dimming
744
744
  // ***********************************************************
745
- node.hueDimming = function hueDimming(_KNXaction, _KNXbrightness_Direction, _dimSpeedInMillisecs = undefined) {
745
+ node.hueDimming = function hueDimming (_KNXaction, _KNXbrightness_Direction, _dimSpeedInMillisecs = undefined) {
746
746
  // 31/10/2023 after many attempts to use dimming_delta function of the HueApeV2, loosing days of my life, without a decent success, will use the standard dimming calculations
747
747
  // i decide to go to the "step brightness" way.
748
748
  try {
749
- let hueTelegram = {};
750
- let numStep = 10; // Steps from 0 to 100 by 10
751
- const extendedConf = {};
749
+ let hueTelegram = {}
750
+ let numStep = 10 // Steps from 0 to 100 by 10
751
+ const extendedConf = {}
752
752
 
753
753
  if (_KNXbrightness_Direction === 0 && _KNXaction === 0) {
754
754
  // STOP DIM
755
- if (node.timerStepDim !== undefined) clearInterval(node.timerStepDim);
756
- node.brightnessStep = null;
757
- node.deleteHueStateQueue(); // Clear dimming queue.
758
- return;
755
+ if (node.timerStepDim !== undefined) clearInterval(node.timerStepDim)
756
+ node.brightnessStep = null
757
+ node.deleteHueStateQueue() // Clear dimming queue.
758
+ return
759
759
  }
760
760
 
761
761
  // 26/03/2024 set the extended configuration as well, because the light was off (so i've been unable to set it up elsewhere)
762
762
  if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false) {
763
763
  // if (node.currentHUEDevice.color !== undefined) extendedConf.color = { xy: node.currentHUEDevice.color.xy }; // DO NOT ADD THE COLOR, BECAUSE THE COLOR HAS ALSO THE BRIGHTNESS, SO ALL THE DATA NEEDED TO BE SWITCHED ON CORRECLY
764
- if (node.currentHUEDevice.color_temperature !== undefined) extendedConf.color_temperature = { mirek: node.currentHUEDevice.color_temperature.mirek };
764
+ if (node.currentHUEDevice.color_temperature !== undefined) extendedConf.color_temperature = { mirek: node.currentHUEDevice.color_temperature.mirek }
765
765
  }
766
766
 
767
767
  // If i'm dimming up while the light is off, start the dim with the initial brightness set to zero
768
768
  if (_KNXbrightness_Direction > 0 && _KNXaction === 1 && node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false) {
769
- node.brightnessStep = null;
770
- node.currentHUEDevice.dimming.brightness = 0;
769
+ node.brightnessStep = null
770
+ node.currentHUEDevice.dimming.brightness = 0
771
771
  }
772
772
 
773
773
  // Set the actual brightness to start with
774
- if (node.brightnessStep === null || node.brightnessStep === undefined) node.brightnessStep = node.currentHUEDevice.dimming.brightness !== undefined ? node.currentHUEDevice.dimming.brightness : 50;
775
- node.brightnessStep = Math.ceil(Number(node.brightnessStep));
774
+ if (node.brightnessStep === null || node.brightnessStep === undefined) node.brightnessStep = node.currentHUEDevice.dimming.brightness !== undefined ? node.currentHUEDevice.dimming.brightness : 50
775
+ node.brightnessStep = Math.ceil(Number(node.brightnessStep))
776
776
 
777
777
  // We have also minDimLevelLight and maxDimLevelLight to take care of.
778
- let minDimLevelLight;
778
+ let minDimLevelLight
779
779
  if (config.minDimLevelLight === undefined) {
780
- minDimLevelLight = 10;
781
- } else if (config.minDimLevelLight === "useHueLightLevel") {
782
- minDimLevelLight = node.currentHUEDevice.dimming.min_dim_level === undefined ? 10 : node.currentHUEDevice.dimming.min_dim_level;
780
+ minDimLevelLight = 10
781
+ } else if (config.minDimLevelLight === 'useHueLightLevel') {
782
+ minDimLevelLight = node.currentHUEDevice.dimming.min_dim_level === undefined ? 10 : node.currentHUEDevice.dimming.min_dim_level
783
783
  } else {
784
- minDimLevelLight = Number(config.minDimLevelLight);
784
+ minDimLevelLight = Number(config.minDimLevelLight)
785
785
  }
786
- const maxDimLevelLight = config.maxDimLevelLight === undefined ? 100 : Number(config.maxDimLevelLight);
786
+ const maxDimLevelLight = config.maxDimLevelLight === undefined ? 100 : Number(config.maxDimLevelLight)
787
787
 
788
788
  // Set the speed
789
- _dimSpeedInMillisecs /= numStep;
790
- numStep = Math.round((maxDimLevelLight - minDimLevelLight) / numStep, 0);
789
+ _dimSpeedInMillisecs /= numStep
790
+ numStep = Math.round((maxDimLevelLight - minDimLevelLight) / numStep, 0)
791
791
 
792
792
  if (_KNXbrightness_Direction > 0 && _KNXaction === 1) {
793
793
  // DIM UP
794
- if (node.timerStepDim !== undefined) clearInterval(node.timerStepDim);
794
+ if (node.timerStepDim !== undefined) clearInterval(node.timerStepDim)
795
795
  node.timerStepDim = setInterval(() => {
796
- node.updateKNXBrightnessState(node.brightnessStep); // Unnecessary, but necessary to set the KNX Status in real time.
797
- node.brightnessStep += numStep;
798
- if (node.brightnessStep > maxDimLevelLight) node.brightnessStep = maxDimLevelLight;
799
- hueTelegram = { dimming: { brightness: node.brightnessStep }, dynamics: { duration: _dimSpeedInMillisecs + 500 } }; // + is to avoid ladder effect
796
+ node.updateKNXBrightnessState(node.brightnessStep) // Unnecessary, but necessary to set the KNX Status in real time.
797
+ node.brightnessStep += numStep
798
+ if (node.brightnessStep > maxDimLevelLight) node.brightnessStep = maxDimLevelLight
799
+ hueTelegram = { dimming: { brightness: node.brightnessStep }, dynamics: { duration: _dimSpeedInMillisecs + 500 } } // + is to avoid ladder effect
800
800
  // Switch on the light if off
801
801
  if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false) {
802
- hueTelegram.on = { on: true };
803
- Object.assign(hueTelegram, extendedConf); // 26/03/2024 add extended conf
802
+ hueTelegram.on = { on: true }
803
+ Object.assign(hueTelegram, extendedConf) // 26/03/2024 add extended conf
804
804
  }
805
- //console.log(hueTelegram)
806
- node.writeHueState(hueTelegram);
807
- if (node.brightnessStep >= maxDimLevelLight) clearInterval(node.timerStepDim);
808
- }, _dimSpeedInMillisecs);
805
+ // console.log(hueTelegram)
806
+ node.writeHueState(hueTelegram)
807
+ if (node.brightnessStep >= maxDimLevelLight) clearInterval(node.timerStepDim)
808
+ }, _dimSpeedInMillisecs)
809
809
  }
810
810
  if (_KNXbrightness_Direction > 0 && _KNXaction === 0) {
811
- if (node.currentHUEDevice.on.on === false) return; // Don't dim down, if the light is already off.
811
+ if (node.currentHUEDevice.on.on === false) return // Don't dim down, if the light is already off.
812
812
  // DIM DOWN
813
- if (node.timerStepDim !== undefined) clearInterval(node.timerStepDim);
813
+ if (node.timerStepDim !== undefined) clearInterval(node.timerStepDim)
814
814
  node.timerStepDim = setInterval(() => {
815
- node.updateKNXBrightnessState(node.brightnessStep); // Unnecessary, but necessary to set the KNX Status in real time.
816
- node.brightnessStep -= numStep;
817
- if (node.brightnessStep < minDimLevelLight) node.brightnessStep = minDimLevelLight;
818
- hueTelegram = { dimming: { brightness: node.brightnessStep }, dynamics: { duration: _dimSpeedInMillisecs + 500 } };// + 100 is to avoid ladder effect
815
+ node.updateKNXBrightnessState(node.brightnessStep) // Unnecessary, but necessary to set the KNX Status in real time.
816
+ node.brightnessStep -= numStep
817
+ if (node.brightnessStep < minDimLevelLight) node.brightnessStep = minDimLevelLight
818
+ hueTelegram = { dimming: { brightness: node.brightnessStep }, dynamics: { duration: _dimSpeedInMillisecs + 500 } }// + 100 is to avoid ladder effect
819
819
  // Switch off the light if on
820
820
  if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === true && node.brightnessStep === 0) {
821
- hueTelegram.on = { on: false };
821
+ hueTelegram.on = { on: false }
822
822
  }
823
- node.writeHueState(hueTelegram);
824
- if (node.brightnessStep <= minDimLevelLight) clearInterval(node.timerStepDim);
825
- }, _dimSpeedInMillisecs);
823
+ node.writeHueState(hueTelegram)
824
+ if (node.brightnessStep <= minDimLevelLight) clearInterval(node.timerStepDim)
825
+ }, _dimSpeedInMillisecs)
826
826
  }
827
827
  } catch (error) { }
828
- };
828
+ }
829
829
  // ***********************************************************
830
830
 
831
831
  // Start dimming tunable white
832
832
  // mirek: required(integer minimum: 153, maximum: 500)
833
833
  // ***********************************************************
834
- node.hueDimmingTunableWhite = function hueDimmingTunableWhite(_KNXaction, _KNXbrightness_DirectionTunableWhite, _dimSpeedInMillisecsTunableWhite = undefined) {
834
+ node.hueDimmingTunableWhite = function hueDimmingTunableWhite (_KNXaction, _KNXbrightness_DirectionTunableWhite, _dimSpeedInMillisecsTunableWhite = undefined) {
835
835
  // 23/23/2023 after many attempts to use dimming_delta function of the HueApeV2, loosing days of my life, without a decent success, will use the standard dimming calculations
836
836
  // i decide to go to the "step brightness" way.
837
837
  try {
838
-
839
838
  if (_KNXbrightness_DirectionTunableWhite === 0 && _KNXaction === 0) {
840
839
  // STOP DIM
841
- if (node.timerStepDimTunableWhite !== undefined) clearInterval(node.timerStepDimTunableWhite);
842
- node.brightnessStepTunableWhite = null;
843
- node.deleteHueStateQueue(); // Clear dimming queue.
844
- return;
840
+ if (node.timerStepDimTunableWhite !== undefined) clearInterval(node.timerStepDimTunableWhite)
841
+ node.brightnessStepTunableWhite = null
842
+ node.deleteHueStateQueue() // Clear dimming queue.
843
+ return
845
844
  }
846
845
 
847
- let numStepTunableWhite = 10; // Steps from 153 to 500
846
+ let numStepTunableWhite = 10 // Steps from 153 to 500
848
847
  if (config.invertDimTunableWhiteDirection === true) {
849
- if (_KNXaction === 1) { _KNXaction = 0; } else { _KNXaction = 1; }
848
+ if (_KNXaction === 1) { _KNXaction = 0 } else { _KNXaction = 1 }
850
849
  }
851
850
 
852
851
  // Set the actual brightness to start with
853
- if (node.brightnessStepTunableWhite === null || node.brightnessStepTunableWhite === undefined) node.brightnessStepTunableWhite = node.currentHUEDevice.color_temperature.mirek || 372;
854
- node.brightnessStepTunableWhite = Math.ceil(Number(node.brightnessStepTunableWhite));
852
+ if (node.brightnessStepTunableWhite === null || node.brightnessStepTunableWhite === undefined) node.brightnessStepTunableWhite = node.currentHUEDevice.color_temperature.mirek || 372
853
+ node.brightnessStepTunableWhite = Math.ceil(Number(node.brightnessStepTunableWhite))
855
854
 
856
855
  // Set the speed
857
- _dimSpeedInMillisecsTunableWhite = Math.ceil(_dimSpeedInMillisecsTunableWhite / numStepTunableWhite);
856
+ _dimSpeedInMillisecsTunableWhite = Math.ceil(_dimSpeedInMillisecsTunableWhite / numStepTunableWhite)
858
857
 
859
- const minDimLevelLightTunableWhite = 153;
860
- const maxDimLevelLightTunableWhite = 500;
861
- //numStepTunableWhite = hueColorConverter.ColorConverter.scale(numStepTunableWhite, [0, 100], [minDimLevelLightTunableWhite, maxDimLevelLightTunableWhite]);
862
- //numStepTunableWhite = hueColorConverter.ColorConverter.scale(numStepTunableWhite, [node.brightnessStepTunableWhite, maxDimLevelLightTunableWhite], [node.brightnessStepTunableWhite, maxDimLevelLightTunableWhite]);
863
- numStepTunableWhite = Math.round((maxDimLevelLightTunableWhite - minDimLevelLightTunableWhite) / numStepTunableWhite, 0);
858
+ const minDimLevelLightTunableWhite = 153
859
+ const maxDimLevelLightTunableWhite = 500
860
+ // numStepTunableWhite = hueColorConverter.ColorConverter.scale(numStepTunableWhite, [0, 100], [minDimLevelLightTunableWhite, maxDimLevelLightTunableWhite]);
861
+ // numStepTunableWhite = hueColorConverter.ColorConverter.scale(numStepTunableWhite, [node.brightnessStepTunableWhite, maxDimLevelLightTunableWhite], [node.brightnessStepTunableWhite, maxDimLevelLightTunableWhite]);
862
+ numStepTunableWhite = Math.round((maxDimLevelLightTunableWhite - minDimLevelLightTunableWhite) / numStepTunableWhite, 0)
864
863
 
865
864
  if (_KNXbrightness_DirectionTunableWhite > 0 && _KNXaction === 1) {
866
865
  // DIM UP
867
- if (node.timerStepDimTunableWhite !== undefined) clearInterval(node.timerStepDimTunableWhite);
866
+ if (node.timerStepDimTunableWhite !== undefined) clearInterval(node.timerStepDimTunableWhite)
868
867
  node.timerStepDimTunableWhite = setInterval(() => {
869
- node.updateKNXLightKelvinPercentageState(node.brightnessStepTunableWhite); // Unnecessary, but necessary to set the KNX Status in real time.
870
- node.brightnessStepTunableWhite += numStepTunableWhite; // *2 to speed up the things
871
- if (node.brightnessStepTunableWhite > maxDimLevelLightTunableWhite) node.brightnessStepTunableWhite = maxDimLevelLightTunableWhite;
872
- const hueTelegram = { color_temperature: { mirek: node.brightnessStepTunableWhite }, dynamics: { duration: _dimSpeedInMillisecsTunableWhite } };
868
+ node.updateKNXLightKelvinPercentageState(node.brightnessStepTunableWhite) // Unnecessary, but necessary to set the KNX Status in real time.
869
+ node.brightnessStepTunableWhite += numStepTunableWhite // *2 to speed up the things
870
+ if (node.brightnessStepTunableWhite > maxDimLevelLightTunableWhite) node.brightnessStepTunableWhite = maxDimLevelLightTunableWhite
871
+ const hueTelegram = { color_temperature: { mirek: node.brightnessStepTunableWhite }, dynamics: { duration: _dimSpeedInMillisecsTunableWhite } }
873
872
  // Switch on the light if off
874
873
  if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false) {
875
- hueTelegram.on = { on: true };
874
+ hueTelegram.on = { on: true }
876
875
  }
877
- node.writeHueState(hueTelegram);
878
- if (node.brightnessStepTunableWhite >= maxDimLevelLightTunableWhite) clearInterval(node.timerStepDimTunableWhite);
879
- }, _dimSpeedInMillisecsTunableWhite);
876
+ node.writeHueState(hueTelegram)
877
+ if (node.brightnessStepTunableWhite >= maxDimLevelLightTunableWhite) clearInterval(node.timerStepDimTunableWhite)
878
+ }, _dimSpeedInMillisecsTunableWhite)
880
879
  }
881
880
  if (_KNXbrightness_DirectionTunableWhite > 0 && _KNXaction === 0) {
882
- if (node.currentHUEDevice.on.on === false) return; // Don't dim down, if the light is already off.
881
+ if (node.currentHUEDevice.on.on === false) return // Don't dim down, if the light is already off.
883
882
  // DIM DOWN
884
- if (node.timerStepDimTunableWhite !== undefined) clearInterval(node.timerStepDimTunableWhite);
883
+ if (node.timerStepDimTunableWhite !== undefined) clearInterval(node.timerStepDimTunableWhite)
885
884
  node.timerStepDimTunableWhite = setInterval(() => {
886
- node.updateKNXLightKelvinPercentageState(node.brightnessStepTunableWhite); // Unnecessary, but necessary to set the KNX Status in real time.
887
- node.brightnessStepTunableWhite -= numStepTunableWhite; // *2 to speed up the things
888
- if (node.brightnessStepTunableWhite < minDimLevelLightTunableWhite) node.brightnessStepTunableWhite = minDimLevelLightTunableWhite;
889
- const hueTelegram = { color_temperature: { mirek: node.brightnessStepTunableWhite }, dynamics: { duration: _dimSpeedInMillisecsTunableWhite } };
885
+ node.updateKNXLightKelvinPercentageState(node.brightnessStepTunableWhite) // Unnecessary, but necessary to set the KNX Status in real time.
886
+ node.brightnessStepTunableWhite -= numStepTunableWhite // *2 to speed up the things
887
+ if (node.brightnessStepTunableWhite < minDimLevelLightTunableWhite) node.brightnessStepTunableWhite = minDimLevelLightTunableWhite
888
+ const hueTelegram = { color_temperature: { mirek: node.brightnessStepTunableWhite }, dynamics: { duration: _dimSpeedInMillisecsTunableWhite } }
890
889
  // Switch off the light if on
891
890
  if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === true && node.brightnessStepTunableWhite === 0) {
892
- hueTelegram.on = { on: false };
891
+ hueTelegram.on = { on: false }
893
892
  }
894
- node.writeHueState(hueTelegram);
895
- if (node.brightnessStepTunableWhite <= minDimLevelLightTunableWhite) clearInterval(node.timerStepDimTunableWhite);
896
- }, _dimSpeedInMillisecsTunableWhite);
893
+ node.writeHueState(hueTelegram)
894
+ if (node.brightnessStepTunableWhite <= minDimLevelLightTunableWhite) clearInterval(node.timerStepDimTunableWhite)
895
+ }, _dimSpeedInMillisecsTunableWhite)
897
896
  }
898
897
  } catch (error) { }
899
- };
898
+ }
900
899
  // ***********************************************************
901
900
 
902
901
  /**
@@ -906,87 +905,87 @@ module.exports = function (RED) {
906
905
  * @param {number} _dimSpeedInMillisecsHSV Speed time in milliseconds
907
906
  * @returns {}
908
907
  */
909
- node.hueDimmingHSV_H = function hueDimmingHSV_H(_KNXaction, _KNXbrightness_DirectionHSV_H, _dimSpeedInMillisecsHSV = undefined) {
908
+ node.hueDimmingHSV_H = function hueDimmingHSV_H (_KNXaction, _KNXbrightness_DirectionHSV_H, _dimSpeedInMillisecsHSV = undefined) {
910
909
  // After many attempts to use dimming_delta function of the HueApiV2, loosing days of my life, without a decent success, will use the standard dimming calculations
911
910
  // i decide to go to the "step brightness" way.
912
911
  try {
913
912
  if (_KNXbrightness_DirectionHSV_H === 0 && _KNXaction === 0) {
914
913
  // STOP DIM
915
- if (node.timerStepDimHSV_H !== undefined) clearInterval(node.timerStepDimHSV_H);
916
- node.deleteHueStateQueue(); // Clear dimming queue.
917
- return;
914
+ if (node.timerStepDimHSV_H !== undefined) clearInterval(node.timerStepDimHSV_H)
915
+ node.deleteHueStateQueue() // Clear dimming queue.
916
+ return
918
917
  }
919
918
 
920
- let xyBrightnessToHsv;
919
+ let xyBrightnessToHsv
921
920
  if (node.currentHUEDevice.color !== undefined && node.currentHUEDevice.color.xy !== undefined) {
922
921
  // Get the XY + brightness from the lamp and transform it into HSV
923
922
  // xyBrightnessToHsv = hueColorConverter.ColorConverter.xyBrightnessToHsv(node.currentHUEDevice.color.xy.x, node.currentHUEDevice.color.xy.y, node.currentHUEDevice.dimming.brightness);
924
- xyBrightnessToHsv = hueColorConverter.ColorConverter.xyBrightnessToHsv(hueColorConverter.ColorConverter.scale(node.currentHUEDevice.color.xy.x, [0, 1], [0, 100]), hueColorConverter.ColorConverter.scale(node.currentHUEDevice.color.xy.y, [0, 1], [0, 100]), node.currentHUEDevice.dimming.brightness);
923
+ xyBrightnessToHsv = hueColorConverter.ColorConverter.xyBrightnessToHsv(hueColorConverter.ColorConverter.scale(node.currentHUEDevice.color.xy.x, [0, 1], [0, 100]), hueColorConverter.ColorConverter.scale(node.currentHUEDevice.color.xy.y, [0, 1], [0, 100]), node.currentHUEDevice.dimming.brightness)
925
924
  } else {
926
- return; // Something wrong here.
925
+ return // Something wrong here.
927
926
  }
928
- let numStepHSV_H = 10; // Steps from 0 to 100
927
+ let numStepHSV_H = 10 // Steps from 0 to 100
929
928
 
930
929
  // Set the actual brightness to start with
931
- if (node.brightnessStepHSV_H === null || node.brightnessStepHSV_H === undefined) node.brightnessStepHSV_H = node.currentHUEDevice.dimming.brightness;
932
- node.brightnessStepHSV_H = Math.ceil(Number(node.brightnessStepHSV_H));
930
+ if (node.brightnessStepHSV_H === null || node.brightnessStepHSV_H === undefined) node.brightnessStepHSV_H = node.currentHUEDevice.dimming.brightness
931
+ node.brightnessStepHSV_H = Math.ceil(Number(node.brightnessStepHSV_H))
933
932
 
934
- const minDimLevelLightHSV_H = 1;
935
- const maxDimLevelLightHSV_H = 100;
936
- numStepHSV_H = Math.round((maxDimLevelLightHSV_H - minDimLevelLightHSV_H) / numStepHSV_H, 0);
933
+ const minDimLevelLightHSV_H = 1
934
+ const maxDimLevelLightHSV_H = 100
935
+ numStepHSV_H = Math.round((maxDimLevelLightHSV_H - minDimLevelLightHSV_H) / numStepHSV_H, 0)
937
936
  // Set the speed
938
- _dimSpeedInMillisecsHSV = Math.ceil(_dimSpeedInMillisecsHSV / (maxDimLevelLightHSV_H / numStepHSV_H));
937
+ _dimSpeedInMillisecsHSV = Math.ceil(_dimSpeedInMillisecsHSV / (maxDimLevelLightHSV_H / numStepHSV_H))
939
938
 
940
939
  if (_KNXbrightness_DirectionHSV_H > 0 && _KNXaction === 1) {
941
940
  // DIM UP
942
- if (node.timerStepDimHSV_H !== undefined) clearInterval(node.timerStepDimHSV_H);
941
+ if (node.timerStepDimHSV_H !== undefined) clearInterval(node.timerStepDimHSV_H)
943
942
  node.timerStepDimHSV_H = setInterval(() => {
944
- node.deleteHueStateQueue(); // Clear dimming queue.
945
- node.brightnessStepHSV_H += numStepHSV_H;
946
- if (node.brightnessStepHSV_H > maxDimLevelLightHSV_H) node.brightnessStepHSV_H = maxDimLevelLightHSV_H;
947
- //node.updateKNXLightHSV_H_State(node.brightnessStepHSV_H); // Unnecessary, but necessary to set the KNX Status in real time.
948
- xyBrightnessToHsv.h = node.brightnessStepHSV_H;
949
- const hsvToXYBri = hueColorConverter.ColorConverter.hsvToxyBrightness(xyBrightnessToHsv, node.currentHUEDevice.color.gamut);
950
- const hueTelegram = { color: { xy: { x: hsvToXYBri.x, y: hsvToXYBri.y } }, dynamics: { duration: _dimSpeedInMillisecsHSV + 500 } }; // Add some ms, to prevent the "ladder" step effect.
943
+ node.deleteHueStateQueue() // Clear dimming queue.
944
+ node.brightnessStepHSV_H += numStepHSV_H
945
+ if (node.brightnessStepHSV_H > maxDimLevelLightHSV_H) node.brightnessStepHSV_H = maxDimLevelLightHSV_H
946
+ // node.updateKNXLightHSV_H_State(node.brightnessStepHSV_H); // Unnecessary, but necessary to set the KNX Status in real time.
947
+ xyBrightnessToHsv.h = node.brightnessStepHSV_H
948
+ const hsvToXYBri = hueColorConverter.ColorConverter.hsvToxyBrightness(xyBrightnessToHsv, node.currentHUEDevice.color.gamut)
949
+ const hueTelegram = { color: { xy: { x: hsvToXYBri.x, y: hsvToXYBri.y } }, dynamics: { duration: _dimSpeedInMillisecsHSV + 500 } } // Add some ms, to prevent the "ladder" step effect.
951
950
  // Switch on the light if off
952
951
  if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false) {
953
- hueTelegram.on = { on: true };
952
+ hueTelegram.on = { on: true }
954
953
  }
955
- node.currentHUEDevice.color.xy = hsvToXYBri;// Unnecessary, but necessary to set the KNX Status in real time.
956
- node.updateKNXLightColorState(node.currentHUEDevice.color);
957
- node.writeHueState(hueTelegram);
954
+ node.currentHUEDevice.color.xy = hsvToXYBri// Unnecessary, but necessary to set the KNX Status in real time.
955
+ node.updateKNXLightColorState(node.currentHUEDevice.color)
956
+ node.writeHueState(hueTelegram)
958
957
  if (node.brightnessStepHSV_H >= maxDimLevelLightHSV_H) {
959
- if (node.timerStepDimHSV_H !== undefined) clearInterval(node.timerStepDimHSV_H);
958
+ if (node.timerStepDimHSV_H !== undefined) clearInterval(node.timerStepDimHSV_H)
960
959
  }
961
- }, _dimSpeedInMillisecsHSV);
960
+ }, _dimSpeedInMillisecsHSV)
962
961
  }
963
962
  if (_KNXbrightness_DirectionHSV_H > 0 && _KNXaction === 0) {
964
- if (node.currentHUEDevice.on.on === false) return; // Don't dim down, if the light is already off.
963
+ if (node.currentHUEDevice.on.on === false) return // Don't dim down, if the light is already off.
965
964
  // DIM DOWN
966
- if (node.timerStepDimHSV_H !== undefined) clearInterval(node.timerStepDimHSV_H);
965
+ if (node.timerStepDimHSV_H !== undefined) clearInterval(node.timerStepDimHSV_H)
967
966
  node.timerStepDimHSV_H = setInterval(() => {
968
- node.deleteHueStateQueue(); // Clear dimming queue.
969
- node.brightnessStepHSV_H -= numStepHSV_H; // *2 to speed up the things
970
- if (node.brightnessStepHSV_H < minDimLevelLightHSV_H) node.brightnessStepHSV_H = minDimLevelLightHSV_H;
971
- //node.updateKNXLightHSV_H_State(node.brightnessStepHSV_H); // Unnecessary, but necessary to set the KNX Status in real time.
967
+ node.deleteHueStateQueue() // Clear dimming queue.
968
+ node.brightnessStepHSV_H -= numStepHSV_H // *2 to speed up the things
969
+ if (node.brightnessStepHSV_H < minDimLevelLightHSV_H) node.brightnessStepHSV_H = minDimLevelLightHSV_H
970
+ // node.updateKNXLightHSV_H_State(node.brightnessStepHSV_H); // Unnecessary, but necessary to set the KNX Status in real time.
972
971
  // Produco l'RGB
973
- xyBrightnessToHsv.h = node.brightnessStepHSV_H;
974
- const hsvToXYBri = hueColorConverter.ColorConverter.hsvToxyBrightness(xyBrightnessToHsv, node.currentHUEDevice.color.gamut);
975
- const hueTelegram = { color: { xy: { x: hsvToXYBri.x, y: hsvToXYBri.y } }, dynamics: { duration: _dimSpeedInMillisecsHSV + 500 } };
972
+ xyBrightnessToHsv.h = node.brightnessStepHSV_H
973
+ const hsvToXYBri = hueColorConverter.ColorConverter.hsvToxyBrightness(xyBrightnessToHsv, node.currentHUEDevice.color.gamut)
974
+ const hueTelegram = { color: { xy: { x: hsvToXYBri.x, y: hsvToXYBri.y } }, dynamics: { duration: _dimSpeedInMillisecsHSV + 500 } }
976
975
  // Switch off the light if on
977
976
  if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === true && node.brightnessStepHSV_H === 0) {
978
- hueTelegram.on = { on: false };
977
+ hueTelegram.on = { on: false }
979
978
  }
980
- node.currentHUEDevice.color.xy = hsvToXYBri;// Unnecessary, but necessary to set the KNX Status in real time.
981
- node.updateKNXLightColorState(node.currentHUEDevice.color);
982
- node.writeHueState(hueTelegram);
979
+ node.currentHUEDevice.color.xy = hsvToXYBri// Unnecessary, but necessary to set the KNX Status in real time.
980
+ node.updateKNXLightColorState(node.currentHUEDevice.color)
981
+ node.writeHueState(hueTelegram)
983
982
  if (node.brightnessStepHSV_H <= minDimLevelLightHSV_H) {
984
- if (node.timerStepDimHSV_H !== undefined) clearInterval(node.timerStepDimHSV_H);
983
+ if (node.timerStepDimHSV_H !== undefined) clearInterval(node.timerStepDimHSV_H)
985
984
  }
986
- }, _dimSpeedInMillisecsHSV);
985
+ }, _dimSpeedInMillisecsHSV)
987
986
  }
988
987
  } catch (error) { /* empty */ }
989
- };
988
+ }
990
989
  /**
991
990
  * Starts dimming / stop dimming of the Saturation
992
991
  * @param {number} _KNXaction 1 for start, 0 for stop
@@ -994,341 +993,339 @@ module.exports = function (RED) {
994
993
  * @param {number} _dimSpeedInMillisecsHSV Speed time in milliseconds
995
994
  * @returns {}
996
995
  */
997
- node.hueDimmingHSV_S = function hueDimmingHSV_S(_KNXaction, _KNXbrightness_DirectionHSV_S, _dimSpeedInMillisecsHSV = undefined) {
996
+ node.hueDimmingHSV_S = function hueDimmingHSV_S (_KNXaction, _KNXbrightness_DirectionHSV_S, _dimSpeedInMillisecsHSV = undefined) {
998
997
  // After many attempts to use dimming_delta function of the HueApiV2, loosing days of my life, without a decent success, will use the standard dimming calculations
999
998
  // i decide to go to the "step brightness" way.
1000
999
  try {
1001
1000
  if (_KNXbrightness_DirectionHSV_S === 0 && _KNXaction === 0) {
1002
1001
  // STOP DIM
1003
- if (node.timerStepDimHSV_S !== undefined) clearInterval(node.timerStepDimHSV_S);
1004
- node.deleteHueStateQueue(); // Clear dimming queue.
1005
- return;
1002
+ if (node.timerStepDimHSV_S !== undefined) clearInterval(node.timerStepDimHSV_S)
1003
+ node.deleteHueStateQueue() // Clear dimming queue.
1004
+ return
1006
1005
  }
1007
1006
 
1008
- let xyBrightnessToHsv;
1007
+ let xyBrightnessToHsv
1009
1008
  if (node.currentHUEDevice.color !== undefined && node.currentHUEDevice.color.xy !== undefined) {
1010
1009
  // Get the XY + brightness from the lamp and transform it into HSV
1011
- xyBrightnessToHsv = hueColorConverter.ColorConverter.xyBrightnessToHsv(hueColorConverter.ColorConverter.scale(node.currentHUEDevice.color.xy.x, [0, 1], [0, 100]), hueColorConverter.ColorConverter.scale(node.currentHUEDevice.color.xy.y, [0, 1], [0, 100]), node.currentHUEDevice.dimming.brightness);
1010
+ xyBrightnessToHsv = hueColorConverter.ColorConverter.xyBrightnessToHsv(hueColorConverter.ColorConverter.scale(node.currentHUEDevice.color.xy.x, [0, 1], [0, 100]), hueColorConverter.ColorConverter.scale(node.currentHUEDevice.color.xy.y, [0, 1], [0, 100]), node.currentHUEDevice.dimming.brightness)
1012
1011
  } else {
1013
- return; // Something wrong here.
1012
+ return // Something wrong here.
1014
1013
  }
1015
- let numStepHSV_S = 10; // Steps from 0 to 100
1014
+ let numStepHSV_S = 10 // Steps from 0 to 100
1016
1015
 
1017
1016
  // Set the actual brightness to start with
1018
- if (node.brightnessStepHSV_S === null || node.brightnessStepHSV_S === undefined) node.brightnessStepHSV_S = node.currentHUEDevice.dimming.brightness;
1019
- node.brightnessStepHSV_S = Math.ceil(Number(node.brightnessStepHSV_S));
1017
+ if (node.brightnessStepHSV_S === null || node.brightnessStepHSV_S === undefined) node.brightnessStepHSV_S = node.currentHUEDevice.dimming.brightness
1018
+ node.brightnessStepHSV_S = Math.ceil(Number(node.brightnessStepHSV_S))
1020
1019
 
1021
- const minDimLevelLightHSV_S = 1;
1022
- const maxDimLevelLightHSV_S = 100;
1023
- numStepHSV_S = Math.round((maxDimLevelLightHSV_S - minDimLevelLightHSV_S) / numStepHSV_S, 0);
1020
+ const minDimLevelLightHSV_S = 1
1021
+ const maxDimLevelLightHSV_S = 100
1022
+ numStepHSV_S = Math.round((maxDimLevelLightHSV_S - minDimLevelLightHSV_S) / numStepHSV_S, 0)
1024
1023
  // Set the speed
1025
- _dimSpeedInMillisecsHSV = Math.ceil(_dimSpeedInMillisecsHSV / (maxDimLevelLightHSV_S / numStepHSV_S));
1024
+ _dimSpeedInMillisecsHSV = Math.ceil(_dimSpeedInMillisecsHSV / (maxDimLevelLightHSV_S / numStepHSV_S))
1026
1025
 
1027
1026
  if (_KNXbrightness_DirectionHSV_S > 0 && _KNXaction === 1) {
1028
1027
  // DIM UP
1029
- if (node.timerStepDimHSV_S !== undefined) clearInterval(node.timerStepDimHSV_S);
1028
+ if (node.timerStepDimHSV_S !== undefined) clearInterval(node.timerStepDimHSV_S)
1030
1029
  node.timerStepDimHSV_S = setInterval(() => {
1031
- node.deleteHueStateQueue(); // Clear dimming queue.
1032
- node.brightnessStepHSV_S += numStepHSV_S;
1033
- if (node.brightnessStepHSV_S > maxDimLevelLightHSV_S) node.brightnessStepHSV_S = maxDimLevelLightHSV_S;
1034
- //node.updateKNXLightHSV_S_State(node.brightnessStepHSV_S); // Unnecessary, but necessary to set the KNX Status in real time.
1035
- xyBrightnessToHsv.s = node.brightnessStepHSV_S;
1036
- const hsvToXYBri = hueColorConverter.ColorConverter.hsvToxyBrightness(xyBrightnessToHsv, node.currentHUEDevice.color.gamut);
1037
- const hueTelegram = { color: { xy: { x: hsvToXYBri.x, y: hsvToXYBri.y } }, dynamics: { duration: _dimSpeedInMillisecsHSV + 500 } }; // Add some ms, to prevent the "ladder" step effect.
1030
+ node.deleteHueStateQueue() // Clear dimming queue.
1031
+ node.brightnessStepHSV_S += numStepHSV_S
1032
+ if (node.brightnessStepHSV_S > maxDimLevelLightHSV_S) node.brightnessStepHSV_S = maxDimLevelLightHSV_S
1033
+ // node.updateKNXLightHSV_S_State(node.brightnessStepHSV_S); // Unnecessary, but necessary to set the KNX Status in real time.
1034
+ xyBrightnessToHsv.s = node.brightnessStepHSV_S
1035
+ const hsvToXYBri = hueColorConverter.ColorConverter.hsvToxyBrightness(xyBrightnessToHsv, node.currentHUEDevice.color.gamut)
1036
+ const hueTelegram = { color: { xy: { x: hsvToXYBri.x, y: hsvToXYBri.y } }, dynamics: { duration: _dimSpeedInMillisecsHSV + 500 } } // Add some ms, to prevent the "ladder" step effect.
1038
1037
  // Switch on the light if off
1039
1038
  if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false) {
1040
- hueTelegram.on = { on: true };
1039
+ hueTelegram.on = { on: true }
1041
1040
  }
1042
- node.currentHUEDevice.color.xy = cloneDeep(hsvToXYBri);// Unnecessary, but necessary to set the KNX Status in real time.
1043
- node.updateKNXLightColorState(node.currentHUEDevice.color);
1044
- node.writeHueState(hueTelegram);
1041
+ node.currentHUEDevice.color.xy = cloneDeep(hsvToXYBri)// Unnecessary, but necessary to set the KNX Status in real time.
1042
+ node.updateKNXLightColorState(node.currentHUEDevice.color)
1043
+ node.writeHueState(hueTelegram)
1045
1044
  if (node.brightnessStepHSV_S >= maxDimLevelLightHSV_S) {
1046
- if (node.timerStepDimHSV_S !== undefined) clearInterval(node.timerStepDimHSV_S);
1045
+ if (node.timerStepDimHSV_S !== undefined) clearInterval(node.timerStepDimHSV_S)
1047
1046
  }
1048
- }, _dimSpeedInMillisecsHSV);
1047
+ }, _dimSpeedInMillisecsHSV)
1049
1048
  }
1050
1049
  if (_KNXbrightness_DirectionHSV_S > 0 && _KNXaction === 0) {
1051
- if (node.currentHUEDevice.on.on === false) return; // Don't dim down, if the light is already off.
1050
+ if (node.currentHUEDevice.on.on === false) return // Don't dim down, if the light is already off.
1052
1051
  // DIM DOWN
1053
- if (node.timerStepDimHSV_S !== undefined) clearInterval(node.timerStepDimHSV_S);
1052
+ if (node.timerStepDimHSV_S !== undefined) clearInterval(node.timerStepDimHSV_S)
1054
1053
  node.timerStepDimHSV_S = setInterval(() => {
1055
- node.deleteHueStateQueue(); // Clear dimming queue.
1056
- node.brightnessStepHSV_S -= numStepHSV_S; // *2 to speed up the things
1057
- if (node.brightnessStepHSV_S < minDimLevelLightHSV_S) node.brightnessStepHSV_S = minDimLevelLightHSV_S;
1058
- //node.updateKNXLightHSV_S_State(node.brightnessStepHSV_S); // Unnecessary, but necessary to set the KNX Status in real time.
1054
+ node.deleteHueStateQueue() // Clear dimming queue.
1055
+ node.brightnessStepHSV_S -= numStepHSV_S // *2 to speed up the things
1056
+ if (node.brightnessStepHSV_S < minDimLevelLightHSV_S) node.brightnessStepHSV_S = minDimLevelLightHSV_S
1057
+ // node.updateKNXLightHSV_S_State(node.brightnessStepHSV_S); // Unnecessary, but necessary to set the KNX Status in real time.
1059
1058
  // Produco l'RGB
1060
- xyBrightnessToHsv.s = node.brightnessStepHSV_S;
1061
- const hsvToXYBri = hueColorConverter.ColorConverter.hsvToxyBrightness(xyBrightnessToHsv, node.currentHUEDevice.color.gamut);
1062
- const hueTelegram = { color: { xy: { x: hsvToXYBri.x, y: hsvToXYBri.y } }, dynamics: { duration: _dimSpeedInMillisecsHSV + 500 } };
1059
+ xyBrightnessToHsv.s = node.brightnessStepHSV_S
1060
+ const hsvToXYBri = hueColorConverter.ColorConverter.hsvToxyBrightness(xyBrightnessToHsv, node.currentHUEDevice.color.gamut)
1061
+ const hueTelegram = { color: { xy: { x: hsvToXYBri.x, y: hsvToXYBri.y } }, dynamics: { duration: _dimSpeedInMillisecsHSV + 500 } }
1063
1062
  // Switch off the light if on
1064
1063
  if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === true && node.brightnessStepHSV_S === 0) {
1065
- hueTelegram.on = { on: false };
1064
+ hueTelegram.on = { on: false }
1066
1065
  }
1067
- node.currentHUEDevice.color.xy = cloneDeep(hsvToXYBri);// Unnecessary, but necessary to set the KNX Status in real time.
1068
- node.updateKNXLightColorState(node.currentHUEDevice.color);
1069
- node.writeHueState(hueTelegram);
1066
+ node.currentHUEDevice.color.xy = cloneDeep(hsvToXYBri)// Unnecessary, but necessary to set the KNX Status in real time.
1067
+ node.updateKNXLightColorState(node.currentHUEDevice.color)
1068
+ node.writeHueState(hueTelegram)
1070
1069
  if (node.brightnessStepHSV_S <= minDimLevelLightHSV_S) {
1071
- if (node.timerStepDimHSV_S !== undefined) clearInterval(node.timerStepDimHSV_S);
1070
+ if (node.timerStepDimHSV_S !== undefined) clearInterval(node.timerStepDimHSV_S)
1072
1071
  }
1073
- }, _dimSpeedInMillisecsHSV);
1072
+ }, _dimSpeedInMillisecsHSV)
1074
1073
  }
1075
1074
  } catch (error) { /* empty */ }
1076
- };
1075
+ }
1077
1076
  // ***********************************************************
1078
1077
 
1079
1078
  node.handleSendHUE = async (_event) => {
1080
- if (_event === undefined) return;
1081
- if (_event.type !== 'grouped_light' && _event.type !== 'light') return;
1079
+ if (_event === undefined) return
1080
+ if (_event.type !== 'grouped_light' && _event.type !== 'light') return
1082
1081
 
1083
1082
  // !!!! >>> if the node is a grouped_light, the only values required, thus present, by HUE apis are "on" and "dimming".
1084
1083
  // !!!! >>> For all others properties like for example color and tunable white, i must get the data from one of the child lights.
1085
1084
 
1086
- //(async () => {
1085
+ // (async () => {
1087
1086
  try {
1088
1087
  if (node.currentHUEDevice === undefined || node.serverHue === null || node.serverHue === undefined) {
1089
1088
  node.setNodeStatusHue({
1090
- fill: "red",
1091
- shape: "ring",
1089
+ fill: 'red',
1090
+ shape: 'ring',
1092
1091
  text: "Rejected HUE light settings. I'm still not ready...",
1093
- payload: "",
1094
- });
1095
- return;
1092
+ payload: ''
1093
+ })
1094
+ return
1096
1095
  }
1097
1096
 
1098
- const receivedHUEObject = cloneDeep(_event);
1097
+ const receivedHUEObject = cloneDeep(_event)
1099
1098
 
1100
- //#region "CALCULATE COLOR AND COLOR TEMPERATURE OF THE LIGHTS BELONGING TO THE GROUPED_LIGHT"
1099
+ // #region "CALCULATE COLOR AND COLOR TEMPERATURE OF THE LIGHTS BELONGING TO THE GROUPED_LIGHT"
1101
1100
  // Check wether the incoming _event belongs to a light belonging to the group_light
1102
1101
  if (node.isGrouped_light === true && receivedHUEObject.type === 'light') {
1103
1102
  // Handling of not by HUE handled Color Temperature and ColorXY
1104
- let modifiedLight;
1105
- const groupChilds = [];
1106
- let AverageColorsXYBrightnessAndTemperature; // Average color xy and color temp if the node is a grouped light.
1103
+ let modifiedLight
1104
+ const groupChilds = []
1105
+ let AverageColorsXYBrightnessAndTemperature // Average color xy and color temp if the node is a grouped light.
1107
1106
  // If the current node is a grouped lights, i must check wether the receivedHUEObject (containing a light) belongs to the node lights collection.
1108
1107
  // Find all the lights in the collection, having the color_temperature capabilities, belonging to the group.
1109
- const devices = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, false);
1108
+ const devices = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, false)
1110
1109
  if (devices.length === 0) {
1111
- devices.push(receivedHUEObject);
1110
+ devices.push(receivedHUEObject)
1112
1111
  }
1113
1112
 
1114
1113
  for (let index = 0; index < devices.length; index++) {
1115
- const element = devices[index];
1114
+ const element = devices[index]
1116
1115
  if (receivedHUEObject.id === element.id) {
1117
- modifiedLight = element;
1116
+ modifiedLight = element
1118
1117
  // The dimming is not necessary, beacause the HUE API already sends a group_light event with the average brightness //if (receivedHUEObject.dimming !== undefined) modifiedLight.dimming = { brightness: receivedHUEObject.dimming.brightness };
1119
- if (receivedHUEObject.color !== undefined && receivedHUEObject.color.xy !== undefined) modifiedLight.color = receivedHUEObject.color;
1120
- if (receivedHUEObject.color_temperature !== undefined) modifiedLight.color_temperature = receivedHUEObject.color_temperature;
1121
- groupChilds.push(modifiedLight);
1118
+ if (receivedHUEObject.color !== undefined && receivedHUEObject.color.xy !== undefined) modifiedLight.color = receivedHUEObject.color
1119
+ if (receivedHUEObject.color_temperature !== undefined) modifiedLight.color_temperature = receivedHUEObject.color_temperature
1120
+ groupChilds.push(modifiedLight)
1122
1121
  } else {
1123
1122
  // Simply append the light
1124
- if ((element.color_temperature !== undefined && element.color_temperature.mirek !== undefined)
1125
- || (element.color !== undefined && element.color.xy !== undefined)) {
1126
- groupChilds.push(element);
1123
+ if ((element.color_temperature !== undefined && element.color_temperature.mirek !== undefined) ||
1124
+ (element.color !== undefined && element.color.xy !== undefined)) {
1125
+ groupChilds.push(element)
1127
1126
  }
1128
1127
  }
1129
1128
  }
1130
1129
 
1131
1130
  // Use the arithmetic average of color xy, brightness and color temperature "averageColorXYandKelvinOfGroupedLights"
1132
- if (groupChilds !== undefined) AverageColorsXYBrightnessAndTemperature = await node.serverHue.getAverageColorsXYBrightnessAndTemperature(groupChilds);
1131
+ if (groupChilds !== undefined) AverageColorsXYBrightnessAndTemperature = await node.serverHue.getAverageColorsXYBrightnessAndTemperature(groupChilds)
1133
1132
 
1134
- // Set the new values based on average calculated above
1133
+ // Set the new values based on average calculated above
1135
1134
  // CHECK FIRST THE COLOR_TEMPERATURE, because it can be undefined, because the current selected color
1136
1135
  // is out of the mirek range, so it cannot be represented with the colore temperature.
1137
1136
  if (receivedHUEObject.color_temperature !== undefined && AverageColorsXYBrightnessAndTemperature.mirek !== undefined && receivedHUEObject.color_temperature.mirel_valid === true) {
1138
- receivedHUEObject.color_temperature.mirek = AverageColorsXYBrightnessAndTemperature.mirek;
1139
- node.currentHUEDevice.color_temperature = { mirek: AverageColorsXYBrightnessAndTemperature.mirek };
1140
- node.updateKNXLightKelvinPercentageState(receivedHUEObject.color_temperature.mirek);
1141
- node.updateKNXLightKelvinState(receivedHUEObject.color_temperature.mirek);
1137
+ receivedHUEObject.color_temperature.mirek = AverageColorsXYBrightnessAndTemperature.mirek
1138
+ node.currentHUEDevice.color_temperature = { mirek: AverageColorsXYBrightnessAndTemperature.mirek }
1139
+ node.updateKNXLightKelvinPercentageState(receivedHUEObject.color_temperature.mirek)
1140
+ node.updateKNXLightKelvinState(receivedHUEObject.color_temperature.mirek)
1142
1141
  } else if (receivedHUEObject.color !== undefined && receivedHUEObject.color.xy !== undefined && AverageColorsXYBrightnessAndTemperature.x !== undefined) {
1143
- receivedHUEObject.color.xy.x = AverageColorsXYBrightnessAndTemperature.x;
1144
- receivedHUEObject.color.xy.y = AverageColorsXYBrightnessAndTemperature.y;
1142
+ receivedHUEObject.color.xy.x = AverageColorsXYBrightnessAndTemperature.x
1143
+ receivedHUEObject.color.xy.y = AverageColorsXYBrightnessAndTemperature.y
1145
1144
  node.currentHUEDevice.color = { xy: { x: AverageColorsXYBrightnessAndTemperature.x, y: AverageColorsXYBrightnessAndTemperature.y } }
1146
- node.updateKNXLightColorState(receivedHUEObject.color);
1145
+ node.updateKNXLightColorState(receivedHUEObject.color)
1147
1146
  }
1148
- // The dimming is not necessary, beacause the HUE API already sends a group_light event with the average brightness
1147
+ // The dimming is not necessary, beacause the HUE API already sends a group_light event with the average brightness
1149
1148
  // if (receivedHUEObject.dimming !== undefined && AverageColorsXYBrightnessAndTemperature.brightness !== undefined) {
1150
1149
  // receivedHUEObject.dimming = { brightness: AverageColorsXYBrightnessAndTemperature.brightness };
1151
1150
  // }
1152
1151
  // --------------------------------------------------------------------------------------------------
1153
1152
  if (modifiedLight !== undefined && modifiedLight.metadata !== undefined && modifiedLight.metadata.name !== undefined) {
1154
- receivedHUEObject.lightName = modifiedLight.metadata.name;
1153
+ receivedHUEObject.lightName = modifiedLight.metadata.name
1155
1154
  }
1156
- node.send(receivedHUEObject);
1157
- return;
1155
+ node.send(receivedHUEObject)
1156
+ return
1158
1157
  }
1159
- //#endregion
1158
+ // #endregion
1160
1159
 
1161
1160
  if (receivedHUEObject.id === node.hueDevice) {
1162
1161
  // Output the msg to the flow
1163
- node.send(receivedHUEObject);
1162
+ node.send(receivedHUEObject)
1164
1163
 
1165
1164
  // // DEBUG testing enable/disable HTML UI Tabs
1166
- //delete _event.dimming;
1167
- //delete _event.color;
1168
- //delete _event.color_temperature;
1169
- //delete _event.color_temperature_delta;
1165
+ // delete _event.dimming;
1166
+ // delete _event.color;
1167
+ // delete _event.color_temperature;
1168
+ // delete _event.color_temperature_delta;
1170
1169
 
1171
1170
  if (receivedHUEObject.on !== undefined) {
1172
- node.updateKNXLightState(receivedHUEObject.on.on);
1171
+ node.updateKNXLightState(receivedHUEObject.on.on)
1173
1172
  // In case of switch off, set the dim to zero
1174
- if (receivedHUEObject.on.on === false && (config.updateKNXBrightnessStatusOnHUEOnOff === undefined || config.updateKNXBrightnessStatusOnHUEOnOff === "onhueoff")) {
1175
- node.updateKNXBrightnessState(0);
1176
- if (receivedHUEObject.dimming !== undefined) delete receivedHUEObject.dimming; // Remove event.dimming, because has beem handled by this function and i don't want the function below to take care of it.
1173
+ if (receivedHUEObject.on.on === false && (config.updateKNXBrightnessStatusOnHUEOnOff === undefined || config.updateKNXBrightnessStatusOnHUEOnOff === 'onhueoff')) {
1174
+ node.updateKNXBrightnessState(0)
1175
+ if (receivedHUEObject.dimming !== undefined) delete receivedHUEObject.dimming // Remove event.dimming, because has beem handled by this function and i don't want the function below to take care of it.
1177
1176
  } else if (receivedHUEObject.on.on === true && node.currentHUEDevice.on.on === false) {
1178
1177
  // Turn on: update the dimming KNX Status value as well, but only if we have a reliable value.
1179
1178
  // For grouped_light, the bridge exposes an aggregated brightness value via /resource/grouped_light/{id}.
1180
- let brightVal;
1179
+ let brightVal
1181
1180
  if (receivedHUEObject.dimming !== undefined && receivedHUEObject.dimming.brightness !== undefined) {
1182
- brightVal = receivedHUEObject.dimming.brightness;
1183
- } else if (node.isGrouped_light === true && typeof node.serverHue?.getHueResourceSnapshot === "function" && config.GALightBrightnessState) {
1181
+ brightVal = receivedHUEObject.dimming.brightness
1182
+ } else if (node.isGrouped_light === true && typeof node.serverHue?.getHueResourceSnapshot === 'function' && config.GALightBrightnessState) {
1184
1183
  try {
1185
- const snapshot = await node.serverHue.getHueResourceSnapshot(node.hueDevice, { forceRefresh: true });
1186
- if (snapshot?.dimming?.brightness !== undefined) brightVal = snapshot.dimming.brightness;
1184
+ const snapshot = await node.serverHue.getHueResourceSnapshot(node.hueDevice, { forceRefresh: true })
1185
+ if (snapshot?.dimming?.brightness !== undefined) brightVal = snapshot.dimming.brightness
1187
1186
  } catch (error) { /* empty */ }
1188
1187
  } else if (node.currentHUEDevice.dimming !== undefined && node.currentHUEDevice.dimming.brightness !== undefined) {
1189
- brightVal = node.currentHUEDevice.dimming.brightness;
1188
+ brightVal = node.currentHUEDevice.dimming.brightness
1190
1189
  }
1191
- if (brightVal !== undefined) node.updateKNXBrightnessState(brightVal);
1190
+ if (brightVal !== undefined) node.updateKNXBrightnessState(brightVal)
1192
1191
  }
1193
- node.currentHUEDevice.on.on = receivedHUEObject.on.on;
1192
+ node.currentHUEDevice.on.on = receivedHUEObject.on.on
1194
1193
  }
1195
1194
 
1196
1195
  if (receivedHUEObject.color !== undefined && receivedHUEObject.color.xy !== undefined) { // fixed https://github.com/Supergiovane/node-red-contrib-knx-ultimate/issues/287
1197
- node.updateKNXLightColorState(receivedHUEObject.color);
1198
- node.currentHUEDevice.color = receivedHUEObject.color;
1196
+ node.updateKNXLightColorState(receivedHUEObject.color)
1197
+ node.currentHUEDevice.color = receivedHUEObject.color
1199
1198
  }
1200
1199
 
1201
1200
  if (receivedHUEObject.dimming !== undefined && receivedHUEObject.dimming.brightness !== undefined) {
1202
- const zeroBrightnessWhenOff = (config.updateKNXBrightnessStatusOnHUEOnOff === undefined || config.updateKNXBrightnessStatusOnHUEOnOff === "onhueoff");
1201
+ const zeroBrightnessWhenOff = (config.updateKNXBrightnessStatusOnHUEOnOff === undefined || config.updateKNXBrightnessStatusOnHUEOnOff === 'onhueoff')
1203
1202
  // Once upon n a time, the light transmit the brightness value of 0.39.
1204
1203
  // To avoid wrongly turn light state on, exit
1205
- if (receivedHUEObject.dimming.brightness < 1) receivedHUEObject.dimming.brightness = 0;
1204
+ if (receivedHUEObject.dimming.brightness < 1) receivedHUEObject.dimming.brightness = 0
1206
1205
  // If the light is OFF and the user wants KNX brightness status to stay 0 while OFF,
1207
1206
  // don't propagate Hue's cached brightness (usually the last/boot brightness) back to KNX.
1208
1207
  if (zeroBrightnessWhenOff === true && node.currentHUEDevice?.on?.on === false && (receivedHUEObject.on === undefined || receivedHUEObject.on.on === false)) {
1209
- if (node.currentHUEDevice.dimming !== undefined) node.currentHUEDevice.dimming.brightness = receivedHUEObject.dimming.brightness;
1208
+ if (node.currentHUEDevice.dimming !== undefined) node.currentHUEDevice.dimming.brightness = receivedHUEObject.dimming.brightness
1210
1209
  } else if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false && receivedHUEObject.dimming.brightness === 0) {
1211
1210
  // Do nothing, because the light is off and the dimming also is 0
1212
1211
  } else {
1213
- if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false && (receivedHUEObject.on === undefined || (receivedHUEObject.on !== undefined && receivedHUEObject.on.on === true))) node.updateKNXLightState(receivedHUEObject.dimming.brightness > 0);
1214
- node.updateKNXBrightnessState(receivedHUEObject.dimming.brightness);
1212
+ if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false && (receivedHUEObject.on === undefined || (receivedHUEObject.on !== undefined && receivedHUEObject.on.on === true))) node.updateKNXLightState(receivedHUEObject.dimming.brightness > 0)
1213
+ node.updateKNXBrightnessState(receivedHUEObject.dimming.brightness)
1215
1214
  // If the brightness reaches zero, the hue lamp "on" property must be set to zero as well
1216
1215
  if (receivedHUEObject.dimming.brightness === 0 && node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === true) {
1217
- node.writeHueState({ on: { on: false } });
1218
- node.currentHUEDevice.on.on = false;
1216
+ node.writeHueState({ on: { on: false } })
1217
+ node.currentHUEDevice.on.on = false
1219
1218
  }
1220
- node.currentHUEDevice.dimming.brightness = receivedHUEObject.dimming.brightness;
1219
+ node.currentHUEDevice.dimming.brightness = receivedHUEObject.dimming.brightness
1221
1220
  }
1222
1221
  }
1223
1222
 
1224
1223
  if (receivedHUEObject.color_temperature !== undefined && receivedHUEObject.color_temperature.mirek !== undefined) {
1225
- node.updateKNXLightKelvinPercentageState(receivedHUEObject.color_temperature.mirek);
1226
- node.updateKNXLightKelvinState(receivedHUEObject.color_temperature.mirek);
1227
- node.currentHUEDevice.color_temperature.mirek = receivedHUEObject.color_temperature.mirek;
1224
+ node.updateKNXLightKelvinPercentageState(receivedHUEObject.color_temperature.mirek)
1225
+ node.updateKNXLightKelvinState(receivedHUEObject.color_temperature.mirek)
1226
+ node.currentHUEDevice.color_temperature.mirek = receivedHUEObject.color_temperature.mirek
1228
1227
  }
1229
1228
  }
1230
1229
  } catch (error) {
1231
1230
  node.status({
1232
- fill: "red",
1233
- shape: "dot",
1234
- text: `HUE->KNX error ${node.id} ${error.message}. Seee Log`,
1235
- });
1236
- RED.log.error(`knxUltimateHueLight: node.handleSendHUE = (_event): ${error.stack}`);
1231
+ fill: 'red',
1232
+ shape: 'dot',
1233
+ text: `HUE->KNX error ${node.id} ${error.message}. Seee Log`
1234
+ })
1235
+ RED.log.error(`knxUltimateHueLight: node.handleSendHUE = (_event): ${error.stack}`)
1237
1236
  }
1238
1237
  // })();
1239
- };
1240
-
1238
+ }
1241
1239
 
1242
1240
  // Leave the name after "function", to avoid <anonymous function> in the stack trace, in caso of errors.
1243
- node.updateKNXBrightnessState = function updateKNXBrightnessState(_value, _outputtype = "write") {
1244
- if (config.GALightBrightnessState !== undefined && config.GALightBrightnessState !== "") {
1245
- const knxMsgPayload = {};
1246
- knxMsgPayload.topic = config.GALightBrightnessState;
1247
- knxMsgPayload.dpt = config.dptLightBrightnessState;
1248
- knxMsgPayload.payload = _value;
1241
+ node.updateKNXBrightnessState = function updateKNXBrightnessState (_value, _outputtype = 'write') {
1242
+ if (config.GALightBrightnessState !== undefined && config.GALightBrightnessState !== '') {
1243
+ const knxMsgPayload = {}
1244
+ knxMsgPayload.topic = config.GALightBrightnessState
1245
+ knxMsgPayload.dpt = config.dptLightBrightnessState
1246
+ knxMsgPayload.payload = _value
1249
1247
  // Send to KNX bus
1250
- if (knxMsgPayload.topic !== "" && knxMsgPayload.topic !== undefined) {
1248
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
1251
1249
  if (node.serverKNX !== null && node.serverKNX !== undefined) {
1252
1250
  node.serverKNX.sendKNXTelegramToKNXEngine({
1253
1251
  grpaddr: knxMsgPayload.topic,
1254
1252
  payload: knxMsgPayload.payload,
1255
1253
  dpt: knxMsgPayload.dpt,
1256
1254
  outputtype: _outputtype,
1257
- nodecallerid: node.id,
1258
- });
1255
+ nodecallerid: node.id
1256
+ })
1259
1257
  }
1260
1258
  }
1261
1259
  node.setNodeStatusHue({
1262
- fill: "blue",
1263
- shape: "ring",
1264
- text: "HUE->KNX Bright",
1265
- payload: knxMsgPayload.payload,
1266
- });
1260
+ fill: 'blue',
1261
+ shape: 'ring',
1262
+ text: 'HUE->KNX Bright',
1263
+ payload: knxMsgPayload.payload
1264
+ })
1267
1265
  }
1268
- };
1266
+ }
1269
1267
 
1270
- node.updateKNXLightState = function updateKNXLightState(_value, _outputtype = "write") {
1268
+ node.updateKNXLightState = function updateKNXLightState (_value, _outputtype = 'write') {
1271
1269
  try {
1272
- const knxMsgPayload = {};
1273
- knxMsgPayload.topic = config.GALightState;
1274
- knxMsgPayload.dpt = config.dptLightState;
1275
- knxMsgPayload.payload = _value;
1276
- if (config.GALightState !== undefined && config.GALightState !== "") {
1277
-
1270
+ const knxMsgPayload = {}
1271
+ knxMsgPayload.topic = config.GALightState
1272
+ knxMsgPayload.dpt = config.dptLightState
1273
+ knxMsgPayload.payload = _value
1274
+ if (config.GALightState !== undefined && config.GALightState !== '') {
1278
1275
  // Check not to have already sent the value
1279
1276
  // Send to KNX bus
1280
- if (knxMsgPayload.topic !== "" && knxMsgPayload.topic !== undefined) {
1277
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
1281
1278
  if (node.serverKNX !== null && node.serverKNX !== undefined) {
1282
1279
  node.serverKNX.sendKNXTelegramToKNXEngine({
1283
1280
  grpaddr: knxMsgPayload.topic,
1284
1281
  payload: knxMsgPayload.payload,
1285
1282
  dpt: knxMsgPayload.dpt,
1286
1283
  outputtype: _outputtype,
1287
- nodecallerid: node.id,
1288
- });
1284
+ nodecallerid: node.id
1285
+ })
1289
1286
  }
1290
1287
  }
1291
1288
  node.setNodeStatusHue({
1292
- fill: "blue",
1293
- shape: "ring",
1294
- text: "HUE->KNX On/Off",
1295
- payload: knxMsgPayload.payload,
1296
- });
1289
+ fill: 'blue',
1290
+ shape: 'ring',
1291
+ text: 'HUE->KNX On/Off',
1292
+ payload: knxMsgPayload.payload
1293
+ })
1297
1294
  }
1298
1295
  } catch (error) {
1299
1296
  /* empty */
1300
1297
  }
1301
- };
1302
-
1303
- node.updateKNXLightKelvinPercentageState = function updateKNXLightKelvinPercentageState(_value, _outputtype = "write") {
1304
- if (config.GALightKelvinPercentageState !== undefined && config.GALightKelvinPercentageState !== "") {
1305
- const knxMsgPayload = {};
1306
- knxMsgPayload.topic = config.GALightKelvinPercentageState;
1307
- knxMsgPayload.dpt = config.dptLightKelvinPercentageState;
1308
- if (config.dptLightKelvinPercentageState === "5.001") {
1309
- const retPercent = hueColorConverter.ColorConverter.scale(_value, [153, 500], [0, 100]);
1310
- knxMsgPayload.payload = 100 - retPercent;
1298
+ }
1299
+
1300
+ node.updateKNXLightKelvinPercentageState = function updateKNXLightKelvinPercentageState (_value, _outputtype = 'write') {
1301
+ if (config.GALightKelvinPercentageState !== undefined && config.GALightKelvinPercentageState !== '') {
1302
+ const knxMsgPayload = {}
1303
+ knxMsgPayload.topic = config.GALightKelvinPercentageState
1304
+ knxMsgPayload.dpt = config.dptLightKelvinPercentageState
1305
+ if (config.dptLightKelvinPercentageState === '5.001') {
1306
+ const retPercent = hueColorConverter.ColorConverter.scale(_value, [153, 500], [0, 100])
1307
+ knxMsgPayload.payload = 100 - retPercent
1311
1308
  }
1312
1309
  // Send to KNX bus
1313
- if (knxMsgPayload.topic !== "" && knxMsgPayload.topic !== undefined) {
1310
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
1314
1311
  if (node.serverKNX !== null && node.serverKNX !== undefined) {
1315
1312
  node.serverKNX.sendKNXTelegramToKNXEngine({
1316
1313
  grpaddr: knxMsgPayload.topic,
1317
1314
  payload: knxMsgPayload.payload,
1318
1315
  dpt: knxMsgPayload.dpt,
1319
1316
  outputtype: _outputtype,
1320
- nodecallerid: node.id,
1321
- });
1317
+ nodecallerid: node.id
1318
+ })
1322
1319
  }
1323
1320
  }
1324
1321
  node.setNodeStatusHue({
1325
- fill: "blue",
1326
- shape: "ring",
1327
- text: "HUE->KNX Tunable White",
1328
- payload: knxMsgPayload.payload,
1329
- });
1322
+ fill: 'blue',
1323
+ shape: 'ring',
1324
+ text: 'HUE->KNX Tunable White',
1325
+ payload: knxMsgPayload.payload
1326
+ })
1330
1327
  }
1331
- };
1328
+ }
1332
1329
 
1333
1330
  // /**
1334
1331
  // * Update the internal HSV variable status and send the valuge in % to the KNX BUS
@@ -1406,178 +1403,178 @@ module.exports = function (RED) {
1406
1403
  * @param {string} _outputtype "write" is the default KNX command
1407
1404
  * @returns {}
1408
1405
  */
1409
- node.updateKNXLightColorState = function updateKNXLightColorState(_value, _outputtype = "write") {
1410
- if (config.GALightColorState !== undefined && config.GALightColorState !== "") {
1411
- if (_value.xy === undefined || _value.xy.x === undefined) return;
1412
- const knxMsgPayload = {};
1413
- knxMsgPayload.topic = config.GALightColorState;
1414
- knxMsgPayload.dpt = config.dptLightColorState;
1406
+ node.updateKNXLightColorState = function updateKNXLightColorState (_value, _outputtype = 'write') {
1407
+ if (config.GALightColorState !== undefined && config.GALightColorState !== '') {
1408
+ if (_value.xy === undefined || _value.xy.x === undefined) return
1409
+ const knxMsgPayload = {}
1410
+ knxMsgPayload.topic = config.GALightColorState
1411
+ knxMsgPayload.dpt = config.dptLightColorState
1415
1412
  try {
1416
1413
  knxMsgPayload.payload = hueColorConverter.ColorConverter.xyBriToRgb(
1417
1414
  _value.xy.x,
1418
1415
  _value.xy.y,
1419
- node.currentHUEDevice !== undefined && node.currentHUEDevice.dimming !== undefined && node.currentHUEDevice.dimming.brightness === undefined ? node.currentHUEDevice.dimming.brightness : 100,
1420
- );
1421
- knxMsgPayload.payload = { red: knxMsgPayload.payload.r, green: knxMsgPayload.payload.g, blue: knxMsgPayload.payload.b };
1416
+ node.currentHUEDevice !== undefined && node.currentHUEDevice.dimming !== undefined && node.currentHUEDevice.dimming.brightness === undefined ? node.currentHUEDevice.dimming.brightness : 100
1417
+ )
1418
+ knxMsgPayload.payload = { red: knxMsgPayload.payload.r, green: knxMsgPayload.payload.g, blue: knxMsgPayload.payload.b }
1422
1419
  // Send to KNX bus
1423
- if (knxMsgPayload.topic !== "" && knxMsgPayload.topic !== undefined) {
1420
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
1424
1421
  if (node.serverKNX !== null && node.serverKNX !== undefined) {
1425
1422
  node.serverKNX.sendKNXTelegramToKNXEngine({
1426
1423
  grpaddr: knxMsgPayload.topic,
1427
1424
  payload: knxMsgPayload.payload,
1428
1425
  dpt: knxMsgPayload.dpt,
1429
1426
  outputtype: _outputtype,
1430
- nodecallerid: node.id,
1431
- });
1427
+ nodecallerid: node.id
1428
+ })
1432
1429
  }
1433
1430
  }
1434
1431
  node.setNodeStatusHue({
1435
- fill: "blue",
1436
- shape: "ring",
1437
- text: "HUE->KNX Color",
1438
- payload: knxMsgPayload.payload,
1439
- });
1432
+ fill: 'blue',
1433
+ shape: 'ring',
1434
+ text: 'HUE->KNX Color',
1435
+ payload: knxMsgPayload.payload
1436
+ })
1440
1437
  } catch (error) { }
1441
1438
  }
1442
- if (config.GALightHSV_S_State !== undefined && config.GALightHSV_S_State !== "") {
1443
- const knxMsgPayload = {};
1444
- knxMsgPayload.topic = config.GALightHSV_S_State;
1445
- knxMsgPayload.dpt = config.dptLightHSV_S_State;
1446
- if (config.dptLightHSV_S_State === "5.001") {
1447
- knxMsgPayload.payload = hueColorConverter.ColorConverter.xyBrightnessToHsv(_value.xy.x, _value.xy.y, node.currentHUEDevice !== undefined && node.currentHUEDevice.dimming !== undefined && node.currentHUEDevice.dimming.brightness === undefined ? node.currentHUEDevice.dimming.brightness : 100, false);
1448
- knxMsgPayload.payload = knxMsgPayload.payload.s;
1439
+ if (config.GALightHSV_S_State !== undefined && config.GALightHSV_S_State !== '') {
1440
+ const knxMsgPayload = {}
1441
+ knxMsgPayload.topic = config.GALightHSV_S_State
1442
+ knxMsgPayload.dpt = config.dptLightHSV_S_State
1443
+ if (config.dptLightHSV_S_State === '5.001') {
1444
+ knxMsgPayload.payload = hueColorConverter.ColorConverter.xyBrightnessToHsv(_value.xy.x, _value.xy.y, node.currentHUEDevice !== undefined && node.currentHUEDevice.dimming !== undefined && node.currentHUEDevice.dimming.brightness === undefined ? node.currentHUEDevice.dimming.brightness : 100, false)
1445
+ knxMsgPayload.payload = knxMsgPayload.payload.s
1449
1446
  }
1450
1447
  // Send to KNX bus
1451
- if (knxMsgPayload.topic !== "" && knxMsgPayload.topic !== undefined) {
1448
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
1452
1449
  if (node.serverKNX !== null && node.serverKNX !== undefined) {
1453
1450
  node.serverKNX.sendKNXTelegramToKNXEngine({
1454
1451
  grpaddr: knxMsgPayload.topic,
1455
1452
  payload: knxMsgPayload.payload,
1456
1453
  dpt: knxMsgPayload.dpt,
1457
- outputtype: _outputtype || "write",
1458
- nodecallerid: node.id,
1459
- });
1454
+ outputtype: _outputtype || 'write',
1455
+ nodecallerid: node.id
1456
+ })
1460
1457
  }
1461
1458
  }
1462
1459
  node.setNodeStatusHue({
1463
- fill: "blue",
1464
- shape: "ring",
1465
- text: "HUE->KNX HSV (S)",
1466
- payload: knxMsgPayload.payload,
1467
- });
1460
+ fill: 'blue',
1461
+ shape: 'ring',
1462
+ text: 'HUE->KNX HSV (S)',
1463
+ payload: knxMsgPayload.payload
1464
+ })
1468
1465
  }
1469
- if (config.GALightHSV_H_State !== undefined && config.GALightHSV_H_State !== "") {
1470
- const knxMsgPayload = {};
1471
- knxMsgPayload.topic = config.GALightHSV_H_State;
1472
- knxMsgPayload.dpt = config.dptLightHSV_H_State;
1473
- if (config.dptLightHSV_H_State === "5.001") {
1474
- knxMsgPayload.payload = hueColorConverter.ColorConverter.xyBrightnessToHsv(_value.xy.x, _value.xy.y, node.currentHUEDevice !== undefined && node.currentHUEDevice.dimming !== undefined && node.currentHUEDevice.dimming.brightness === undefined ? node.currentHUEDevice.dimming.brightness : 100, false);
1475
- knxMsgPayload.payload = 100 - knxMsgPayload.payload.h;
1466
+ if (config.GALightHSV_H_State !== undefined && config.GALightHSV_H_State !== '') {
1467
+ const knxMsgPayload = {}
1468
+ knxMsgPayload.topic = config.GALightHSV_H_State
1469
+ knxMsgPayload.dpt = config.dptLightHSV_H_State
1470
+ if (config.dptLightHSV_H_State === '5.001') {
1471
+ knxMsgPayload.payload = hueColorConverter.ColorConverter.xyBrightnessToHsv(_value.xy.x, _value.xy.y, node.currentHUEDevice !== undefined && node.currentHUEDevice.dimming !== undefined && node.currentHUEDevice.dimming.brightness === undefined ? node.currentHUEDevice.dimming.brightness : 100, false)
1472
+ knxMsgPayload.payload = 100 - knxMsgPayload.payload.h
1476
1473
  }
1477
1474
  // Send to KNX bus
1478
- if (knxMsgPayload.topic !== "" && knxMsgPayload.topic !== undefined) {
1475
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
1479
1476
  if (node.serverKNX !== null && node.serverKNX !== undefined) {
1480
1477
  node.serverKNX.sendKNXTelegramToKNXEngine({
1481
1478
  grpaddr: knxMsgPayload.topic,
1482
1479
  payload: knxMsgPayload.payload,
1483
1480
  dpt: knxMsgPayload.dpt,
1484
- outputtype: _outputtype || "write",
1485
- nodecallerid: node.id,
1486
- });
1481
+ outputtype: _outputtype || 'write',
1482
+ nodecallerid: node.id
1483
+ })
1487
1484
  }
1488
1485
  }
1489
1486
  node.setNodeStatusHue({
1490
- fill: "blue",
1491
- shape: "ring",
1492
- text: "HUE->KNX HSV (H)",
1493
- payload: knxMsgPayload.payload,
1494
- });
1487
+ fill: 'blue',
1488
+ shape: 'ring',
1489
+ text: 'HUE->KNX HSV (H)',
1490
+ payload: knxMsgPayload.payload
1491
+ })
1495
1492
  }
1496
- };
1497
-
1498
- node.updateKNXLightKelvinState = function updateKNXLightKelvinState(_value, _outputtype = "write") {
1499
- if (config.GALightKelvinState !== undefined && config.GALightKelvinState !== "") {
1500
- const knxMsgPayload = {};
1501
- let kelvinValue = 0;
1502
- knxMsgPayload.topic = config.GALightKelvinState;
1503
- knxMsgPayload.dpt = config.dptLightKelvinState;
1504
- if (config.dptLightKelvinState === "7.600") {
1505
- knxMsgPayload.payload = hueColorConverter.ColorConverter.mirekToKelvin(_value);
1506
- //knxMsgPayload.payload = hueColorConverter.ColorConverter.scale(kelvinValue, [2000, 6535], [0, 65535]);
1507
- } else if (config.dptLightKelvinState === "9.002") {
1508
- knxMsgPayload.payload = hueColorConverter.ColorConverter.mirekToKelvin(_value);
1493
+ }
1494
+
1495
+ node.updateKNXLightKelvinState = function updateKNXLightKelvinState (_value, _outputtype = 'write') {
1496
+ if (config.GALightKelvinState !== undefined && config.GALightKelvinState !== '') {
1497
+ const knxMsgPayload = {}
1498
+ const kelvinValue = 0
1499
+ knxMsgPayload.topic = config.GALightKelvinState
1500
+ knxMsgPayload.dpt = config.dptLightKelvinState
1501
+ if (config.dptLightKelvinState === '7.600') {
1502
+ knxMsgPayload.payload = hueColorConverter.ColorConverter.mirekToKelvin(_value)
1503
+ // knxMsgPayload.payload = hueColorConverter.ColorConverter.scale(kelvinValue, [2000, 6535], [0, 65535]);
1504
+ } else if (config.dptLightKelvinState === '9.002') {
1505
+ knxMsgPayload.payload = hueColorConverter.ColorConverter.mirekToKelvin(_value)
1509
1506
  }
1510
1507
  // Send to KNX bus
1511
- if (knxMsgPayload.topic !== "" && knxMsgPayload.topic !== undefined) {
1508
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
1512
1509
  if (node.serverKNX !== null && node.serverKNX !== undefined) {
1513
1510
  node.serverKNX.sendKNXTelegramToKNXEngine({
1514
1511
  grpaddr: knxMsgPayload.topic,
1515
1512
  payload: knxMsgPayload.payload,
1516
1513
  dpt: knxMsgPayload.dpt,
1517
1514
  outputtype: _outputtype,
1518
- nodecallerid: node.id,
1519
- });
1515
+ nodecallerid: node.id
1516
+ })
1520
1517
  }
1521
1518
 
1522
1519
  node.setNodeStatusHue({
1523
- fill: "blue",
1524
- shape: "ring",
1525
- text: "HUE->KNX Kelvin",
1526
- payload: knxMsgPayload.payload,
1527
- });
1520
+ fill: 'blue',
1521
+ shape: 'ring',
1522
+ text: 'HUE->KNX Kelvin',
1523
+ payload: knxMsgPayload.payload
1524
+ })
1528
1525
  }
1529
1526
  }
1530
- };
1527
+ }
1531
1528
 
1532
1529
  // On each deploy, unsubscribe+resubscribe
1533
1530
  if (node.serverKNX) {
1534
- node.serverKNX.removeClient(node);
1535
- node.serverKNX.addClient(node);
1531
+ node.serverKNX.removeClient(node)
1532
+ node.serverKNX.addClient(node)
1536
1533
  }
1537
1534
  if (node.serverHue) {
1538
1535
  try {
1539
- node.serverHue.removeClient(node);
1540
- node.serverHue.addClient(node);
1536
+ node.serverHue.removeClient(node)
1537
+ node.serverHue.addClient(node)
1541
1538
  } catch (error) {
1542
- RED.log.error("knxUltimateHueLight: if (node.serverKNX): " + error.message);
1539
+ RED.log.error('knxUltimateHueLight: if (node.serverKNX): ' + error.message)
1543
1540
  }
1544
1541
  }
1545
1542
 
1546
1543
  node.on('input', (msg, send, done) => {
1547
1544
  try {
1548
- const state = RED.util.cloneMessage(msg);
1549
- node.writeHueState(state);
1545
+ const state = RED.util.cloneMessage(msg)
1546
+ node.writeHueState(state)
1550
1547
  node.setNodeStatusHue({
1551
- fill: "green",
1552
- shape: "dot",
1553
- text: "->HUE",
1554
- payload: "Flow msg.",
1555
- });
1548
+ fill: 'green',
1549
+ shape: 'dot',
1550
+ text: '->HUE',
1551
+ payload: 'Flow msg.'
1552
+ })
1556
1553
  } catch (error) {
1557
1554
  node.setNodeStatusHue({
1558
- fill: "red",
1559
- shape: "dot",
1560
- text: "->HUE",
1561
- payload: error.message,
1562
- });
1555
+ fill: 'red',
1556
+ shape: 'dot',
1557
+ text: '->HUE',
1558
+ payload: error.message
1559
+ })
1563
1560
  }
1564
1561
  // Once finished, call 'done'.
1565
1562
  // This call is wrapped in a check that 'done' exists
1566
1563
  // so the node will work in earlier versions of Node-RED (<1.0)
1567
1564
  if (done) {
1568
- done();
1565
+ done()
1569
1566
  }
1570
- });
1567
+ })
1571
1568
 
1572
- node.on("close", (done) => {
1569
+ node.on('close', (done) => {
1573
1570
  if (node.serverKNX) {
1574
- node.serverKNX.removeClient(node);
1571
+ node.serverKNX.removeClient(node)
1575
1572
  }
1576
1573
  if (node.serverHue) {
1577
- node.serverHue.removeClient(node);
1574
+ node.serverHue.removeClient(node)
1578
1575
  }
1579
- done();
1580
- });
1576
+ done()
1577
+ })
1581
1578
  }
1582
- RED.nodes.registerType("knxUltimateHueLight", knxUltimateHueLight);
1583
- };
1579
+ RED.nodes.registerType('knxUltimateHueLight', knxUltimateHueLight)
1580
+ }