node-red-contrib-knx-ultimate 2.2.19 → 2.2.21

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.
@@ -35,6 +35,30 @@ module.exports = function (RED) {
35
35
  node.isGrouped_light = config.hueDevice.split("#")[1] === "grouped_light";
36
36
  node.hueDevice = config.hueDevice.split("#")[0];
37
37
  node.initializingAtStart = (config.readStatusAtStartup === undefined || config.readStatusAtStartup === "yes");
38
+ config.specifySwitchOnBrightness === undefined ? "yes" : config.specifySwitchOnBrightness;
39
+ // Transform HEX in RGB and stringified json in json oblects.
40
+ if (config.colorAtSwitchOnDayTime.indexOf("#") !== -1) {
41
+ // Transform to rgb.
42
+ try {
43
+ config.colorAtSwitchOnDayTime = hueColorConverter.ColorConverter.hexRgb(config.colorAtSwitchOnDayTime.replace("#", ""));
44
+ } catch (error) {
45
+ config.colorAtSwitchOnDayTime = { red: 255, green: 255, blue: 255 };
46
+ }
47
+ } else {
48
+ config.colorAtSwitchOnDayTime = JSON.parse(config.colorAtSwitchOnDayTime);
49
+ }
50
+ // Same thing, but with night color
51
+ if (config.colorAtSwitchOnNightTime.indexOf("#") !== -1) {
52
+ // Transform to rgb.
53
+ try {
54
+ config.colorAtSwitchOnNightTime = hueColorConverter.ColorConverter.hexRgb(config.colorAtSwitchOnNightTime.replace("#", ""));
55
+ } catch (error) {
56
+ config.colorAtSwitchOnNightTime = { red: 12, green: 0, blue: 10 };
57
+ }
58
+ } else {
59
+ config.colorAtSwitchOnNightTime = JSON.parse(config.colorAtSwitchOnNightTime);
60
+ }
61
+
38
62
 
39
63
  // Used to call the status update from the config node.
40
64
  node.setNodeStatus = ({
@@ -71,42 +95,42 @@ module.exports = function (RED) {
71
95
  case config.GALightSwitch:
72
96
  msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightSwitch));
73
97
  if (msg.payload === true) {
74
- // The user selected specific color/brightness at switch on.
98
+ // Check wether the user selected specific color/brightness at switch on.
75
99
  let jColorChoosen = null;
76
- if (node.DayTime === true && (config.specifySwitchOnBrightness === undefined || config.specifySwitchOnBrightness === "yes")) {
77
- try {
78
- jColorChoosen = JSON.parse(config.colorAtSwitchOnDayTime);
79
- if (jColorChoosen.green === undefined) jColorChoosen.green = jColorChoosen.hasOwnProperty("geen") ? jColorChoosen.geen : jColorChoosen.green;
80
- } catch (error) {
81
- jColorChoosen = { red: 255, green: 255, blue: 255 };
82
- }
83
- } else if (node.DayTime === false && config.enableDayNightLighting === "yes") {
84
- try {
85
- jColorChoosen = JSON.parse(config.colorAtSwitchOnNightTime);
86
- } catch (error) {
87
- jColorChoosen = { red: 10, green: 10, blue: 10 };
88
- }
100
+ if (node.DayTime === true && (config.specifySwitchOnBrightness === "yes" || config.specifySwitchOnBrightness === "temperature")) {
101
+ jColorChoosen = config.colorAtSwitchOnDayTime;
102
+ } else if (node.DayTime === false && (config.enableDayNightLighting === "yes" || config.enableDayNightLighting === "temperature")) {
103
+ jColorChoosen = config.colorAtSwitchOnNightTime;
89
104
  }
90
- if (jColorChoosen !== null) {
105
+
106
+ // Now we have a jColorChoosen. Proceed illuminating the light
107
+ if (jColorChoosen !== null && jColorChoosen.kelvin === undefined) {
108
+ // RGB
91
109
  let gamut = null;
92
- if (
93
- node.currentHUEDevice !== undefined
94
- && node.currentHUEDevice.hasOwnProperty("color")
95
- && node.currentHUEDevice.color.hasOwnProperty("gamut_type")
96
- ) {
110
+ if (node.currentHUEDevice !== undefined && node.currentHUEDevice.hasOwnProperty("color") && node.currentHUEDevice.color.hasOwnProperty("gamut_type")) {
97
111
  gamut = node.currentHUEDevice.color.gamut_type;
98
112
  }
99
113
  const dretXY = hueColorConverter.ColorConverter.rgbToXy(jColorChoosen.red, jColorChoosen.green, jColorChoosen.blue, gamut);
100
- const dbright = hueColorConverter.ColorConverter.getBrightnessFromRGB(jColorChoosen.red, jColorChoosen.green, jColorChoosen.blue);
101
- node.currentHUEDevice.dimming.brightness = dbright;
114
+ const dbright = hueColorConverter.ColorConverter.getBrightnessFromRGBOrHex(jColorChoosen.red, jColorChoosen.green, jColorChoosen.blue);
115
+ node.currentHUEDevice.dimming.brightness = Math.round(dbright, 0);
102
116
  node.updateKNXBrightnessState(node.currentHUEDevice.dimming.brightness);
103
117
  state = dbright > 0 ? { on: { on: true }, dimming: { brightness: dbright }, color: { xy: dretXY } } : { on: { on: false } };
104
- } else {
118
+ } if (jColorChoosen !== null && jColorChoosen.kelvin !== undefined) {
119
+ // Kelvin
120
+ const dbright = jColorChoosen.brightness;
121
+ const mirek = hueColorConverter.ColorConverter.kelvinToMirek(jColorChoosen.kelvin);
122
+ node.currentHUEDevice.color_temperature.mirek = mirek;
123
+ node.currentHUEDevice.dimming.brightness = dbright;
124
+ node.updateKNXBrightnessState(node.currentHUEDevice.dimming.brightness);
125
+ // Kelvin temp
126
+ state = dbright > 0 ? { on: { on: true }, dimming: { brightness: dbright }, color_temperature: { mirek: mirek } } : { on: { on: false } };
127
+ } else if (jColorChoosen === null || jColorChoosen === undefined) {
105
128
  state = { on: { on: true } };
106
129
  }
107
130
  } else {
108
131
  state = { on: { on: false } };
109
132
  }
133
+
110
134
  node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, state, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
111
135
  node.setNodeStatusHue({
112
136
  fill: "green",
@@ -125,30 +149,37 @@ module.exports = function (RED) {
125
149
  });
126
150
  break;
127
151
  case config.GALightKelvin:
152
+ let retMirek;
128
153
  msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightKelvin));
129
- let retMirek = hueColorConverter.ColorConverter.scale(msg.payload, [0, 65535], [153, 500]);
154
+ if (config.dptLightKelvin === "7.600") {
155
+ if (msg.payload > 65535) msg.payload = 65535;
156
+ if (msg.payload < 0) msg.payload = 0;
157
+ retMirek = hueColorConverter.ColorConverter.scale(msg.payload, [0, 65535], [500, 153]);
158
+ } else if (config.dptLightKelvin === "9.002") {
159
+ // Relative temperature in Kelvin. Use HUE scale.
160
+ if (msg.payload > 6535) msg.payload = 6535;
161
+ if (msg.payload < 2000) msg.payload = 2000;
162
+ retMirek = hueColorConverter.ColorConverter.scale(msg.payload, [2000, 6535], [500, 153]);
163
+ }
130
164
  state = { color_temperature: { mirek: retMirek } };
131
165
  node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, state, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
132
166
  node.setNodeStatusHue({
133
167
  fill: "green",
134
168
  shape: "dot",
135
169
  text: "KNX->HUE",
136
- payload: state,
170
+ payload: msg.payload,
137
171
  });
138
172
  break;
139
173
  case config.GADaylightSensor:
140
- if (config.enableDayNightLighting === "yes") {
141
- node.DayTime = Boolean(dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptDaylightSensor)));
142
- if (config.invertDayNight !== undefined && config.invertDayNight === true) node.DayTime = !node.DayTime;
143
- node.setNodeStatusHue({
144
- fill: "green",
145
- shape: "dot",
146
- text: "KNX->HUE Daytime",
147
- payload: node.DayTime,
148
- });
149
- } else {
150
- node.DayTime = true;
151
- }
174
+ node.DayTime = Boolean(dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptDaylightSensor)));
175
+ if (config.invertDayNight !== undefined && config.invertDayNight === true) node.DayTime = !node.DayTime;
176
+ node.setNodeStatusHue({
177
+ fill: "green",
178
+ shape: "dot",
179
+ text: "KNX->HUE Daytime",
180
+ payload: node.DayTime,
181
+ });
182
+
152
183
  break;
