zigbee-herdsman-converters 14.0.667 → 14.0.669
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 +16 -0
- package/converters/toZigbee.js +26 -14
- package/devices/awox.js +1 -1
- package/devices/connecte.js +1 -5
- package/devices/ecosmart.js +1 -1
- package/devices/eglo.js +7 -0
- package/devices/fantem.js +1 -1
- package/devices/ge.js +7 -3
- package/devices/ikea.js +1 -1
- package/devices/legrand.js +43 -4
- package/devices/lellki.js +3 -5
- package/devices/lidl.js +1 -2
- package/devices/makegood.js +2 -1
- package/devices/mecrator.js +2 -1
- package/devices/miboxer.js +1 -1
- package/devices/moes.js +1 -2
- package/devices/namron.js +1 -1
- package/devices/neo.js +1 -1
- package/devices/philips.js +7 -0
- package/devices/sinope.js +5 -4
- package/devices/sunricher.js +1 -1
- package/devices/tuya.js +60 -10
- package/devices/ubisys.js +3 -3
- package/devices/useelink.js +2 -2
- package/devices/woox.js +1 -4
- package/devices/zemismart.js +4 -8
- package/lib/reporting.js +1 -1
- package/lib/tuya.js +24 -3
- package/package.json +1 -1
package/converters/fromZigbee.js
CHANGED
|
@@ -3476,6 +3476,22 @@ const converters = {
|
|
|
3476
3476
|
return result;
|
|
3477
3477
|
},
|
|
3478
3478
|
},
|
|
3479
|
+
sinope_thermostat: {
|
|
3480
|
+
cluster: 'hvacThermostat',
|
|
3481
|
+
type: ['readResponse'],
|
|
3482
|
+
convert: (model, msg, publish, options, meta) => {
|
|
3483
|
+
const lookup = {0: 'unoccupied', 1: 'occupied'};
|
|
3484
|
+
const lookup1 = {0: 'on_demand', 1: 'sensing'};
|
|
3485
|
+
const result = {};
|
|
3486
|
+
if (msg.data.hasOwnProperty('1024')) {
|
|
3487
|
+
result.thermostat_occupancy = lookup[msg.data['1024']];
|
|
3488
|
+
}
|
|
3489
|
+
if (msg.data.hasOwnProperty('1026')) {
|
|
3490
|
+
result.backlight_auto_dim = lookup1[msg.data['1026']];
|
|
3491
|
+
}
|
|
3492
|
+
return result;
|
|
3493
|
+
},
|
|
3494
|
+
},
|
|
3479
3495
|
danfoss_thermostat: {
|
|
3480
3496
|
cluster: 'hvacThermostat',
|
|
3481
3497
|
type: ['attributeReport', 'readResponse'],
|
package/converters/toZigbee.js
CHANGED
|
@@ -884,17 +884,28 @@ const converters = {
|
|
|
884
884
|
// TODO: same problem as above.
|
|
885
885
|
// TODO: if transition is not specified, should use device default (OnTransitionTime), not 0.
|
|
886
886
|
if (transition.specified || globalStore.getValue(entity, 'turnedOffWithTransition') === true) {
|
|
887
|
-
const
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
887
|
+
const levelConfig = utils.getObjectProperty(meta.state, 'level_config', {});
|
|
888
|
+
let onLevel = utils.getObjectProperty(levelConfig, 'on_level', 0);
|
|
889
|
+
if (onLevel === 0 && entity.meta.onLevelSupported !== false) {
|
|
890
|
+
try {
|
|
891
|
+
const attributeRead = await entity.read('genLevelCtrl', ['onLevel']);
|
|
892
|
+
if (attributeRead !== undefined) {
|
|
893
|
+
onLevel = attributeRead['onLevel'];
|
|
894
|
+
}
|
|
895
|
+
} catch (e) {
|
|
896
|
+
// OnLevel not supported
|
|
895
897
|
}
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
+
}
|
|
899
|
+
if (onLevel === 0) {
|
|
900
|
+
onLevel = 'previous';
|
|
901
|
+
entity.meta.onLevelSupported = false;
|
|
902
|
+
entity.save();
|
|
903
|
+
}
|
|
904
|
+
if (onLevel === 255 || onLevel === 'previous') {
|
|
905
|
+
const current = utils.getObjectProperty(meta.state, 'brightness', 254);
|
|
906
|
+
brightness = globalStore.getValue(entity, 'brightness', current);
|
|
907
|
+
} else {
|
|
908
|
+
brightness = onLevel;
|
|
898
909
|
}
|
|
899
910
|
// Published state might have gotten clobbered by reporting.
|
|
900
911
|
publishBrightness = true;
|
|
@@ -1359,6 +1370,7 @@ const converters = {
|
|
|
1359
1370
|
}
|
|
1360
1371
|
const unoccupiedHeatingSetpoint = result;
|
|
1361
1372
|
await entity.write('hvacThermostat', {unoccupiedHeatingSetpoint});
|
|
1373
|
+
return {state: {unoccupied_heating_setpoint: value}};
|
|
1362
1374
|
},
|
|
1363
1375
|
convertGet: async (entity, key, meta) => {
|
|
1364
1376
|
await entity.read('hvacThermostat', ['unoccupiedHeatingSetpoint']);
|
|
@@ -1394,6 +1406,7 @@ const converters = {
|
|
|
1394
1406
|
}
|
|
1395
1407
|
const unoccupiedCoolingSetpoint = result;
|
|
1396
1408
|
await entity.write('hvacThermostat', {unoccupiedCoolingSetpoint});
|
|
1409
|
+
return {state: {unoccupied_cooling_setpoint: value}};
|
|
1397
1410
|
},
|
|
1398
1411
|
convertGet: async (entity, key, meta) => {
|
|
1399
1412
|
await entity.read('hvacThermostat', ['unoccupiedCoolingSetpoint']);
|
|
@@ -4286,17 +4299,16 @@ const converters = {
|
|
|
4286
4299
|
const sinopeOccupancy = {0: 'unoccupied', 1: 'occupied'};
|
|
4287
4300
|
const SinopeOccupancy = utils.getKey(sinopeOccupancy, value, value, Number);
|
|
4288
4301
|
await entity.write('hvacThermostat', {SinopeOccupancy});
|
|
4302
|
+
return {state: {'thermostat_occupancy': value}};
|
|
4289
4303
|
},
|
|
4290
4304
|
},
|
|
4291
4305
|
sinope_thermostat_backlight_autodim_param: {
|
|
4292
4306
|
key: ['backlight_auto_dim'],
|
|
4293
4307
|
convertSet: async (entity, key, value, meta) => {
|
|
4294
|
-
const sinopeBacklightParam = {
|
|
4295
|
-
0: 'on demand',
|
|
4296
|
-
1: 'sensing',
|
|
4297
|
-
};
|
|
4308
|
+
const sinopeBacklightParam = {0: 'on_demand', 1: 'sensing'};
|
|
4298
4309
|
const SinopeBacklight = utils.getKey(sinopeBacklightParam, value, value, Number);
|
|
4299
4310
|
await entity.write('hvacThermostat', {SinopeBacklight});
|
|
4311
|
+
return {state: {'backlight_auto_dim': value}};
|
|
4300
4312
|
},
|
|
4301
4313
|
},
|
|
4302
4314
|
sinope_thermostat_enable_outdoor_temperature: {
|
package/devices/awox.js
CHANGED
package/devices/connecte.js
CHANGED
|
@@ -14,11 +14,7 @@ module.exports = [
|
|
|
14
14
|
fromZigbee: [fz.connecte_thermostat],
|
|
15
15
|
toZigbee: [tz.connecte_thermostat],
|
|
16
16
|
onEvent: tuya.onEventSetTime,
|
|
17
|
-
configure:
|
|
18
|
-
const endpoint = device.getEndpoint(1);
|
|
19
|
-
// Do a "magic" read on the basic cluster to trigger the thermostat start reporting.
|
|
20
|
-
await endpoint.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
|
|
21
|
-
},
|
|
17
|
+
configure: tuya.configureMagicPacket,
|
|
22
18
|
exposes: [
|
|
23
19
|
exposes.binary('state', ea.STATE_SET, 'ON', 'OFF')
|
|
24
20
|
.withDescription('On/off state of the switch'),
|
package/devices/ecosmart.js
CHANGED
|
@@ -47,7 +47,7 @@ module.exports = [
|
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
49
|
// eslint-disable-next-line
|
|
50
|
-
zigbeeModel: ['\u0000\u0002\u0000\u0004\u0000\f]�\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000e', '\u0000\u0002\u0000\u0004\"�T\u0004\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000e', '\u0000\u0002\u0000\u0004\u0000\f^�\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000e','\u0000\u0002\u0000\u0004\u0011�\"�\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000e','\u0000\u0002\u0000\u0004� �P\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000e','\u0000\u0002\u0000\u0004\u0000\f^\u0014\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000e'],
|
|
50
|
+
zigbeeModel: ['\u0000\u0002\u0000\u0004T\u0002\u000eZ\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000e', '\u0000\u0002\u0000\u0004\u0000\f]�\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000e', '\u0000\u0002\u0000\u0004\"�T\u0004\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000e', '\u0000\u0002\u0000\u0004\u0000\f^�\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000e','\u0000\u0002\u0000\u0004\u0011�\"�\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000e','\u0000\u0002\u0000\u0004� �P\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000e','\u0000\u0002\u0000\u0004\u0000\f^\u0014\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000e'],
|
|
51
51
|
model: 'D1533',
|
|
52
52
|
vendor: 'EcoSmart',
|
|
53
53
|
description: 'PAR20/A19 bright white bulb',
|
package/devices/eglo.js
CHANGED
|
@@ -8,4 +8,11 @@ module.exports = [
|
|
|
8
8
|
description: 'ROVITO-Z ceiling light',
|
|
9
9
|
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 370]}),
|
|
10
10
|
},
|
|
11
|
+
{
|
|
12
|
+
zigbeeModel: ['ESMLFzm_w6_TW'],
|
|
13
|
+
model: '12242',
|
|
14
|
+
vendor: 'EGLO',
|
|
15
|
+
description: 'ST64 adjustable white filament bulb',
|
|
16
|
+
extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
|
|
17
|
+
},
|
|
11
18
|
];
|
package/devices/fantem.js
CHANGED
|
@@ -42,7 +42,7 @@ module.exports = [
|
|
|
42
42
|
const endpoint = device.getEndpoint(1);
|
|
43
43
|
// Enables reporting of physical state changes
|
|
44
44
|
// https://github.com/Koenkk/zigbee2mqtt/issues/9057#issuecomment-1007742130
|
|
45
|
-
await
|
|
45
|
+
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
|
|
46
46
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
|
|
47
47
|
},
|
|
48
48
|
},
|
package/devices/ge.js
CHANGED
|
@@ -61,11 +61,15 @@ module.exports = [
|
|
|
61
61
|
model: '45856GE',
|
|
62
62
|
vendor: 'GE',
|
|
63
63
|
description: 'In-wall smart switch',
|
|
64
|
-
|
|
64
|
+
fromZigbee: [fz.on_off, fz.metering],
|
|
65
|
+
toZigbee: [tz.on_off],
|
|
66
|
+
exposes: [e.switch(), e.energy(), e.power()],
|
|
65
67
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
66
68
|
const endpoint = device.getEndpoint(1);
|
|
67
|
-
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
|
|
68
|
-
await reporting.
|
|
69
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'seMetering']);
|
|
70
|
+
await reporting.instantaneousDemand(endpoint);
|
|
71
|
+
await reporting.currentSummDelivered(endpoint);
|
|
72
|
+
endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 10000, multiplier: 1});
|
|
69
73
|
},
|
|
70
74
|
},
|
|
71
75
|
{
|
package/devices/ikea.js
CHANGED
|
@@ -1000,7 +1000,7 @@ module.exports = [
|
|
|
1000
1000
|
extend: tradfriExtend.light_onoff_brightness(),
|
|
1001
1001
|
},
|
|
1002
1002
|
{
|
|
1003
|
-
zigbeeModel: ['
|
|
1003
|
+
zigbeeModel: ['TRADFRIbulbPAR38WS900lm'],
|
|
1004
1004
|
model: 'LED2006R9',
|
|
1005
1005
|
vendor: 'IKEA',
|
|
1006
1006
|
description: 'TRADFRI E26 PAR38 LED bulb 900 lumen, dimmable, white spectrum, downlight',
|
package/devices/legrand.js
CHANGED
|
@@ -15,12 +15,24 @@ const readInitialBatteryState = async (type, data, device) => {
|
|
|
15
15
|
}
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
const tzLocal = {
|
|
19
|
+
auto_mode: {
|
|
20
|
+
key: ['auto_mode'],
|
|
21
|
+
convertSet: async (entity, key, value, meta) => {
|
|
22
|
+
const mode = {'off': 0x00, 'auto': 0x02, 'on_override': 0x03};
|
|
23
|
+
const payload = {data: Buffer.from([mode[value]])};
|
|
24
|
+
await entity.command('manuSpecificLegrandDevices3', 'command0', payload);
|
|
25
|
+
return {state: {'auto_mode': value}};
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
18
30
|
module.exports = [
|
|
19
31
|
{
|
|
20
|
-
zigbeeModel: ['
|
|
21
|
-
'\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000
|
|
22
|
-
model: '
|
|
23
|
-
description: 'DIN contactor module
|
|
32
|
+
zigbeeModel: [' Dry contact\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'+
|
|
33
|
+
'\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'],
|
|
34
|
+
model: '412173',
|
|
35
|
+
description: 'DIN dry contactor module',
|
|
24
36
|
vendor: 'Legrand',
|
|
25
37
|
extend: extend.switch(),
|
|
26
38
|
fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement, fz.legrand_cluster_fc01, fz.ignore_basic_report, fz.ignore_genOta],
|
|
@@ -34,6 +46,32 @@ module.exports = [
|
|
|
34
46
|
await reporting.onOff(endpoint);
|
|
35
47
|
await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
|
|
36
48
|
await reporting.activePower(endpoint);
|
|
49
|
+
// Read configuration values that are not sent periodically as well as current power (activePower).
|
|
50
|
+
await endpoint.read('haElectricalMeasurement', ['activePower', 0xf000, 0xf001, 0xf002]);
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
zigbeeModel: [' Contactor\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'+
|
|
55
|
+
'\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'],
|
|
56
|
+
model: '412171',
|
|
57
|
+
description: 'DIN contactor module ( Bticino FC80CC )',
|
|
58
|
+
vendor: 'Legrand',
|
|
59
|
+
extend: extend.switch(),
|
|
60
|
+
fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement, fz.legrand_cluster_fc01, fz.ignore_basic_report, fz.ignore_genOta],
|
|
61
|
+
toZigbee: [tz.legrand_deviceMode, tz.on_off, tz.legrand_identify, tz.electrical_measurement_power, tzLocal.auto_mode],
|
|
62
|
+
exposes: [exposes.switch().withState('state', true, 'On/off (works only if device is in "switch" mode)'),
|
|
63
|
+
e.power().withAccess(ea.STATE_GET),
|
|
64
|
+
exposes.enum('device_mode', ea.ALL, ['switch', 'auto'])
|
|
65
|
+
.withDescription('Switch: allow manual on/off, auto uses contact\'s C1/C2 wired actions for Peak/Off-Peak ' +
|
|
66
|
+
'electricity rates'),
|
|
67
|
+
exposes.enum('auto_mode', ea.STATE_SET, ['off', 'auto', 'on_override'])
|
|
68
|
+
.withDescription('Off/auto/on (override) (works only if device is set to "auto" mode)')],
|
|
69
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
70
|
+
const endpoint = device.getEndpoint(1);
|
|
71
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genIdentify', 'genOnOff', 'haElectricalMeasurement']);
|
|
72
|
+
await reporting.onOff(endpoint);
|
|
73
|
+
await reporting.activePower(endpoint);
|
|
74
|
+
await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
|
|
37
75
|
},
|
|
38
76
|
},
|
|
39
77
|
{
|
|
@@ -216,6 +254,7 @@ module.exports = [
|
|
|
216
254
|
ota: ota.zigbeeOTA,
|
|
217
255
|
fromZigbee: [fz.identify, fz.on_off],
|
|
218
256
|
toZigbee: [tz.on_off, tz.legrand_identify],
|
|
257
|
+
whiteLabel: [{vendor: 'Bticino', model: '3584C'}],
|
|
219
258
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
220
259
|
const endpoint = device.getEndpoint(1);
|
|
221
260
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genBinaryInput']);
|
package/devices/lellki.js
CHANGED
|
@@ -23,9 +23,7 @@ module.exports = [
|
|
|
23
23
|
return {l1: 1, l2: 2, l3: 3, l4: 4, l5: 5};
|
|
24
24
|
},
|
|
25
25
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
26
|
-
await
|
|
27
|
-
'manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
|
|
28
|
-
|
|
26
|
+
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
|
|
29
27
|
for (const ID of [1, 2, 3, 4, 5]) {
|
|
30
28
|
await reporting.bind(device.getEndpoint(ID), coordinatorEndpoint, ['genOnOff']);
|
|
31
29
|
}
|
|
@@ -115,7 +113,7 @@ module.exports = [
|
|
|
115
113
|
toZigbee: [tz.on_off, tz.tuya_switch_power_outage_memory],
|
|
116
114
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
117
115
|
const endpoint = device.getEndpoint(1);
|
|
118
|
-
await
|
|
116
|
+
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
|
|
119
117
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
|
|
120
118
|
endpoint.saveClusterAttributeKeyValue('haElectricalMeasurement', {acCurrentDivisor: 1000, acCurrentMultiplier: 1});
|
|
121
119
|
endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 100, multiplier: 1});
|
|
@@ -138,7 +136,7 @@ module.exports = [
|
|
|
138
136
|
toZigbee: [tz.on_off, tz.tuya_switch_power_outage_memory],
|
|
139
137
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
140
138
|
const endpoint = device.getEndpoint(1);
|
|
141
|
-
await
|
|
139
|
+
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
|
|
142
140
|
for (const ep of [1, 2, 3]) {
|
|
143
141
|
await reporting.bind(device.getEndpoint(ep), coordinatorEndpoint, ['genOnOff']);
|
|
144
142
|
await reporting.onOff(device.getEndpoint(ep));
|
package/devices/lidl.js
CHANGED
|
@@ -515,8 +515,7 @@ module.exports = [
|
|
|
515
515
|
extend: extend.switch(),
|
|
516
516
|
meta: {multiEndpoint: true},
|
|
517
517
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
518
|
-
|
|
519
|
-
await endpoint.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
|
|
518
|
+
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
|
|
520
519
|
for (const ID of [1, 2, 3]) {
|
|
521
520
|
await reporting.bind(device.getEndpoint(ID), coordinatorEndpoint, ['genOnOff']);
|
|
522
521
|
}
|
package/devices/makegood.js
CHANGED
|
@@ -2,6 +2,7 @@ const exposes = require('../lib/exposes');
|
|
|
2
2
|
const fz = require('../converters/fromZigbee');
|
|
3
3
|
const tz = require('../converters/toZigbee');
|
|
4
4
|
const reporting = require('../lib/reporting');
|
|
5
|
+
const tuya = require('../lib/tuya');
|
|
5
6
|
const utils = require('../lib/utils');
|
|
6
7
|
const e = exposes.presets;
|
|
7
8
|
const ea = exposes.access;
|
|
@@ -36,7 +37,7 @@ module.exports = [
|
|
|
36
37
|
},
|
|
37
38
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
38
39
|
const endpoint = device.getEndpoint(1);
|
|
39
|
-
await
|
|
40
|
+
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
|
|
40
41
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'seMetering']);
|
|
41
42
|
await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
|
|
42
43
|
await reporting.rmsVoltage(endpoint, {change: 5});
|
package/devices/mecrator.js
CHANGED
|
@@ -2,6 +2,7 @@ const exposes = require('../lib/exposes');
|
|
|
2
2
|
const fz = require('../converters/fromZigbee');
|
|
3
3
|
const tz = require('../converters/toZigbee');
|
|
4
4
|
const reporting = require('../lib/reporting');
|
|
5
|
+
const tuya = require('../lib/tuya');
|
|
5
6
|
const e = exposes.presets;
|
|
6
7
|
const ea = exposes.access;
|
|
7
8
|
|
|
@@ -24,7 +25,7 @@ module.exports = [
|
|
|
24
25
|
meta: {multiEndpoint: true},
|
|
25
26
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
26
27
|
const endpoint = device.getEndpoint(1);
|
|
27
|
-
await
|
|
28
|
+
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
|
|
28
29
|
endpoint.saveClusterAttributeKeyValue('haElectricalMeasurement', {acCurrentDivisor: 1000, acCurrentMultiplier: 1});
|
|
29
30
|
endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 100, multiplier: 1});
|
|
30
31
|
device.save();
|
package/devices/miboxer.js
CHANGED
|
@@ -77,7 +77,7 @@ module.exports = [
|
|
|
77
77
|
exposes: [e.battery(), e.battery_voltage()],
|
|
78
78
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
79
79
|
const endpoint = device.getEndpoint(1);
|
|
80
|
-
await
|
|
80
|
+
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
|
|
81
81
|
await endpoint.command('genGroups', 'miboxerSetZones', {zones: [
|
|
82
82
|
{zoneNum: 1, groupId: 101},
|
|
83
83
|
{zoneNum: 2, groupId: 102},
|
package/devices/moes.js
CHANGED
|
@@ -38,8 +38,7 @@ module.exports = [
|
|
|
38
38
|
},
|
|
39
39
|
meta: {multiEndpoint: true},
|
|
40
40
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
41
|
-
await
|
|
42
|
-
['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
|
|
41
|
+
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
|
|
43
42
|
await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
|
|
44
43
|
await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
|
|
45
44
|
await reporting.onOff(device.getEndpoint(1));
|
package/devices/namron.js
CHANGED
|
@@ -461,7 +461,7 @@ module.exports = [
|
|
|
461
461
|
await reporting.thermostatKeypadLockMode(endpoint);
|
|
462
462
|
|
|
463
463
|
await endpoint.configureReporting('hvacThermostat', [{
|
|
464
|
-
attribute: '
|
|
464
|
+
attribute: 'occupancy',
|
|
465
465
|
minimumReportInterval: 0,
|
|
466
466
|
maximumReportInterval: constants.repInterval.HOUR,
|
|
467
467
|
reportableChange: null,
|
package/devices/neo.js
CHANGED
|
@@ -79,7 +79,7 @@ module.exports = [
|
|
|
79
79
|
],
|
|
80
80
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
81
81
|
const endpoint = device.getEndpoint(1);
|
|
82
|
-
await
|
|
82
|
+
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
|
|
83
83
|
await endpoint.command('manuSpecificTuya', 'mcuVersionRequest', {'seq': 0x0002});
|
|
84
84
|
},
|
|
85
85
|
},
|
package/devices/philips.js
CHANGED
|
@@ -2914,4 +2914,11 @@ module.exports = [
|
|
|
2914
2914
|
description: 'Hue White ambiance BR30 E26',
|
|
2915
2915
|
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
|
|
2916
2916
|
},
|
|
2917
|
+
{
|
|
2918
|
+
zigbeeModel: ['LCX012'],
|
|
2919
|
+
model: '929003535301',
|
|
2920
|
+
vendor: 'Philips',
|
|
2921
|
+
description: 'Hue Festivia gradient light string 250',
|
|
2922
|
+
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
2923
|
+
},
|
|
2917
2924
|
];
|
package/devices/sinope.js
CHANGED
|
@@ -15,20 +15,20 @@ module.exports = [
|
|
|
15
15
|
description: 'Zigbee line volt thermostat',
|
|
16
16
|
meta: {thermostat: {dontMapPIHeatingDemand: true}},
|
|
17
17
|
fromZigbee: [fz.legacy.sinope_thermostat_att_report, fz.legacy.hvac_user_interface, fz.electrical_measurement, fz.metering,
|
|
18
|
-
fz.ignore_temperature_report, fz.legacy.sinope_thermostat_state],
|
|
18
|
+
fz.ignore_temperature_report, fz.legacy.sinope_thermostat_state, fz.sinope_thermostat],
|
|
19
19
|
toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint,
|
|
20
20
|
tz.thermostat_temperature_display_mode, tz.thermostat_keypad_lockout, tz.thermostat_system_mode, tz.thermostat_running_state,
|
|
21
21
|
tz.sinope_thermostat_occupancy, tz.sinope_thermostat_backlight_autodim_param, tz.sinope_thermostat_time,
|
|
22
22
|
tz.sinope_thermostat_enable_outdoor_temperature, tz.sinope_thermostat_outdoor_temperature, tz.sinope_time_format],
|
|
23
23
|
exposes: [e.local_temperature(), e.keypad_lockout(), e.power(), e.current(), e.voltage(), e.energy(),
|
|
24
24
|
exposes.climate().withSetpoint('occupied_heating_setpoint', 5, 30, 0.5).withLocalTemperature()
|
|
25
|
-
.withSystemMode(['off', 'heat']).withRunningState(['idle', 'heat']),
|
|
25
|
+
.withSystemMode(['off', 'heat']).withRunningState(['idle', 'heat']).withPiHeatingDemand(),
|
|
26
|
+
exposes.enum('thermostat_occupancy', ea.SET, ['unoccupied', 'occupied']).withDescription('Occupancy state of the thermostat'),
|
|
26
27
|
exposes.enum('backlight_auto_dim', ea.SET, ['on demand', 'sensing']).withDescription('Control backlight dimming behavior')],
|
|
27
28
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
28
29
|
const endpoint = device.getEndpoint(1);
|
|
29
30
|
const binds = ['genBasic', 'genIdentify', 'genGroups', 'hvacThermostat', 'hvacUserInterfaceCfg', 'msTemperatureMeasurement',
|
|
30
31
|
'haElectricalMeasurement', 'seMetering', 'manuSpecificSinope'];
|
|
31
|
-
|
|
32
32
|
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
33
33
|
await reporting.thermostatTemperature(endpoint);
|
|
34
34
|
await reporting.thermostatPIHeatingDemand(endpoint);
|
|
@@ -72,7 +72,7 @@ module.exports = [
|
|
|
72
72
|
description: 'Zigbee line volt thermostat',
|
|
73
73
|
meta: {thermostat: {dontMapPIHeatingDemand: true}},
|
|
74
74
|
fromZigbee: [fz.legacy.sinope_thermostat_att_report, fz.legacy.hvac_user_interface, fz.electrical_measurement, fz.metering,
|
|
75
|
-
fz.ignore_temperature_report, fz.legacy.sinope_thermostat_state],
|
|
75
|
+
fz.ignore_temperature_report, fz.legacy.sinope_thermostat_state, fz.sinope_thermostat],
|
|
76
76
|
toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint,
|
|
77
77
|
tz.thermostat_temperature_display_mode, tz.thermostat_keypad_lockout, tz.thermostat_system_mode, tz.thermostat_running_state,
|
|
78
78
|
tz.sinope_thermostat_occupancy, tz.sinope_thermostat_backlight_autodim_param, tz.sinope_thermostat_time,
|
|
@@ -80,6 +80,7 @@ module.exports = [
|
|
|
80
80
|
exposes: [e.local_temperature(), e.keypad_lockout(), e.power(), e.current(), e.voltage(), e.energy(),
|
|
81
81
|
exposes.climate().withSetpoint('occupied_heating_setpoint', 5, 30, 0.5).withLocalTemperature()
|
|
82
82
|
.withSystemMode(['off', 'heat']).withRunningState(['idle', 'heat']).withPiHeatingDemand(),
|
|
83
|
+
exposes.enum('thermostat_occupancy', ea.SET, ['unoccupied', 'occupied']).withDescription('Occupancy state of the thermostat'),
|
|
83
84
|
exposes.enum('backlight_auto_dim', ea.SET, ['on demand', 'sensing']).withDescription('Control backlight dimming behavior')],
|
|
84
85
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
85
86
|
const endpoint = device.getEndpoint(1);
|
package/devices/sunricher.js
CHANGED
|
@@ -465,7 +465,7 @@ module.exports = [
|
|
|
465
465
|
await reporting.thermostatKeypadLockMode(endpoint);
|
|
466
466
|
|
|
467
467
|
await endpoint.configureReporting('hvacThermostat', [{
|
|
468
|
-
attribute: '
|
|
468
|
+
attribute: 'occupancy',
|
|
469
469
|
minimumReportInterval: 0,
|
|
470
470
|
maximumReportInterval: constants.repInterval.HOUR,
|
|
471
471
|
reportableChange: null,
|
package/devices/tuya.js
CHANGED
|
@@ -665,6 +665,7 @@ module.exports = [
|
|
|
665
665
|
model: 'TS0204',
|
|
666
666
|
vendor: 'TuYa',
|
|
667
667
|
description: 'Gas sensor',
|
|
668
|
+
whiteLabel: [{vendor: 'Tesla Smart', model: 'TSL-SEN-GAS'}],
|
|
668
669
|
fromZigbee: [fz.ias_gas_alarm_1, fz.ignore_basic_report],
|
|
669
670
|
toZigbee: [],
|
|
670
671
|
exposes: [e.gas(), e.tamper()],
|
|
@@ -674,6 +675,7 @@ module.exports = [
|
|
|
674
675
|
model: 'TS0205',
|
|
675
676
|
vendor: 'TuYa',
|
|
676
677
|
description: 'Smoke sensor',
|
|
678
|
+
whiteLabel: [{vendor: 'Tesla Smart', model: 'TSL-SEN-SMOKE'}],
|
|
677
679
|
fromZigbee: [fz.ias_smoke_alarm_1, fz.battery, fz.ignore_basic_report],
|
|
678
680
|
toZigbee: [],
|
|
679
681
|
exposes: [e.smoke(), e.battery_low(), e.tamper(), e.battery()],
|
|
@@ -702,7 +704,11 @@ module.exports = [
|
|
|
702
704
|
fromZigbee: [fz.ias_contact_alarm_1, fz.battery, fz.ignore_basic_report, fz.ias_contact_alarm_1_report],
|
|
703
705
|
toZigbee: [],
|
|
704
706
|
exposes: [e.contact(), e.battery_low(), e.tamper(), e.battery(), e.battery_voltage()],
|
|
705
|
-
whiteLabel: [
|
|
707
|
+
whiteLabel: [
|
|
708
|
+
{vendor: 'CR Smart Home', model: 'TS0203'},
|
|
709
|
+
{vendor: 'TuYa', model: 'iH-F001'},
|
|
710
|
+
{vendor: 'Tesla Smart', model: 'TSL-SEN-DOOR'},
|
|
711
|
+
],
|
|
706
712
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
707
713
|
try {
|
|
708
714
|
const endpoint = device.getEndpoint(1);
|
|
@@ -1837,12 +1843,7 @@ module.exports = [
|
|
|
1837
1843
|
},
|
|
1838
1844
|
meta: {multiEndpoint: true},
|
|
1839
1845
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1840
|
-
|
|
1841
|
-
try {
|
|
1842
|
-
await ep1.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
|
|
1843
|
-
} catch (e) {
|
|
1844
|
-
// Fails for some: https://github.com/Koenkk/zigbee2mqtt/discussions/13368
|
|
1845
|
-
}
|
|
1846
|
+
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
|
|
1846
1847
|
await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
|
|
1847
1848
|
await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
|
|
1848
1849
|
},
|
|
@@ -2465,7 +2466,8 @@ module.exports = [
|
|
|
2465
2466
|
.withDescription('Recover state after power outage'),
|
|
2466
2467
|
exposes.enum('indicator_mode', ea.ALL, ['off', 'off/on', 'on/off', 'on'])
|
|
2467
2468
|
.withDescription('Plug LED indicator mode'), e.child_lock()],
|
|
2468
|
-
onEvent:
|
|
2469
|
+
onEvent: (type, data, device, options) =>
|
|
2470
|
+
tuya.onEventMeasurementPoll(type, data, device, options, true, device.applicationVersion === 160),
|
|
2469
2471
|
},
|
|
2470
2472
|
{
|
|
2471
2473
|
fingerprint: tuya.fingerprint('TS0601', ['_TZE200_ntcy3xu1']),
|
|
@@ -2510,7 +2512,7 @@ module.exports = [
|
|
|
2510
2512
|
onEvent: tuya.onEventsetTime,
|
|
2511
2513
|
},
|
|
2512
2514
|
{
|
|
2513
|
-
fingerprint: tuya.fingerprint('TS0601', ['
|
|
2515
|
+
fingerprint: tuya.fingerprint('TS0601', ['_TZE200_bkkmqmyo', '_TZE200_eaac7dkw']),
|
|
2514
2516
|
model: 'TS0601_din_1',
|
|
2515
2517
|
vendor: 'TuYa',
|
|
2516
2518
|
description: 'Zigbee DIN energy meter',
|
|
@@ -2522,7 +2524,7 @@ module.exports = [
|
|
|
2522
2524
|
meta: {
|
|
2523
2525
|
tuyaDatapoints: [
|
|
2524
2526
|
[1, 'energy', tuya.valueConverter.divideBy100],
|
|
2525
|
-
[6, null, tuya.valueConverter.
|
|
2527
|
+
[6, null, tuya.valueConverter.phaseVariant1], // voltage and current
|
|
2526
2528
|
[16, 'state', tuya.valueConverter.onOff],
|
|
2527
2529
|
[102, 'produced_energy', tuya.valueConverter.divideBy100],
|
|
2528
2530
|
[103, 'power', tuya.valueConverter.raw],
|
|
@@ -2539,6 +2541,54 @@ module.exports = [
|
|
|
2539
2541
|
},
|
|
2540
2542
|
whiteLabel: [{vendor: 'Hiking', model: 'DDS238-2'}, {vendor: 'TuYa', model: 'RC-MCB'}],
|
|
2541
2543
|
},
|
|
2544
|
+
{
|
|
2545
|
+
fingerprint: tuya.fingerprint('TS0601', ['_TZE200_lsanae15']),
|
|
2546
|
+
model: 'TS0601_din_2',
|
|
2547
|
+
vendor: 'TuYa',
|
|
2548
|
+
description: 'Zigbee DIN energy meter',
|
|
2549
|
+
fromZigbee: [tuya.fzDataPoints],
|
|
2550
|
+
toZigbee: [tuya.tzDataPoints],
|
|
2551
|
+
configure: tuya.configureMagicPacket,
|
|
2552
|
+
whiteLabel: [{vendor: 'XOCA', model: 'DAC2161C'}],
|
|
2553
|
+
exposes: [tuya.exposes.switch(), e.energy(), e.power(), e.voltage(), e.current(),
|
|
2554
|
+
exposes.enum('fault', ea.STATE, ['clear', 'over_current_threshold', 'over_power_threshold',
|
|
2555
|
+
'over_voltage threshold', 'wrong_frequency_threshold']).withDescription('Fault status of the device (clear = nothing)'),
|
|
2556
|
+
exposes.enum('threshold_1', ea.STATE, ['not_set', 'over_current_threshold', 'over_voltage_threshold'])
|
|
2557
|
+
.withDescription('State of threshold_1'),
|
|
2558
|
+
exposes.binary('threshold_1_protection', ea.STATE, 'ON', 'OFF')
|
|
2559
|
+
.withDescription('OFF - alarm only, ON - relay will be off when threshold reached'),
|
|
2560
|
+
exposes.numeric('threshold_1_value', ea.STATE)
|
|
2561
|
+
.withDescription('Can be in Volt or Ampere depending on threshold setting. Setup the value on the device'),
|
|
2562
|
+
exposes.enum('threshold_2', ea.STATE, ['not_set', 'over_current_threshold', 'over_voltage_threshold'])
|
|
2563
|
+
.withDescription('State of threshold_2'),
|
|
2564
|
+
exposes.binary('threshold_2_protection', ea.STATE, 'ON', 'OFF')
|
|
2565
|
+
.withDescription('OFF - alarm only, ON - relay will be off when threshold reached'),
|
|
2566
|
+
exposes.numeric('threshold_2_value', ea.STATE)
|
|
2567
|
+
.withDescription('Setup value on the device'),
|
|
2568
|
+
exposes.binary('clear_fault', ea.STATE_SET, 'ON', 'OFF')
|
|
2569
|
+
.withDescription('Turn ON to clear last the fault'),
|
|
2570
|
+
exposes.text('meter_id', ea.STATE).withDescription('Meter ID (ID of device)'),
|
|
2571
|
+
],
|
|
2572
|
+
meta: {
|
|
2573
|
+
tuyaDatapoints: [
|
|
2574
|
+
[1, 'energy', tuya.valueConverter.divideBy100],
|
|
2575
|
+
[3, null, null], // Monthly, but sends data only after request
|
|
2576
|
+
[4, null, null], // Dayly, but sends data only after request
|
|
2577
|
+
[6, null, tuya.valueConverter.phaseVariant2], // voltage and current
|
|
2578
|
+
[10, 'fault', tuya.valueConverterBasic.lookup({'clear': 0, 'over_current_threshold': 1,
|
|
2579
|
+
'over_power_threshold': 2, 'over_voltage_threshold': 4, 'wrong_frequency_threshold': 8})],
|
|
2580
|
+
[11, null, null], // Frozen - strange function, in native app - nothing is clear
|
|
2581
|
+
[16, 'state', tuya.valueConverter.onOff],
|
|
2582
|
+
[17, null, tuya.valueConverter.threshold], // It's settable, but can't write converter
|
|
2583
|
+
[18, 'meter_id', tuya.valueConverter.raw],
|
|
2584
|
+
[20, 'clear_fault', tuya.valueConverter.onOff], // Clear fault
|
|
2585
|
+
[21, null, null], // Forward Energy T1 - don't know what this
|
|
2586
|
+
[22, null, null], // Forward Energy T2 - don't know what this
|
|
2587
|
+
[23, null, null], // Forward Energy T3 - don't know what this
|
|
2588
|
+
[24, null, null], // Forward Energy T4 - don't know what this
|
|
2589
|
+
],
|
|
2590
|
+
},
|
|
2591
|
+
},
|
|
2542
2592
|
{
|
|
2543
2593
|
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_byzdayie'},
|
|
2544
2594
|
{modelID: 'TS0601', manufacturerName: '_TZE200_fsb6zw01'},
|
package/devices/ubisys.js
CHANGED
|
@@ -95,8 +95,8 @@ const ubisys = {
|
|
|
95
95
|
cluster: 'hvacThermostat',
|
|
96
96
|
type: ['attributeReport', 'readResponse'],
|
|
97
97
|
convert: (model, msg, publish, options, meta) => {
|
|
98
|
-
if (msg.data.hasOwnProperty('
|
|
99
|
-
return {vacation_mode: msg.data.
|
|
98
|
+
if (msg.data.hasOwnProperty('occupancy')) {
|
|
99
|
+
return {vacation_mode: msg.data.occupancy === 0};
|
|
100
100
|
}
|
|
101
101
|
},
|
|
102
102
|
},
|
|
@@ -516,7 +516,7 @@ const ubisys = {
|
|
|
516
516
|
thermostat_vacation_mode: {
|
|
517
517
|
key: ['vacation_mode'],
|
|
518
518
|
convertGet: async (entity, key, meta) => {
|
|
519
|
-
await entity.read('hvacThermostat', ['
|
|
519
|
+
await entity.read('hvacThermostat', ['occupancy']);
|
|
520
520
|
},
|
|
521
521
|
},
|
|
522
522
|
},
|
package/devices/useelink.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const exposes = require('../lib/exposes');
|
|
2
2
|
const reporting = require('../lib/reporting');
|
|
3
3
|
const extend = require('../lib/extend');
|
|
4
|
+
const tuya = require('../lib/tuya');
|
|
4
5
|
const e = exposes.presets;
|
|
5
6
|
|
|
6
7
|
module.exports = [
|
|
@@ -32,8 +33,7 @@ module.exports = [
|
|
|
32
33
|
extend: extend.switch(),
|
|
33
34
|
meta: {multiEndpoint: true},
|
|
34
35
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
35
|
-
await
|
|
36
|
-
['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
|
|
36
|
+
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
|
|
37
37
|
for (const ID of [1, 2, 3, 4, 5]) {
|
|
38
38
|
await reporting.bind(device.getEndpoint(ID), coordinatorEndpoint, ['genOnOff']);
|
|
39
39
|
}
|
package/devices/woox.js
CHANGED
|
@@ -107,10 +107,7 @@ module.exports = [
|
|
|
107
107
|
onEvent: tuya.onEventSetTime,
|
|
108
108
|
exposes: [e.switch(), e.battery()],
|
|
109
109
|
meta: {disableDefaultResponse: true},
|
|
110
|
-
configure:
|
|
111
|
-
const endpoint = device.getEndpoint(1);
|
|
112
|
-
await endpoint.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
|
|
113
|
-
},
|
|
110
|
+
configure: tuya.configureMagicPacket,
|
|
114
111
|
},
|
|
115
112
|
{
|
|
116
113
|
fingerprint: [{modelID: 'TS0505A', manufacturerName: '_TZ3000_keabpigv'}],
|
package/devices/zemismart.js
CHANGED
|
@@ -70,8 +70,7 @@ module.exports = [
|
|
|
70
70
|
whiteLabel: [{vendor: 'BSEED', model: 'TS0003', description: 'Zigbee switch'}],
|
|
71
71
|
meta: {multiEndpoint: true, disableDefaultResponse: true},
|
|
72
72
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
73
|
-
await
|
|
74
|
-
['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
|
|
73
|
+
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
|
|
75
74
|
await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
|
|
76
75
|
await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
|
|
77
76
|
await reporting.bind(device.getEndpoint(3), coordinatorEndpoint, ['genOnOff']);
|
|
@@ -91,9 +90,8 @@ module.exports = [
|
|
|
91
90
|
return {'left': 1, 'center': 2, 'right': 3};
|
|
92
91
|
},
|
|
93
92
|
meta: {multiEndpoint: true},
|
|
94
|
-
configure: async (device, coordinatorEndpoint) => {
|
|
95
|
-
await
|
|
96
|
-
['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
|
|
93
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
94
|
+
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
|
|
97
95
|
for (const endpointID of [1, 2, 3]) {
|
|
98
96
|
const endpoint = device.getEndpoint(endpointID);
|
|
99
97
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
|
|
@@ -144,9 +142,7 @@ module.exports = [
|
|
|
144
142
|
},
|
|
145
143
|
meta: {multiEndpoint: true},
|
|
146
144
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
147
|
-
await
|
|
148
|
-
'manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
|
|
149
|
-
|
|
145
|
+
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
|
|
150
146
|
await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
|
|
151
147
|
await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
|
|
152
148
|
await reporting.onOff(device.getEndpoint(1));
|
package/lib/reporting.js
CHANGED
|
@@ -179,7 +179,7 @@ module.exports = {
|
|
|
179
179
|
await endpoint.configureReporting('hvacThermostat', p);
|
|
180
180
|
},
|
|
181
181
|
thermostatOcupancy: async (endpoint, overrides) => {
|
|
182
|
-
const p = payload('
|
|
182
|
+
const p = payload('occupancy', 0, repInterval.HOUR, 0, overrides);
|
|
183
183
|
await endpoint.configureReporting('hvacThermostat', p);
|
|
184
184
|
},
|
|
185
185
|
thermostatTemperatureSetpointHold: async (endpoint, overrides) => {
|
package/lib/tuya.js
CHANGED
|
@@ -1257,12 +1257,33 @@ const valueConverter = {
|
|
|
1257
1257
|
divideBy100: valueConverterBasic.divideBy(100),
|
|
1258
1258
|
divideBy10: valueConverterBasic.divideBy(10),
|
|
1259
1259
|
raw: valueConverterBasic.raw(),
|
|
1260
|
-
|
|
1260
|
+
phaseVariant1: {
|
|
1261
1261
|
from: (v) => {
|
|
1262
1262
|
const buffer = Buffer.from(v, 'base64');
|
|
1263
1263
|
return {voltage: (buffer[14] | buffer[13] << 8) / 10, current: (buffer[12] | buffer[11] << 8) / 1000};
|
|
1264
1264
|
},
|
|
1265
1265
|
},
|
|
1266
|
+
phaseVariant2: {
|
|
1267
|
+
from: (v) => {
|
|
1268
|
+
const buf = Buffer.from(v, 'base64');
|
|
1269
|
+
return {voltage: (buf[1] | buf[0] << 8) / 10, current: (buf[4] | buf[3] << 8) / 1000, power: (buf[7] | buf[6] << 8)};
|
|
1270
|
+
},
|
|
1271
|
+
},
|
|
1272
|
+
threshold: {
|
|
1273
|
+
from: (v) => {
|
|
1274
|
+
const buffer = Buffer.from(v, 'base64');
|
|
1275
|
+
const stateLookup = {0: 'not_set', 1: 'over_current_threshold', 3: 'over_voltage_threshold'};
|
|
1276
|
+
const protectionLookup = {0: 'OFF', 1: 'ON'};
|
|
1277
|
+
return {
|
|
1278
|
+
threshold_1_protection: protectionLookup[buffer[1]],
|
|
1279
|
+
threshold_1: stateLookup[buffer[0]],
|
|
1280
|
+
threshold_1_value: (buffer[3] | buffer[2] << 8),
|
|
1281
|
+
threshold_2_protection: protectionLookup[buffer[5]],
|
|
1282
|
+
threshold_2: stateLookup[buffer[4]],
|
|
1283
|
+
threshold_2_value: (buffer[7] | buffer[6] << 8),
|
|
1284
|
+
};
|
|
1285
|
+
},
|
|
1286
|
+
},
|
|
1266
1287
|
true0ElseFalse: {from: (v) => v === 0},
|
|
1267
1288
|
selfTestResult: valueConverterBasic.lookup({'checking': 0, 'success': 1, 'failure': 2, 'others': 3}),
|
|
1268
1289
|
lockUnlock: valueConverterBasic.lookup({'LOCK': true, 'UNLOCK': false}),
|
|
@@ -1441,7 +1462,7 @@ const tzDataPoints = {
|
|
|
1441
1462
|
'system_mode', 'heating_stop', 'current_heating_setpoint', 'local_temperature_calibration', 'preset', 'boost_timeset_countdown',
|
|
1442
1463
|
'holiday_start_stop', 'holiday_temperature', 'comfort_temperature', 'eco_temperature', 'working_day', 'week_schedule_programming',
|
|
1443
1464
|
'online', 'holiday_mode_date', 'schedule', 'schedule_monday', 'schedule_tuesday', 'schedule_wednesday', 'schedule_thursday',
|
|
1444
|
-
'schedule_friday', 'schedule_saturday', 'schedule_sunday',
|
|
1465
|
+
'schedule_friday', 'schedule_saturday', 'schedule_sunday', 'clear_fault',
|
|
1445
1466
|
],
|
|
1446
1467
|
convertSet: async (entity, key, value, meta) => {
|
|
1447
1468
|
// A set converter is only called once; therefore we need to loop
|
|
@@ -1496,7 +1517,7 @@ const fzDataPoints = {
|
|
|
1496
1517
|
result = {...result, ...dpEntry[2].from(value, meta)};
|
|
1497
1518
|
}
|
|
1498
1519
|
} else {
|
|
1499
|
-
meta.logger.
|
|
1520
|
+
meta.logger.debug(`Datapoint ${dpId} not defined for '${meta.device.manufacturerName}' ` +
|
|
1500
1521
|
`with data ${JSON.stringify(dpValue)}`);
|
|
1501
1522
|
}
|
|
1502
1523
|
}
|