zigbee-herdsman-converters 14.0.688 → 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/converters/fromZigbee.js +0 -25
- package/devices/ctm.js +59 -12
- package/devices/fantem.js +2 -1
- package/devices/ikea.js +2 -1
- package/devices/mecrator.js +1 -1
- package/devices/moes.js +2 -1
- package/devices/osram.js +40 -0
- package/devices/philips.js +5 -3
- package/devices/tuya.js +26 -9
- package/devices/zemismart.js +3 -0
- package/lib/philips.js +95 -36
- package/package.json +3 -3
package/converters/fromZigbee.js
CHANGED
|
@@ -5040,31 +5040,6 @@ const converters = {
|
|
|
5040
5040
|
}
|
|
5041
5041
|
},
|
|
5042
5042
|
},
|
|
5043
|
-
tuya_smoke: {
|
|
5044
|
-
cluster: 'manuSpecificTuya',
|
|
5045
|
-
type: ['commandDataResponse', 'commandDataReport'],
|
|
5046
|
-
convert: (model, msg, publish, options, meta) => {
|
|
5047
|
-
const result = {};
|
|
5048
|
-
for (const dpValue of msg.data.dpValues) {
|
|
5049
|
-
const dp = dpValue.dp;
|
|
5050
|
-
const value = tuya.getDataValue(dpValue);
|
|
5051
|
-
switch (dp) {
|
|
5052
|
-
case tuya.dataPoints.state:
|
|
5053
|
-
result.smoke = value === 0;
|
|
5054
|
-
break;
|
|
5055
|
-
case 14:
|
|
5056
|
-
// battery state, ignore
|
|
5057
|
-
break;
|
|
5058
|
-
case 15:
|
|
5059
|
-
result.battery = value;
|
|
5060
|
-
break;
|
|
5061
|
-
default:
|
|
5062
|
-
meta.logger.warn(`zigbee-herdsman-converters:tuya_smoke: Unrecognized DP #${ dp} with data ${JSON.stringify(dpValue)}`);
|
|
5063
|
-
}
|
|
5064
|
-
}
|
|
5065
|
-
return result;
|
|
5066
|
-
},
|
|
5067
|
-
},
|
|
5068
5043
|
tuya_woox_smoke: {
|
|
5069
5044
|
cluster: 'manuSpecificTuya',
|
|
5070
5045
|
type: ['commandDataResponse'],
|
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/fantem.js
CHANGED
|
@@ -48,7 +48,8 @@ module.exports = [
|
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
50
|
fingerprint: [{modelID: 'TS0202', manufacturerName: '_TZ3210_rxqls8v0'},
|
|
51
|
-
{modelID: 'TS0202', manufacturerName: '_TZ3210_zmy9hjay'}
|
|
51
|
+
{modelID: 'TS0202', manufacturerName: '_TZ3210_zmy9hjay'},
|
|
52
|
+
{modelID: 'TS0202', manufacturerName: '_TZ3210_wuhzzfqg'}],
|
|
52
53
|
model: 'ZB003-X',
|
|
53
54
|
vendor: 'Fantem',
|
|
54
55
|
description: '4 in 1 multi sensor',
|
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',
|
|
@@ -901,6 +901,7 @@ module.exports = [
|
|
|
901
901
|
vendor: 'IKEA',
|
|
902
902
|
description: 'TRADFRI LED bulb E14 470 lumen, opal, dimmable, white spectrum, color spectrum',
|
|
903
903
|
extend: tradfriExtend.light_onoff_brightness_colortemp_color(),
|
|
904
|
+
meta: {turnsOffAtBrightness1: true},
|
|
904
905
|
},
|
|
905
906
|
{
|
|
906
907
|
zigbeeModel: ['TRADFRIbulbE14WWclear250lm', 'TRADFRIbulbE12WWclear250lm'],
|
package/devices/mecrator.js
CHANGED
|
@@ -30,7 +30,7 @@ module.exports = [
|
|
|
30
30
|
},
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
|
-
fingerprint:
|
|
33
|
+
fingerprint: tuya.fingerprint('TS011F', ['_TZ3210_7jnk7l3k', '_TZ3210_raqjcxo5']),
|
|
34
34
|
model: 'SPP02GIP',
|
|
35
35
|
vendor: 'Mercator',
|
|
36
36
|
description: 'Ikuü double outdoors power point',
|
package/devices/moes.js
CHANGED
|
@@ -341,7 +341,8 @@ module.exports = [
|
|
|
341
341
|
]),
|
|
342
342
|
meta: {applyRedFix: true, enhancedHue: false},
|
|
343
343
|
fromZigbee: extend.light_onoff_brightness_colortemp_color().fromZigbee,
|
|
344
|
-
exposes: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500], disableColorTempStartup: true
|
|
344
|
+
exposes: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500], disableColorTempStartup: true,
|
|
345
|
+
disablePowerOnBehavior: true}).exposes.concat([
|
|
345
346
|
exposes.binary('do_not_disturb', ea.STATE_SET, true, false)
|
|
346
347
|
.withDescription('Do not disturb mode'),
|
|
347
348
|
exposes.enum('color_power_on_behavior', ea.STATE_SET, ['initial', 'previous', 'cutomized'])
|
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'],
|
|
@@ -2495,13 +2496,20 @@ module.exports = [
|
|
|
2495
2496
|
},
|
|
2496
2497
|
{
|
|
2497
2498
|
zigbeeModel: ['5p1vj8r'],
|
|
2498
|
-
fingerprint:
|
|
2499
|
+
fingerprint: tuya.fingerprint('TS0601', ['_TZE200_t5p1vj8r', '_TZE200_uebojraa', '_TZE200_vzekyi4c', '_TZE200_yh7aoahi']),
|
|
2499
2500
|
model: 'TS0601_smoke',
|
|
2500
2501
|
vendor: 'TuYa',
|
|
2501
2502
|
description: 'Smoke sensor',
|
|
2502
|
-
fromZigbee: [fz.
|
|
2503
|
-
toZigbee: [],
|
|
2504
|
-
exposes: [e.smoke(), e.battery()],
|
|
2503
|
+
fromZigbee: [tuya.fz.datapoints],
|
|
2504
|
+
toZigbee: [tuya.tz.datapoints],
|
|
2505
|
+
exposes: [e.smoke(), e.battery(), tuya.exposes.batteryState()],
|
|
2506
|
+
meta: {
|
|
2507
|
+
tuyaDatapoints: [
|
|
2508
|
+
[1, 'smoke', tuya.valueConverter.true0ElseFalse],
|
|
2509
|
+
[14, 'battery_state', tuya.valueConverter.batteryState],
|
|
2510
|
+
[15, 'battery', tuya.valueConverter.raw],
|
|
2511
|
+
],
|
|
2512
|
+
},
|
|
2505
2513
|
},
|
|
2506
2514
|
{
|
|
2507
2515
|
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_5d3vhjro'}],
|
|
@@ -2833,7 +2841,7 @@ module.exports = [
|
|
|
2833
2841
|
model: 'TS0014',
|
|
2834
2842
|
vendor: 'TuYa',
|
|
2835
2843
|
description: 'Smart light switch - 4 gang without neutral wire',
|
|
2836
|
-
extend: tuya.extend.switch({endpoints: ['l1', 'l2', 'l3', 'l4']}),
|
|
2844
|
+
extend: tuya.extend.switch({backlightMode: true, endpoints: ['l1', 'l2', 'l3', 'l4']}),
|
|
2837
2845
|
endpoint: (device) => {
|
|
2838
2846
|
return {'l1': 1, 'l2': 2, 'l3': 3, 'l4': 4};
|
|
2839
2847
|
},
|
|
@@ -2877,6 +2885,15 @@ module.exports = [
|
|
|
2877
2885
|
exposes: [e.action(['scene_1', 'scene_2', 'scene_3', 'scene_4', 'scene_5', 'scene_6'])],
|
|
2878
2886
|
toZigbee: [],
|
|
2879
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
|
+
},
|
|
2880
2897
|
{
|
|
2881
2898
|
zigbeeModel: ['q9mpfhw'],
|
|
2882
2899
|
model: 'SNTZ009',
|
package/devices/zemismart.js
CHANGED
|
@@ -83,6 +83,9 @@ module.exports = [
|
|
|
83
83
|
description: 'Smart light switch and socket - 2 gang with neutral wire',
|
|
84
84
|
extend: tuya.extend.switch({endpoints: ['left', 'center', 'right']}),
|
|
85
85
|
meta: {multiEndpoint: true},
|
|
86
|
+
endpoint: () => {
|
|
87
|
+
return {'left': 1, 'center': 2, 'right': 3};
|
|
88
|
+
},
|
|
86
89
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
87
90
|
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
|
|
88
91
|
for (const endpointID of [1, 2, 3]) {
|
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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zigbee-herdsman-converters",
|
|
3
|
-
"version": "14.0.
|
|
3
|
+
"version": "14.0.690",
|
|
4
4
|
"description": "Collection of device converters to be used with zigbee-herdsman",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
},
|
|
35
35
|
"homepage": "https://github.com/Koenkk/zigbee-herdsman-converters",
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"axios": "
|
|
37
|
+
"axios": "^1.2.1",
|
|
38
38
|
"buffer-crc32": "^0.2.13",
|
|
39
39
|
"https-proxy-agent": "^5.0.1",
|
|
40
40
|
"tar-stream": "^2.2.0",
|
|
41
|
-
"zigbee-herdsman": "^0.14.
|
|
41
|
+
"zigbee-herdsman": "^0.14.80"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"eslint": "*",
|