153
184
  case config.GALightHSV:
154
185
  if (config.dptLightHSV === "3.007") {
@@ -209,7 +240,7 @@ module.exports = function (RED) {
209
240
  gamut = node.currentHUEDevice.color.gamut_type;
210
241
  }
211
242
  const retXY = hueColorConverter.ColorConverter.rgbToXy(msg.payload.red, msg.payload.green, msg.payload.blue, gamut);
212
- const bright = hueColorConverter.ColorConverter.getBrightnessFromRGB(msg.payload.red, msg.payload.green, msg.payload.blue);
243
+ const bright = hueColorConverter.ColorConverter.getBrightnessFromRGBOrHex(msg.payload.red, msg.payload.green, msg.payload.blue);
213
244
  // state = bright > 0 ? { on: { on: true }, dimming: { brightness: bright }, color: { xy: retXY } } : { on: { on: false } }
214
245
  state = { dimming: { brightness: bright }, color: { xy: retXY } };
215
246
  if (node.currentHUEDevice === undefined) {
@@ -276,7 +307,7 @@ module.exports = function (RED) {
276
307
  gamut = node.currentHUEDevice.color.gamut_type;
277
308
  }
278
309
  const retXY = hueColorConverter.ColorConverter.rgbToXy(red, green, blue, gamut);
279
- const bright = hueColorConverter.ColorConverter.getBrightnessFromRGB(red, green, blue);
310
+ const bright = hueColorConverter.ColorConverter.getBrightnessFromRGBOrHex(red, green, blue);
280
311
  state = bright > 0 ? { on: { on: true }, dimming: { brightness: bright }, color: { xy: retXY } } : { on: { on: false } };
281
312
  node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, state, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
282
313
  } catch (error) { }
@@ -604,17 +635,20 @@ module.exports = function (RED) {
604
635
  knxMsgPayload.topic = config.GALightKelvinState;
605
636
  knxMsgPayload.dpt = config.dptLightKelvinState;
606
637
  if (config.dptLightKelvinState === "7.600") {
607
- knxMsgPayload.payload = hueColorConverter.ColorConverter.scale(_value, [153, 500], [0, 65535]);
608
- // Send to KNX bus
609
- if (knxMsgPayload.topic !== "" && knxMsgPayload.topic !== undefined) {
610
- node.server.writeQueueAdd({
611
- grpaddr: knxMsgPayload.topic,
612
- payload: knxMsgPayload.payload,
613
- dpt: knxMsgPayload.dpt,
614
- outputtype: "write",
615
- nodecallerid: node.id,
616
- });
617
- }
638
+ knxMsgPayload.payload = hueColorConverter.ColorConverter.scale(_value, [153, 500], [65535, 0]);
639
+ } else if (config.dptLightKelvinState === "9.002") {
640
+ knxMsgPayload.payload = hueColorConverter.ColorConverter.scale(_value, [153, 500], [6535, 2000]);
641
+ }
642
+ // Send to KNX bus
643
+ if (knxMsgPayload.topic !== "" && knxMsgPayload.topic !== undefined) {
644
+ node.server.writeQueueAdd({
645
+ grpaddr: knxMsgPayload.topic,
646
+ payload: knxMsgPayload.payload,
647
+ dpt: knxMsgPayload.dpt,
648
+ outputtype: "write",
649
+ nodecallerid: node.id,
650
+ });
651
+
618
652
  node.setNodeStatusHue({
619
653
  fill: "blue",
620
654
  shape: "ring",
@@ -1,3 +1,5 @@
1
+ <script type="text/javascript" src="resources/node-red-contrib-knx-ultimate/11f26b4500.js"></script>
2
+
1
3
  <script type="text/javascript">
2
4
  RED.nodes.registerType('knxUltimateHueLightSensor', {
3
5
  category: "KNX Ultimate",
@@ -228,7 +230,7 @@
228
230
 
229
231
 
230
232
  </script>
231
- <script src="resources/node-red-contrib-knx-ultimate/11f26b4500.js"></script>
233
+
232
234
 
233
235
  <script type="text/markdown" data-help-name="knxUltimateHueLightSensor">
234
236
  This node lets you get the events from your HUE motion device.
@@ -1,3 +1,5 @@
1
+ <script type="text/javascript" src="resources/node-red-contrib-knx-ultimate/11f26b4500.js"></script>
2
+
1
3
  <script type="text/javascript">
2
4
  RED.nodes.registerType('knxUltimateHueMotion', {
3
5
  category: "KNX Ultimate",
@@ -217,7 +219,6 @@
217
219
 
218
220
 
219
221
  </script>
220
- <script src="resources/node-red-contrib-knx-ultimate/11f26b4500.js"></script>
221
222
 
222
223
  <script type="text/markdown" data-help-name="knxUltimateHueMotion">
223
224
  This node lets you get the events from your HUE motion device.
@@ -1,3 +1,5 @@
1
+ <script type="text/javascript" src="resources/node-red-contrib-knx-ultimate/11f26b4500.js"></script>
2
+
1
3
  <script type="text/javascript">
2
4
  RED.nodes.registerType('knxUltimateHueScene', {
3
5
  category: "KNX Ultimate",
@@ -283,7 +285,6 @@
283
285
 
284
286
 
285
287
  </script>
286
- <script src="resources/node-red-contrib-knx-ultimate/11f26b4500.js"></script>
287
288
 
288
289
  <script type="text/markdown" data-help-name="knxUltimateHueScene">
289
290
  This node lets you recall a HUE scene, via KNX.
@@ -1,3 +1,5 @@
1
+ <script type="text/javascript" src="resources/node-red-contrib-knx-ultimate/11f26b4500.js"></script>
2
+
1
3
  <script type="text/javascript">
2
4
  RED.nodes.registerType('knxUltimateHueTapDial', {
3
5
  category: "KNX Ultimate",
@@ -219,7 +221,6 @@
219
221
 
220
222
 
221
223
  </script>
222
- <script src="resources/node-red-contrib-knx-ultimate/11f26b4500.js"></script>
223
224
 
224
225
  <script type="text/markdown" data-help-name="knxUltimateHueTapDial">
225
226
  This node lets you get the events from your HUE rotary device, for example the Tap Dial.
@@ -1,3 +1,5 @@
1
+ <script type="text/javascript" src="resources/node-red-contrib-knx-ultimate/11f26b4500.js"></script>
2
+
1
3
  <script type="text/javascript">
2
4
  RED.nodes.registerType('knxUltimateHueTemperatureSensor', {
3
5
  category: "KNX Ultimate",
@@ -227,7 +229,6 @@
227
229
 
228
230
 
229
231
  </script>
230
- <script src="resources/node-red-contrib-knx-ultimate/11f26b4500.js"></script>
231
232
 
232
233
  <script type="text/markdown" data-help-name="knxUltimateHueTemperatureSensor" This node lets you get the events from
233
234
  your HUE temperature device. Here you can get the HUE temperature events, that represents a celsius value, evetytime
@@ -1,7 +1,165 @@
1
- const convert = require('color-convert');
2
-
1
+ // Part of this code, thanks to https://github.com/Shnoo/js-CIE-1931-rgb-color-converter
3
2
  class ColorConverter {
3
+ // static getBrightnessFromRGBOrHex(red, green, blue) {
4
+ // const hsv = convert.rgb.hsv(red, green, blue);
5
+ // const brightness = hsv[2];
6
+ // return brightness;
7
+ // }
8
+
9
+
10
+ static getBrightnessFromRGBOrHex(Rint, Gint, Bint) { // takes sRGB channels as 8 bit integers
11
+
12
+ var Rlin = (Rint / 255.0) ** 2.218; // Convert int to decimal 0-1 and linearize
13
+ var Glin = (Gint / 255.0) ** 2.218; // ** is the exponentiation operator, older JS needs Math.pow() instead
14
+ var Blin = (Bint / 255.0) ** 2.218; // 2.218 Gamma for sRGB linearization. 2.218 sets unity with the piecewise sRGB at #777 .... 2.2 or 2.223 could be used instead
15
+
16
+ var Ylum = Rlin * 0.2126 + Glin * 0.7156 + Blin * 0.0722; // convert to Luminance Y
17
+
18
+ return Math.pow(Ylum, 0.43) * 100; // Convert to lightness (0 to 100)
19
+ }
20
+
21
+ static convert_1_255_ToPercentage(number) {
22
+ const percentage = (number / 255) * 100;
23
+ return percentage;
24
+ }
25
+
26
+ static kelvinToMirek(_kelvin) {
27
+ return Math.round(1000000 / _kelvin, 0);
28
+ }
29
+
30
+ static mirekToKelvin(_mirek) {
31
+ return Math.round(1000000 / _mirek, 0);
32
+ }
33
+
34
+ // Linear interpolation of input y given starting and ending ranges
35
+ static scale(y, range1 = [0, 100], range2 = [0, 255]) {
36
+ const [xMin, xMax] = range2;
37
+ const [yMin, yMax] = range1;
38
+ const percent = (y - yMin) / (yMax - yMin);
39
+ const ans = percent * (xMax - xMin) + xMin;
40
+ return Math.round(ans);
41
+ }
42
+
43
+ // Thanks to: https://github.com/sindresorhus/rgb-hex
44
+ static rgbHex(red, green, blue, alpha) {
45
+ const toHex = (red, green, blue, alpha) => ((blue | green << 8 | red << 16) | 1 << 24).toString(16).slice(1) + alpha;
46
+ const parseCssRgbString = (input) => {
47
+ const parts = input.replace(/rgba?\(([^)]+)\)/, '$1').split(/[,\s/]+/).filter(Boolean);
48
+ if (parts.length < 3) {
49
+ return;
50
+ }
51
+
52
+ const parseValue = (value, max) => {
53
+ value = value.trim();
54
+
55
+ if (value.endsWith('%')) {
56
+ return Math.min(Number.parseFloat(value) * max / 100, max);
57
+ }
58
+
59
+ return Math.min(Number.parseFloat(value), max);
60
+ };
61
+
62
+ const red = parseValue(parts[0], 255);
63
+ const green = parseValue(parts[1], 255);
64
+ const blue = parseValue(parts[2], 255);
65
+ let alpha;
66
+
67
+ if (parts.length === 4) {
68
+ alpha = parseValue(parts[3], 1);
69
+ }
70
+
71
+ return [red, green, blue, alpha];
72
+ };
73
+
74
+ let isPercent = (red + (alpha || '')).toString().includes('%');
75
+
76
+ if (typeof red === 'string' && !green) { // Single string parameter.
77
+ const parsed = parseCssRgbString(red);
78
+ if (!parsed) {
79
+ throw new TypeError('Invalid or unsupported color format.');
80
+ }
81
+
82
+ isPercent = false;
83
+ [red, green, blue, alpha] = parsed;
84
+ } else if (alpha !== undefined) {
85
+ alpha = Number.parseFloat(alpha);
86
+ }
4
87
 
88
+ if (typeof red !== 'number'
89
+ || typeof green !== 'number'
90
+ || typeof blue !== 'number'
91
+ || red > 255
92
+ || green > 255
93
+ || blue > 255
94
+ ) {
95
+ throw new TypeError('Expected three numbers below 256');
96
+ }
97
+
98
+ if (typeof alpha === 'number') {
99
+ if (!isPercent && alpha >= 0 && alpha <= 1) {
100
+ alpha = Math.round(255 * alpha);
101
+ } else if (isPercent && alpha >= 0 && alpha <= 100) {
102
+ alpha = Math.round(255 * alpha / 100);
103
+ } else {
104
+ throw new TypeError(`Expected alpha value (${alpha}) as a fraction or percentage`);
105
+ }
106
+
107
+ alpha = (alpha | 1 << 8).toString(16).slice(1); // eslint-disable-line no-mixed-operators
108
+ } else {
109
+ alpha = '';
110
+ }
111
+
112
+ return toHex(red, green, blue, alpha);
113
+ }
114
+
115
+ // Thanks to: https://github.com/sindresorhus/hex-rgb
116
+ static hexRgb(hex, options = {}) {
117
+ const hexCharacters = 'a-f\\d';
118
+ const match3or4Hex = `#?[${hexCharacters}]{3}[${hexCharacters}]?`;
119
+ const match6or8Hex = `#?[${hexCharacters}]{6}([${hexCharacters}]{2})?`;
120
+ const nonHexChars = new RegExp(`[^#${hexCharacters}]`, 'gi');
121
+ const validHexSize = new RegExp(`^${match3or4Hex}$|^${match6or8Hex}$`, 'i');
122
+
123
+ if (typeof hex !== 'string' || nonHexChars.test(hex) || !validHexSize.test(hex)) {
124
+ throw new TypeError('Expected a valid hex string');
125
+ }
126
+
127
+ hex = hex.replace(/^#/, '');
128
+ let alphaFromHex = 1;
129
+
130
+ if (hex.length === 8) {
131
+ alphaFromHex = Number.parseInt(hex.slice(6, 8), 16) / 255;
132
+ hex = hex.slice(0, 6);
133
+ }
134
+
135
+ if (hex.length === 4) {
136
+ alphaFromHex = Number.parseInt(hex.slice(3, 4).repeat(2), 16) / 255;
137
+ hex = hex.slice(0, 3);
138
+ }
139
+
140
+ if (hex.length === 3) {
141
+ hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
142
+ }
143
+
144
+ const number = Number.parseInt(hex, 16);
145
+ const red = number >> 16;
146
+ const green = (number >> 8) & 255;
147
+ const blue = number & 255;
148
+ const alpha = typeof options.alpha === 'number' ? options.alpha : alphaFromHex;
149
+
150
+ if (options.format === 'array') {
151
+ return [red, green, blue, alpha];
152
+ }
153
+
154
+ if (options.format === 'css') {
155
+ const alphaString = alpha === 1 ? '' : ` / ${Number((alpha * 100).toFixed(2))}%`;
156
+ return `rgb(${red} ${green} ${blue}${alphaString})`;
157
+ }
158
+
159
+ return {
160
+ red, green, blue, alpha,
161
+ };
162
+ }
5
163
 
6
164
  static getGamutRanges() {
7
165
  const gamutA = {
@@ -33,31 +191,52 @@ class ColorConverter {
33
191
  };
34
192
  }
35
193
 
36
- static getLightColorGamutRange(gamutTypeABC = null) {
194
+ static getLightColorGamutRange(modelId = null) {
37
195
  const ranges = ColorConverter.getGamutRanges();
38
196
  const { gamutA } = ranges;
39
197
  const { gamutB } = ranges;
40
198
  const { gamutC } = ranges;
41
199
 
42
200
  const philipsModels = {
43
- A: gamutA,
44
- B: gamutB,
45
- C: gamutC,
201
+ LST001: gamutA,
202
+ LLC010: gamutA,
203
+ LLC011: gamutA,
204
+ LLC012: gamutA,
205
+ LLC006: gamutA,
206
+ LLC005: gamutA,
207
+ LLC007: gamutA,
208
+ LLC014: gamutA,
209
+ LLC013: gamutA,
210
+
211
+ LCT001: gamutB,
212
+ LCT007: gamutB,
213
+ LCT002: gamutB,
214
+ LCT003: gamutB,
215
+ LLM001: gamutB,
216
+
217
+ LCT010: gamutC,
218
+ LCT014: gamutC,
219
+ LCT015: gamutC,
220
+ LCT016: gamutC,
221
+ LCT011: gamutC,
222
+ LLC020: gamutC,
223
+ LST002: gamutC,
224
+ LCT012: gamutC,
46
225
  };
47
226
 
48
- if (philipsModels[gamutTypeABC]) {
49
- return philipsModels[gamutTypeABC];
227
+ if (philipsModels[modelId]) {
228
+ return philipsModels[modelId];
50
229
  }
51
230
 
52
231
  return ranges.default;
53
232
  }
54
233
 
55
- static rgbToXy(red, green, blue, gamutTypeABC = null) {
234
+ static rgbToXy(red, green, blue, modelId = null) {
56
235
  function getGammaCorrectedValue(value) {
57
236
  return (value > 0.04045) ? ((value + 0.055) / (1.0 + 0.055)) ** 2.4 : (value / 12.92);
58
237
  }
59
238
 
60
- const colorGamut = ColorConverter.getLightColorGamutRange(gamutTypeABC);
239
+ const colorGamut = ColorConverter.getLightColorGamutRange(modelId);
61
240
 
62
241
  red = parseFloat(red / 255);
63
242
  green = parseFloat(green / 255);
@@ -83,17 +262,6 @@ class ColorConverter {
83
262
  return xy;
84
263
  }
85
264
 
86
- static getBrightnessFromRGB(red, green, blue) {
87
- const hsv = convert.rgb.hsv(red, green, blue);
88
- const brightness = hsv[2];
89
- return brightness;
90
- }
91
-
92
- static convert_1_255_ToPercentage(number) {
93
- const percentage = (number / 255) * 100;
94
- return percentage;
95
- }
96
-
97
265
  static xyIsInGamutRange(xy, gamut) {
98
266
  gamut = gamut || ColorConverter.getGamutRanges().gamutC;
99
267
  if (Array.isArray(xy)) {
@@ -211,9 +379,9 @@ class ColorConverter {
211
379
  const Y = bri / 255;
212
380
  const X = (Y / y) * x;
213
381
  const Z = (Y / y) * z;
214
- let r = X * 1.612 - Y * 0.203 - Z * 0.302;
215
- let g = -X * 0.509 + Y * 1.412 + Z * 0.066;
216
- let b = X * 0.026 - Y * 0.072 + Z * 0.962;
382
+ let r = X * 1.656492 - Y * 0.354851 - Z * 0.255038;
383
+ let g = -X * 0.707196 + Y * 1.655397 + Z * 0.036152;
384
+ let b = X * 0.051713 - Y * 0.121364 + Z * 1.011530;
217
385
 
218
386
  r = getReversedGammaCorrectedValue(r);
219
387
  g = getReversedGammaCorrectedValue(g);
@@ -233,19 +401,10 @@ class ColorConverter {
233
401
  }
234
402
 
235
403
  return {
236
- red: Math.floor(r * 255),
237
- green: Math.floor(g * 255),
238
- blue: Math.floor(b * 255),
404
+ r: Math.floor(r * 255),
405
+ g: Math.floor(g * 255),
406
+ b: Math.floor(b * 255),
239
407
  };
240
408
  }
241
-
242
- // Linear interpolation of input y given starting and ending ranges
243
- static scale(y, range1 = [0, 100], range2 = [0, 255]) {
244
- const [xMin, xMax] = range2;
245
- const [yMin, yMax] = range1;
246
- const percent = (y - yMin) / (yMax - yMin);
247
- const ans = percent * (xMax - xMin) + xMin;
248
- return Math.round(ans);
249
- }
250
409
  }
251
410
  exports.ColorConverter = ColorConverter;
package/package.json CHANGED
@@ -3,11 +3,10 @@
3
3
  "engines": {
4
4
  "node": ">=16.0.0"
5
5
  },
6
- "version": "2.2.19",
6
+ "version": "2.2.21",
7
7
  "description": "Control your KNX intallation via Node-Red! Single Node KNX IN/OUT with optional ETS group address importer. Easy to use and highly configurable. With integrated Philips HUE devices control.",
8
8
  "dependencies": {
9
9
  "binary-parser": "2.2.1",
10
- "color-convert": "2.0.1",
11
10
  "crypto-js": "4.2.0",
12
11
  "dns-sync": "0.2.1",
13
12
  "eventsource": "2.0.2",