zigbee-herdsman-converters 14.0.608 → 14.0.611
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/toZigbee.js +5 -5
- package/devices/bticino.js +10 -8
- package/devices/ledvance.js +8 -0
- package/devices/legrand.js +14 -11
- package/devices/lidl.js +22 -0
- package/devices/mecrator.js +17 -0
- package/devices/moes.js +12 -4
- package/devices/niko.js +1 -2
- package/devices/onesti.js +3 -1
- package/devices/perenio.js +90 -5
- package/devices/qoto.js +113 -0
- package/devices/sylvania.js +1 -1
- package/devices/tuya.js +7 -3
- package/devices/woox.js +1 -0
- package/package.json +2 -2
package/converters/toZigbee.js
CHANGED
|
@@ -4633,22 +4633,22 @@ const converters = {
|
|
|
4633
4633
|
}
|
|
4634
4634
|
},
|
|
4635
4635
|
},
|
|
4636
|
-
|
|
4636
|
+
legrand_settingEnableLedInDark: {
|
|
4637
4637
|
// connected power outlet is on attribute 2 and not 1
|
|
4638
|
-
key: ['
|
|
4638
|
+
key: ['led_in_dark'],
|
|
4639
4639
|
convertSet: async (entity, key, value, meta) => {
|
|
4640
4640
|
// enable or disable the LED (blue) when permitJoin=false (LED off)
|
|
4641
4641
|
const enableLedIfOn = value === 'ON' || (value === 'OFF' ? false : !!value);
|
|
4642
4642
|
const payload = {1: {value: enableLedIfOn, type: 16}};
|
|
4643
4643
|
await entity.write('manuSpecificLegrandDevices', payload, manufacturerOptions.legrand);
|
|
4644
|
-
return {state: {'
|
|
4644
|
+
return {state: {'led_in_dark': value}};
|
|
4645
4645
|
},
|
|
4646
4646
|
convertGet: async (entity, key, meta) => {
|
|
4647
4647
|
await entity.read('manuSpecificLegrandDevices', [0x0001], manufacturerOptions.legrand);
|
|
4648
4648
|
},
|
|
4649
4649
|
},
|
|
4650
4650
|
legrand_settingEnableLedIfOn: {
|
|
4651
|
-
key: ['
|
|
4651
|
+
key: ['led_if_on'],
|
|
4652
4652
|
convertSet: async (entity, key, value, meta) => {
|
|
4653
4653
|
// enable the LED when the light object is "doing something"
|
|
4654
4654
|
// on the light switch, the LED is on when the light is on,
|
|
@@ -4656,7 +4656,7 @@ const converters = {
|
|
|
4656
4656
|
const enableLedIfOn = value === 'ON' || (value === 'OFF' ? false : !!value);
|
|
4657
4657
|
const payload = {2: {value: enableLedIfOn, type: 16}};
|
|
4658
4658
|
await entity.write('manuSpecificLegrandDevices', payload, manufacturerOptions.legrand);
|
|
4659
|
-
return {state: {'
|
|
4659
|
+
return {state: {'led_if_on': value}};
|
|
4660
4660
|
},
|
|
4661
4661
|
convertGet: async (entity, key, meta) => {
|
|
4662
4662
|
await entity.read('manuSpecificLegrandDevices', [0x0002], manufacturerOptions.legrand);
|
package/devices/bticino.js
CHANGED
|
@@ -13,11 +13,12 @@ module.exports = [
|
|
|
13
13
|
vendor: 'BTicino',
|
|
14
14
|
description: 'Light switch with neutral',
|
|
15
15
|
fromZigbee: [fz.identify, fz.on_off, fz.K4003C_binary_input, fz.legrand_cluster_fc01],
|
|
16
|
-
toZigbee: [tz.on_off, tz.
|
|
16
|
+
toZigbee: [tz.on_off, tz.legrand_settingEnableLedInDark, tz.legrand_settingEnableLedIfOn, tz.legrand_identify],
|
|
17
17
|
exposes: [
|
|
18
18
|
e.switch(), e.action(['identify', 'on', 'off']),
|
|
19
|
-
exposes.binary('
|
|
20
|
-
|
|
19
|
+
exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing to
|
|
20
|
+
see the switch in the dark`),
|
|
21
|
+
exposes.binary('led_if_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is turned on'),
|
|
21
22
|
],
|
|
22
23
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
23
24
|
const endpoint = device.getEndpoint(1);
|
|
@@ -31,7 +32,7 @@ module.exports = [
|
|
|
31
32
|
description: 'Dimmer switch with neutral',
|
|
32
33
|
extend: extend.light_onoff_brightness({noConfigure: true}),
|
|
33
34
|
fromZigbee: [fz.brightness, fz.identify, fz.on_off, fz.lighting_ballast_configuration, fz.legrand_cluster_fc01],
|
|
34
|
-
toZigbee: [tz.light_onoff_brightness, tz.
|
|
35
|
+
toZigbee: [tz.light_onoff_brightness, tz.legrand_settingEnableLedInDark, tz.legrand_settingEnableLedIfOn,
|
|
35
36
|
tz.legrand_deviceMode, tz.legrand_identify, tz.ballast_config],
|
|
36
37
|
exposes: [e.light_brightness(),
|
|
37
38
|
exposes.numeric('ballast_minimum_level', ea.ALL).withValueMin(1).withValueMax(254)
|
|
@@ -39,8 +40,9 @@ module.exports = [
|
|
|
39
40
|
exposes.numeric('ballast_maximum_level', ea.ALL).withValueMin(1).withValueMax(254)
|
|
40
41
|
.withDescription('Specifies the maximum brightness value'),
|
|
41
42
|
exposes.binary('device_mode', ea.ALL, 'dimmer_on', 'dimmer_off').withDescription('Allow the device to change brightness'),
|
|
42
|
-
exposes.binary('
|
|
43
|
-
|
|
43
|
+
exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing to
|
|
44
|
+
see the switch in the dark`),
|
|
45
|
+
exposes.binary('led_if_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is turned on')],
|
|
44
46
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
45
47
|
await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
|
|
46
48
|
const endpoint = device.getEndpoint(1);
|
|
@@ -62,7 +64,7 @@ module.exports = [
|
|
|
62
64
|
fromZigbee: [fz.identify, fz.ignore_basic_report, fz.ignore_zclversion_read, fz.bticino_4027C_binary_input_moving,
|
|
63
65
|
fz.cover_position_tilt],
|
|
64
66
|
toZigbee: [tz.bticino_4027C_cover_state, tz.bticino_4027C_cover_position, tz.legrand_identify,
|
|
65
|
-
tz.
|
|
67
|
+
tz.legrand_settingEnableLedInDark],
|
|
66
68
|
exposes: [e.cover_position()],
|
|
67
69
|
meta: {coverInverted: true},
|
|
68
70
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
@@ -95,7 +97,7 @@ module.exports = [
|
|
|
95
97
|
vendor: 'BTicino',
|
|
96
98
|
description: 'Power socket with power consumption monitoring',
|
|
97
99
|
fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement],
|
|
98
|
-
toZigbee: [tz.on_off, tz.
|
|
100
|
+
toZigbee: [tz.on_off, tz.legrand_settingEnableLedInDark, tz.legrand_identify],
|
|
99
101
|
exposes: [e.switch(), e.action(['identify']), e.power(), e.voltage(), e.current()],
|
|
100
102
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
101
103
|
const endpoint = device.getEndpoint(1);
|
package/devices/ledvance.js
CHANGED
|
@@ -167,4 +167,12 @@ module.exports = [
|
|
|
167
167
|
extend: extend.ledvance.light_onoff_brightness_colortemp_color({colorTempRange: [153, 370]}),
|
|
168
168
|
ota: ota.ledvance,
|
|
169
169
|
},
|
|
170
|
+
{
|
|
171
|
+
zigbeeModel: ['CLA 60 DIM'],
|
|
172
|
+
model: '4058075728981',
|
|
173
|
+
vendor: 'LEDVANCE',
|
|
174
|
+
description: 'SMART+ Classic A E27 dimmable white',
|
|
175
|
+
extend: extend.ledvance.light_onoff_brightness(),
|
|
176
|
+
ota: ota.ledvance,
|
|
177
|
+
},
|
|
170
178
|
];
|
package/devices/legrand.js
CHANGED
|
@@ -106,7 +106,7 @@ module.exports = [
|
|
|
106
106
|
fz.identify, fz.ignore_basic_report,
|
|
107
107
|
// support binary report on moving state (supposed)
|
|
108
108
|
fz.legrand_binary_input_moving, fz.cover_position_tilt],
|
|
109
|
-
toZigbee: [tz.cover_state, tz.cover_position_tilt, tz.legrand_identify, tz.
|
|
109
|
+
toZigbee: [tz.cover_state, tz.cover_position_tilt, tz.legrand_identify, tz.legrand_settingEnableLedInDark],
|
|
110
110
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
111
111
|
const endpoint = device.getEndpoint(1);
|
|
112
112
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genBinaryInput', 'closuresWindowCovering', 'genIdentify']);
|
|
@@ -175,7 +175,7 @@ module.exports = [
|
|
|
175
175
|
description: 'Wired switch without neutral',
|
|
176
176
|
extend: extend.light_onoff_brightness({noConfigure: true}),
|
|
177
177
|
fromZigbee: [fz.brightness, fz.identify, fz.on_off, fz.lighting_ballast_configuration, fz.legrand_cluster_fc01],
|
|
178
|
-
toZigbee: [tz.light_onoff_brightness, tz.
|
|
178
|
+
toZigbee: [tz.light_onoff_brightness, tz.legrand_settingEnableLedInDark, tz.legrand_settingEnableLedIfOn,
|
|
179
179
|
tz.legrand_deviceMode, tz.legrand_identify, tz.ballast_config],
|
|
180
180
|
exposes: [e.light_brightness(),
|
|
181
181
|
exposes.numeric('ballast_minimum_level', ea.ALL).withValueMin(1).withValueMax(254)
|
|
@@ -183,8 +183,9 @@ module.exports = [
|
|
|
183
183
|
exposes.numeric('ballast_maximum_level', ea.ALL).withValueMin(1).withValueMax(254)
|
|
184
184
|
.withDescription('Specifies the maximum brightness value'),
|
|
185
185
|
exposes.binary('device_mode', ea.ALL, 'dimmer_on', 'dimmer_off').withDescription('Allow the device to change brightness'),
|
|
186
|
-
exposes.binary('
|
|
187
|
-
|
|
186
|
+
exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing to
|
|
187
|
+
see the switch in the dark`),
|
|
188
|
+
exposes.binary('led_if_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is turned on')],
|
|
188
189
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
189
190
|
await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
|
|
190
191
|
const endpoint = device.getEndpoint(1);
|
|
@@ -201,8 +202,9 @@ module.exports = [
|
|
|
201
202
|
ota: ota.zigbeeOTA,
|
|
202
203
|
description: 'Power socket with power consumption monitoring',
|
|
203
204
|
fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement],
|
|
204
|
-
toZigbee: [tz.on_off, tz.
|
|
205
|
-
exposes: [e.switch(), e.action(['identify']), e.power()
|
|
205
|
+
toZigbee: [tz.on_off, tz.legrand_settingEnableLedInDark, tz.legrand_identify, tz.legrand_settingEnableLedIfOn],
|
|
206
|
+
exposes: [e.switch(), e.action(['identify']), e.power(),
|
|
207
|
+
exposes.binary('led_if_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the device is turned on')],
|
|
206
208
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
207
209
|
const endpoint = device.getEndpoint(1);
|
|
208
210
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genIdentify', 'genOnOff', 'haElectricalMeasurement']);
|
|
@@ -256,7 +258,7 @@ module.exports = [
|
|
|
256
258
|
vendor: 'Legrand',
|
|
257
259
|
description: 'DIN power consumption module',
|
|
258
260
|
fromZigbee: [fz.identify, fz.metering, fz.electrical_measurement, fz.ignore_basic_report, fz.ignore_genOta, fz.legrand_power_alarm],
|
|
259
|
-
toZigbee: [tz.
|
|
261
|
+
toZigbee: [tz.legrand_settingEnableLedInDark, tz.legrand_identify, tz.electrical_measurement_power, tz.legrand_powerAlarm],
|
|
260
262
|
exposes: [e.power().withAccess(ea.STATE_GET), exposes.binary('power_alarm_active', ea.STATE, true, false),
|
|
261
263
|
exposes.binary('power_alarm', ea.ALL, true, false).withDescription('Enable/disable the power alarm')],
|
|
262
264
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
@@ -344,11 +346,12 @@ module.exports = [
|
|
|
344
346
|
vendor: 'Legrand',
|
|
345
347
|
description: 'Double wired switch with neutral',
|
|
346
348
|
fromZigbee: [fz.on_off, fz.legrand_binary_input_on_off, fz.legrand_cluster_fc01],
|
|
347
|
-
toZigbee: [tz.on_off, tz.
|
|
349
|
+
toZigbee: [tz.on_off, tz.legrand_settingEnableLedInDark, tz.legrand_settingEnableLedIfOn],
|
|
348
350
|
exposes: [e.switch().withEndpoint('left'),
|
|
349
351
|
e.switch().withEndpoint('right'),
|
|
350
|
-
exposes.binary('
|
|
351
|
-
|
|
352
|
+
exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing to
|
|
353
|
+
see the switch in the dark`),
|
|
354
|
+
exposes.binary('led_if_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is turned on')],
|
|
352
355
|
meta: {multiEndpoint: true},
|
|
353
356
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
354
357
|
const endpointLeft = device.getEndpoint(2);
|
|
@@ -368,7 +371,7 @@ module.exports = [
|
|
|
368
371
|
ota: ota.zigbeeOTA,
|
|
369
372
|
description: 'Outlet with power consumption monitoring',
|
|
370
373
|
fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement],
|
|
371
|
-
toZigbee: [tz.on_off, tz.
|
|
374
|
+
toZigbee: [tz.on_off, tz.legrand_settingEnableLedInDark, tz.legrand_identify],
|
|
372
375
|
exposes: [e.switch(), e.action(['identify']), e.power()],
|
|
373
376
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
374
377
|
const endpoint = device.getEndpoint(1);
|
package/devices/lidl.js
CHANGED
|
@@ -378,6 +378,28 @@ module.exports = [
|
|
|
378
378
|
await reporting.onOff(endpoint);
|
|
379
379
|
},
|
|
380
380
|
},
|
|
381
|
+
{
|
|
382
|
+
fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_ynmowqk2'}],
|
|
383
|
+
model: 'HG08673-FR',
|
|
384
|
+
vendor: 'Lidl',
|
|
385
|
+
description: 'Silvercrest smart plug FR with power monitoring',
|
|
386
|
+
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.ignore_basic_report, fz.tuya_switch_power_outage_memory],
|
|
387
|
+
toZigbee: [tz.on_off, tz.tuya_switch_power_outage_memory],
|
|
388
|
+
exposes: [e.switch(), e.power(), e.current(), e.voltage().withAccess(ea.STATE),
|
|
389
|
+
e.energy(), exposes.enum('power_outage_memory', ea.ALL, ['on', 'off', 'restore'])
|
|
390
|
+
.withDescription('Recover state after power outage')],
|
|
391
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
392
|
+
const endpoint = device.getEndpoint(1);
|
|
393
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement']);
|
|
394
|
+
endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 100, multiplier: 1});
|
|
395
|
+
endpoint.saveClusterAttributeKeyValue('haElectricalMeasurement', {
|
|
396
|
+
acVoltageMultiplier: 1, acVoltageDivisor: 1, acCurrentMultiplier: 1, acCurrentDivisor: 1000, acPowerMultiplier: 1,
|
|
397
|
+
acPowerDivisor: 1,
|
|
398
|
+
});
|
|
399
|
+
},
|
|
400
|
+
options: [exposes.options.measurement_poll_interval()],
|
|
401
|
+
onEvent: tuya.onEventMeasurementPoll,
|
|
402
|
+
},
|
|
381
403
|
{
|
|
382
404
|
fingerprint: [{modelID: 'TS004F', manufacturerName: '_TZ3000_rco1yzb1'}],
|
|
383
405
|
model: 'HG08164',
|
package/devices/mecrator.js
CHANGED
|
@@ -62,4 +62,21 @@ module.exports = [
|
|
|
62
62
|
device.save();
|
|
63
63
|
},
|
|
64
64
|
},
|
|
65
|
+
{
|
|
66
|
+
fingerprint: [{modelID: 'TS0501', manufacturerName: '_TZ3210_lzqq3u4r'},
|
|
67
|
+
{modelID: 'TS0501', manufacturerName: '_TZ3210_4whigl8i'}],
|
|
68
|
+
model: 'SSWF01G',
|
|
69
|
+
description: 'AC fan controller',
|
|
70
|
+
vendor: 'Mercator',
|
|
71
|
+
fromZigbee: [fz.on_off, fz.fan],
|
|
72
|
+
toZigbee: [tz.fan_mode, tz.on_off],
|
|
73
|
+
exposes: [e.switch(), e.fan().withModes(['off', 'low', 'medium', 'high', 'on'])],
|
|
74
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
75
|
+
const endpoint = device.getEndpoint(1);
|
|
76
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genBasic', 'genOta', 'genTime', 'genGroups', 'genScenes']);
|
|
77
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genIdentify', 'manuSpecificTuya', 'hvacFanCtrl']);
|
|
78
|
+
await reporting.onOff(endpoint);
|
|
79
|
+
await reporting.fanMode(endpoint);
|
|
80
|
+
},
|
|
81
|
+
},
|
|
65
82
|
];
|
package/devices/moes.js
CHANGED
|
@@ -273,9 +273,14 @@ module.exports = [
|
|
|
273
273
|
exposes: [e.switch().withEndpoint('l1').setAccess('state', ea.STATE_SET),
|
|
274
274
|
e.switch().withEndpoint('l2').setAccess('state', ea.STATE_SET),
|
|
275
275
|
e.switch().withEndpoint('l3').setAccess('state', ea.STATE_SET),
|
|
276
|
-
e.switch().withEndpoint('l4').setAccess('state', ea.STATE_SET)
|
|
277
|
-
|
|
278
|
-
|
|
276
|
+
e.switch().withEndpoint('l4').setAccess('state', ea.STATE_SET),
|
|
277
|
+
exposes.enum('indicate_light', ea.STATE_SET, Object.values(tuya.moesSwitch.indicateLight))
|
|
278
|
+
.withDescription('Indicator light status'),
|
|
279
|
+
exposes.enum('power_on_behavior', ea.STATE_SET, Object.values(tuya.moesSwitch.powerOnBehavior))
|
|
280
|
+
.withDescription('Controls the behavior when the device is powered on')],
|
|
281
|
+
fromZigbee: [fz.ignore_basic_report, fz.tuya_switch, fz.moes_switch],
|
|
282
|
+
toZigbee: [tz.tuya_switch_state, tz.moes_switch],
|
|
283
|
+
onEvent: tuya.onEventSetLocalTime,
|
|
279
284
|
meta: {multiEndpoint: true},
|
|
280
285
|
endpoint: (device) => {
|
|
281
286
|
// Endpoint selection is made in tuya_switch_state
|
|
@@ -428,7 +433,10 @@ module.exports = [
|
|
|
428
433
|
exposes.enum('calibration', ea.STATE_SET, ['OFF', 'ON']), exposes.enum('motor_reversal', ea.STATE_SET, ['OFF', 'ON'])],
|
|
429
434
|
},
|
|
430
435
|
{
|
|
431
|
-
fingerprint: [
|
|
436
|
+
fingerprint: [
|
|
437
|
+
{modelID: 'TS1201', manufacturerName: '_TZ3290_j37rooaxrcdcqo5n'},
|
|
438
|
+
{modelID: 'TS1201', manufacturerName: '_TZ3290_ot6ewjvmejq5ekhl'},
|
|
439
|
+
],
|
|
432
440
|
model: 'UFO-R11',
|
|
433
441
|
vendor: 'Moes',
|
|
434
442
|
description: 'Universal smart IR remote control',
|
package/devices/niko.js
CHANGED
|
@@ -61,9 +61,8 @@ const local = {
|
|
|
61
61
|
if (!operationModeLookup.hasOwnProperty(value)) {
|
|
62
62
|
throw new Error(`operation_mode was called with an invalid value (${value})`);
|
|
63
63
|
} else {
|
|
64
|
-
const operationModeProperty = `operation_mode${meta.endpoint_name ? `_${meta.endpoint_name}` : ''}`;
|
|
65
64
|
await entity.write('manuSpecificNiko1', {'switchOperationMode': operationModeLookup[value]});
|
|
66
|
-
return {state: {
|
|
65
|
+
return {state: {operation_mode: value.toLowerCase()}};
|
|
67
66
|
}
|
|
68
67
|
},
|
|
69
68
|
convertGet: async (entity, key, meta) => {
|
package/devices/onesti.js
CHANGED
|
@@ -8,7 +8,7 @@ const constants = require('../lib/constants');
|
|
|
8
8
|
|
|
9
9
|
module.exports = [
|
|
10
10
|
{
|
|
11
|
-
zigbeeModel: ['easyCodeTouch_v1', 'EasyCodeTouch'],
|
|
11
|
+
zigbeeModel: ['easyCodeTouch_v1', 'EasyCodeTouch', 'EasyFingerTouch'],
|
|
12
12
|
model: 'easyCodeTouch_v1',
|
|
13
13
|
vendor: 'Onesti Products AS',
|
|
14
14
|
description: 'Zigbee module for EasyAccess code touch series',
|
|
@@ -21,6 +21,8 @@ module.exports = [
|
|
|
21
21
|
await reporting.lockState(endpoint);
|
|
22
22
|
await reporting.batteryPercentageRemaining(endpoint);
|
|
23
23
|
await endpoint.read('closuresDoorLock', ['lockState', 'soundVolume']);
|
|
24
|
+
device.powerSource = 'Battery';
|
|
25
|
+
device.save();
|
|
24
26
|
},
|
|
25
27
|
exposes: [e.lock(), e.battery(), e.sound_volume(),
|
|
26
28
|
e.lock_action_source_name(), e.lock_action_user(),
|
package/devices/perenio.js
CHANGED
|
@@ -59,15 +59,30 @@ const fzPerenio = {
|
|
|
59
59
|
type: ['attributeReport', 'readResponse'],
|
|
60
60
|
convert: (model, msg, publish, options, meta) => {
|
|
61
61
|
const result = {};
|
|
62
|
+
if (msg.data.hasOwnProperty(2)) {
|
|
63
|
+
result['rms_current'] = msg.data[2];
|
|
64
|
+
}
|
|
62
65
|
if (msg.data.hasOwnProperty(3)) {
|
|
63
66
|
result['rms_voltage'] = msg.data[3];
|
|
64
67
|
}
|
|
68
|
+
if (msg.data.hasOwnProperty(4)) {
|
|
69
|
+
result['voltage_min'] = msg.data[4];
|
|
70
|
+
}
|
|
71
|
+
if (msg.data.hasOwnProperty(5)) {
|
|
72
|
+
result['voltage_max'] = msg.data[5];
|
|
73
|
+
}
|
|
65
74
|
if (msg.data.hasOwnProperty(10)) {
|
|
66
75
|
result['active_power'] = msg.data[10];
|
|
67
76
|
}
|
|
77
|
+
if (msg.data.hasOwnProperty(11)) {
|
|
78
|
+
result['power_max'] = msg.data[11];
|
|
79
|
+
}
|
|
68
80
|
if (msg.data.hasOwnProperty(14)) {
|
|
69
81
|
result['consumed_energy'] = msg.data[14];
|
|
70
82
|
}
|
|
83
|
+
if (msg.data.hasOwnProperty(15)) {
|
|
84
|
+
result['consumed_energy_limit'] = msg.data[15];
|
|
85
|
+
}
|
|
71
86
|
if (msg.data.hasOwnProperty(24)) {
|
|
72
87
|
result['rssi'] = msg.data[24];
|
|
73
88
|
}
|
|
@@ -84,6 +99,7 @@ const fzPerenio = {
|
|
|
84
99
|
result['alarm_voltage_min'] = false;
|
|
85
100
|
result['alarm_voltage_max'] = false;
|
|
86
101
|
result['alarm_power_max'] = false;
|
|
102
|
+
result['alarm_consumed_energy'] = false;
|
|
87
103
|
} else {
|
|
88
104
|
if (msg.data[1] & 1) {
|
|
89
105
|
result['alarm_voltage_min'] = true;
|
|
@@ -94,6 +110,9 @@ const fzPerenio = {
|
|
|
94
110
|
if (msg.data[1] & 4) {
|
|
95
111
|
result['alarm_power_max'] = true;
|
|
96
112
|
}
|
|
113
|
+
if (msg.data[1] & 8) {
|
|
114
|
+
result['alarm_consumed_energy'] = true;
|
|
115
|
+
}
|
|
97
116
|
}
|
|
98
117
|
}
|
|
99
118
|
return result;
|
|
@@ -135,15 +154,51 @@ const tzPerenio = {
|
|
|
135
154
|
},
|
|
136
155
|
},
|
|
137
156
|
alarms_reset: {
|
|
138
|
-
key: ['alarm_voltage_min', 'alarm_voltage_max', 'alarm_power_max'],
|
|
157
|
+
key: ['alarm_voltage_min', 'alarm_voltage_max', 'alarm_power_max', 'alarm_consumed_energy'],
|
|
139
158
|
convertSet: async (entity, key, val, meta) => {
|
|
140
159
|
await entity.write(64635, {1: {value: 0, type: 0x20}}, {manufacturerCode: 0x007B});
|
|
141
|
-
return {state: {alarm_voltage_min: false, alarm_voltage_max: false, alarm_power_max: false}};
|
|
160
|
+
return {state: {alarm_voltage_min: false, alarm_voltage_max: false, alarm_power_max: false, alarm_consumed_energy: false}};
|
|
142
161
|
},
|
|
143
162
|
convertGet: async (entity, key, meta) => {
|
|
144
163
|
await entity.read(64635, [1]);
|
|
145
164
|
},
|
|
146
165
|
},
|
|
166
|
+
alarms_limits: {
|
|
167
|
+
key: ['voltage_min', 'voltage_max', 'power_max', 'consumed_energy_limit'],
|
|
168
|
+
convertSet: async (entity, key, val, meta) => {
|
|
169
|
+
switch (key) {
|
|
170
|
+
case 'voltage_min':
|
|
171
|
+
await entity.write(64635, {4: {value: val, type: 0x21}}, {manufacturerCode: 0x007B});
|
|
172
|
+
break;
|
|
173
|
+
case 'voltage_max':
|
|
174
|
+
await entity.write(64635, {5: {value: val, type: 0x21}}, {manufacturerCode: 0x007B});
|
|
175
|
+
break;
|
|
176
|
+
case 'power_max':
|
|
177
|
+
await entity.write(64635, {11: {value: val, type: 0x21}}, {manufacturerCode: 0x007B});
|
|
178
|
+
break;
|
|
179
|
+
case 'consumed_energy_limit':
|
|
180
|
+
await entity.write(64635, {15: {value: val, type: 0x21}}, {manufacturerCode: 0x007B});
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
return {state: {[key]: val}};
|
|
184
|
+
},
|
|
185
|
+
convertGet: async (entity, key, meta) => {
|
|
186
|
+
switch (key) {
|
|
187
|
+
case 'voltage_min':
|
|
188
|
+
await entity.read(64635, [4]);
|
|
189
|
+
break;
|
|
190
|
+
case 'voltage_max':
|
|
191
|
+
await entity.read(64635, [5]);
|
|
192
|
+
break;
|
|
193
|
+
case 'power_max':
|
|
194
|
+
await entity.read(64635, [11]);
|
|
195
|
+
break;
|
|
196
|
+
case 'consumed_energy_limit':
|
|
197
|
+
await entity.read(64635, [15]);
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
},
|
|
147
202
|
on_off_mod: {
|
|
148
203
|
key: ['state', 'on_time', 'off_wait_time'],
|
|
149
204
|
convertSet: async (entity, key, value, meta) => {
|
|
@@ -291,8 +346,8 @@ module.exports = [
|
|
|
291
346
|
model: 'PEHPL0X',
|
|
292
347
|
vendor: 'Perenio',
|
|
293
348
|
description: 'Power link',
|
|
294
|
-
fromZigbee: [fz.on_off, fzPerenio.smart_plug],
|
|
295
|
-
toZigbee: [tzPerenio.on_off_mod, tzPerenio.default_state, tzPerenio.alarms_reset],
|
|
349
|
+
fromZigbee: [fz.on_off, fzPerenio.smart_plug, fz.metering],
|
|
350
|
+
toZigbee: [tzPerenio.on_off_mod, tzPerenio.default_state, tzPerenio.alarms_reset, tzPerenio.alarms_limits],
|
|
296
351
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
297
352
|
const endpoint = device.getEndpoint(1);
|
|
298
353
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 64635]);
|
|
@@ -303,7 +358,26 @@ module.exports = [
|
|
|
303
358
|
reportableChange: 0,
|
|
304
359
|
}];
|
|
305
360
|
await endpoint.configureReporting('genOnOff', payload);
|
|
306
|
-
await endpoint.
|
|
361
|
+
await endpoint.configureReporting(64635, [{
|
|
362
|
+
attribute: {ID: 0x000a, type: 0x21},
|
|
363
|
+
minimumReportInterval: 5,
|
|
364
|
+
maximumReportInterval: 60,
|
|
365
|
+
reportableChange: 0,
|
|
366
|
+
}]);
|
|
367
|
+
await endpoint.configureReporting(64635, [{
|
|
368
|
+
attribute: {ID: 0x000e, type: 0x23},
|
|
369
|
+
minimumReportInterval: 5,
|
|
370
|
+
maximumReportInterval: 60,
|
|
371
|
+
reportableChange: 0,
|
|
372
|
+
}]);
|
|
373
|
+
await endpoint.configureReporting(64635, [{
|
|
374
|
+
attribute: {ID: 0x0003, type: 0x21},
|
|
375
|
+
minimumReportInterval: 5,
|
|
376
|
+
maximumReportInterval: 5,
|
|
377
|
+
reportableChange: 0,
|
|
378
|
+
}]);
|
|
379
|
+
await endpoint.read(64635, [0, 1, 2, 3]);
|
|
380
|
+
await endpoint.read(64635, [4, 5, 11, 15]);
|
|
307
381
|
},
|
|
308
382
|
exposes: [
|
|
309
383
|
e.switch(),
|
|
@@ -317,6 +391,17 @@ module.exports = [
|
|
|
317
391
|
.withDescription('Indicates if the alarm is triggered on the voltage rise above the limit, allows to reset alarms'),
|
|
318
392
|
exposes.binary('alarm_power_max', ea.ALL, true, false)
|
|
319
393
|
.withDescription('Indicates if the alarm is triggered on the active power rise above the limit, allows to reset alarms'),
|
|
394
|
+
exposes.binary('alarm_consumed_energy', ea.ALL, true, false)
|
|
395
|
+
.withDescription(
|
|
396
|
+
'Indicates if the alarm is triggered when the consumption energy limit is reached, allows to reset alarms'),
|
|
397
|
+
exposes.numeric('voltage_min', ea.ALL).withValueMin(0).withValueMax(253)
|
|
398
|
+
.withDescription('Minimum allowable voltage limit for alarms.'),
|
|
399
|
+
exposes.numeric('voltage_max', ea.ALL).withValueMin(0).withValueMax(253)
|
|
400
|
+
.withDescription('Maximum allowable voltage limit for alarms.'),
|
|
401
|
+
exposes.numeric('power_max', ea.ALL).withValueMin(0).withValueMax(65534)
|
|
402
|
+
.withDescription('Maximum allowable power limit for alarms.'),
|
|
403
|
+
exposes.numeric('consumed_energy_limit', ea.ALL).withValueMin(0).withValueMax(65534)
|
|
404
|
+
.withDescription('Limit of electric energy consumption in kW*h. 0 value represents no limit'),
|
|
320
405
|
exposes.numeric('rssi', ea.STATE).withUnit('dB')
|
|
321
406
|
.withDescription('RSSI seen by the device').withValueMin(-128).withValueMax(127),
|
|
322
407
|
],
|
package/devices/qoto.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const fz = require('../converters/fromZigbee');
|
|
2
|
+
const exposes = require('../lib/exposes');
|
|
3
|
+
const tuya = require('../lib/tuya');
|
|
4
|
+
const e = exposes.presets;
|
|
5
|
+
const ea = exposes.access;
|
|
6
|
+
|
|
7
|
+
const dataPoints = {
|
|
8
|
+
valve_state_auto_shutdown: 2,
|
|
9
|
+
water_flow: 3,
|
|
10
|
+
shutdown_timer: 11,
|
|
11
|
+
remaining_watering_time: 101,
|
|
12
|
+
valve_state: 102,
|
|
13
|
+
last_watering_duration: 107,
|
|
14
|
+
battery: 110,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const fzLocal = {
|
|
18
|
+
watering_timer: {
|
|
19
|
+
cluster: 'manuSpecificTuya',
|
|
20
|
+
type: ['commandDataReport'],
|
|
21
|
+
convert: (model, msg, publish, options, meta) => {
|
|
22
|
+
const result = {};
|
|
23
|
+
for (const dpValue of msg.data.dpValues) {
|
|
24
|
+
const dp = dpValue.dp; // First we get the data point ID
|
|
25
|
+
const value = tuya.getDataValue(dpValue); // This function will take care of converting the data to proper JS type
|
|
26
|
+
switch (dp) {
|
|
27
|
+
case dataPoints.water_flow: {
|
|
28
|
+
result.water_flow = value;
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
case dataPoints.remaining_watering_time: {
|
|
32
|
+
result.remaining_watering_time = value;
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
case dataPoints.last_watering_duration: {
|
|
36
|
+
result.last_watering_duration = value;
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
case dataPoints.valve_state: {
|
|
41
|
+
result.valve_state = value;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
case dataPoints.shutdown_timer: {
|
|
46
|
+
result.shutdown_timer = value;
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
case dataPoints.valve_state_auto_shutdown: {
|
|
50
|
+
result.valve_state_auto_shutdown = value;
|
|
51
|
+
result.valve_state = value;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
case dataPoints.battery: {
|
|
56
|
+
result.battery = value;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
default: {
|
|
60
|
+
meta.logger.debug(`>>> UNKNOWN DP #${dp} with data "${JSON.stringify(dpValue)}"`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const tzLocal = {
|
|
70
|
+
valve_state: {
|
|
71
|
+
key: ['valve_state'],
|
|
72
|
+
convertSet: async (entity, key, value, meta) => {
|
|
73
|
+
await tuya.sendDataPointValue(entity, dataPoints.valve_state, value);
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
shutdown_timer: {
|
|
77
|
+
key: ['shutdown_timer'],
|
|
78
|
+
convertSet: async (entity, key, value, meta) => {
|
|
79
|
+
await tuya.sendDataPointValue(entity, dataPoints.shutdown_timer, value);
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
valve_state_auto_shutdown: {
|
|
83
|
+
key: ['valve_state_auto_shutdown'],
|
|
84
|
+
convertSet: async (entity, key, value, meta) => {
|
|
85
|
+
await tuya.sendDataPointValue(entity, dataPoints.valve_state_auto_shutdown, value);
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
module.exports = [
|
|
91
|
+
{
|
|
92
|
+
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_arge1ptm'}],
|
|
93
|
+
model: 'QT-05M',
|
|
94
|
+
vendor: 'QOTO',
|
|
95
|
+
description: 'Solar powered garden watering timer',
|
|
96
|
+
fromZigbee: [fz.ignore_basic_report, fz.ignore_tuya_set_time, fz.ignore_onoff_report, fzLocal.watering_timer],
|
|
97
|
+
toZigbee: [tzLocal.valve_state, tzLocal.shutdown_timer, tzLocal.valve_state_auto_shutdown],
|
|
98
|
+
exposes: [
|
|
99
|
+
exposes.numeric('water_flow', ea.STATE).withUnit('%').withValueMin(0).withDescription('Current water flow in %.'),
|
|
100
|
+
exposes.numeric('last_watering_duration', ea.STATE).withUnit('sec').withValueMin(0)
|
|
101
|
+
.withDescription('Last watering duration in seconds.'),
|
|
102
|
+
exposes.numeric('remaining_watering_time', ea.STATE).withUnit('sec').withValueMin(0)
|
|
103
|
+
.withDescription('Remaning watering time (for auto shutdown). Updates every minute, and every 10s in the last minute.'),
|
|
104
|
+
exposes.numeric('valve_state', ea.STATE_SET).withValueMin(0).withValueMax(100).withValueStep(5).withUnit('%')
|
|
105
|
+
.withDescription('Set valve to %.'),
|
|
106
|
+
exposes.numeric('shutdown_timer', ea.STATE_SET).withValueMin(0).withValueMax(14400).withUnit('sec')
|
|
107
|
+
.withDescription('Auto shutdown in seconds.'),
|
|
108
|
+
exposes.numeric('valve_state_auto_shutdown', ea.STATE_SET).withValueMin(0).withValueMax(100).withValueStep(5).withUnit('%')
|
|
109
|
+
.withDescription('Set valve to % with auto shutdown.'),
|
|
110
|
+
e.battery(),
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
];
|
package/devices/sylvania.js
CHANGED
package/devices/tuya.js
CHANGED
|
@@ -20,7 +20,7 @@ const TS011Fplugs = ['_TZ3000_5f43h46b', '_TZ3000_cphmq0q7', '_TZ3000_dpo1ysak',
|
|
|
20
20
|
'_TZ3000_rdtixbnu', '_TZ3000_typdpbpg', '_TZ3000_kx0pris5', '_TZ3000_amdymr7l', '_TZ3000_z1pnpsdo', '_TZ3000_ksw8qtmt',
|
|
21
21
|
'_TZ3000_1h2x4akh', '_TZ3000_9vo5icau', '_TZ3000_cehuw1lw', '_TZ3000_ko6v90pg', '_TZ3000_f1bapcit', '_TZ3000_cjrngdr3',
|
|
22
22
|
'_TZ3000_zloso4jk', '_TZ3000_r6buo8ba', '_TZ3000_iksasdbv', '_TZ3000_idrffznf', '_TZ3000_okaz9tjs', '_TZ3210_q7oryllx',
|
|
23
|
-
'_TZ3000_ss98ec5d', '_TZ3000_gznh2xla'];
|
|
23
|
+
'_TZ3000_ss98ec5d', '_TZ3000_gznh2xla', '_TZ3000_hdopuwv6', '_TZ3000_gvn91tmx'];
|
|
24
24
|
|
|
25
25
|
const tzLocal = {
|
|
26
26
|
hpsz: {
|
|
@@ -801,6 +801,7 @@ module.exports = [
|
|
|
801
801
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_remypqqm'},
|
|
802
802
|
{modelID: 'TS0505B', manufacturerName: '_TZ3000_kohbva1f'},
|
|
803
803
|
{modelID: 'TS0505B', manufacturerName: '_TZ3000_luit1t00'},
|
|
804
|
+
{modelID: 'TS0505B', manufacturerName: '_TZ3210_r5afgmkl'},
|
|
804
805
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_wslkvrau'},
|
|
805
806
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_0rn9qhnu'},
|
|
806
807
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_ejctepku'},
|
|
@@ -818,6 +819,7 @@ module.exports = [
|
|
|
818
819
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_mzdax7ha'},
|
|
819
820
|
{modelID: 'TS0505B', manufacturerName: '_TZB210_tmi0rihb'},
|
|
820
821
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_a4s41wm4'},
|
|
822
|
+
{modelID: 'TS0505B', manufacturerName: '_TZ3210_ijczzg9h'},
|
|
821
823
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_qxenlrin'},
|
|
822
824
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_iwbaamgh'},
|
|
823
825
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_klv2wul0'},
|
|
@@ -826,6 +828,7 @@ module.exports = [
|
|
|
826
828
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_cuqkfz2q'},
|
|
827
829
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_6amjviba'},
|
|
828
830
|
{modelID: 'TS0505B', manufacturerName: '_TZ3000_xr5m6kfg'},
|
|
831
|
+
{modelID: 'TS0505B', manufacturerName: '_TZ3210_xr5m6kfg'},
|
|
829
832
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_bf175wi4'}],
|
|
830
833
|
model: 'TS0505B',
|
|
831
834
|
vendor: 'TuYa',
|
|
@@ -887,7 +890,8 @@ module.exports = [
|
|
|
887
890
|
{modelID: 'TS0501B', manufacturerName: '_TZ3210_wuheofsg'},
|
|
888
891
|
{modelID: 'TS0501B', manufacturerName: '_TZ3210_e5t9bfdv'},
|
|
889
892
|
{modelID: 'TS0501B', manufacturerName: '_TZ3210_19qb27da'},
|
|
890
|
-
{modelID: 'TS0501B', manufacturerName: '_TZ3210_4zinq6io'}
|
|
893
|
+
{modelID: 'TS0501B', manufacturerName: '_TZ3210_4zinq6io'},
|
|
894
|
+
{modelID: 'TS0501B', manufacturerName: '_TZ3210_93gnbdgz'}],
|
|
891
895
|
model: 'TS0501B',
|
|
892
896
|
description: 'Zigbee light',
|
|
893
897
|
vendor: 'TuYa',
|
|
@@ -1465,7 +1469,7 @@ module.exports = [
|
|
|
1465
1469
|
},
|
|
1466
1470
|
},
|
|
1467
1471
|
{
|
|
1468
|
-
fingerprint: [{modelID: 'TS004F', manufacturerName: '_TZ3000_xabckq1v'}],
|
|
1472
|
+
fingerprint: [{modelID: 'TS004F', manufacturerName: '_TZ3000_xabckq1v'}, {modelID: 'TS004F', manufacturerName: '_TZ3000_czuyt8lz'}],
|
|
1469
1473
|
model: 'TS004F',
|
|
1470
1474
|
vendor: 'TuYa',
|
|
1471
1475
|
description: 'Wireless switch with 4 buttons',
|
package/devices/woox.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zigbee-herdsman-converters",
|
|
3
|
-
"version": "14.0.
|
|
3
|
+
"version": "14.0.611",
|
|
4
4
|
"description": "Collection of device converters to be used with zigbee-herdsman",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -38,7 +38,7 @@
|
|
|
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.53"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"eslint": "*",
|