zigbee-herdsman-converters 14.0.409 → 14.0.413
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 +105 -22
- package/converters/toZigbee.js +59 -10
- package/devices/bticino.js +10 -10
- package/devices/custom_devices_diy.js +21 -0
- package/devices/gledopto.js +30 -11
- package/devices/jasco.js +18 -0
- package/devices/legrand.js +33 -12
- package/devices/lixee.js +574 -0
- package/devices/moes.js +22 -9
- package/devices/m/303/274ller_licht.js +3 -2
- package/devices/philips.js +11 -2
- package/devices/schwaiger.js +7 -0
- package/devices/sengled.js +9 -2
- package/devices/sonoff.js +11 -0
- package/devices/sunricher.js +1 -1
- package/devices/tuya.js +20 -11
- package/devices/xiaomi.js +6 -5
- package/index.js +3 -2
- package/lib/extend.js +7 -5
- package/lib/ota/index.js +1 -0
- package/lib/ota/lixee.js +57 -0
- package/lib/tuya.js +17 -0
- package/npm-shrinkwrap.json +426 -401
- package/package.json +2 -2
package/converters/fromZigbee.js
CHANGED
|
@@ -616,6 +616,25 @@ const converters = {
|
|
|
616
616
|
return result;
|
|
617
617
|
},
|
|
618
618
|
},
|
|
619
|
+
meter_identification: {
|
|
620
|
+
cluster: 'haMeterIdentification',
|
|
621
|
+
type: ['readResponse'],
|
|
622
|
+
convert: (model, msg, publish, options, meta) => {
|
|
623
|
+
const result = {};
|
|
624
|
+
const elements = [
|
|
625
|
+
/* 0x000A*/ 'softwareRevision',
|
|
626
|
+
/* 0x000D*/ 'availablePower',
|
|
627
|
+
/* 0x000E*/ 'powerThreshold',
|
|
628
|
+
];
|
|
629
|
+
for (const at of elements) {
|
|
630
|
+
const atSnake = at.split(/(?=[A-Z])/).join('_').toLowerCase();
|
|
631
|
+
if (msg.data[at]) {
|
|
632
|
+
result[atSnake] = msg.data[at];
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
return result;
|
|
636
|
+
},
|
|
637
|
+
},
|
|
619
638
|
metering: {
|
|
620
639
|
/**
|
|
621
640
|
* When using this converter also add the following to the configure method of the device:
|
|
@@ -2395,6 +2414,32 @@ const converters = {
|
|
|
2395
2414
|
}
|
|
2396
2415
|
},
|
|
2397
2416
|
},
|
|
2417
|
+
moes_switch: {
|
|
2418
|
+
cluster: 'manuSpecificTuya',
|
|
2419
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
2420
|
+
convert: (model, msg, publish, options, meta) => {
|
|
2421
|
+
const dpValue = tuya.firstDpValue(msg, meta, 'moes_switch');
|
|
2422
|
+
const dp = dpValue.dp;
|
|
2423
|
+
|
|
2424
|
+
// tuya_switch datapoints
|
|
2425
|
+
if (dp >= 1 && dp <= 4) {
|
|
2426
|
+
return null;
|
|
2427
|
+
}
|
|
2428
|
+
|
|
2429
|
+
const value = tuya.getDataValue(dpValue);
|
|
2430
|
+
|
|
2431
|
+
switch (dp) {
|
|
2432
|
+
case tuya.dataPoints.moesSwitchPowerOnBehavior:
|
|
2433
|
+
return {power_on_behavior: tuya.moesSwitch.powerOnBehavior[value]};
|
|
2434
|
+
case tuya.dataPoints.moesSwitchIndicateLight:
|
|
2435
|
+
return {indicate_light: tuya.moesSwitch.indicateLight[value]};
|
|
2436
|
+
default:
|
|
2437
|
+
meta.logger.warn(`fromZigbee:moes_switch: NOT RECOGNIZED DP #${
|
|
2438
|
+
dp} with data ${JSON.stringify(dpValue)}`);
|
|
2439
|
+
break;
|
|
2440
|
+
}
|
|
2441
|
+
},
|
|
2442
|
+
},
|
|
2398
2443
|
eurotronic_thermostat: {
|
|
2399
2444
|
cluster: 'hvacThermostat',
|
|
2400
2445
|
type: ['attributeReport', 'readResponse'],
|
|
@@ -2598,6 +2643,31 @@ const converters = {
|
|
|
2598
2643
|
}
|
|
2599
2644
|
},
|
|
2600
2645
|
},
|
|
2646
|
+
ts011f_plug_indicator_mode: {
|
|
2647
|
+
cluster: 'genOnOff',
|
|
2648
|
+
type: ['attributeReport', 'readResponse'],
|
|
2649
|
+
convert: (model, msg, publish, options, meta) => {
|
|
2650
|
+
const property = 'tuyaBacklightMode'; // 0x8001 or 32769
|
|
2651
|
+
if (msg.data.hasOwnProperty(property)) {
|
|
2652
|
+
const value = msg.data[property];
|
|
2653
|
+
const lookup = {0: 'off', 1: 'off/on', 2: 'on/off', 3: 'on'};
|
|
2654
|
+
if (lookup.hasOwnProperty(value)) {
|
|
2655
|
+
return {indicator_mode: lookup[value]};
|
|
2656
|
+
}
|
|
2657
|
+
}
|
|
2658
|
+
},
|
|
2659
|
+
},
|
|
2660
|
+
ts011f_plug_child_mode: {
|
|
2661
|
+
cluster: 'genOnOff',
|
|
2662
|
+
type: ['attributeReport', 'readResponse'],
|
|
2663
|
+
convert: (model, msg, publish, options, meta) => {
|
|
2664
|
+
const property = (0x8000).toString(); // 32768
|
|
2665
|
+
if (msg.data.hasOwnProperty(property)) {
|
|
2666
|
+
const value = msg.data[property];
|
|
2667
|
+
return {child_lock: value ? 'LOCK' : 'UNLOCK'};
|
|
2668
|
+
}
|
|
2669
|
+
},
|
|
2670
|
+
},
|
|
2601
2671
|
WSZ01_on_off_action: {
|
|
2602
2672
|
cluster: 65029,
|
|
2603
2673
|
type: 'raw',
|
|
@@ -5020,27 +5090,28 @@ const converters = {
|
|
|
5020
5090
|
}
|
|
5021
5091
|
},
|
|
5022
5092
|
},
|
|
5023
|
-
|
|
5093
|
+
legrand_cluster_fc01: {
|
|
5024
5094
|
cluster: 'manuSpecificLegrandDevices',
|
|
5025
5095
|
type: ['readResponse'],
|
|
5026
5096
|
convert: (model, msg, publish, options, meta) => {
|
|
5027
5097
|
const payload = {};
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
payload.device_mode = 'unknown';
|
|
5098
|
+
|
|
5099
|
+
if (msg.data.hasOwnProperty('0')) {
|
|
5100
|
+
const option0 = msg.data['0'];
|
|
5101
|
+
|
|
5102
|
+
if (option0 === 0x0001) payload.device_mode = 'pilot_off';
|
|
5103
|
+
else if (option0 === 0x0002) payload.device_mode = 'pilot_on';
|
|
5104
|
+
else if (option0 === 0x0003) payload.device_mode = 'switch';
|
|
5105
|
+
else if (option0 === 0x0004) payload.device_mode = 'auto';
|
|
5106
|
+
else if (option0 === 0x0100) payload.device_mode = 'dimmer_off';
|
|
5107
|
+
else if (option0 === 0x0101) payload.device_mode = 'dimmer_on';
|
|
5108
|
+
else {
|
|
5109
|
+
meta.logger.warn(`device_mode ${option0} not recognized, please fix me`);
|
|
5110
|
+
payload.device_mode = 'unknown';
|
|
5111
|
+
}
|
|
5043
5112
|
}
|
|
5113
|
+
if (msg.data.hasOwnProperty('1')) payload.permanent_led = msg.data['1'] === 0x00 ? 'OFF' : 'ON';
|
|
5114
|
+
if (msg.data.hasOwnProperty('2')) payload.led_when_on = msg.data['2'] === 0x00 ? 'OFF' : 'ON';
|
|
5044
5115
|
return payload;
|
|
5045
5116
|
},
|
|
5046
5117
|
},
|
|
@@ -5168,8 +5239,16 @@ const converters = {
|
|
|
5168
5239
|
aqara_opple: {
|
|
5169
5240
|
cluster: 'aqaraOpple',
|
|
5170
5241
|
type: ['attributeReport', 'readResponse'],
|
|
5171
|
-
options:
|
|
5172
|
-
|
|
5242
|
+
options: (definition) => {
|
|
5243
|
+
const result = [];
|
|
5244
|
+
if (definition.exposes.find((e) => e.name === 'temperature')) {
|
|
5245
|
+
result.push(exposes.options.precision('temperature'), exposes.options.calibration('temperature'));
|
|
5246
|
+
}
|
|
5247
|
+
if (definition.exposes.find((e) => e.name === 'illuminance')) {
|
|
5248
|
+
result.push(exposes.options.precision('illuminance'), exposes.options.calibration('illuminance', 'percentual'));
|
|
5249
|
+
}
|
|
5250
|
+
return result;
|
|
5251
|
+
},
|
|
5173
5252
|
convert: (model, msg, publish, options, meta) => {
|
|
5174
5253
|
const payload = {};
|
|
5175
5254
|
if (msg.data.hasOwnProperty('247')) {
|
|
@@ -5282,8 +5361,11 @@ const converters = {
|
|
|
5282
5361
|
if (index == 1) {
|
|
5283
5362
|
payload.voltage = value;
|
|
5284
5363
|
payload.battery = batteryVoltageToPercentage(value, '3V_2100');
|
|
5285
|
-
} else if (index === 3)
|
|
5286
|
-
|
|
5364
|
+
} else if (index === 3) {
|
|
5365
|
+
if (!['WXCJKG11LM ', 'WXCJKG12LM', 'WXCJKG13LM'].includes(model.model)) {
|
|
5366
|
+
payload.temperature = calibrateAndPrecisionRoundOptions(value, options, 'temperature'); // 0x03
|
|
5367
|
+
}
|
|
5368
|
+
} else if (index === 5) {
|
|
5287
5369
|
if (['JT-BZ-01AQ/A', 'RTCZCGQ11LM'].includes(model.model)) payload.power_outage_count = value;
|
|
5288
5370
|
} else if (index === 100) {
|
|
5289
5371
|
if (['QBKG20LM', 'QBKG31LM', 'QBKG39LM', 'QBKG41LM', 'QBCZ15LM'].includes(model.model)) {
|
|
@@ -5315,8 +5397,9 @@ const converters = {
|
|
|
5315
5397
|
payload.presence_event = {0: 'enter', 1: 'leave', 2: 'left_enter', 3: 'right_leave', 4: 'right_enter',
|
|
5316
5398
|
5: 'left_leave', 6: 'approach', 7: 'away', 255: null}[value];
|
|
5317
5399
|
}
|
|
5318
|
-
} else if (index ===103)
|
|
5319
|
-
|
|
5400
|
+
} else if (index === 103) {
|
|
5401
|
+
if (['RTCZCGQ11LM'].includes(model.model)) payload.monitoring_mode = value === 1 ? 'left_right' : 'undirected';
|
|
5402
|
+
} else if (index === 105) {
|
|
5320
5403
|
if (['RTCGQ13LM'].includes(model.model)) {
|
|
5321
5404
|
payload.motion_sensitivity = {1: 'low', 2: 'medium', 3: 'high'}[value];
|
|
5322
5405
|
} else if (['RTCZCGQ11LM'].includes(model.model)) {
|
package/converters/toZigbee.js
CHANGED
|
@@ -2211,7 +2211,7 @@ const converters = {
|
|
|
2211
2211
|
key: ['led_disabled_night'],
|
|
2212
2212
|
convertSet: async (entity, key, value, meta) => {
|
|
2213
2213
|
if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ14LM', 'QBCZ15LM', 'QBKG19LM', 'QBKG20LM', 'QBKG25LM', 'QBKG26LM',
|
|
2214
|
-
'QBKG31LM', 'QBKG34LM', 'DLKZMK11LM'].includes(meta.mapped.model)) {
|
|
2214
|
+
'QBKG31LM', 'QBKG34LM', 'DLKZMK11LM', 'SSM-U01'].includes(meta.mapped.model)) {
|
|
2215
2215
|
await entity.write('aqaraOpple', {0x0203: {value: value ? 1 : 0, type: 0x10}}, manufacturerOptions.xiaomi);
|
|
2216
2216
|
} else if (['ZNCZ11LM'].includes(meta.mapped.model)) {
|
|
2217
2217
|
const payload = value ?
|
|
@@ -2226,7 +2226,7 @@ const converters = {
|
|
|
2226
2226
|
},
|
|
2227
2227
|
convertGet: async (entity, key, meta) => {
|
|
2228
2228
|
if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ15LM', 'QBCZ14LM', 'QBKG19LM', 'QBKG20LM', 'QBKG25LM', 'QBKG26LM',
|
|
2229
|
-
'QBKG31LM', 'QBKG34LM', 'DLKZMK11LM'].includes(meta.mapped.model)) {
|
|
2229
|
+
'QBKG31LM', 'QBKG34LM', 'DLKZMK11LM', 'SSM-U01'].includes(meta.mapped.model)) {
|
|
2230
2230
|
await entity.read('aqaraOpple', [0x0203], manufacturerOptions.xiaomi);
|
|
2231
2231
|
} else {
|
|
2232
2232
|
throw new Error('Not supported');
|
|
@@ -3206,6 +3206,30 @@ const converters = {
|
|
|
3206
3206
|
await entity.read('genOnOff', ['moesStartUpOnOff']);
|
|
3207
3207
|
},
|
|
3208
3208
|
},
|
|
3209
|
+
moes_switch: {
|
|
3210
|
+
key: ['power_on_behavior', 'indicate_light'],
|
|
3211
|
+
convertSet: async (entity, key, value, meta) => {
|
|
3212
|
+
switch (key) {
|
|
3213
|
+
case 'power_on_behavior':
|
|
3214
|
+
await tuya.sendDataPointEnum(
|
|
3215
|
+
entity,
|
|
3216
|
+
tuya.dataPoints.moesSwitchPowerOnBehavior,
|
|
3217
|
+
utils.getKey(tuya.moesSwitch.powerOnBehavior, value),
|
|
3218
|
+
);
|
|
3219
|
+
break;
|
|
3220
|
+
case 'indicate_light':
|
|
3221
|
+
await tuya.sendDataPointEnum(
|
|
3222
|
+
entity,
|
|
3223
|
+
tuya.dataPoints.moesSwitchIndicateLight,
|
|
3224
|
+
utils.getKey(tuya.moesSwitch.indicateLight, value),
|
|
3225
|
+
);
|
|
3226
|
+
break;
|
|
3227
|
+
default:
|
|
3228
|
+
meta.logger.warn(`toZigbee.moes_switch: Unhandled Key ${key}`);
|
|
3229
|
+
break;
|
|
3230
|
+
}
|
|
3231
|
+
},
|
|
3232
|
+
},
|
|
3209
3233
|
moes_thermostat_sensor: {
|
|
3210
3234
|
key: ['sensor'],
|
|
3211
3235
|
convertSet: async (entity, key, value, meta) => {
|
|
@@ -4499,6 +4523,10 @@ const converters = {
|
|
|
4499
4523
|
const enableLedIfOn = value === 'ON' || (value === 'OFF' ? false : !!value);
|
|
4500
4524
|
const payload = {1: {value: enableLedIfOn, type: 16}};
|
|
4501
4525
|
await entity.write('manuSpecificLegrandDevices', payload, manufacturerOptions.legrand);
|
|
4526
|
+
return {state: {'permanent_led': value}};
|
|
4527
|
+
},
|
|
4528
|
+
convertGet: async (entity, key, meta) => {
|
|
4529
|
+
await entity.read('manuSpecificLegrandDevices', [0x0001], manufacturerOptions.legrand);
|
|
4502
4530
|
},
|
|
4503
4531
|
},
|
|
4504
4532
|
legrand_settingEnableLedIfOn: {
|
|
@@ -4510,15 +4538,10 @@ const converters = {
|
|
|
4510
4538
|
const enableLedIfOn = value === 'ON' || (value === 'OFF' ? false : !!value);
|
|
4511
4539
|
const payload = {2: {value: enableLedIfOn, type: 16}};
|
|
4512
4540
|
await entity.write('manuSpecificLegrandDevices', payload, manufacturerOptions.legrand);
|
|
4541
|
+
return {state: {'led_when_on': value}};
|
|
4513
4542
|
},
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
key: ['dimmer_enabled'],
|
|
4517
|
-
convertSet: async (entity, key, value, meta) => {
|
|
4518
|
-
// enable the dimmer, requires a recent firmware on the device
|
|
4519
|
-
const enableDimmer = value === 'ON' || (value === 'OFF' ? false : !!value);
|
|
4520
|
-
const payload = {0: {value: enableDimmer ? 0x0101 : 0x0100, type: 9}};
|
|
4521
|
-
await entity.write('manuSpecificLegrandDevices', payload, manufacturerOptions.legrand);
|
|
4543
|
+
convertGet: async (entity, key, meta) => {
|
|
4544
|
+
await entity.read('manuSpecificLegrandDevices', [0x0002], manufacturerOptions.legrand);
|
|
4522
4545
|
},
|
|
4523
4546
|
},
|
|
4524
4547
|
legrand_deviceMode: {
|
|
@@ -5971,6 +5994,32 @@ const converters = {
|
|
|
5971
5994
|
await entity.read('genOnOff', ['tuyaBacklightMode']);
|
|
5972
5995
|
},
|
|
5973
5996
|
},
|
|
5997
|
+
ts011f_plug_indicator_mode: {
|
|
5998
|
+
key: ['indicator_mode'],
|
|
5999
|
+
convertSet: async (entity, key, value, meta) => {
|
|
6000
|
+
if (typeof value === 'string') {
|
|
6001
|
+
value = value.toLowerCase();
|
|
6002
|
+
const lookup = {'off': 0, 'off/on': 1, 'on/off': 2, 'on': 3};
|
|
6003
|
+
utils.validateValue(value, Object.keys(lookup));
|
|
6004
|
+
value = lookup[value];
|
|
6005
|
+
}
|
|
6006
|
+
|
|
6007
|
+
if (typeof value === 'number' && value >= 0 && value <= 3) {
|
|
6008
|
+
await entity.write('genOnOff', {tuyaBacklightMode: value});
|
|
6009
|
+
} else {
|
|
6010
|
+
meta.logger.warn(`toZigbee.ts011f_plug_indicator_mode: Unsupported value ${value}`);
|
|
6011
|
+
}
|
|
6012
|
+
},
|
|
6013
|
+
convertGet: async (entity, key, meta) => {
|
|
6014
|
+
await entity.read('genOnOff', ['tuyaBacklightMode']);
|
|
6015
|
+
},
|
|
6016
|
+
},
|
|
6017
|
+
ts011f_plug_child_mode: {
|
|
6018
|
+
key: ['child_lock'],
|
|
6019
|
+
convertSet: async (entity, key, value, meta) => {
|
|
6020
|
+
await entity.write('genOnOff', {0x8000: {value: value === 'LOCK', type: 0x10}});
|
|
6021
|
+
},
|
|
6022
|
+
},
|
|
5974
6023
|
hy_thermostat: {
|
|
5975
6024
|
key: [
|
|
5976
6025
|
'child_lock', 'current_heating_setpoint', 'local_temperature_calibration',
|
package/devices/bticino.js
CHANGED
|
@@ -12,12 +12,12 @@ module.exports = [
|
|
|
12
12
|
model: 'K4003C/L4003C/N4003C/NT4003C',
|
|
13
13
|
vendor: 'BTicino',
|
|
14
14
|
description: 'Light switch with neutral',
|
|
15
|
-
fromZigbee: [fz.identify, fz.on_off, fz.K4003C_binary_input],
|
|
15
|
+
fromZigbee: [fz.identify, fz.on_off, fz.K4003C_binary_input, fz.legrand_cluster_fc01],
|
|
16
16
|
toZigbee: [tz.on_off, tz.legrand_settingAlwaysEnableLed, tz.legrand_settingEnableLedIfOn, tz.legrand_identify],
|
|
17
17
|
exposes: [
|
|
18
18
|
e.switch(), e.action(['identify', 'on', 'off']),
|
|
19
|
-
exposes.binary('permanent_led', ea.
|
|
20
|
-
exposes.binary('led_when_on', ea.
|
|
19
|
+
exposes.binary('permanent_led', ea.ALL, 'ON', 'OFF').withDescription('Enable or disable the permanent blue LED'),
|
|
20
|
+
exposes.binary('led_when_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is on'),
|
|
21
21
|
],
|
|
22
22
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
23
23
|
const endpoint = device.getEndpoint(1);
|
|
@@ -30,17 +30,17 @@ module.exports = [
|
|
|
30
30
|
vendor: 'BTicino',
|
|
31
31
|
description: 'Dimmer switch with neutral',
|
|
32
32
|
extend: extend.light_onoff_brightness({noConfigure: true}),
|
|
33
|
-
fromZigbee: [fz.brightness, fz.identify, fz.on_off, fz.lighting_ballast_configuration],
|
|
33
|
+
fromZigbee: [fz.brightness, fz.identify, fz.on_off, fz.lighting_ballast_configuration, fz.legrand_cluster_fc01],
|
|
34
34
|
toZigbee: [tz.light_onoff_brightness, tz.legrand_settingAlwaysEnableLed, tz.legrand_settingEnableLedIfOn,
|
|
35
|
-
tz.
|
|
35
|
+
tz.legrand_deviceMode, tz.legrand_identify, tz.ballast_config],
|
|
36
36
|
exposes: [e.light_brightness(),
|
|
37
37
|
exposes.numeric('ballast_minimum_level', ea.ALL).withValueMin(1).withValueMax(254)
|
|
38
38
|
.withDescription('Specifies the minimum brightness value'),
|
|
39
39
|
exposes.numeric('ballast_maximum_level', ea.ALL).withValueMin(1).withValueMax(254)
|
|
40
40
|
.withDescription('Specifies the maximum brightness value'),
|
|
41
|
-
exposes.binary('
|
|
42
|
-
exposes.binary('permanent_led', ea.
|
|
43
|
-
exposes.binary('led_when_on', ea.
|
|
41
|
+
exposes.binary('device_mode', ea.ALL, 'dimmer_on', 'dimmer_off').withDescription('Allow the device to change brightness'),
|
|
42
|
+
exposes.binary('permanent_led', ea.ALL, 'ON', 'OFF').withDescription('Enable or disable the permanent blue LED'),
|
|
43
|
+
exposes.binary('led_when_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is on')],
|
|
44
44
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
45
45
|
await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
|
|
46
46
|
const endpoint = device.getEndpoint(1);
|
|
@@ -76,10 +76,10 @@ module.exports = [
|
|
|
76
76
|
description: 'DIN power consumption module (same as Legrand 412015)',
|
|
77
77
|
vendor: 'BTicino',
|
|
78
78
|
extend: extend.switch(),
|
|
79
|
-
fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement, fz.
|
|
79
|
+
fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement, fz.legrand_cluster_fc01, fz.ignore_basic_report, fz.ignore_genOta],
|
|
80
80
|
toZigbee: [tz.legrand_deviceMode, tz.on_off, tz.legrand_identify, tz.electrical_measurement_power],
|
|
81
81
|
exposes: [exposes.switch().withState('state', true, 'On/off (works only if device is in "switch" mode)'),
|
|
82
|
-
e.power().withAccess(ea.STATE_GET), exposes.enum(
|
|
82
|
+
e.power().withAccess(ea.STATE_GET), exposes.enum('device_mode', ea.ALL, ['switch', 'auto'])
|
|
83
83
|
.withDescription('switch: allow on/off, auto will use wired action via C1/C2 on contactor for example with HC/HP')],
|
|
84
84
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
85
85
|
const endpoint = device.getEndpoint(1);
|
|
@@ -375,4 +375,25 @@ module.exports = [
|
|
|
375
375
|
},
|
|
376
376
|
exposes: [e.battery(), e.illuminance(), e.temperature(), e.humidity(), e.pressure()],
|
|
377
377
|
},
|
|
378
|
+
{
|
|
379
|
+
zigbeeModel: ['EFEKTA_eFlower_Pro'],
|
|
380
|
+
model: 'EFEKTA_eFlower_Pro',
|
|
381
|
+
vendor: 'Custom devices (DiY)',
|
|
382
|
+
description: '[Plant Wattering Sensor with e-ink display 2.13](https://efektalab.com/eFlowerPro)',
|
|
383
|
+
fromZigbee: [fz.temperature, fz.humidity, fz.illuminance, fz.soil_moisture, fz.battery],
|
|
384
|
+
toZigbee: [tz.factory_reset],
|
|
385
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
386
|
+
const firstEndpoint = device.getEndpoint(1);
|
|
387
|
+
await reporting.bind(firstEndpoint, coordinatorEndpoint, [
|
|
388
|
+
'genPowerCfg', 'msTemperatureMeasurement', 'msRelativeHumidity', 'msIlluminanceMeasurement', 'msSoilMoisture']);
|
|
389
|
+
const overides = {min: 0, max: 21600, change: 0};
|
|
390
|
+
await reporting.batteryVoltage(firstEndpoint, overides);
|
|
391
|
+
await reporting.batteryPercentageRemaining(firstEndpoint, overides);
|
|
392
|
+
await reporting.temperature(firstEndpoint, overides);
|
|
393
|
+
await reporting.humidity(firstEndpoint, overides);
|
|
394
|
+
await reporting.illuminance(firstEndpoint, overides);
|
|
395
|
+
await reporting.soil_moisture(firstEndpoint, overides);
|
|
396
|
+
},
|
|
397
|
+
exposes: [e.soil_moisture(), e.battery(), e.illuminance(), e.temperature(), e.humidity()],
|
|
398
|
+
},
|
|
378
399
|
];
|
package/devices/gledopto.js
CHANGED
|
@@ -65,7 +65,11 @@ const gledoptoExtend = {
|
|
|
65
65
|
const configureReadModelID = async (device, coordinatorEndpoint, logger) => {
|
|
66
66
|
// https://github.com/Koenkk/zigbee-herdsman-converters/issues/3016#issuecomment-1027726604
|
|
67
67
|
const endpoint = device.endpoints[0];
|
|
68
|
-
|
|
68
|
+
const oldModel = device.modelID;
|
|
69
|
+
const newModel = (await endpoint.read('genBasic', ['modelId'])).modelId;
|
|
70
|
+
if (oldModel != newModel) {
|
|
71
|
+
logger.info(`Detected Gledopto device mode change, from '${oldModel}' to '${newModel}'`);
|
|
72
|
+
}
|
|
69
73
|
};
|
|
70
74
|
|
|
71
75
|
module.exports = [
|
|
@@ -122,8 +126,11 @@ module.exports = [
|
|
|
122
126
|
vendor: 'Gledopto',
|
|
123
127
|
ota: ota.zigbeeOTA,
|
|
124
128
|
description: 'Zigbee LED Controller WW/CW (pro)',
|
|
125
|
-
extend: gledoptoExtend.light_onoff_brightness_colortemp(),
|
|
126
|
-
configure:
|
|
129
|
+
extend: gledoptoExtend.light_onoff_brightness_colortemp({noConfigure: true}),
|
|
130
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
131
|
+
await extend.light_onoff_brightness_colortemp().configure(device, coordinatorEndpoint, logger);
|
|
132
|
+
await configureReadModelID(device, coordinatorEndpoint, logger);
|
|
133
|
+
},
|
|
127
134
|
},
|
|
128
135
|
{
|
|
129
136
|
fingerprint: [
|
|
@@ -186,8 +193,11 @@ module.exports = [
|
|
|
186
193
|
vendor: 'Gledopto',
|
|
187
194
|
ota: ota.zigbeeOTA,
|
|
188
195
|
description: 'Zigbee LED Controller RGBW (pro)',
|
|
189
|
-
extend: gledoptoExtend.light_onoff_brightness_colortemp_color(),
|
|
190
|
-
configure:
|
|
196
|
+
extend: gledoptoExtend.light_onoff_brightness_colortemp_color({noConfigure: true}),
|
|
197
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
198
|
+
await extend.light_onoff_brightness_colortemp_color().configure(device, coordinatorEndpoint, logger);
|
|
199
|
+
await configureReadModelID(device, coordinatorEndpoint, logger);
|
|
200
|
+
},
|
|
191
201
|
},
|
|
192
202
|
{
|
|
193
203
|
fingerprint: [
|
|
@@ -245,8 +255,11 @@ module.exports = [
|
|
|
245
255
|
vendor: 'Gledopto',
|
|
246
256
|
ota: ota.zigbeeOTA,
|
|
247
257
|
description: 'Zigbee LED Controller RGB (pro)',
|
|
248
|
-
extend: gledoptoExtend.light_onoff_brightness_color(),
|
|
249
|
-
configure:
|
|
258
|
+
extend: gledoptoExtend.light_onoff_brightness_color({noConfigure: true}),
|
|
259
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
260
|
+
await extend.light_onoff_brightness_color().configure(device, coordinatorEndpoint, logger);
|
|
261
|
+
await configureReadModelID(device, coordinatorEndpoint, logger);
|
|
262
|
+
},
|
|
250
263
|
},
|
|
251
264
|
{
|
|
252
265
|
zigbeeModel: ['GL-C-008P'],
|
|
@@ -254,9 +267,12 @@ module.exports = [
|
|
|
254
267
|
vendor: 'Gledopto',
|
|
255
268
|
ota: ota.zigbeeOTA,
|
|
256
269
|
description: 'Zigbee LED Controller RGB+CCT (pro)',
|
|
257
|
-
extend: gledoptoExtend.light_onoff_brightness_colortemp_color({colorTempRange: [158, 495]}),
|
|
270
|
+
extend: gledoptoExtend.light_onoff_brightness_colortemp_color({colorTempRange: [158, 495], noConfigure: true}),
|
|
258
271
|
meta: {disableDefaultResponse: true},
|
|
259
|
-
configure:
|
|
272
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
273
|
+
await extend.light_onoff_brightness_colortemp_color().configure(device, coordinatorEndpoint, logger);
|
|
274
|
+
await configureReadModelID(device, coordinatorEndpoint, logger);
|
|
275
|
+
},
|
|
260
276
|
},
|
|
261
277
|
{
|
|
262
278
|
zigbeeModel: ['GL-C-009'],
|
|
@@ -277,8 +293,11 @@ module.exports = [
|
|
|
277
293
|
vendor: 'Gledopto',
|
|
278
294
|
ota: ota.zigbeeOTA,
|
|
279
295
|
description: 'Zigbee LED Controller W (pro)',
|
|
280
|
-
extend: gledoptoExtend.light_onoff_brightness(),
|
|
281
|
-
configure:
|
|
296
|
+
extend: gledoptoExtend.light_onoff_brightness({noConfigure: true}),
|
|
297
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
298
|
+
await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
|
|
299
|
+
await configureReadModelID(device, coordinatorEndpoint, logger);
|
|
300
|
+
},
|
|
282
301
|
},
|
|
283
302
|
{
|
|
284
303
|
zigbeeModel: ['GL-C-009S'],
|
package/devices/jasco.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
const fz = require('../converters/fromZigbee');
|
|
1
2
|
const reporting = require('../lib/reporting');
|
|
2
3
|
const extend = require('../lib/extend');
|
|
3
4
|
const exposes = require('../lib/exposes');
|
|
4
5
|
const e = exposes.presets;
|
|
5
6
|
|
|
7
|
+
|
|
6
8
|
module.exports = [
|
|
7
9
|
{
|
|
8
10
|
zigbeeModel: ['35938'],
|
|
@@ -32,4 +34,20 @@ module.exports = [
|
|
|
32
34
|
await reporting.instantaneousDemand(endpoint);
|
|
33
35
|
},
|
|
34
36
|
},
|
|
37
|
+
{
|
|
38
|
+
zigbeeModel: ['43095'],
|
|
39
|
+
model: '43095',
|
|
40
|
+
vendor: 'Jasco Products',
|
|
41
|
+
description: 'Zigbee smart plug-in switch with energy metering',
|
|
42
|
+
fromZigbee: [fz.command_on_state, fz.command_off_state, fz.metering],
|
|
43
|
+
extend: extend.switch(),
|
|
44
|
+
exposes: [e.switch(), e.power(), e.energy()],
|
|
45
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
46
|
+
const endpoint1 = device.getEndpoint(1);
|
|
47
|
+
await reporting.bind(endpoint1, coordinatorEndpoint, ['genOnOff', 'seMetering']);
|
|
48
|
+
await reporting.onOff(endpoint1);
|
|
49
|
+
await reporting.instantaneousDemand(endpoint1);
|
|
50
|
+
await reporting.readMeteringMultiplierDivisor(endpoint1);
|
|
51
|
+
},
|
|
52
|
+
},
|
|
35
53
|
];
|
package/devices/legrand.js
CHANGED
|
@@ -36,10 +36,10 @@ module.exports = [
|
|
|
36
36
|
description: 'Legrand (or Bticino) DIN contactor module',
|
|
37
37
|
vendor: 'Legrand',
|
|
38
38
|
extend: extend.switch(),
|
|
39
|
-
fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement, fz.
|
|
39
|
+
fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement, fz.legrand_cluster_fc01, fz.ignore_basic_report, fz.ignore_genOta],
|
|
40
40
|
toZigbee: [tz.legrand_deviceMode, tz.on_off, tz.legrand_identify, tz.electrical_measurement_power],
|
|
41
41
|
exposes: [exposes.switch().withState('state', true, 'On/off (works only if device is in "switch" mode)'),
|
|
42
|
-
e.power().withAccess(ea.STATE_GET), exposes.enum(
|
|
42
|
+
e.power().withAccess(ea.STATE_GET), exposes.enum('device_mode', ea.ALL, ['switch', 'auto'])
|
|
43
43
|
.withDescription('switch: allow on/off, auto will use wired action via C1/C2 on contactor for example with HC/HP')],
|
|
44
44
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
45
45
|
const endpoint = device.getEndpoint(1);
|
|
@@ -56,10 +56,10 @@ module.exports = [
|
|
|
56
56
|
description: 'Legrand (or Bticino) DIN smart relay for light control (note: Legrand 412170 may be similar to Bticino FC80RC)',
|
|
57
57
|
vendor: 'Legrand',
|
|
58
58
|
extend: extend.switch(),
|
|
59
|
-
fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement, fz.
|
|
59
|
+
fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement, fz.legrand_cluster_fc01, fz.ignore_basic_report, fz.ignore_genOta],
|
|
60
60
|
toZigbee: [tz.legrand_deviceMode, tz.on_off, tz.legrand_identify, tz.electrical_measurement_power],
|
|
61
61
|
exposes: [exposes.switch().withState('state', true, 'On/off (works only if device is in "switch" mode)'),
|
|
62
|
-
e.power().withAccess(ea.STATE_GET), exposes.enum(
|
|
62
|
+
e.power().withAccess(ea.STATE_GET), exposes.enum('device_mode', ea.ALL, ['switch', 'auto'])
|
|
63
63
|
.withDescription('switch: allow on/off, auto will use wired action via C1/C2 on teleruptor with buttons')],
|
|
64
64
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
65
65
|
const endpoint = device.getEndpoint(1);
|
|
@@ -171,20 +171,19 @@ module.exports = [
|
|
|
171
171
|
zigbeeModel: [' Dimmer switch w/o neutral\u0000\u0000\u0000\u0000\u0000'],
|
|
172
172
|
model: '067771',
|
|
173
173
|
vendor: 'Legrand',
|
|
174
|
-
// led blink RED when battery is low
|
|
175
174
|
description: 'Wired switch without neutral',
|
|
176
175
|
extend: extend.light_onoff_brightness({noConfigure: true}),
|
|
177
|
-
fromZigbee: [fz.brightness, fz.identify, fz.on_off, fz.lighting_ballast_configuration],
|
|
176
|
+
fromZigbee: [fz.brightness, fz.identify, fz.on_off, fz.lighting_ballast_configuration, fz.legrand_cluster_fc01],
|
|
178
177
|
toZigbee: [tz.light_onoff_brightness, tz.legrand_settingAlwaysEnableLed, tz.legrand_settingEnableLedIfOn,
|
|
179
|
-
tz.
|
|
178
|
+
tz.legrand_deviceMode, tz.legrand_identify, tz.ballast_config],
|
|
180
179
|
exposes: [e.light_brightness(),
|
|
181
180
|
exposes.numeric('ballast_minimum_level', ea.ALL).withValueMin(1).withValueMax(254)
|
|
182
181
|
.withDescription('Specifies the minimum brightness value'),
|
|
183
182
|
exposes.numeric('ballast_maximum_level', ea.ALL).withValueMin(1).withValueMax(254)
|
|
184
183
|
.withDescription('Specifies the maximum brightness value'),
|
|
185
|
-
exposes.binary('
|
|
186
|
-
exposes.binary('permanent_led', ea.
|
|
187
|
-
exposes.binary('led_when_on', ea.
|
|
184
|
+
exposes.binary('device_mode', ea.ALL, 'dimmer_on', 'dimmer_off').withDescription('Allow the device to change brightness'),
|
|
185
|
+
exposes.binary('permanent_led', ea.ALL, 'ON', 'OFF').withDescription('Enable or disable the permanent blue LED'),
|
|
186
|
+
exposes.binary('led_when_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is on')],
|
|
188
187
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
189
188
|
await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
|
|
190
189
|
const endpoint = device.getEndpoint(1);
|
|
@@ -306,9 +305,9 @@ module.exports = [
|
|
|
306
305
|
model: '064882',
|
|
307
306
|
vendor: 'Legrand',
|
|
308
307
|
description: 'Cable outlet with pilot wire and consumption measurement',
|
|
309
|
-
fromZigbee: [fz.
|
|
308
|
+
fromZigbee: [fz.legrand_cluster_fc01, fz.legrand_cable_outlet_mode, fz.on_off, fz.electrical_measurement],
|
|
310
309
|
toZigbee: [tz.legrand_deviceMode, tz.legrand_cableOutletMode, tz.on_off, tz.electrical_measurement_power],
|
|
311
|
-
exposes: [exposes.
|
|
310
|
+
exposes: [exposes.binary('device_mode', ea.ALL, 'pilot_on', 'pilot_off'),
|
|
312
311
|
exposes.enum('cable_outlet_mode', ea.ALL, ['comfort', 'comfort-1', 'comfort-2', 'eco', 'frost_protection', 'off']),
|
|
313
312
|
exposes.switch().withState('state', true, 'Works only when the pilot wire is deactivated'),
|
|
314
313
|
e.power().withAccess(ea.STATE_GET)],
|
|
@@ -320,4 +319,26 @@ module.exports = [
|
|
|
320
319
|
await reporting.activePower(endpoint);
|
|
321
320
|
},
|
|
322
321
|
},
|
|
322
|
+
{
|
|
323
|
+
zigbeeModel: [' NLIS - Double light switch\u0000\u0000\u0000\u0000'],
|
|
324
|
+
model: '067772',
|
|
325
|
+
vendor: 'Legrand',
|
|
326
|
+
description: 'Double wired switch with neutral',
|
|
327
|
+
fromZigbee: [fz.on_off, fz.legrand_cluster_fc01],
|
|
328
|
+
toZigbee: [tz.on_off, tz.legrand_settingAlwaysEnableLed, tz.legrand_settingEnableLedIfOn],
|
|
329
|
+
exposes: [e.switch().withEndpoint('left'),
|
|
330
|
+
e.switch().withEndpoint('right'),
|
|
331
|
+
exposes.binary('permanent_led', ea.ALL, 'ON', 'OFF').withDescription('Enable or disable the permanent blue LED'),
|
|
332
|
+
exposes.binary('led_when_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is on')],
|
|
333
|
+
meta: {multiEndpoint: true},
|
|
334
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
335
|
+
const endpointLeft = device.getEndpoint(1);
|
|
336
|
+
await reporting.bind(endpointLeft, coordinatorEndpoint, ['genOnOff']);
|
|
337
|
+
const endpointRight = device.getEndpoint(2);
|
|
338
|
+
await reporting.bind(endpointRight, coordinatorEndpoint, ['genOnOff']);
|
|
339
|
+
},
|
|
340
|
+
endpoint: (device) => {
|
|
341
|
+
return {left: 1, right: 2};
|
|
342
|
+
},
|
|
343
|
+
},
|
|
323
344
|
];
|