zigbee-herdsman-converters 14.0.351 → 14.0.355
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 +28 -2
- package/converters/toZigbee.js +10 -10
- package/devices/ikea.js +12 -2
- package/devices/kwikset.js +15 -0
- package/devices/philips.js +12 -3
- package/devices/schneider_electric.js +15 -0
- package/devices/siglis.js +88 -11
- package/devices/sonoff.js +2 -2
- package/devices/tuya.js +4 -3
- package/devices/xiaomi.js +14 -21
- package/index.js +2 -2
- package/npm-shrinkwrap.json +1 -1
- package/package.json +1 -1
package/converters/fromZigbee.js
CHANGED
|
@@ -1035,6 +1035,7 @@ const converters = {
|
|
|
1035
1035
|
cluster: 'genScenes',
|
|
1036
1036
|
type: 'commandRecall',
|
|
1037
1037
|
convert: (model, msg, publish, options, meta) => {
|
|
1038
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1038
1039
|
const payload = {action: postfixWithEndpointName(`recall_${msg.data.sceneid}`, msg, model)};
|
|
1039
1040
|
addActionGroup(payload, msg, model);
|
|
1040
1041
|
return payload;
|
|
@@ -1044,6 +1045,7 @@ const converters = {
|
|
|
1044
1045
|
cluster: 'ssIasAce',
|
|
1045
1046
|
type: 'commandPanic',
|
|
1046
1047
|
convert: (model, msg, publish, options, meta) => {
|
|
1048
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1047
1049
|
const payload = {action: postfixWithEndpointName(`panic`, msg, model)};
|
|
1048
1050
|
addActionGroup(payload, msg, model);
|
|
1049
1051
|
return payload;
|
|
@@ -1067,6 +1069,7 @@ const converters = {
|
|
|
1067
1069
|
cluster: 'ssIasAce',
|
|
1068
1070
|
type: 'commandArm',
|
|
1069
1071
|
convert: (model, msg, publish, options, meta) => {
|
|
1072
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1070
1073
|
const payload = converters.command_arm.convert(model, msg, publish, options, meta);
|
|
1071
1074
|
if (!payload) return;
|
|
1072
1075
|
payload.action_transaction = msg.meta.zclTransactionSequenceNumber;
|
|
@@ -1077,6 +1080,7 @@ const converters = {
|
|
|
1077
1080
|
cluster: 'closuresWindowCovering',
|
|
1078
1081
|
type: 'commandStop',
|
|
1079
1082
|
convert: (model, msg, publish, options, meta) => {
|
|
1083
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1080
1084
|
const payload = {action: postfixWithEndpointName('stop', msg, model)};
|
|
1081
1085
|
addActionGroup(payload, msg, model);
|
|
1082
1086
|
return payload;
|
|
@@ -1086,6 +1090,7 @@ const converters = {
|
|
|
1086
1090
|
cluster: 'closuresWindowCovering',
|
|
1087
1091
|
type: 'commandUpOpen',
|
|
1088
1092
|
convert: (model, msg, publish, options, meta) => {
|
|
1093
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1089
1094
|
const payload = {action: postfixWithEndpointName('open', msg, model)};
|
|
1090
1095
|
addActionGroup(payload, msg, model);
|
|
1091
1096
|
return payload;
|
|
@@ -1095,6 +1100,7 @@ const converters = {
|
|
|
1095
1100
|
cluster: 'closuresWindowCovering',
|
|
1096
1101
|
type: 'commandDownClose',
|
|
1097
1102
|
convert: (model, msg, publish, options, meta) => {
|
|
1103
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1098
1104
|
const payload = {action: postfixWithEndpointName('close', msg, model)};
|
|
1099
1105
|
addActionGroup(payload, msg, model);
|
|
1100
1106
|
return payload;
|
|
@@ -1104,6 +1110,7 @@ const converters = {
|
|
|
1104
1110
|
cluster: 'genOnOff',
|
|
1105
1111
|
type: 'commandOn',
|
|
1106
1112
|
convert: (model, msg, publish, options, meta) => {
|
|
1113
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1107
1114
|
const payload = {action: postfixWithEndpointName('on', msg, model)};
|
|
1108
1115
|
addActionGroup(payload, msg, model);
|
|
1109
1116
|
return payload;
|
|
@@ -1113,6 +1120,7 @@ const converters = {
|
|
|
1113
1120
|
cluster: 'genOnOff',
|
|
1114
1121
|
type: 'commandOff',
|
|
1115
1122
|
convert: (model, msg, publish, options, meta) => {
|
|
1123
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1116
1124
|
const payload = {action: postfixWithEndpointName('off', msg, model)};
|
|
1117
1125
|
addActionGroup(payload, msg, model);
|
|
1118
1126
|
return payload;
|
|
@@ -1122,6 +1130,7 @@ const converters = {
|
|
|
1122
1130
|
cluster: 'genOnOff',
|
|
1123
1131
|
type: 'commandOffWithEffect',
|
|
1124
1132
|
convert: (model, msg, publish, options, meta) => {
|
|
1133
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1125
1134
|
const payload = {action: postfixWithEndpointName(`off`, msg, model)};
|
|
1126
1135
|
addActionGroup(payload, msg, model);
|
|
1127
1136
|
return payload;
|
|
@@ -1131,6 +1140,7 @@ const converters = {
|
|
|
1131
1140
|
cluster: 'genOnOff',
|
|
1132
1141
|
type: 'commandToggle',
|
|
1133
1142
|
convert: (model, msg, publish, options, meta) => {
|
|
1143
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1134
1144
|
const payload = {action: postfixWithEndpointName('toggle', msg, model)};
|
|
1135
1145
|
addActionGroup(payload, msg, model);
|
|
1136
1146
|
return payload;
|
|
@@ -1141,6 +1151,7 @@ const converters = {
|
|
|
1141
1151
|
type: ['commandMoveToLevel', 'commandMoveToLevelWithOnOff'],
|
|
1142
1152
|
options: [exposes.options.simulated_brightness()],
|
|
1143
1153
|
convert: (model, msg, publish, options, meta) => {
|
|
1154
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1144
1155
|
const payload = {
|
|
1145
1156
|
action: postfixWithEndpointName(`brightness_move_to_level`, msg, model),
|
|
1146
1157
|
action_level: msg.data.level,
|
|
@@ -1161,6 +1172,7 @@ const converters = {
|
|
|
1161
1172
|
type: ['commandMove', 'commandMoveWithOnOff'],
|
|
1162
1173
|
options: [exposes.options.simulated_brightness()],
|
|
1163
1174
|
convert: (model, msg, publish, options, meta) => {
|
|
1175
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1164
1176
|
const direction = msg.data.movemode === 1 ? 'down' : 'up';
|
|
1165
1177
|
const action = postfixWithEndpointName(`brightness_move_${direction}`, msg, model);
|
|
1166
1178
|
const payload = {action, action_rate: msg.data.rate};
|
|
@@ -1195,6 +1207,7 @@ const converters = {
|
|
|
1195
1207
|
type: ['commandStep', 'commandStepWithOnOff'],
|
|
1196
1208
|
options: [exposes.options.simulated_brightness()],
|
|
1197
1209
|
convert: (model, msg, publish, options, meta) => {
|
|
1210
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1198
1211
|
const direction = msg.data.stepmode === 1 ? 'down' : 'up';
|
|
1199
1212
|
const payload = {
|
|
1200
1213
|
action: postfixWithEndpointName(`brightness_step_${direction}`, msg, model),
|
|
@@ -1220,6 +1233,7 @@ const converters = {
|
|
|
1220
1233
|
type: ['commandStop', 'commandStopWithOnOff'],
|
|
1221
1234
|
options: [exposes.options.simulated_brightness()],
|
|
1222
1235
|
convert: (model, msg, publish, options, meta) => {
|
|
1236
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1223
1237
|
if (options.simulated_brightness) {
|
|
1224
1238
|
clearInterval(globalStore.getValue(msg.endpoint, 'simulated_brightness_timer'));
|
|
1225
1239
|
globalStore.putValue(msg.endpoint, 'simulated_brightness_timer', undefined);
|
|
@@ -1234,6 +1248,7 @@ const converters = {
|
|
|
1234
1248
|
cluster: 'lightingColorCtrl',
|
|
1235
1249
|
type: ['commandMoveColorTemp'],
|
|
1236
1250
|
convert: (model, msg, publish, options, meta) => {
|
|
1251
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1237
1252
|
const direction = msg.data.movemode === 1 ? 'down' : 'up';
|
|
1238
1253
|
const action = postfixWithEndpointName(`color_temperature_move_${direction}`, msg, model);
|
|
1239
1254
|
const payload = {action, action_rate: msg.data.rate, action_minimum: msg.data.minimum, action_maximum: msg.data.maximum};
|
|
@@ -1245,6 +1260,7 @@ const converters = {
|
|
|
1245
1260
|
cluster: 'lightingColorCtrl',
|
|
1246
1261
|
type: 'commandStepColorTemp',
|
|
1247
1262
|
convert: (model, msg, publish, options, meta) => {
|
|
1263
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1248
1264
|
const direction = msg.data.stepmode === 1 ? 'up' : 'down';
|
|
1249
1265
|
const payload = {
|
|
1250
1266
|
action: postfixWithEndpointName(`color_temperature_step_${direction}`, msg, model),
|
|
@@ -1263,6 +1279,7 @@ const converters = {
|
|
|
1263
1279
|
cluster: 'lightingColorCtrl',
|
|
1264
1280
|
type: 'commandEnhancedMoveToHueAndSaturation',
|
|
1265
1281
|
convert: (model, msg, publish, options, meta) => {
|
|
1282
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1266
1283
|
const payload = {
|
|
1267
1284
|
action: postfixWithEndpointName(`enhanced_move_to_hue_and_saturation`, msg, model),
|
|
1268
1285
|
action_enhanced_hue: msg.data.enhancehue,
|
|
@@ -1279,6 +1296,7 @@ const converters = {
|
|
|
1279
1296
|
cluster: 'lightingColorCtrl',
|
|
1280
1297
|
type: ['commandStepHue'],
|
|
1281
1298
|
convert: (model, msg, publish, options, meta) => {
|
|
1299
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1282
1300
|
const direction = msg.data.stepmode === 1 ? 'up' : 'down';
|
|
1283
1301
|
const payload = {
|
|
1284
1302
|
action: postfixWithEndpointName(`color_hue_step_${direction}`, msg, model),
|
|
@@ -1293,6 +1311,7 @@ const converters = {
|
|
|
1293
1311
|
cluster: 'lightingColorCtrl',
|
|
1294
1312
|
type: ['commandStepSaturation'],
|
|
1295
1313
|
convert: (model, msg, publish, options, meta) => {
|
|
1314
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1296
1315
|
const direction = msg.data.stepmode === 1 ? 'up' : 'down';
|
|
1297
1316
|
const payload = {
|
|
1298
1317
|
action: postfixWithEndpointName(`color_saturation_step_${direction}`, msg, model),
|
|
@@ -1307,6 +1326,7 @@ const converters = {
|
|
|
1307
1326
|
cluster: 'lightingColorCtrl',
|
|
1308
1327
|
type: 'commandColorLoopSet',
|
|
1309
1328
|
convert: (model, msg, publish, options, meta) => {
|
|
1329
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1310
1330
|
const updateFlags = msg.data.updateflags;
|
|
1311
1331
|
const actionLookup = {
|
|
1312
1332
|
0x00: 'deactivate',
|
|
@@ -1336,6 +1356,7 @@ const converters = {
|
|
|
1336
1356
|
cluster: 'lightingColorCtrl',
|
|
1337
1357
|
type: 'commandMoveToColorTemp',
|
|
1338
1358
|
convert: (model, msg, publish, options, meta) => {
|
|
1359
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1339
1360
|
const payload = {
|
|
1340
1361
|
action: postfixWithEndpointName(`color_temperature_move`, msg, model),
|
|
1341
1362
|
action_color_temperature: msg.data.colortemp,
|
|
@@ -1349,6 +1370,7 @@ const converters = {
|
|
|
1349
1370
|
cluster: 'lightingColorCtrl',
|
|
1350
1371
|
type: 'commandMoveToColor',
|
|
1351
1372
|
convert: (model, msg, publish, options, meta) => {
|
|
1373
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1352
1374
|
const payload = {
|
|
1353
1375
|
action: postfixWithEndpointName(`color_move`, msg, model),
|
|
1354
1376
|
action_color: {
|
|
@@ -1365,6 +1387,7 @@ const converters = {
|
|
|
1365
1387
|
cluster: 'lightingColorCtrl',
|
|
1366
1388
|
type: 'commandMoveHue',
|
|
1367
1389
|
convert: (model, msg, publish, options, meta) => {
|
|
1390
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1368
1391
|
const movestop = msg.data.movemode == 1 ? 'move' : 'stop';
|
|
1369
1392
|
const action = postfixWithEndpointName(`hue_${movestop}`, msg, model);
|
|
1370
1393
|
const payload = {action, action_rate: msg.data.rate};
|
|
@@ -1376,6 +1399,7 @@ const converters = {
|
|
|
1376
1399
|
cluster: 'lightingColorCtrl',
|
|
1377
1400
|
type: 'commandMoveToSaturation',
|
|
1378
1401
|
convert: (model, msg, publish, options, meta) => {
|
|
1402
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1379
1403
|
const payload = {
|
|
1380
1404
|
action: postfixWithEndpointName('move_to_saturation', msg, model),
|
|
1381
1405
|
action_saturation: msg.data.saturation,
|
|
@@ -1389,6 +1413,7 @@ const converters = {
|
|
|
1389
1413
|
cluster: 'lightingColorCtrl',
|
|
1390
1414
|
type: 'commandMoveToHue',
|
|
1391
1415
|
convert: (model, msg, publish, options, meta) => {
|
|
1416
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1392
1417
|
const payload = {
|
|
1393
1418
|
action: postfixWithEndpointName(`move_to_hue`, msg, model),
|
|
1394
1419
|
action_hue: msg.data.hue,
|
|
@@ -1413,6 +1438,7 @@ const converters = {
|
|
|
1413
1438
|
cluster: 'genOnOff',
|
|
1414
1439
|
type: 'commandOn',
|
|
1415
1440
|
convert: (model, msg, publish, options, meta) => {
|
|
1441
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1416
1442
|
const property = postfixWithEndpointName('state', msg, model);
|
|
1417
1443
|
return {[property]: 'ON'};
|
|
1418
1444
|
},
|
|
@@ -1421,6 +1447,7 @@ const converters = {
|
|
|
1421
1447
|
cluster: 'genOnOff',
|
|
1422
1448
|
type: 'commandOff',
|
|
1423
1449
|
convert: (model, msg, publish, options, meta) => {
|
|
1450
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1424
1451
|
const property = postfixWithEndpointName('state', msg, model);
|
|
1425
1452
|
return {[property]: 'OFF'};
|
|
1426
1453
|
},
|
|
@@ -5114,11 +5141,10 @@ const converters = {
|
|
|
5114
5141
|
let buttonLookup = null;
|
|
5115
5142
|
if (['WXKG02LM_rev2', 'WXKG07LM', 'WXKG17LM'].includes(model.model)) buttonLookup = {1: 'left', 2: 'right', 3: 'both'};
|
|
5116
5143
|
if (['QBKG12LM', 'QBKG24LM'].includes(model.model)) buttonLookup = {5: 'left', 6: 'right', 7: 'both'};
|
|
5117
|
-
if (['QBKG25LM'].includes(model.model)) buttonLookup = {41: 'left', 42: 'center', 43: 'right'};
|
|
5118
5144
|
if (['QBKG39LM', 'QBKG41LM', 'WS-EUK02', 'WS-EUK04', 'QBKG20LM', 'QBKG31LM'].includes(model.model)) {
|
|
5119
5145
|
buttonLookup = {41: 'left', 42: 'right', 51: 'both'};
|
|
5120
5146
|
}
|
|
5121
|
-
if (['QBKG26LM', 'QBKG34LM'].includes(model.model)) {
|
|
5147
|
+
if (['QBKG25LM', 'QBKG26LM', 'QBKG34LM'].includes(model.model)) {
|
|
5122
5148
|
buttonLookup = {
|
|
5123
5149
|
41: 'left', 42: 'center', 43: 'right',
|
|
5124
5150
|
51: 'left_center', 52: 'left_right', 53: 'center_right',
|
package/converters/toZigbee.js
CHANGED
|
@@ -1982,9 +1982,9 @@ const converters = {
|
|
|
1982
1982
|
xiaomi_switch_power_outage_memory: {
|
|
1983
1983
|
key: ['power_outage_memory'],
|
|
1984
1984
|
convertSet: async (entity, key, value, meta) => {
|
|
1985
|
-
if (['ZNCZ04LM', '
|
|
1986
|
-
'WS-EUK01', 'WS-EUK02', 'WS-EUK03', 'WS-EUK04', '
|
|
1987
|
-
'QBKG34LM', '
|
|
1985
|
+
if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ14LM', 'QBCZ15LM', 'SSM-U01', 'SSM-U02', 'DLKZMK11LM', 'DLKZMK12LM',
|
|
1986
|
+
'WS-EUK01', 'WS-EUK02', 'WS-EUK03', 'WS-EUK04', 'QBKG19LM', 'QBKG20LM', 'QBKG25LM', 'QBKG26LM',
|
|
1987
|
+
'QBKG31LM', 'QBKG34LM', 'QBKG38LM', 'QBKG39LM', 'QBKG40LM', 'QBKG41LM'].includes(meta.mapped.model)) {
|
|
1988
1988
|
await entity.write('aqaraOpple', {0x0201: {value: value ? 1 : 0, type: 0x10}}, manufacturerOptions.xiaomi);
|
|
1989
1989
|
} else if (['ZNCZ02LM', 'QBCZ11LM'].includes(meta.mapped.model)) {
|
|
1990
1990
|
const payload = value ?
|
|
@@ -2005,9 +2005,9 @@ const converters = {
|
|
|
2005
2005
|
return {state: {power_outage_memory: value}};
|
|
2006
2006
|
},
|
|
2007
2007
|
convertGet: async (entity, key, meta) => {
|
|
2008
|
-
if (['ZNCZ04LM', '
|
|
2009
|
-
'WS-
|
|
2010
|
-
'QBKG38LM', 'QBKG40LM', 'QBKG41LM'].includes(meta.mapped.model)) {
|
|
2008
|
+
if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ14LM', 'QBCZ15LM', 'SSM-U01', 'SSM-U02', 'DLKZMK11LM', 'DLKZMK12LM',
|
|
2009
|
+
'WS-EUK01', 'WS-EUK02', 'WS-EUK03', 'WS-EUK04', 'QBKG19LM', 'QBKG20LM', 'QBKG25LM', 'QBKG26LM',
|
|
2010
|
+
'QBKG31LM', 'QBKG34LM', 'QBKG38LM', 'QBKG39LM', 'QBKG40LM', 'QBKG41LM'].includes(meta.mapped.model)) {
|
|
2011
2011
|
await entity.read('aqaraOpple', [0x0201]);
|
|
2012
2012
|
} else if (['ZNCZ02LM', 'QBCZ11LM', 'ZNCZ11LM'].includes(meta.mapped.model)) {
|
|
2013
2013
|
await entity.read('aqaraOpple', [0xFFF0]);
|
|
@@ -2105,8 +2105,8 @@ const converters = {
|
|
|
2105
2105
|
xiaomi_led_disabled_night: {
|
|
2106
2106
|
key: ['led_disabled_night'],
|
|
2107
2107
|
convertSet: async (entity, key, value, meta) => {
|
|
2108
|
-
if (['ZNCZ04LM', 'ZNCZ15LM', '
|
|
2109
|
-
'QBKG34LM'].includes(meta.mapped.model)) {
|
|
2108
|
+
if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ14LM', 'QBCZ15LM', 'QBKG19LM', 'QBKG20LM', 'QBKG25LM', 'QBKG26LM',
|
|
2109
|
+
'QBKG34LM', 'DLKZMK11LM'].includes(meta.mapped.model)) {
|
|
2110
2110
|
await entity.write('aqaraOpple', {0x0203: {value: value ? 1 : 0, type: 0x10}}, manufacturerOptions.xiaomi);
|
|
2111
2111
|
} else if (['ZNCZ11LM'].includes(meta.mapped.model)) {
|
|
2112
2112
|
const payload = value ?
|
|
@@ -2120,8 +2120,8 @@ const converters = {
|
|
|
2120
2120
|
return {state: {led_disabled_night: value}};
|
|
2121
2121
|
},
|
|
2122
2122
|
convertGet: async (entity, key, meta) => {
|
|
2123
|
-
if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ15LM', 'QBCZ14LM', '
|
|
2124
|
-
'QBKG34LM'].includes(meta.mapped.model)) {
|
|
2123
|
+
if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ15LM', 'QBCZ14LM', 'QBKG19LM', 'QBKG20LM', 'QBKG25LM', 'QBKG26LM',
|
|
2124
|
+
'QBKG34LM', 'DLKZMK11LM'].includes(meta.mapped.model)) {
|
|
2125
2125
|
await entity.read('aqaraOpple', [0x0203], manufacturerOptions.xiaomi);
|
|
2126
2126
|
} else {
|
|
2127
2127
|
throw new Error('Not supported');
|
package/devices/ikea.js
CHANGED
|
@@ -546,7 +546,12 @@ module.exports = [
|
|
|
546
546
|
toZigbee: [],
|
|
547
547
|
ota: ota.tradfri,
|
|
548
548
|
meta: {battery: {dontDividePercentage: true}},
|
|
549
|
-
configure:
|
|
549
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
550
|
+
// Binding genOnOff is not required to make device send events.
|
|
551
|
+
const endpoint = device.getEndpoint(1);
|
|
552
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
553
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
554
|
+
},
|
|
550
555
|
},
|
|
551
556
|
{
|
|
552
557
|
zigbeeModel: ['TRADFRI on/off switch'],
|
|
@@ -596,7 +601,12 @@ module.exports = [
|
|
|
596
601
|
toZigbee: [],
|
|
597
602
|
ota: ota.tradfri,
|
|
598
603
|
meta: {disableActionGroup: true, battery: {dontDividePercentage: true}},
|
|
599
|
-
configure:
|
|
604
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
605
|
+
// Binding genOnOff is not required to make device send events.
|
|
606
|
+
const endpoint = device.getEndpoint(1);
|
|
607
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
608
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
609
|
+
},
|
|
600
610
|
},
|
|
601
611
|
{
|
|
602
612
|
zigbeeModel: ['SYMFONISK Sound Controller'],
|
package/devices/kwikset.js
CHANGED
|
@@ -35,6 +35,21 @@ module.exports = [
|
|
|
35
35
|
},
|
|
36
36
|
exposes: [e.lock(), e.battery()],
|
|
37
37
|
},
|
|
38
|
+
{
|
|
39
|
+
zigbeeModel: ['SMARTCODE_DEADBOLT_10_W3'],
|
|
40
|
+
model: '99140-031',
|
|
41
|
+
vendor: 'Kwikset',
|
|
42
|
+
description: 'SmartCode traditional electronic deadbolt',
|
|
43
|
+
fromZigbee: [fz.lock, fz.lock_operation_event, fz.battery],
|
|
44
|
+
toZigbee: [tz.lock],
|
|
45
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
46
|
+
const endpoint = device.getEndpoint(2);
|
|
47
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['closuresDoorLock', 'genPowerCfg']);
|
|
48
|
+
await reporting.lockState(endpoint);
|
|
49
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
50
|
+
},
|
|
51
|
+
exposes: [e.lock(), e.battery()],
|
|
52
|
+
},
|
|
38
53
|
{
|
|
39
54
|
zigbeeModel: ['SMARTCODE_DEADBOLT_5'],
|
|
40
55
|
model: '99100-045',
|
package/devices/philips.js
CHANGED
|
@@ -1104,7 +1104,7 @@ module.exports = [
|
|
|
1104
1104
|
ota: ota.zigbeeOTA,
|
|
1105
1105
|
},
|
|
1106
1106
|
{
|
|
1107
|
-
zigbeeModel: ['LCW002', '4090230P9'],
|
|
1107
|
+
zigbeeModel: ['LCW002', '4090230P9', '929003053101'],
|
|
1108
1108
|
model: '4090230P9',
|
|
1109
1109
|
vendor: 'Philips',
|
|
1110
1110
|
description: 'Hue Liane',
|
|
@@ -1457,9 +1457,18 @@ module.exports = [
|
|
|
1457
1457
|
zigbeeModel: ['1746430P7'],
|
|
1458
1458
|
model: '1746430P7',
|
|
1459
1459
|
vendor: 'Philips',
|
|
1460
|
-
description: 'Hue outdoor Resonate wall lamp',
|
|
1460
|
+
description: 'Hue outdoor Resonate wall lamp (black)',
|
|
1461
1461
|
meta: {turnsOffAtBrightness1: true},
|
|
1462
|
-
extend: hueExtend.light_onoff_brightness_colortemp_color(),
|
|
1462
|
+
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
1463
|
+
ota: ota.zigbeeOTA,
|
|
1464
|
+
},
|
|
1465
|
+
{
|
|
1466
|
+
zigbeeModel: ['1746447P7'],
|
|
1467
|
+
model: '1746447P7',
|
|
1468
|
+
vendor: 'Philips',
|
|
1469
|
+
description: 'Hue outdoor Resonate wall lamp (silver)',
|
|
1470
|
+
meta: {turnsOffAtBrightness1: true},
|
|
1471
|
+
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
1463
1472
|
ota: ota.zigbeeOTA,
|
|
1464
1473
|
},
|
|
1465
1474
|
{
|
|
@@ -8,6 +8,21 @@ const e = exposes.presets;
|
|
|
8
8
|
const ea = exposes.access;
|
|
9
9
|
|
|
10
10
|
module.exports = [
|
|
11
|
+
{
|
|
12
|
+
zigbeeModel: ['NHPB/SHUTTER/1'],
|
|
13
|
+
model: 'S520567',
|
|
14
|
+
vendor: 'Schneider Electric',
|
|
15
|
+
description: 'Roller shutter',
|
|
16
|
+
fromZigbee: [fz.cover_position_tilt],
|
|
17
|
+
toZigbee: [tz.cover_position_tilt, tz.cover_state],
|
|
18
|
+
exposes: [e.cover_position()],
|
|
19
|
+
meta: {coverInverted: true},
|
|
20
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
21
|
+
const endpoint = device.getEndpoint(5);
|
|
22
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['closuresWindowCovering']);
|
|
23
|
+
await reporting.currentPositionLiftPercentage(endpoint);
|
|
24
|
+
},
|
|
25
|
+
},
|
|
11
26
|
{
|
|
12
27
|
zigbeeModel: ['iTRV'],
|
|
13
28
|
model: 'WV704R0A0902',
|
package/devices/siglis.js
CHANGED
|
@@ -1,9 +1,46 @@
|
|
|
1
|
-
const fz = require('
|
|
2
|
-
const tz = require('
|
|
3
|
-
const exposes = require('
|
|
4
|
-
const reporting = require('
|
|
1
|
+
const fz = require('../converters/fromZigbee');
|
|
2
|
+
const tz = require('../converters/toZigbee');
|
|
3
|
+
const exposes = require('../lib/exposes');
|
|
4
|
+
const reporting = require('../lib/reporting');
|
|
5
5
|
const e = exposes.presets;
|
|
6
6
|
|
|
7
|
+
const siglisManufacturerCode = 0x129C;
|
|
8
|
+
const zigfredEndpoint = 5;
|
|
9
|
+
|
|
10
|
+
const zifgredFromZigbee = {
|
|
11
|
+
cluster: 'manuSpecificSiglisZigfred',
|
|
12
|
+
type: ['attributeReport'],
|
|
13
|
+
convert: (model, msg, publish, options, meta) => {
|
|
14
|
+
const buttonEvent = msg.data['buttonEvent'];
|
|
15
|
+
|
|
16
|
+
if (buttonEvent != null) {
|
|
17
|
+
const buttonLookup = {
|
|
18
|
+
0: 'button_1',
|
|
19
|
+
1: 'button_2',
|
|
20
|
+
2: 'button_3',
|
|
21
|
+
3: 'button_4',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const actionLookup = {
|
|
25
|
+
0: 'release',
|
|
26
|
+
1: 'single',
|
|
27
|
+
2: 'double',
|
|
28
|
+
3: 'hold',
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const button = buttonEvent & 0xff;
|
|
32
|
+
const state = (buttonEvent >> 8) & 0xff;
|
|
33
|
+
|
|
34
|
+
const buttonName = buttonLookup[button];
|
|
35
|
+
const stateName = actionLookup[state];
|
|
36
|
+
|
|
37
|
+
if (buttonName && stateName) {
|
|
38
|
+
const action = `${buttonName}_${stateName}`;
|
|
39
|
+
return {action};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
};
|
|
7
44
|
|
|
8
45
|
module.exports = [
|
|
9
46
|
{
|
|
@@ -11,27 +48,67 @@ module.exports = [
|
|
|
11
48
|
model: 'ZFU-1D-CH',
|
|
12
49
|
vendor: 'Siglis',
|
|
13
50
|
description: 'zigfred uno smart in-wall switch',
|
|
14
|
-
exposes: [e.light_brightness_colorxy().withEndpoint('l1'), e.switch().withEndpoint('l2'), e.light_brightness().withEndpoint('l3')
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
51
|
+
exposes: [e.light_brightness_colorxy().withEndpoint('l1'), e.switch().withEndpoint('l2'), e.light_brightness().withEndpoint('l3'),
|
|
52
|
+
e.action([
|
|
53
|
+
'button_1_single', 'button_1_double', 'button_1_hold', 'button_1_release',
|
|
54
|
+
'button_2_single', 'button_2_double', 'button_2_hold', 'button_2_release',
|
|
55
|
+
'button_3_single', 'button_3_double', 'button_3_hold', 'button_3_release',
|
|
56
|
+
'button_4_single', 'button_4_double', 'button_4_hold', 'button_4_release',
|
|
57
|
+
])],
|
|
58
|
+
fromZigbee: [
|
|
59
|
+
zifgredFromZigbee,
|
|
60
|
+
fz.color_colortemp,
|
|
61
|
+
fz.on_off,
|
|
62
|
+
fz.brightness,
|
|
63
|
+
fz.level_config,
|
|
64
|
+
fz.power_on_behavior,
|
|
65
|
+
fz.ignore_basic_report,
|
|
66
|
+
],
|
|
67
|
+
toZigbee: [
|
|
68
|
+
tz.light_onoff_brightness,
|
|
69
|
+
tz.light_color,
|
|
70
|
+
tz.ignore_transition,
|
|
71
|
+
tz.ignore_rate,
|
|
72
|
+
tz.light_brightness_move,
|
|
73
|
+
tz.light_brightness_step,
|
|
74
|
+
tz.level_config,
|
|
75
|
+
tz.power_on_behavior,
|
|
76
|
+
tz.light_hue_saturation_move,
|
|
77
|
+
tz.light_hue_saturation_step,
|
|
78
|
+
tz.light_color_options,
|
|
79
|
+
tz.light_color_mode,
|
|
80
|
+
],
|
|
19
81
|
meta: {multiEndpoint: true},
|
|
20
82
|
endpoint: (device) => {
|
|
21
|
-
return {
|
|
83
|
+
return {
|
|
84
|
+
'l1': zigfredEndpoint,
|
|
85
|
+
'l2': 6,
|
|
86
|
+
'l3': 7,
|
|
87
|
+
};
|
|
22
88
|
},
|
|
23
89
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
24
|
-
const controlEp = device.getEndpoint(
|
|
90
|
+
const controlEp = device.getEndpoint(zigfredEndpoint);
|
|
25
91
|
const relayEp = device.getEndpoint(6);
|
|
26
92
|
const dimmerEp = device.getEndpoint(7);
|
|
93
|
+
|
|
27
94
|
// Bind Control EP (LED)
|
|
28
95
|
await reporting.bind(controlEp, coordinatorEndpoint, ['genOnOff']);
|
|
29
96
|
await reporting.bind(controlEp, coordinatorEndpoint, ['genLevelCtrl']);
|
|
30
97
|
await reporting.onOff(controlEp);
|
|
31
98
|
await reporting.brightness(controlEp);
|
|
99
|
+
await reporting.bind(controlEp, coordinatorEndpoint, ['manuSpecificSiglisZigfred']);
|
|
100
|
+
const payload = [{
|
|
101
|
+
attribute: 'buttonEvent',
|
|
102
|
+
minimumReportInterval: 0,
|
|
103
|
+
maximumReportInterval: 0,
|
|
104
|
+
reportableChange: 0,
|
|
105
|
+
}];
|
|
106
|
+
await controlEp.configureReporting('manuSpecificSiglisZigfred', payload, {manufacturerCode: siglisManufacturerCode});
|
|
107
|
+
|
|
32
108
|
// Bind Relay EP
|
|
33
109
|
await reporting.bind(relayEp, coordinatorEndpoint, ['genOnOff']);
|
|
34
110
|
await reporting.onOff(relayEp);
|
|
111
|
+
|
|
35
112
|
// Bind Dimmer EP
|
|
36
113
|
await reporting.bind(dimmerEp, coordinatorEndpoint, ['genOnOff']);
|
|
37
114
|
await reporting.bind(dimmerEp, coordinatorEndpoint, ['genLevelCtrl']);
|
package/devices/sonoff.js
CHANGED
|
@@ -70,11 +70,11 @@ module.exports = [
|
|
|
70
70
|
exposes: [e.battery(), e.action(['single', 'double', 'long'])],
|
|
71
71
|
fromZigbee: [fz.ewelink_action, fz.battery],
|
|
72
72
|
toZigbee: [],
|
|
73
|
-
meta: {battery: {voltageToPercentage: '3V_2500'}},
|
|
74
73
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
75
74
|
const endpoint = device.getEndpoint(1);
|
|
76
75
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genPowerCfg']);
|
|
77
76
|
await reporting.batteryVoltage(endpoint);
|
|
77
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
78
78
|
},
|
|
79
79
|
},
|
|
80
80
|
{
|
|
@@ -126,12 +126,12 @@ module.exports = [
|
|
|
126
126
|
description: 'Motion sensor',
|
|
127
127
|
fromZigbee: [fz.ias_occupancy_alarm_1, fz.battery],
|
|
128
128
|
toZigbee: [],
|
|
129
|
-
meta: {battery: {voltageToPercentage: '3V_2500'}},
|
|
130
129
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
131
130
|
const endpoint = device.getEndpoint(1);
|
|
132
131
|
const bindClusters = ['genPowerCfg'];
|
|
133
132
|
await reporting.bind(endpoint, coordinatorEndpoint, bindClusters);
|
|
134
133
|
await reporting.batteryVoltage(endpoint);
|
|
134
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
135
135
|
},
|
|
136
136
|
exposes: [e.occupancy(), e.battery_low(), e.tamper(), e.battery()],
|
|
137
137
|
},
|
package/devices/tuya.js
CHANGED
|
@@ -10,7 +10,8 @@ const ea = exposes.access;
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
const TS011Fplugs = ['_TZ3000_5f43h46b', '_TZ3000_cphmq0q7', '_TZ3000_dpo1ysak', '_TZ3000_ew3ldmgx', '_TZ3000_gjnozsaz',
|
|
13
|
-
'_TZ3000_jvzvulen', '_TZ3000_mraovvmm', '_TZ3000_nfnmi125', '_TZ3000_ps3dmato', '_TZ3000_w0qqde0g', '_TZ3000_u5u4cakc'
|
|
13
|
+
'_TZ3000_jvzvulen', '_TZ3000_mraovvmm', '_TZ3000_nfnmi125', '_TZ3000_ps3dmato', '_TZ3000_w0qqde0g', '_TZ3000_u5u4cakc',
|
|
14
|
+
'_TZ3000_rdtixbnu'];
|
|
14
15
|
|
|
15
16
|
module.exports = [
|
|
16
17
|
{
|
|
@@ -1189,7 +1190,7 @@ module.exports = [
|
|
|
1189
1190
|
exposes: [e.humidity(), e.temperature(), e.battery()],
|
|
1190
1191
|
},
|
|
1191
1192
|
{
|
|
1192
|
-
fingerprint: [{modelID: 'TS0011', manufacturerName: '_TZ3000_l8fsgo6p'}],
|
|
1193
|
+
fingerprint: [{modelID: 'TS0011', manufacturerName: '_TZ3000_l8fsgo6p'}, {modelID: 'TS0011', manufacturerName: '_TZ3000_ji4araar'}],
|
|
1193
1194
|
zigbeeModel: ['TS0011'],
|
|
1194
1195
|
model: 'TS0011',
|
|
1195
1196
|
vendor: 'TuYa',
|
|
@@ -1209,7 +1210,7 @@ module.exports = [
|
|
|
1209
1210
|
},
|
|
1210
1211
|
},
|
|
1211
1212
|
{
|
|
1212
|
-
fingerprint: [{modelID: 'TS0011', manufacturerName: '
|
|
1213
|
+
fingerprint: [{modelID: 'TS0011', manufacturerName: '_TZ3000_qmi1cfuq'},
|
|
1213
1214
|
{modelID: 'TS0011', manufacturerName: '_TZ3000_txpirhfq'}],
|
|
1214
1215
|
model: 'TS0011_switch_module',
|
|
1215
1216
|
vendor: 'TuYa',
|
package/devices/xiaomi.js
CHANGED
|
@@ -584,7 +584,7 @@ module.exports = [
|
|
|
584
584
|
model: 'QBKG25LM',
|
|
585
585
|
vendor: 'Xiaomi',
|
|
586
586
|
description: 'Aqara D1 3 gang smart wall switch (no neutral wire)',
|
|
587
|
-
fromZigbee: [fz.on_off, fz.
|
|
587
|
+
fromZigbee: [fz.on_off, fz.xiaomi_multistate_action, fz.aqara_opple],
|
|
588
588
|
toZigbee: [tz.on_off, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_switch_power_outage_memory, tz.xiaomi_led_disabled_night,
|
|
589
589
|
tz.aqara_switch_mode_switch],
|
|
590
590
|
meta: {multiEndpoint: true},
|
|
@@ -607,9 +607,9 @@ module.exports = [
|
|
|
607
607
|
'Quick mode makes the device respond faster.'),
|
|
608
608
|
e.power_outage_memory(), e.led_disabled_night(), e.temperature().withAccess(ea.STATE),
|
|
609
609
|
e.action([
|
|
610
|
-
'left_single', 'left_double', '
|
|
611
|
-
'
|
|
612
|
-
'
|
|
610
|
+
'left_single', 'left_double', 'center_single', 'center_double', 'right_single', 'right_double',
|
|
611
|
+
'single_left_center', 'double_left_center', 'single_left_right', 'double_left_right',
|
|
612
|
+
'single_center_right', 'double_center_right', 'single_all', 'double_all']),
|
|
613
613
|
],
|
|
614
614
|
onEvent: preventReset,
|
|
615
615
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
@@ -622,11 +622,8 @@ module.exports = [
|
|
|
622
622
|
model: 'QBKG26LM',
|
|
623
623
|
vendor: 'Xiaomi',
|
|
624
624
|
description: 'Aqara D1 3 gang smart wall switch (with neutral wire)',
|
|
625
|
-
extend: extend.switch(),
|
|
626
625
|
exposes: [
|
|
627
|
-
e.switch().withEndpoint('left'),
|
|
628
|
-
e.switch().withEndpoint('center'),
|
|
629
|
-
e.switch().withEndpoint('right'),
|
|
626
|
+
e.switch().withEndpoint('left'), e.switch().withEndpoint('center'), e.switch().withEndpoint('right'),
|
|
630
627
|
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
|
|
631
628
|
.withDescription('Decoupled mode for left button')
|
|
632
629
|
.withEndpoint('left'),
|
|
@@ -636,27 +633,22 @@ module.exports = [
|
|
|
636
633
|
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
|
|
637
634
|
.withDescription('Decoupled mode for right button')
|
|
638
635
|
.withEndpoint('right'),
|
|
639
|
-
e.power().withAccess(ea.STATE), e.
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
'
|
|
636
|
+
e.power().withAccess(ea.STATE), e.power_outage_memory(), e.led_disabled_night(),
|
|
637
|
+
e.temperature().withAccess(ea.STATE),
|
|
638
|
+
e.action([
|
|
639
|
+
'single_left', 'double_left', 'single_center', 'double_center', 'single_right', 'double_right',
|
|
643
640
|
'single_left_center', 'double_left_center', 'single_left_right', 'double_left_right',
|
|
644
641
|
'single_center_right', 'double_center_right', 'single_all', 'double_all']),
|
|
645
642
|
],
|
|
646
|
-
fromZigbee: [fz.on_off, fz.
|
|
647
|
-
toZigbee: [tz.on_off, tz.xiaomi_switch_operation_mode_opple
|
|
643
|
+
fromZigbee: [fz.on_off, fz.xiaomi_power, fz.aqara_opple, fz.xiaomi_multistate_action],
|
|
644
|
+
toZigbee: [tz.on_off, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_switch_power_outage_memory,
|
|
645
|
+
tz.xiaomi_led_disabled_night],
|
|
648
646
|
meta: {multiEndpoint: true},
|
|
649
647
|
endpoint: (device) => {
|
|
650
|
-
return {'left': 1, 'center': 2, 'right': 3
|
|
648
|
+
return {'left': 1, 'center': 2, 'right': 3};
|
|
651
649
|
},
|
|
652
650
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
653
651
|
await device.getEndpoint(1).write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f, disableResponse: true});
|
|
654
|
-
await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
|
|
655
|
-
await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
|
|
656
|
-
await reporting.bind(device.getEndpoint(3), coordinatorEndpoint, ['genOnOff']);
|
|
657
|
-
await reporting.onOff(device.getEndpoint(1));
|
|
658
|
-
await reporting.onOff(device.getEndpoint(2));
|
|
659
|
-
await reporting.onOff(device.getEndpoint(3));
|
|
660
652
|
},
|
|
661
653
|
onEvent: preventReset,
|
|
662
654
|
},
|
|
@@ -1725,6 +1717,7 @@ module.exports = [
|
|
|
1725
1717
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1726
1718
|
await device.getEndpoint(1).write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f, disableResponse: true});
|
|
1727
1719
|
},
|
|
1720
|
+
ota: ota.zigbeeOTA,
|
|
1728
1721
|
},
|
|
1729
1722
|
{
|
|
1730
1723
|
zigbeeModel: ['lumi.magnet.agl02'],
|
package/index.js
CHANGED
|
@@ -46,7 +46,6 @@ const converterRequiredFields = {
|
|
|
46
46
|
description: 'String',
|
|
47
47
|
fromZigbee: 'Array',
|
|
48
48
|
toZigbee: 'Array',
|
|
49
|
-
exposes: 'Array',
|
|
50
49
|
};
|
|
51
50
|
|
|
52
51
|
function validateDefinition(definition) {
|
|
@@ -56,6 +55,7 @@ function validateDefinition(definition) {
|
|
|
56
55
|
const msg = `Converter field ${field} expected type doenst match to ${definition[field]}`;
|
|
57
56
|
assert.strictEqual(definition[field].constructor.name, expectedType, msg);
|
|
58
57
|
}
|
|
58
|
+
assert.ok(Array.isArray(definition.exposes) || typeof definition.exposes === 'function', 'Exposes incorrect');
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
function addDefinition(definition) {
|
|
@@ -77,7 +77,7 @@ function addDefinition(definition) {
|
|
|
77
77
|
|
|
78
78
|
definition.toZigbee.push(tz.scene_store, tz.scene_recall, tz.scene_add, tz.scene_remove, tz.scene_remove_all, tz.read, tz.write);
|
|
79
79
|
|
|
80
|
-
if (definition.exposes) {
|
|
80
|
+
if (definition.exposes && Array.isArray(definition.exposes)) {
|
|
81
81
|
definition.exposes = definition.exposes.concat([exposes.presets.linkquality()]);
|
|
82
82
|
}
|
|
83
83
|
|
package/npm-shrinkwrap.json
CHANGED