zigbee-herdsman-converters 14.0.689 → 14.0.690
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/devices/ctm.js +59 -12
- package/devices/ikea.js +1 -1
- package/devices/osram.js +40 -0
- package/devices/philips.js +5 -3
- package/devices/tuya.js +15 -5
- package/lib/philips.js +95 -36
- package/package.json +1 -1
package/devices/ctm.js
CHANGED
|
@@ -19,6 +19,19 @@ const dataType = {
|
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
const fzLocal = {
|
|
22
|
+
ctm_mbd_device_enabled: {
|
|
23
|
+
cluster: 'genOnOff',
|
|
24
|
+
type: ['attributeReport', 'readResponse'],
|
|
25
|
+
convert: (model, msg, publish, options, meta) => {
|
|
26
|
+
const result = {};
|
|
27
|
+
const data = msg.data;
|
|
28
|
+
if (data.hasOwnProperty('onOff')) {
|
|
29
|
+
result.device_enabled = data['onOff'] ? 'ON' : 'OFF';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return result;
|
|
33
|
+
},
|
|
34
|
+
},
|
|
22
35
|
ctm_device_mode: {
|
|
23
36
|
cluster: 'genOnOff',
|
|
24
37
|
type: ['attributeReport', 'readResponse'],
|
|
@@ -72,6 +85,19 @@ const fzLocal = {
|
|
|
72
85
|
return result;
|
|
73
86
|
},
|
|
74
87
|
},
|
|
88
|
+
ctm_relay_state: {
|
|
89
|
+
cluster: 'genOnOff',
|
|
90
|
+
type: ['attributeReport', 'readResponse'],
|
|
91
|
+
convert: (model, msg, publish, options, meta) => {
|
|
92
|
+
const result = {};
|
|
93
|
+
const data = msg.data;
|
|
94
|
+
if (data.hasOwnProperty(0x5001)) {
|
|
95
|
+
result.state = data[0x5001] ? 'ON' : 'OFF';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return result;
|
|
99
|
+
},
|
|
100
|
+
},
|
|
75
101
|
ctm_temperature_offset: {
|
|
76
102
|
cluster: 'msTemperatureMeasurement',
|
|
77
103
|
type: ['attributeReport', 'readResponse'],
|
|
@@ -281,6 +307,15 @@ const fzLocal = {
|
|
|
281
307
|
|
|
282
308
|
|
|
283
309
|
const tzLocal = {
|
|
310
|
+
ctm_mbd_device_enabled: {
|
|
311
|
+
key: ['device_enabled'],
|
|
312
|
+
convertSet: async (entity, key, value, meta) => {
|
|
313
|
+
await entity.command('genOnOff', value.toLowerCase(), {}, utils.getOptions(meta.mapped, entity));
|
|
314
|
+
},
|
|
315
|
+
convertGet: async (entity, key, meta) => {
|
|
316
|
+
await entity.read('genOnOff', ['onOff']);
|
|
317
|
+
},
|
|
318
|
+
},
|
|
284
319
|
ctm_device_mode: {
|
|
285
320
|
key: ['device_mode'],
|
|
286
321
|
convertGet: async (entity, key, meta) => {
|
|
@@ -308,6 +343,16 @@ const tzLocal = {
|
|
|
308
343
|
await entity.read('genOnOff', [0x5000], {manufacturerCode: 0x1337});
|
|
309
344
|
},
|
|
310
345
|
},
|
|
346
|
+
ctm_relay_state: {
|
|
347
|
+
key: ['state'],
|
|
348
|
+
convertSet: async (entity, key, value, meta) => {
|
|
349
|
+
await entity.write('genOnOff',
|
|
350
|
+
{0x5001: {value: {'OFF': 0, 'ON': 1}[value], type: dataType.boolean}}, {manufacturerCode: 0x1337});
|
|
351
|
+
},
|
|
352
|
+
convertGet: async (entity, key, meta) => {
|
|
353
|
+
await entity.read('genOnOff', [0x5001], {manufacturerCode: 0x1337});
|
|
354
|
+
},
|
|
355
|
+
},
|
|
311
356
|
ctm_temperature_offset: {
|
|
312
357
|
key: ['temperature_offset'],
|
|
313
358
|
convertSet: async (entity, key, value, meta) => {
|
|
@@ -728,7 +773,7 @@ module.exports = [
|
|
|
728
773
|
],
|
|
729
774
|
},
|
|
730
775
|
{
|
|
731
|
-
zigbeeModel: ['mStikk Outlet'],
|
|
776
|
+
zigbeeModel: ['mStikk Outlet', 'mStikk 16A', 'mStikk 25A', 'Tavlerele 25A'],
|
|
732
777
|
model: 'mStikk_Outlet',
|
|
733
778
|
vendor: 'CTM Lyng',
|
|
734
779
|
description: 'mStikk OP, wall socket',
|
|
@@ -834,7 +879,7 @@ module.exports = [
|
|
|
834
879
|
exposes.binary('child_lock', ea.STATE, 'locked', 'unlocked')
|
|
835
880
|
.withDescription('Physical input on the device enabled/disabled'),
|
|
836
881
|
exposes.numeric('group_id', ea.STATE)
|
|
837
|
-
.withDescription('The device sends commands with this group ID. Put
|
|
882
|
+
.withDescription('The device sends commands with this group ID. Put devices in this group to control them.'),
|
|
838
883
|
],
|
|
839
884
|
},
|
|
840
885
|
{
|
|
@@ -866,10 +911,12 @@ module.exports = [
|
|
|
866
911
|
meta: {disableDefaultResponse: true},
|
|
867
912
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
868
913
|
const endpoint = device.getEndpoint(1);
|
|
869
|
-
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff'
|
|
914
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
|
|
870
915
|
await endpoint.read('genOnOff', ['onOff']);
|
|
871
916
|
await reporting.onOff(endpoint);
|
|
872
|
-
|
|
917
|
+
const endpoint2 = device.getEndpoint(2);
|
|
918
|
+
await reporting.bind(endpoint2, coordinatorEndpoint, ['ssIasZone']);
|
|
919
|
+
await endpoint2.read('ssIasZone', ['iasCieAddr', 'zoneState', 'zoneId']);
|
|
873
920
|
},
|
|
874
921
|
exposes: [e.switch(), e.water_leak(),
|
|
875
922
|
exposes.binary('active_water_leak', ea.STATE, true, false)
|
|
@@ -897,7 +944,7 @@ module.exports = [
|
|
|
897
944
|
exposes: [e.temperature(), e.battery(), e.battery_low(), e.smoke(),
|
|
898
945
|
e.action(['on', 'off']),
|
|
899
946
|
exposes.numeric('group_id', ea.STATE)
|
|
900
|
-
.withDescription('The device sends commands with this group ID. Put
|
|
947
|
+
.withDescription('The device sends commands with this group ID. Put devices in this group to control them.'),
|
|
901
948
|
],
|
|
902
949
|
},
|
|
903
950
|
{
|
|
@@ -924,8 +971,8 @@ module.exports = [
|
|
|
924
971
|
model: 'MBD-S',
|
|
925
972
|
vendor: 'CTM Lyng',
|
|
926
973
|
description: 'MBD-S, motion detector with 16A relay',
|
|
927
|
-
fromZigbee: [fz.
|
|
928
|
-
toZigbee: [
|
|
974
|
+
fromZigbee: [fz.illuminance, fz.occupancy, fzLocal.ctm_mbd_device_enabled, fzLocal.ctm_relay_state],
|
|
975
|
+
toZigbee: [tzLocal.ctm_mbd_device_enabled, tzLocal.ctm_relay_state],
|
|
929
976
|
meta: {disableDefaultResponse: true},
|
|
930
977
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
931
978
|
const endpoint = device.getEndpoint(1);
|
|
@@ -936,13 +983,13 @@ module.exports = [
|
|
|
936
983
|
await reporting.illuminance(endpoint);
|
|
937
984
|
await endpoint.read('msOccupancySensing', ['occupancy']);
|
|
938
985
|
await reporting.occupancy(endpoint);
|
|
939
|
-
//
|
|
940
|
-
await endpoint.read('genOnOff', [
|
|
986
|
+
// Relay State
|
|
987
|
+
await endpoint.read('genOnOff', [0x5001], {manufacturerCode: 0x1337});
|
|
941
988
|
await endpoint.configureReporting('genOnOff', [{
|
|
942
|
-
attribute: {ID:
|
|
943
|
-
minimumReportInterval:
|
|
989
|
+
attribute: {ID: 0x5001, type: dataType.boolean},
|
|
990
|
+
minimumReportInterval: 1,
|
|
944
991
|
maximumReportInterval: constants.repInterval.HOUR,
|
|
945
|
-
reportableChange:
|
|
992
|
+
reportableChange: 0}], {manufacturerCode: 0x1337});
|
|
946
993
|
},
|
|
947
994
|
exposes: [e.switch(), e.illuminance(), e.illuminance_lux(), e.occupancy(),
|
|
948
995
|
exposes.binary('device_enabled', ea.ALL, 'ON', 'OFF')
|
package/devices/ikea.js
CHANGED
|
@@ -375,7 +375,7 @@ module.exports = [
|
|
|
375
375
|
extend: tradfriExtend.light_onoff_brightness_colortemp(),
|
|
376
376
|
},
|
|
377
377
|
{
|
|
378
|
-
zigbeeModel: ['TRADFRIbulbE26WSglobeclear800lm', 'TRADFRIbulbE27WSglobeclear806lm'],
|
|
378
|
+
zigbeeModel: ['TRADFRIbulbE26WSglobeclear800lm', 'TRADFRIbulbE27WSglobeclear806lm', 'TRADFRIbulbE26WSglobeclear806lm'],
|
|
379
379
|
model: 'LED2004G8',
|
|
380
380
|
vendor: 'IKEA',
|
|
381
381
|
description: 'TRADFRI LED bulb E26/E27 800/806 lumen, dimmable, white spectrum, clear',
|
package/devices/osram.js
CHANGED
|
@@ -3,8 +3,24 @@ const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/lega
|
|
|
3
3
|
const ota = require('../lib/ota');
|
|
4
4
|
const reporting = require('../lib/reporting');
|
|
5
5
|
const extend = require('../lib/extend');
|
|
6
|
+
const utils = require('../lib/utils');
|
|
6
7
|
const e = exposes.presets;
|
|
7
8
|
|
|
9
|
+
const fzLocal = {
|
|
10
|
+
pbc_level_to_action: {
|
|
11
|
+
cluster: 'genLevelCtrl',
|
|
12
|
+
type: ['commandMoveWithOnOff', 'commandStopWithOnOff', 'commandMove', 'commandStop', 'commandMoveToLevelWithOnOff'],
|
|
13
|
+
convert: (model, msg, publish, options, meta) => {
|
|
14
|
+
if (utils.hasAlreadyProcessedMessage(msg, model)) return;
|
|
15
|
+
const lookup = {
|
|
16
|
+
commandMoveWithOnOff: 'hold', commandMove: 'hold', commandStopWithOnOff: 'release',
|
|
17
|
+
commandStop: 'release', commandMoveToLevelWithOnOff: 'toggle',
|
|
18
|
+
};
|
|
19
|
+
return {[utils.postfixWithEndpointName('action', msg, model, meta)]: lookup[msg.type]};
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
8
24
|
module.exports = [
|
|
9
25
|
{
|
|
10
26
|
zigbeeModel: ['Gardenspot RGB'],
|
|
@@ -476,4 +492,28 @@ module.exports = [
|
|
|
476
492
|
extend: extend.ledvance.light_onoff_brightness_colortemp({colorTempRange: [153, 370]}),
|
|
477
493
|
ota: ota.ledvance,
|
|
478
494
|
},
|
|
495
|
+
{
|
|
496
|
+
zigbeeModel: ['PBC'],
|
|
497
|
+
model: '4052899930377',
|
|
498
|
+
vendor: 'OSRAM',
|
|
499
|
+
description: 'Lightify pro push button controller (PBC)',
|
|
500
|
+
meta: {multiEndpoint: true},
|
|
501
|
+
endpoint: (device) => {
|
|
502
|
+
return {'l1': 1, 'l2': 2, 'l3': 3, 'l4': 4};
|
|
503
|
+
},
|
|
504
|
+
fromZigbee: [fzLocal.pbc_level_to_action],
|
|
505
|
+
exposes: [
|
|
506
|
+
e.action(['hold', 'release', 'toggle']).withEndpoint('l1'),
|
|
507
|
+
e.action(['hold', 'release', 'toggle']).withEndpoint('l2'),
|
|
508
|
+
e.action(['hold', 'release', 'toggle']).withEndpoint('l3'),
|
|
509
|
+
e.action(['hold', 'release', 'toggle']).withEndpoint('l4'),
|
|
510
|
+
],
|
|
511
|
+
toZigbee: [],
|
|
512
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
513
|
+
await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genLevelCtrl']);
|
|
514
|
+
await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genLevelCtrl']);
|
|
515
|
+
await reporting.bind(device.getEndpoint(3), coordinatorEndpoint, ['genLevelCtrl']);
|
|
516
|
+
await reporting.bind(device.getEndpoint(4), coordinatorEndpoint, ['genLevelCtrl']);
|
|
517
|
+
},
|
|
518
|
+
},
|
|
479
519
|
];
|
package/devices/philips.js
CHANGED
|
@@ -112,10 +112,12 @@ const fzLocal = {
|
|
|
112
112
|
cluster: 'manuSpecificPhilips2',
|
|
113
113
|
type: ['attributeReport', 'readResponse'],
|
|
114
114
|
convert: (model, msg, publish, options, meta) => {
|
|
115
|
-
if (msg.data.hasOwnProperty('state')) {
|
|
115
|
+
if (msg.data && msg.data.hasOwnProperty('state')) {
|
|
116
116
|
const input = msg.data['state'].toString('hex');
|
|
117
|
-
const
|
|
118
|
-
|
|
117
|
+
const decoded = philips.decodeGradientColors(input, opts);
|
|
118
|
+
if (decoded.color_mode === 'gradient') {
|
|
119
|
+
return {gradient: decoded.colors};
|
|
120
|
+
}
|
|
119
121
|
}
|
|
120
122
|
return {};
|
|
121
123
|
},
|
package/devices/tuya.js
CHANGED
|
@@ -1134,9 +1134,9 @@ module.exports = [
|
|
|
1134
1134
|
model: 'IH012-RT01',
|
|
1135
1135
|
vendor: 'TuYa',
|
|
1136
1136
|
description: 'Motion sensor',
|
|
1137
|
-
fromZigbee: [fz.ias_occupancy_alarm_1, fz.ignore_basic_report, fz.ZM35HQ_attr],
|
|
1137
|
+
fromZigbee: [fz.ias_occupancy_alarm_1, fz.ignore_basic_report, fz.ZM35HQ_attr, fz.battery],
|
|
1138
1138
|
toZigbee: [tz.ZM35HQ_attr],
|
|
1139
|
-
exposes: [e.occupancy(), e.battery_low(), e.tamper(),
|
|
1139
|
+
exposes: [e.occupancy(), e.battery_low(), e.tamper(), e.battery(), e.battery_voltage(),
|
|
1140
1140
|
exposes.enum('sensitivity', ea.ALL, ['low', 'medium', 'high']).withDescription('PIR sensor sensitivity'),
|
|
1141
1141
|
exposes.enum('keep_time', ea.ALL, [30, 60, 120]).withDescription('PIR keep time in seconds'),
|
|
1142
1142
|
],
|
|
@@ -1840,8 +1840,9 @@ module.exports = [
|
|
|
1840
1840
|
endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 100, multiplier: 1});
|
|
1841
1841
|
device.save();
|
|
1842
1842
|
},
|
|
1843
|
-
whiteLabel: [{vendor: 'Aubess', model: '
|
|
1844
|
-
exposes: [e.switch(), e.power(), e.voltage().withAccess(ea.STATE), e.energy(), e.power_on_behavior(),
|
|
1843
|
+
whiteLabel: [{vendor: 'Aubess', model: 'WHD02'}],
|
|
1844
|
+
exposes: [e.switch(), e.power(), e.current(), e.voltage().withAccess(ea.STATE), e.energy(), e.power_on_behavior(),
|
|
1845
|
+
tuya.exposes.switchType()],
|
|
1845
1846
|
},
|
|
1846
1847
|
{
|
|
1847
1848
|
zigbeeModel: ['TS0001'],
|
|
@@ -2840,7 +2841,7 @@ module.exports = [
|
|
|
2840
2841
|
model: 'TS0014',
|
|
2841
2842
|
vendor: 'TuYa',
|
|
2842
2843
|
description: 'Smart light switch - 4 gang without neutral wire',
|
|
2843
|
-
extend: tuya.extend.switch({endpoints: ['l1', 'l2', 'l3', 'l4']}),
|
|
2844
|
+
extend: tuya.extend.switch({backlightMode: true, endpoints: ['l1', 'l2', 'l3', 'l4']}),
|
|
2844
2845
|
endpoint: (device) => {
|
|
2845
2846
|
return {'l1': 1, 'l2': 2, 'l3': 3, 'l4': 4};
|
|
2846
2847
|
},
|
|
@@ -2884,6 +2885,15 @@ module.exports = [
|
|
|
2884
2885
|
exposes: [e.action(['scene_1', 'scene_2', 'scene_3', 'scene_4', 'scene_5', 'scene_6'])],
|
|
2885
2886
|
toZigbee: [],
|
|
2886
2887
|
},
|
|
2888
|
+
{
|
|
2889
|
+
zigbeeModel: ['TS0026'],
|
|
2890
|
+
model: 'TS0026',
|
|
2891
|
+
vendor: 'TuYa',
|
|
2892
|
+
description: '6 button scene wall switch',
|
|
2893
|
+
fromZigbee: [fzLocal.scenes_recall_scene_65029],
|
|
2894
|
+
exposes: [e.action(['scene_1', 'scene_2', 'scene_3', 'scene_4', 'scene_5', 'scene_6'])],
|
|
2895
|
+
toZigbee: [],
|
|
2896
|
+
},
|
|
2887
2897
|
{
|
|
2888
2898
|
zigbeeModel: ['q9mpfhw'],
|
|
2889
2899
|
model: 'SNTZ009',
|
package/lib/philips.js
CHANGED
|
@@ -27,25 +27,45 @@ const decodeScaledGradientToRGB = (p) => {
|
|
|
27
27
|
return new ColorXY(xx, yy).toRGB().toHEX();
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
const COLOR_MODE_GRADIENT = '4b01';
|
|
31
|
+
const COLOR_MODE_COLOR_XY = '0b00';
|
|
32
|
+
const COLOR_MODE_COLOR_TEMP = '0f00';
|
|
33
33
|
|
|
34
|
+
// decoder for manuSpecificPhilips2.state
|
|
35
|
+
function decodeGradientColors(input, opts) {
|
|
36
|
+
// Gradient mode (4b01)
|
|
37
|
+
// Example: 4b010164fb74346b1350000000f3297fda7d55da7d55f3297fda7d552800
|
|
34
38
|
// 4b01 - mode? (4) (0b00 single color?, 4b01 gradient?)
|
|
35
|
-
// 01 - on/off (2)
|
|
39
|
+
// 01 - on/off (2)
|
|
36
40
|
// 64 - brightness (2)
|
|
37
|
-
// fb74346b - unknown (8)
|
|
41
|
+
// fb74346b - unknown (8) - Might be XY Color?
|
|
38
42
|
// 13 - length (2)
|
|
39
43
|
// 50 - ncolors (2)
|
|
40
44
|
// 000000 - unknown (6)
|
|
41
45
|
// f3297fda7d55da7d55f3297fda7d55 - colors (6 * ncolors)
|
|
42
46
|
// 28 - segments (2)
|
|
43
47
|
// 00 - offset (2)
|
|
44
|
-
|
|
45
|
-
//
|
|
48
|
+
//
|
|
49
|
+
// Temperature mode (0f00)
|
|
50
|
+
// Example: 0f0000044d01ab6f7067
|
|
51
|
+
// 0f00 - mode (4)
|
|
52
|
+
// 01 - on/off (2)
|
|
53
|
+
// 1a - brightness (2)
|
|
54
|
+
// 4d01 - color temperature (4)
|
|
55
|
+
// ab6f7067 - unknown (8)
|
|
56
|
+
//
|
|
57
|
+
// XY Color mode (0b00)
|
|
58
|
+
// Example: 0b00010460b09c4e
|
|
59
|
+
// 0b00 - mode (4) == 0b00 single color mode
|
|
60
|
+
// 01 - on/off (2)
|
|
61
|
+
// 04 - brightness (2)
|
|
62
|
+
// 60b09c4e - color (8) (xLow, xHigh, yLow, yHigh)
|
|
63
|
+
|
|
64
|
+
// Device color mode
|
|
65
|
+
const mode = input.slice(0, 4);
|
|
46
66
|
input = input.slice(4);
|
|
47
67
|
|
|
48
|
-
// On/off (
|
|
68
|
+
// On/off (2 bytes)
|
|
49
69
|
const on = parseInt(input.slice(0, 2), 16) === 1;
|
|
50
70
|
input = input.slice(2);
|
|
51
71
|
|
|
@@ -53,46 +73,85 @@ function decodeGradientColors(input, opts) {
|
|
|
53
73
|
const brightness = parseInt(input.slice(0, 2), 16);
|
|
54
74
|
input = input.slice(2);
|
|
55
75
|
|
|
56
|
-
//
|
|
57
|
-
|
|
76
|
+
// Gradient mode
|
|
77
|
+
if (mode === COLOR_MODE_GRADIENT) {
|
|
78
|
+
// Unknown (8 bytes)
|
|
79
|
+
input = input.slice(8);
|
|
58
80
|
|
|
59
|
-
|
|
60
|
-
|
|
81
|
+
// Length (2 bytes)
|
|
82
|
+
input = input.slice(2);
|
|
61
83
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
84
|
+
// Number of colors (2 bytes)
|
|
85
|
+
const nColors = parseInt(input.slice(0, 2), 16) >> 4;
|
|
86
|
+
input = input.slice(2);
|
|
65
87
|
|
|
66
|
-
|
|
67
|
-
|
|
88
|
+
// Unknown (6 bytes)
|
|
89
|
+
input = input.slice(6);
|
|
68
90
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
91
|
+
// Colors (6 * nColors bytes)
|
|
92
|
+
const colorsPayload = input.slice(0, 6 * nColors);
|
|
93
|
+
input = input.slice(6 * nColors);
|
|
94
|
+
const colors = colorsPayload.match(/.{6}/g).map(decodeScaledGradientToRGB);
|
|
73
95
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
96
|
+
// Segments (2 bytes)
|
|
97
|
+
const segments = parseInt(input.slice(0, 2), 16) >> 3;
|
|
98
|
+
input = input.slice(2);
|
|
77
99
|
|
|
78
|
-
|
|
79
|
-
|
|
100
|
+
// Offset (2 bytes)
|
|
101
|
+
const offset = parseInt(input.slice(0, 2), 16) >> 3;
|
|
80
102
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
103
|
+
if (opts && opts.reverse) {
|
|
104
|
+
colors.reverse();
|
|
105
|
+
}
|
|
84
106
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
gradient_extras: {
|
|
89
|
-
colors: nColors,
|
|
107
|
+
return {
|
|
108
|
+
color_mode: 'gradient',
|
|
109
|
+
colors,
|
|
90
110
|
segments,
|
|
91
111
|
offset,
|
|
92
112
|
brightness,
|
|
93
113
|
on,
|
|
94
|
-
}
|
|
95
|
-
}
|
|
114
|
+
};
|
|
115
|
+
} else if (mode === COLOR_MODE_COLOR_XY) {
|
|
116
|
+
// XY Color mode
|
|
117
|
+
const xLow = parseInt(input.slice(0, 2), 16);
|
|
118
|
+
input = input.slice(2);
|
|
119
|
+
const xHigh = parseInt(input.slice(0, 2), 16) << 8;
|
|
120
|
+
input = input.slice(2);
|
|
121
|
+
const yHigh = parseInt(input.slice(0, 2), 16);
|
|
122
|
+
input = input.slice(2);
|
|
123
|
+
const yLow = parseInt(input.slice(0, 2), 16) << 8;
|
|
124
|
+
input = input.slice(2);
|
|
125
|
+
|
|
126
|
+
const x = xHigh | xLow;
|
|
127
|
+
const y = yHigh | yLow;
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
color_mode: 'color_xy',
|
|
131
|
+
x: Math.round(x / 65535 * 10000) / 10000,
|
|
132
|
+
y: Math.round(y / 65535 * 10000) / 10000,
|
|
133
|
+
brightness,
|
|
134
|
+
on,
|
|
135
|
+
};
|
|
136
|
+
} else if (mode === COLOR_MODE_COLOR_TEMP) {
|
|
137
|
+
// Color temperature mode
|
|
138
|
+
const low = parseInt(input.slice(0, 2), 16);
|
|
139
|
+
input = input.slice(2);
|
|
140
|
+
const high = parseInt(input.slice(0, 2), 16) << 8;
|
|
141
|
+
input = input.slice(2);
|
|
142
|
+
|
|
143
|
+
const temp = high | low;
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
color_mode: 'color_temp',
|
|
147
|
+
color_temp: temp,
|
|
148
|
+
brightness,
|
|
149
|
+
on,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Unknown mode
|
|
154
|
+
return {};
|
|
96
155
|
}
|
|
97
156
|
|
|
98
157
|
// Value is a list of RGB HEX colors
|