zigbee-herdsman-converters 15.0.91 → 15.0.93
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/bosch.js +160 -18
- package/devices/climax.js +2 -2
- package/devices/heimgard_technologies.js +18 -0
- package/devices/namron.js +0 -7
- package/devices/niko.js +32 -12
- package/devices/tuya.js +1 -0
- package/devices/zemismart.js +1 -1
- package/package.json +1 -1
package/devices/bosch.js
CHANGED
|
@@ -4,7 +4,6 @@ const fz = require('../converters/fromZigbee');
|
|
|
4
4
|
const tz = require('../converters/toZigbee');
|
|
5
5
|
const reporting = require('../lib/reporting');
|
|
6
6
|
const utils = require('../lib/utils');
|
|
7
|
-
const extend = require('../lib/extend');
|
|
8
7
|
const constants = require('../lib/constants');
|
|
9
8
|
const ota = require('../lib/ota');
|
|
10
9
|
const e = exposes.presets;
|
|
@@ -13,6 +12,26 @@ const ea = exposes.access;
|
|
|
13
12
|
// Radiator Thermostat II
|
|
14
13
|
const boschManufacturer = {manufacturerCode: 0x1209};
|
|
15
14
|
|
|
15
|
+
// BMCT
|
|
16
|
+
const stateDeviceType = {
|
|
17
|
+
'light': 0x04,
|
|
18
|
+
'shutter': 0x01,
|
|
19
|
+
};
|
|
20
|
+
// BMCT
|
|
21
|
+
const stateMotor = {
|
|
22
|
+
'idle': 0x00,
|
|
23
|
+
'opening': 0x02,
|
|
24
|
+
'closing': 0x01,
|
|
25
|
+
};
|
|
26
|
+
// BMCT
|
|
27
|
+
const stateSwitchType = {
|
|
28
|
+
'button': 0x01,
|
|
29
|
+
'button_key_change': 0x02,
|
|
30
|
+
'rocker_switch': 0x03,
|
|
31
|
+
'rocker_rwitch_key_change': 0x04,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
|
|
16
35
|
// Twinguard
|
|
17
36
|
const smokeSensitivity = {
|
|
18
37
|
'low': 3,
|
|
@@ -55,6 +74,84 @@ const displayedTemperature = {
|
|
|
55
74
|
|
|
56
75
|
// Radiator Thermostat II
|
|
57
76
|
const tzLocal = {
|
|
77
|
+
bmct: {
|
|
78
|
+
key: [
|
|
79
|
+
'device_type',
|
|
80
|
+
'switch_type',
|
|
81
|
+
'child_lock', 'child_lock_left', 'child_lock_right',
|
|
82
|
+
'calibration_closing_time', 'calibration_opening_time',
|
|
83
|
+
'state',
|
|
84
|
+
],
|
|
85
|
+
convertSet: async (entity, key, value, meta) => {
|
|
86
|
+
if (key === 'state') {
|
|
87
|
+
const state = value.toLowerCase();
|
|
88
|
+
utils.validateValue(state, ['toggle', 'off', 'on', 'open', 'close', 'stop']);
|
|
89
|
+
if ( state === 'on' || state === 'off' || state === 'toggle') {
|
|
90
|
+
await entity.command('genOnOff', state, {}, utils.getOptions(meta.mapped, entity));
|
|
91
|
+
if (state === 'toggle') {
|
|
92
|
+
const currentState = meta.state[`state${meta.endpoint_name ? `_${meta.endpoint_name}` : ''}`];
|
|
93
|
+
return currentState ? {state: {state: currentState === 'OFF' ? 'ON' : 'OFF'}} : {};
|
|
94
|
+
} else {
|
|
95
|
+
return {state: {state: state.toUpperCase()}};
|
|
96
|
+
}
|
|
97
|
+
} else if ( state === 'open' || state === 'close' || state === 'stop') {
|
|
98
|
+
const lookup = {'open': 'upOpen', 'close': 'downClose', 'stop': 'stop', 'on': 'upOpen', 'off': 'downClose'};
|
|
99
|
+
value = value.toLowerCase();
|
|
100
|
+
utils.validateValue(value, Object.keys(lookup));
|
|
101
|
+
await entity.command('closuresWindowCovering', lookup[value], {}, utils.getOptions(meta.mapped, entity));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (key === 'device_type') {
|
|
105
|
+
const index = stateDeviceType[value];
|
|
106
|
+
await entity.write(0xFCA0, {0x0000: {value: index, type: 0x30}}, boschManufacturer);
|
|
107
|
+
return {state: {device_type: value}};
|
|
108
|
+
}
|
|
109
|
+
if (key === 'switch_type') {
|
|
110
|
+
const index = stateSwitchType[value];
|
|
111
|
+
await entity.write(0xFCA0, {0x0001: {value: index, type: 0x30}}, boschManufacturer);
|
|
112
|
+
return {state: {switch_type: value}};
|
|
113
|
+
}
|
|
114
|
+
if (key === 'child_lock') {
|
|
115
|
+
const index = stateOffOn[value];
|
|
116
|
+
await entity.write(0xFCA0, {0x0008: {value: index, type: 0x10}}, boschManufacturer);
|
|
117
|
+
return {state: {child_lock: value}};
|
|
118
|
+
}
|
|
119
|
+
if (key === 'calibration_closing_time') {
|
|
120
|
+
const index = value *10;
|
|
121
|
+
await entity.write(0xFCA0, {0x0002: {value: index, type: 0x23}}, boschManufacturer);
|
|
122
|
+
return {state: {calibration_closing_time: value}};
|
|
123
|
+
}
|
|
124
|
+
if (key === 'calibration_opening_time') {
|
|
125
|
+
const index = value *10;
|
|
126
|
+
await entity.write(0xFCA0, {0x0003: {value: index, type: 0x23}}, boschManufacturer);
|
|
127
|
+
return {state: {calibration_opening_time: value}};
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
convertGet: async (entity, key, meta) => {
|
|
131
|
+
switch (key) {
|
|
132
|
+
case 'state':
|
|
133
|
+
await entity.read('genOnOff', ['onOff']);
|
|
134
|
+
break;
|
|
135
|
+
case 'device_type':
|
|
136
|
+
await entity.read(0xFCA0, [0x0000], boschManufacturer);
|
|
137
|
+
break;
|
|
138
|
+
case 'switch_type':
|
|
139
|
+
await entity.read(0xFCA0, [0x0001], boschManufacturer);
|
|
140
|
+
break;
|
|
141
|
+
case 'child_lock':
|
|
142
|
+
await entity.read(0xFCA0, [0x0008], boschManufacturer);
|
|
143
|
+
break;
|
|
144
|
+
case 'calibration_closing_time':
|
|
145
|
+
await entity.read(0xFCA0, [0x0002], boschManufacturer);
|
|
146
|
+
break;
|
|
147
|
+
case 'calibration_opening_time':
|
|
148
|
+
await entity.read(0xFCA0, [0x0003], boschManufacturer);
|
|
149
|
+
break;
|
|
150
|
+
default: // Unknown key
|
|
151
|
+
throw new Error(`Unhandled key toZigbee.bcmt.convertGet ${key}`);
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
},
|
|
58
155
|
bwa1: {
|
|
59
156
|
key: ['alarm_on_motion', 'test'],
|
|
60
157
|
convertSet: async (entity, key, value, meta) => {
|
|
@@ -256,6 +353,27 @@ const tzLocal = {
|
|
|
256
353
|
|
|
257
354
|
|
|
258
355
|
const fzLocal = {
|
|
356
|
+
bmct: {
|
|
357
|
+
cluster: '64672',
|
|
358
|
+
type: ['attributeReport', 'readResponse'],
|
|
359
|
+
options: [],
|
|
360
|
+
convert: (model, msg, publish, options, meta) => {
|
|
361
|
+
const result = {};
|
|
362
|
+
const data = msg.data;
|
|
363
|
+
if (data.hasOwnProperty(0x0000)) {
|
|
364
|
+
result.device_type = (Object.keys(stateDeviceType)[msg.data[0x0000]]);
|
|
365
|
+
} else if (data.hasOwnProperty(0x0001)) {
|
|
366
|
+
result.switch_type = (Object.keys(stateSwitchType)[msg.data[0x0001]]);
|
|
367
|
+
} else if (data.hasOwnProperty(0x0002)) {
|
|
368
|
+
result.calibration_closing_time = msg.data[0x0002];
|
|
369
|
+
} else if (data.hasOwnProperty(0x0003)) {
|
|
370
|
+
result.calibration_opening_time = msg.data[0x0003];
|
|
371
|
+
} else if (data.hasOwnProperty(0x0013)) {
|
|
372
|
+
result.motor_state = (Object.keys(stateMotor)[msg.data[0x0013]]);
|
|
373
|
+
}
|
|
374
|
+
return result;
|
|
375
|
+
},
|
|
376
|
+
},
|
|
259
377
|
bwa1_alarm_on_motion: {
|
|
260
378
|
cluster: '64684',
|
|
261
379
|
type: ['attributeReport', 'readResponse'],
|
|
@@ -742,27 +860,51 @@ const definition = [
|
|
|
742
860
|
zigbeeModel: ['RBSH-MMS-ZB-EU'],
|
|
743
861
|
model: 'BMCT-SLZ',
|
|
744
862
|
vendor: 'Bosch',
|
|
745
|
-
description: 'Light/shutter control II',
|
|
746
|
-
|
|
747
|
-
|
|
863
|
+
description: 'Bosch Light/shutter control unit II',
|
|
864
|
+
fromZigbee: [fzLocal.bmct, fz.cover_position_tilt, fz.on_off, fz.power_on_behavior],
|
|
865
|
+
toZigbee: [tzLocal.bmct, tz.cover_position_tilt, tz.on_off, tz.power_on_behavior],
|
|
866
|
+
meta: {multiEndpoint: true},
|
|
748
867
|
endpoint: (device) => {
|
|
749
|
-
return {'
|
|
868
|
+
return {'left': 2, 'right': 3};
|
|
750
869
|
},
|
|
751
|
-
meta: {multiEndpoint: true},
|
|
752
870
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
await reporting.bind(
|
|
764
|
-
await reporting.
|
|
871
|
+
const endpoint1 = device.getEndpoint(1);
|
|
872
|
+
await reporting.bind(endpoint1, coordinatorEndpoint, ['genIdentify', 'closuresWindowCovering', 64672]);
|
|
873
|
+
await endpoint1.unbind('genOnOff', coordinatorEndpoint);
|
|
874
|
+
await endpoint1.read(64672, [0x0000, 0x0001, 0x0002, 0x0003, 0x0008, 0x0013], boschManufacturer);
|
|
875
|
+
const endpoint2 = device.getEndpoint(2);
|
|
876
|
+
await endpoint2.read(64672, [0x0008], boschManufacturer);
|
|
877
|
+
await reporting.bind(endpoint2, coordinatorEndpoint, ['genIdentify', 'genOnOff']);
|
|
878
|
+
await reporting.onOff(endpoint2);
|
|
879
|
+
const endpoint3 = device.getEndpoint(3);
|
|
880
|
+
await endpoint3.read(64672, [0x0008], boschManufacturer);
|
|
881
|
+
await reporting.bind(endpoint3, coordinatorEndpoint, ['genIdentify', 'genOnOff']);
|
|
882
|
+
await reporting.onOff(endpoint3);
|
|
765
883
|
},
|
|
884
|
+
exposes: [
|
|
885
|
+
// light
|
|
886
|
+
exposes.enum('device_type', ea.ALL, Object.keys(stateDeviceType))
|
|
887
|
+
.withDescription('Device type: '),
|
|
888
|
+
exposes.enum('switch_type', ea.ALL, Object.keys(stateSwitchType))
|
|
889
|
+
.withDescription('Module controlled by a rocker switch or a button'),
|
|
890
|
+
e.switch().withEndpoint('left'),
|
|
891
|
+
e.switch().withEndpoint('right'),
|
|
892
|
+
e.power_on_behavior().withEndpoint('right'),
|
|
893
|
+
e.power_on_behavior().withEndpoint('left'),
|
|
894
|
+
exposes.binary('child_lock', ea.ALL, 'ON', 'OFF').withEndpoint('left')
|
|
895
|
+
.withDescription('Enable/Disable child lock'),
|
|
896
|
+
exposes.binary('child_lock', ea.ALL, 'ON', 'OFF').withEndpoint('right')
|
|
897
|
+
.withDescription('Enable/Disable child lock'),
|
|
898
|
+
// cover
|
|
899
|
+
e.cover_position().setAccess('state', ea.ALL),
|
|
900
|
+
exposes.enum('motor_state', ea.STATE, Object.keys(stateMotor))
|
|
901
|
+
.withDescription('Shutter motor actual state '),
|
|
902
|
+
exposes.binary('child_lock', ea.ALL, 'ON', 'OFF').withDescription('Enable/Disable child lock'),
|
|
903
|
+
exposes.numeric('calibration_closing_time', ea.ALL).withUnit('S')
|
|
904
|
+
.withDescription('Calibration opening time').withValueMin(1).withValueMax(90),
|
|
905
|
+
exposes.numeric('calibration_opening_time', ea.ALL).withUnit('S')
|
|
906
|
+
.withDescription('Calibration closing time').withValueMin(1).withValueMax(90),
|
|
907
|
+
],
|
|
766
908
|
},
|
|
767
909
|
];
|
|
768
910
|
|
package/devices/climax.js
CHANGED
|
@@ -82,14 +82,14 @@ module.exports = [
|
|
|
82
82
|
vendor: 'Climax',
|
|
83
83
|
description: 'Smart siren',
|
|
84
84
|
fromZigbee: [fz.battery, fz.ias_wd, fz.ias_enroll, fz.ias_siren],
|
|
85
|
-
toZigbee: [tz.warning_simple, tz.ias_max_duration, tz.warning],
|
|
85
|
+
toZigbee: [tz.warning_simple, tz.ias_max_duration, tz.warning, tz.squawk],
|
|
86
86
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
87
87
|
const endpoint = device.getEndpoint(1);
|
|
88
88
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genBasic', 'ssIasZone', 'ssIasWd']);
|
|
89
89
|
await endpoint.read('ssIasZone', ['zoneState', 'iasCieAddr', 'zoneId']);
|
|
90
90
|
await endpoint.read('ssIasWd', ['maxDuration']);
|
|
91
91
|
},
|
|
92
|
-
exposes: [e.battery_low(), e.tamper(), e.warning(),
|
|
92
|
+
exposes: [e.battery_low(), e.tamper(), e.warning(), e.squawk(),
|
|
93
93
|
exposes.numeric('max_duration', ea.ALL).withUnit('s').withValueMin(0).withValueMax(600).withDescription('Duration of Siren'),
|
|
94
94
|
exposes.binary('alarm', ea.SET, 'START', 'OFF').withDescription('Manual start of siren')],
|
|
95
95
|
},
|
|
@@ -24,6 +24,24 @@ module.exports = [
|
|
|
24
24
|
exposes: [
|
|
25
25
|
e.lock(), e.battery(), e.auto_relock_time().withValueMin(0).withValueMax(3600), e.sound_volume()],
|
|
26
26
|
},
|
|
27
|
+
{
|
|
28
|
+
zigbeeModel: ['HT-SLM-2'],
|
|
29
|
+
model: 'HT-SLM-2',
|
|
30
|
+
vendor: 'Heimgard Technologies',
|
|
31
|
+
description: 'Doorlock with fingerprint',
|
|
32
|
+
fromZigbee: [fz.lock, fz.battery, fz.lock_pin_code_response, fz.lock_user_status_response],
|
|
33
|
+
toZigbee: [tz.lock, tz.lock_sound_volume, tz.identify, tz.pincode_lock, tz.lock_userstatus],
|
|
34
|
+
meta: {pinCodeCount: 39},
|
|
35
|
+
ota: ota.zigbeeOTA,
|
|
36
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
37
|
+
const endpoint = device.getEndpoint(1);
|
|
38
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['closuresDoorLock', 'genPowerCfg']);
|
|
39
|
+
await reporting.lockState(endpoint);
|
|
40
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
41
|
+
await endpoint.read('closuresDoorLock', ['lockState', 'soundVolume']);
|
|
42
|
+
},
|
|
43
|
+
exposes: [e.lock(), e.pincode(), e.battery(), e.sound_volume()],
|
|
44
|
+
},
|
|
27
45
|
{
|
|
28
46
|
zigbeeModel: ['HC-IWDIM-1'],
|
|
29
47
|
model: 'HC-IWDIM-1',
|
package/devices/namron.js
CHANGED
|
@@ -481,13 +481,6 @@ module.exports = [
|
|
|
481
481
|
await reporting.thermostatUnoccupiedHeatingSetpoint(endpoint);
|
|
482
482
|
await reporting.thermostatKeypadLockMode(endpoint);
|
|
483
483
|
|
|
484
|
-
await endpoint.configureReporting('hvacThermostat', [{
|
|
485
|
-
attribute: 'occupancy',
|
|
486
|
-
minimumReportInterval: 0,
|
|
487
|
-
maximumReportInterval: constants.repInterval.HOUR,
|
|
488
|
-
reportableChange: null,
|
|
489
|
-
}]);
|
|
490
|
-
|
|
491
484
|
// Metering
|
|
492
485
|
await endpoint.read('haElectricalMeasurement', ['acVoltageMultiplier', 'acVoltageDivisor', 'acCurrentMultiplier']);
|
|
493
486
|
await endpoint.read('haElectricalMeasurement', ['acCurrentDivisor']);
|
package/devices/niko.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const exposes = require('../lib/exposes');
|
|
2
2
|
const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
|
|
3
3
|
const tz = require('../converters/toZigbee');
|
|
4
|
+
const utils = require('../lib/utils');
|
|
4
5
|
const reporting = require('../lib/reporting');
|
|
5
6
|
const e = exposes.presets;
|
|
6
7
|
const ea = exposes.access;
|
|
@@ -13,9 +14,8 @@ const local = {
|
|
|
13
14
|
convert: (model, msg, publish, options, meta) => {
|
|
14
15
|
const state = {};
|
|
15
16
|
if (msg.data.hasOwnProperty('switchOperationMode')) {
|
|
16
|
-
const operationModeProperty = `operation_mode${meta.endpoint_name ? `_${meta.endpoint_name}` : ''}`;
|
|
17
17
|
const operationModeMap = {0x02: 'control_relay', 0x01: 'decoupled', 0x00: 'unknown'};
|
|
18
|
-
state[
|
|
18
|
+
state['operation_mode'] = operationModeMap[msg.data.switchOperationMode];
|
|
19
19
|
}
|
|
20
20
|
return state;
|
|
21
21
|
},
|
|
@@ -29,9 +29,22 @@ const local = {
|
|
|
29
29
|
if (msg.data.hasOwnProperty('switchAction')) {
|
|
30
30
|
// NOTE: a single press = two seperate values reported, 16 followed by 64
|
|
31
31
|
// a hold/release cyle = three seperate values, 16, 32, and 48
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
const actionMap = (model.model == '552-721X1') ? {
|
|
33
|
+
16: null,
|
|
34
|
+
64: 'single',
|
|
35
|
+
32: 'hold',
|
|
36
|
+
48: 'release',
|
|
37
|
+
} : {
|
|
38
|
+
16: null,
|
|
39
|
+
64: 'single_left',
|
|
40
|
+
32: 'hold_left',
|
|
41
|
+
48: 'release_left',
|
|
42
|
+
4096: 'single_right',
|
|
43
|
+
8192: 'hold_right',
|
|
44
|
+
12288: 'release_right',
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
state['action'] = actionMap[msg.data.switchAction];
|
|
35
48
|
}
|
|
36
49
|
return state;
|
|
37
50
|
},
|
|
@@ -75,12 +88,18 @@ const local = {
|
|
|
75
88
|
if (!operationModeLookup.hasOwnProperty(value)) {
|
|
76
89
|
throw new Error(`operation_mode was called with an invalid value (${value})`);
|
|
77
90
|
} else {
|
|
78
|
-
await
|
|
91
|
+
await utils.enforceEndpoint(entity, key, meta).write(
|
|
92
|
+
'manuSpecificNiko1',
|
|
93
|
+
{'switchOperationMode': operationModeLookup[value]},
|
|
94
|
+
);
|
|
79
95
|
return {state: {operation_mode: value.toLowerCase()}};
|
|
80
96
|
}
|
|
81
97
|
},
|
|
82
98
|
convertGet: async (entity, key, meta) => {
|
|
83
|
-
await
|
|
99
|
+
await utils.enforceEndpoint(entity, key, meta).read(
|
|
100
|
+
'manuSpecificNiko1',
|
|
101
|
+
['switchOperationMode'],
|
|
102
|
+
);
|
|
84
103
|
},
|
|
85
104
|
},
|
|
86
105
|
switch_led_enable: {
|
|
@@ -259,7 +278,7 @@ module.exports = [
|
|
|
259
278
|
endpoint: (device) => {
|
|
260
279
|
return {'l1': 1, 'l2': 2};
|
|
261
280
|
},
|
|
262
|
-
meta: {
|
|
281
|
+
meta: {multiEndpointEnforce: {'operation_mode': 1}},
|
|
263
282
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
264
283
|
const ep1 = device.getEndpoint(1);
|
|
265
284
|
const ep2 = device.getEndpoint(2);
|
|
@@ -272,10 +291,11 @@ module.exports = [
|
|
|
272
291
|
},
|
|
273
292
|
exposes: [
|
|
274
293
|
e.switch().withEndpoint('l1'), e.switch().withEndpoint('l2'),
|
|
275
|
-
e.action([
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
294
|
+
e.action([
|
|
295
|
+
'single_left', 'hold_left', 'release_left',
|
|
296
|
+
'single_right', 'hold_right', 'release_right',
|
|
297
|
+
]),
|
|
298
|
+
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled']),
|
|
279
299
|
exposes.binary('led_enable', ea.ALL, true, false).withEndpoint('l1').withDescription('Enable LED'),
|
|
280
300
|
exposes.binary('led_enable', ea.ALL, true, false).withEndpoint('l2').withDescription('Enable LED'),
|
|
281
301
|
exposes.binary('led_state', ea.ALL, 'ON', 'OFF').withEndpoint('l1').withDescription('LED State'),
|
package/devices/tuya.js
CHANGED
|
@@ -805,6 +805,7 @@ module.exports = [
|
|
|
805
805
|
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_bq5c8xfe'},
|
|
806
806
|
{modelID: 'TS0601', manufacturerName: '_TZE200_bjawzodf'},
|
|
807
807
|
{modelID: 'TS0601', manufacturerName: '_TZE200_qyflbnbj'},
|
|
808
|
+
{modelID: 'TS0601', manufacturerName: '_TZE200_vs0skpuc'},
|
|
808
809
|
{modelID: 'TS0601', manufacturerName: '_TZE200_9yapgbuv'},
|
|
809
810
|
{modelID: 'TS0601', manufacturerName: '_TZE200_zl1kmjqx'}],
|
|
810
811
|
model: 'TS0601_temperature_humidity_sensor',
|
package/devices/zemismart.js
CHANGED
|
@@ -199,7 +199,7 @@ module.exports = [
|
|
|
199
199
|
exposes: [e.cover_position().setAccess('position', ea.STATE_SET)],
|
|
200
200
|
},
|
|
201
201
|
{
|
|
202
|
-
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_1n2kyphz'}],
|
|
202
|
+
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_1n2kyphz'}, {modelID: 'TS0601', manufacturerName: '_TZE200_shkxsgis'}],
|
|
203
203
|
model: 'TB26-4',
|
|
204
204
|
vendor: 'Zemismart',
|
|
205
205
|
description: '4-gang smart wall switch',
|