zigbee-herdsman-converters 14.0.402 → 14.0.403
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 +47 -46
- package/converters/toZigbee.js +13 -2
- package/devices/casaia.js +8 -0
- package/devices/legrand.js +2 -2
- package/devices/moes.js +1 -1
- package/devices/tuya.js +4 -1
- package/devices/xiaomi.js +12 -12
- package/lib/exposes.js +1 -0
- package/npm-shrinkwrap.json +1 -1
- package/package.json +1 -1
package/converters/fromZigbee.js
CHANGED
|
@@ -1046,7 +1046,7 @@ const converters = {
|
|
|
1046
1046
|
cluster: 'genScenes',
|
|
1047
1047
|
type: 'commandRecall',
|
|
1048
1048
|
convert: (model, msg, publish, options, meta) => {
|
|
1049
|
-
if (
|
|
1049
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1050
1050
|
const payload = {action: postfixWithEndpointName(`recall_${msg.data.sceneid}`, msg, model)};
|
|
1051
1051
|
addActionGroup(payload, msg, model);
|
|
1052
1052
|
return payload;
|
|
@@ -1056,7 +1056,7 @@ const converters = {
|
|
|
1056
1056
|
cluster: 'ssIasAce',
|
|
1057
1057
|
type: 'commandPanic',
|
|
1058
1058
|
convert: (model, msg, publish, options, meta) => {
|
|
1059
|
-
if (
|
|
1059
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1060
1060
|
const payload = {action: postfixWithEndpointName(`panic`, msg, model)};
|
|
1061
1061
|
addActionGroup(payload, msg, model);
|
|
1062
1062
|
return payload;
|
|
@@ -1066,7 +1066,7 @@ const converters = {
|
|
|
1066
1066
|
cluster: 'ssIasAce',
|
|
1067
1067
|
type: 'commandArm',
|
|
1068
1068
|
convert: (model, msg, publish, options, meta) => {
|
|
1069
|
-
if (
|
|
1069
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1070
1070
|
const payload = {
|
|
1071
1071
|
action: postfixWithEndpointName(constants.armMode[msg.data['armmode']], msg, model),
|
|
1072
1072
|
action_code: msg.data.code,
|
|
@@ -1090,7 +1090,7 @@ const converters = {
|
|
|
1090
1090
|
cluster: 'closuresWindowCovering',
|
|
1091
1091
|
type: 'commandStop',
|
|
1092
1092
|
convert: (model, msg, publish, options, meta) => {
|
|
1093
|
-
if (
|
|
1093
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1094
1094
|
const payload = {action: postfixWithEndpointName('stop', msg, model)};
|
|
1095
1095
|
addActionGroup(payload, msg, model);
|
|
1096
1096
|
return payload;
|
|
@@ -1100,7 +1100,7 @@ const converters = {
|
|
|
1100
1100
|
cluster: 'closuresWindowCovering',
|
|
1101
1101
|
type: 'commandUpOpen',
|
|
1102
1102
|
convert: (model, msg, publish, options, meta) => {
|
|
1103
|
-
if (
|
|
1103
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1104
1104
|
const payload = {action: postfixWithEndpointName('open', msg, model)};
|
|
1105
1105
|
addActionGroup(payload, msg, model);
|
|
1106
1106
|
return payload;
|
|
@@ -1110,7 +1110,7 @@ const converters = {
|
|
|
1110
1110
|
cluster: 'closuresWindowCovering',
|
|
1111
1111
|
type: 'commandDownClose',
|
|
1112
1112
|
convert: (model, msg, publish, options, meta) => {
|
|
1113
|
-
if (
|
|
1113
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1114
1114
|
const payload = {action: postfixWithEndpointName('close', msg, model)};
|
|
1115
1115
|
addActionGroup(payload, msg, model);
|
|
1116
1116
|
return payload;
|
|
@@ -1120,7 +1120,7 @@ const converters = {
|
|
|
1120
1120
|
cluster: 'genOnOff',
|
|
1121
1121
|
type: 'commandOn',
|
|
1122
1122
|
convert: (model, msg, publish, options, meta) => {
|
|
1123
|
-
if (
|
|
1123
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1124
1124
|
const payload = {action: postfixWithEndpointName('on', msg, model)};
|
|
1125
1125
|
addActionGroup(payload, msg, model);
|
|
1126
1126
|
return payload;
|
|
@@ -1130,7 +1130,7 @@ const converters = {
|
|
|
1130
1130
|
cluster: 'genOnOff',
|
|
1131
1131
|
type: 'commandOff',
|
|
1132
1132
|
convert: (model, msg, publish, options, meta) => {
|
|
1133
|
-
if (
|
|
1133
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1134
1134
|
const payload = {action: postfixWithEndpointName('off', msg, model)};
|
|
1135
1135
|
addActionGroup(payload, msg, model);
|
|
1136
1136
|
return payload;
|
|
@@ -1140,7 +1140,7 @@ const converters = {
|
|
|
1140
1140
|
cluster: 'genOnOff',
|
|
1141
1141
|
type: 'commandOffWithEffect',
|
|
1142
1142
|
convert: (model, msg, publish, options, meta) => {
|
|
1143
|
-
if (
|
|
1143
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1144
1144
|
const payload = {action: postfixWithEndpointName(`off`, msg, model)};
|
|
1145
1145
|
addActionGroup(payload, msg, model);
|
|
1146
1146
|
return payload;
|
|
@@ -1150,7 +1150,7 @@ const converters = {
|
|
|
1150
1150
|
cluster: 'genOnOff',
|
|
1151
1151
|
type: 'commandToggle',
|
|
1152
1152
|
convert: (model, msg, publish, options, meta) => {
|
|
1153
|
-
if (
|
|
1153
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1154
1154
|
const payload = {action: postfixWithEndpointName('toggle', msg, model)};
|
|
1155
1155
|
addActionGroup(payload, msg, model);
|
|
1156
1156
|
return payload;
|
|
@@ -1161,7 +1161,7 @@ const converters = {
|
|
|
1161
1161
|
type: ['commandMoveToLevel', 'commandMoveToLevelWithOnOff'],
|
|
1162
1162
|
options: [exposes.options.simulated_brightness()],
|
|
1163
1163
|
convert: (model, msg, publish, options, meta) => {
|
|
1164
|
-
if (
|
|
1164
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1165
1165
|
const payload = {
|
|
1166
1166
|
action: postfixWithEndpointName(`brightness_move_to_level`, msg, model),
|
|
1167
1167
|
action_level: msg.data.level,
|
|
@@ -1183,7 +1183,7 @@ const converters = {
|
|
|
1183
1183
|
type: ['commandMove', 'commandMoveWithOnOff'],
|
|
1184
1184
|
options: [exposes.options.simulated_brightness()],
|
|
1185
1185
|
convert: (model, msg, publish, options, meta) => {
|
|
1186
|
-
if (
|
|
1186
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1187
1187
|
const direction = msg.data.movemode === 1 ? 'down' : 'up';
|
|
1188
1188
|
const action = postfixWithEndpointName(`brightness_move_${direction}`, msg, model);
|
|
1189
1189
|
const payload = {action, action_rate: msg.data.rate};
|
|
@@ -1219,7 +1219,7 @@ const converters = {
|
|
|
1219
1219
|
type: ['commandStep', 'commandStepWithOnOff'],
|
|
1220
1220
|
options: [exposes.options.simulated_brightness()],
|
|
1221
1221
|
convert: (model, msg, publish, options, meta) => {
|
|
1222
|
-
if (
|
|
1222
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1223
1223
|
const direction = msg.data.stepmode === 1 ? 'down' : 'up';
|
|
1224
1224
|
const payload = {
|
|
1225
1225
|
action: postfixWithEndpointName(`brightness_step_${direction}`, msg, model),
|
|
@@ -1246,7 +1246,7 @@ const converters = {
|
|
|
1246
1246
|
type: ['commandStop', 'commandStopWithOnOff'],
|
|
1247
1247
|
options: [exposes.options.simulated_brightness()],
|
|
1248
1248
|
convert: (model, msg, publish, options, meta) => {
|
|
1249
|
-
if (
|
|
1249
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1250
1250
|
if (options.simulated_brightness) {
|
|
1251
1251
|
clearInterval(globalStore.getValue(msg.endpoint, 'simulated_brightness_timer'));
|
|
1252
1252
|
globalStore.putValue(msg.endpoint, 'simulated_brightness_timer', undefined);
|
|
@@ -1261,7 +1261,7 @@ const converters = {
|
|
|
1261
1261
|
cluster: 'lightingColorCtrl',
|
|
1262
1262
|
type: ['commandMoveColorTemp'],
|
|
1263
1263
|
convert: (model, msg, publish, options, meta) => {
|
|
1264
|
-
if (
|
|
1264
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1265
1265
|
const direction = msg.data.movemode === 1 ? 'down' : 'up';
|
|
1266
1266
|
const action = postfixWithEndpointName(`color_temperature_move_${direction}`, msg, model);
|
|
1267
1267
|
const payload = {action, action_rate: msg.data.rate, action_minimum: msg.data.minimum, action_maximum: msg.data.maximum};
|
|
@@ -1273,7 +1273,7 @@ const converters = {
|
|
|
1273
1273
|
cluster: 'lightingColorCtrl',
|
|
1274
1274
|
type: 'commandStepColorTemp',
|
|
1275
1275
|
convert: (model, msg, publish, options, meta) => {
|
|
1276
|
-
if (
|
|
1276
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1277
1277
|
const direction = msg.data.stepmode === 1 ? 'up' : 'down';
|
|
1278
1278
|
const payload = {
|
|
1279
1279
|
action: postfixWithEndpointName(`color_temperature_step_${direction}`, msg, model),
|
|
@@ -1292,7 +1292,7 @@ const converters = {
|
|
|
1292
1292
|
cluster: 'lightingColorCtrl',
|
|
1293
1293
|
type: 'commandEnhancedMoveToHueAndSaturation',
|
|
1294
1294
|
convert: (model, msg, publish, options, meta) => {
|
|
1295
|
-
if (
|
|
1295
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1296
1296
|
const payload = {
|
|
1297
1297
|
action: postfixWithEndpointName(`enhanced_move_to_hue_and_saturation`, msg, model),
|
|
1298
1298
|
action_enhanced_hue: msg.data.enhancehue,
|
|
@@ -1309,7 +1309,7 @@ const converters = {
|
|
|
1309
1309
|
cluster: 'lightingColorCtrl',
|
|
1310
1310
|
type: ['commandStepHue'],
|
|
1311
1311
|
convert: (model, msg, publish, options, meta) => {
|
|
1312
|
-
if (
|
|
1312
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1313
1313
|
const direction = msg.data.stepmode === 1 ? 'up' : 'down';
|
|
1314
1314
|
const payload = {
|
|
1315
1315
|
action: postfixWithEndpointName(`color_hue_step_${direction}`, msg, model),
|
|
@@ -1324,7 +1324,7 @@ const converters = {
|
|
|
1324
1324
|
cluster: 'lightingColorCtrl',
|
|
1325
1325
|
type: ['commandStepSaturation'],
|
|
1326
1326
|
convert: (model, msg, publish, options, meta) => {
|
|
1327
|
-
if (
|
|
1327
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1328
1328
|
const direction = msg.data.stepmode === 1 ? 'up' : 'down';
|
|
1329
1329
|
const payload = {
|
|
1330
1330
|
action: postfixWithEndpointName(`color_saturation_step_${direction}`, msg, model),
|
|
@@ -1339,7 +1339,7 @@ const converters = {
|
|
|
1339
1339
|
cluster: 'lightingColorCtrl',
|
|
1340
1340
|
type: 'commandColorLoopSet',
|
|
1341
1341
|
convert: (model, msg, publish, options, meta) => {
|
|
1342
|
-
if (
|
|
1342
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1343
1343
|
const updateFlags = msg.data.updateflags;
|
|
1344
1344
|
const actionLookup = {
|
|
1345
1345
|
0x00: 'deactivate',
|
|
@@ -1369,7 +1369,7 @@ const converters = {
|
|
|
1369
1369
|
cluster: 'lightingColorCtrl',
|
|
1370
1370
|
type: 'commandMoveToColorTemp',
|
|
1371
1371
|
convert: (model, msg, publish, options, meta) => {
|
|
1372
|
-
if (
|
|
1372
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1373
1373
|
const payload = {
|
|
1374
1374
|
action: postfixWithEndpointName(`color_temperature_move`, msg, model),
|
|
1375
1375
|
action_color_temperature: msg.data.colortemp,
|
|
@@ -1383,7 +1383,7 @@ const converters = {
|
|
|
1383
1383
|
cluster: 'lightingColorCtrl',
|
|
1384
1384
|
type: 'commandMoveToColor',
|
|
1385
1385
|
convert: (model, msg, publish, options, meta) => {
|
|
1386
|
-
if (
|
|
1386
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1387
1387
|
const payload = {
|
|
1388
1388
|
action: postfixWithEndpointName(`color_move`, msg, model),
|
|
1389
1389
|
action_color: {
|
|
@@ -1400,7 +1400,7 @@ const converters = {
|
|
|
1400
1400
|
cluster: 'lightingColorCtrl',
|
|
1401
1401
|
type: 'commandMoveHue',
|
|
1402
1402
|
convert: (model, msg, publish, options, meta) => {
|
|
1403
|
-
if (
|
|
1403
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1404
1404
|
const movestop = msg.data.movemode == 1 ? 'move' : 'stop';
|
|
1405
1405
|
const action = postfixWithEndpointName(`hue_${movestop}`, msg, model);
|
|
1406
1406
|
const payload = {action, action_rate: msg.data.rate};
|
|
@@ -1412,7 +1412,7 @@ const converters = {
|
|
|
1412
1412
|
cluster: 'lightingColorCtrl',
|
|
1413
1413
|
type: 'commandMoveToSaturation',
|
|
1414
1414
|
convert: (model, msg, publish, options, meta) => {
|
|
1415
|
-
if (
|
|
1415
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1416
1416
|
const payload = {
|
|
1417
1417
|
action: postfixWithEndpointName('move_to_saturation', msg, model),
|
|
1418
1418
|
action_saturation: msg.data.saturation,
|
|
@@ -1426,7 +1426,7 @@ const converters = {
|
|
|
1426
1426
|
cluster: 'lightingColorCtrl',
|
|
1427
1427
|
type: 'commandMoveToHue',
|
|
1428
1428
|
convert: (model, msg, publish, options, meta) => {
|
|
1429
|
-
if (
|
|
1429
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1430
1430
|
const payload = {
|
|
1431
1431
|
action: postfixWithEndpointName(`move_to_hue`, msg, model),
|
|
1432
1432
|
action_hue: msg.data.hue,
|
|
@@ -1441,7 +1441,7 @@ const converters = {
|
|
|
1441
1441
|
cluster: 'ssIasAce',
|
|
1442
1442
|
type: 'commandEmergency',
|
|
1443
1443
|
convert: (model, msg, publish, options, meta) => {
|
|
1444
|
-
if (
|
|
1444
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1445
1445
|
const payload = {action: postfixWithEndpointName(`emergency`, msg, model)};
|
|
1446
1446
|
addActionGroup(payload, msg, model);
|
|
1447
1447
|
return payload;
|
|
@@ -1451,7 +1451,7 @@ const converters = {
|
|
|
1451
1451
|
cluster: 'genOnOff',
|
|
1452
1452
|
type: 'commandOn',
|
|
1453
1453
|
convert: (model, msg, publish, options, meta) => {
|
|
1454
|
-
if (
|
|
1454
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1455
1455
|
const property = postfixWithEndpointName('state', msg, model);
|
|
1456
1456
|
return {[property]: 'ON'};
|
|
1457
1457
|
},
|
|
@@ -1460,7 +1460,7 @@ const converters = {
|
|
|
1460
1460
|
cluster: 'genOnOff',
|
|
1461
1461
|
type: 'commandOff',
|
|
1462
1462
|
convert: (model, msg, publish, options, meta) => {
|
|
1463
|
-
if (
|
|
1463
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
1464
1464
|
const property = postfixWithEndpointName('state', msg, model);
|
|
1465
1465
|
return {[property]: 'OFF'};
|
|
1466
1466
|
},
|
|
@@ -2185,7 +2185,7 @@ const converters = {
|
|
|
2185
2185
|
cluster: 'ssIasZone',
|
|
2186
2186
|
type: 'commandStatusChangeNotification',
|
|
2187
2187
|
convert: (model, msg, publish, options, meta) => {
|
|
2188
|
-
if (
|
|
2188
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
2189
2189
|
const lookup = {1: 'pressed'};
|
|
2190
2190
|
const zoneStatus = msg.data.zonestatus;
|
|
2191
2191
|
return {
|
|
@@ -4522,7 +4522,7 @@ const converters = {
|
|
|
4522
4522
|
cluster: 'genScenes',
|
|
4523
4523
|
type: 'commandTradfriArrowSingle',
|
|
4524
4524
|
convert: (model, msg, publish, options, meta) => {
|
|
4525
|
-
if (
|
|
4525
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
4526
4526
|
if (msg.data.value === 2) {
|
|
4527
4527
|
// This is send on toggle hold, ignore it as a toggle_hold is already handled above.
|
|
4528
4528
|
return;
|
|
@@ -4536,7 +4536,7 @@ const converters = {
|
|
|
4536
4536
|
cluster: 'genScenes',
|
|
4537
4537
|
type: 'commandTradfriArrowHold',
|
|
4538
4538
|
convert: (model, msg, publish, options, meta) => {
|
|
4539
|
-
if (
|
|
4539
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
4540
4540
|
const direction = msg.data.value === 3329 ? 'left' : 'right';
|
|
4541
4541
|
globalStore.putValue(msg.endpoint, 'direction', direction);
|
|
4542
4542
|
return {action: `arrow_${direction}_hold`};
|
|
@@ -4547,7 +4547,7 @@ const converters = {
|
|
|
4547
4547
|
type: 'commandTradfriArrowRelease',
|
|
4548
4548
|
options: [exposes.options.legacy()],
|
|
4549
4549
|
convert: (model, msg, publish, options, meta) => {
|
|
4550
|
-
if (
|
|
4550
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
4551
4551
|
const direction = globalStore.getValue(msg.endpoint, 'direction');
|
|
4552
4552
|
if (direction) {
|
|
4553
4553
|
globalStore.clearValue(msg.endpoint, 'direction');
|
|
@@ -5257,7 +5257,7 @@ const converters = {
|
|
|
5257
5257
|
else if (index === 5) {
|
|
5258
5258
|
if (['JT-BZ-01AQ/A'].includes(model.model)) payload.power_outage_count = value;
|
|
5259
5259
|
} else if (index === 100) {
|
|
5260
|
-
if (['QBKG20LM', 'QBKG39LM', 'QBKG41LM', 'QBCZ15LM'].includes(model.model)) {
|
|
5260
|
+
if (['QBKG20LM', 'QBKG31LM', 'QBKG39LM', 'QBKG41LM', 'QBCZ15LM'].includes(model.model)) {
|
|
5261
5261
|
const mapping = model.model === 'QBCZ15LM' ? 'relay' : 'left';
|
|
5262
5262
|
payload[`state_${mapping}`] = value === 1 ? 'ON' : 'OFF';
|
|
5263
5263
|
} else if (['WXKG14LM', 'WXKG16LM', 'WXKG17LM'].includes(model.model)) {
|
|
@@ -5266,7 +5266,7 @@ const converters = {
|
|
|
5266
5266
|
payload.state = value === 1 ? 'ON' : 'OFF';
|
|
5267
5267
|
}
|
|
5268
5268
|
} else if (index === 101) {
|
|
5269
|
-
if (['
|
|
5269
|
+
if (['QBKG20LM', 'QBKG31LM', 'QBKG39LM', 'QBKG41LM', 'QBCZ15LM'].includes(model.model)) {
|
|
5270
5270
|
const mapping = model.model === 'QBCZ15LM' ? 'usb' : 'right';
|
|
5271
5271
|
payload[`state_${mapping}`] = value === 1 ? 'ON' : 'OFF';
|
|
5272
5272
|
} else if (['QBKG25LM', 'QBKG34LM'].includes(model.model)) {
|
|
@@ -5303,6 +5303,7 @@ const converters = {
|
|
|
5303
5303
|
}
|
|
5304
5304
|
if (msg.data.hasOwnProperty('4')) payload.mode_switch = {4: 'anti_flicker_mode', 1: 'quick_mode'}[msg.data['4']];
|
|
5305
5305
|
if (msg.data.hasOwnProperty('10')) payload.switch_type = {1: 'toggle', 2: 'momentary'}[msg.data['10']];
|
|
5306
|
+
if (msg.data.hasOwnProperty('240')) payload.flip_indicator_light = msg.data['240'] === 1 ? 'ON' : 'OFF';
|
|
5306
5307
|
if (msg.data.hasOwnProperty('258')) payload.detection_interval = msg.data['258'];
|
|
5307
5308
|
if (msg.data.hasOwnProperty('268')) {
|
|
5308
5309
|
if (['RTCGQ13LM'].includes(model.model)) {
|
|
@@ -5395,7 +5396,7 @@ const converters = {
|
|
|
5395
5396
|
cluster: 'genMultistateInput',
|
|
5396
5397
|
type: ['attributeReport'],
|
|
5397
5398
|
convert: (model, msg, publish, options, meta) => {
|
|
5398
|
-
if (
|
|
5399
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
5399
5400
|
let actionLookup = {0: 'hold', 1: 'single', 2: 'double', 3: 'triple', 255: 'release'};
|
|
5400
5401
|
if (model.model === 'WXKG12LM') {
|
|
5401
5402
|
actionLookup = {...actionLookup, 16: 'hold', 17: 'release', 18: 'shake'};
|
|
@@ -5541,7 +5542,7 @@ const converters = {
|
|
|
5541
5542
|
`increase it with this option (value is in ms).`),
|
|
5542
5543
|
],
|
|
5543
5544
|
convert: (model, msg, publish, options, meta) => {
|
|
5544
|
-
if (
|
|
5545
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
5545
5546
|
const state = msg.data['onOff'];
|
|
5546
5547
|
|
|
5547
5548
|
// 0 = click down, 1 = click up, else = multiple clicks
|
|
@@ -5847,7 +5848,7 @@ const converters = {
|
|
|
5847
5848
|
cluster: 'genMultistateInput',
|
|
5848
5849
|
type: ['attributeReport', 'readResponse'],
|
|
5849
5850
|
convert: (model, msg, publish, options, meta) => {
|
|
5850
|
-
if (
|
|
5851
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
5851
5852
|
const actionLookup = {0: 'hold', 255: 'release', 1: 'single', 2: 'double', 3: 'triple', 5: 'quintuple', 6: 'many'};
|
|
5852
5853
|
const button = msg.endpoint.ID;
|
|
5853
5854
|
const value = msg.data.presentValue;
|
|
@@ -5870,7 +5871,7 @@ const converters = {
|
|
|
5870
5871
|
cluster: 'genOnOff',
|
|
5871
5872
|
type: 'commandOn',
|
|
5872
5873
|
convert: (model, msg, publish, options, meta) => {
|
|
5873
|
-
if (
|
|
5874
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
5874
5875
|
return {action: 'button_2_single'};
|
|
5875
5876
|
},
|
|
5876
5877
|
},
|
|
@@ -5878,7 +5879,7 @@ const converters = {
|
|
|
5878
5879
|
cluster: 'genOnOff',
|
|
5879
5880
|
type: 'commandOff',
|
|
5880
5881
|
convert: (model, msg, publish, options, meta) => {
|
|
5881
|
-
if (
|
|
5882
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
5882
5883
|
return {action: 'button_1_single'};
|
|
5883
5884
|
},
|
|
5884
5885
|
},
|
|
@@ -5886,7 +5887,7 @@ const converters = {
|
|
|
5886
5887
|
cluster: 'genLevelCtrl',
|
|
5887
5888
|
type: 'commandStep',
|
|
5888
5889
|
convert: (model, msg, publish, options, meta) => {
|
|
5889
|
-
if (
|
|
5890
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
5890
5891
|
const button = msg.data.stepmode === 0 ? '4' : '3';
|
|
5891
5892
|
return {action: `button_${button}_single`};
|
|
5892
5893
|
},
|
|
@@ -5896,7 +5897,7 @@ const converters = {
|
|
|
5896
5897
|
type: 'commandStop',
|
|
5897
5898
|
options: [exposes.options.legacy()],
|
|
5898
5899
|
convert: (model, msg, publish, options, meta) => {
|
|
5899
|
-
if (
|
|
5900
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
5900
5901
|
if (globalStore.hasValue(msg.endpoint, 'button')) {
|
|
5901
5902
|
const value = globalStore.getValue(msg.endpoint, 'button');
|
|
5902
5903
|
const duration = Date.now() - value.start;
|
|
@@ -5910,7 +5911,7 @@ const converters = {
|
|
|
5910
5911
|
cluster: 'genLevelCtrl',
|
|
5911
5912
|
type: 'commandMove',
|
|
5912
5913
|
convert: (model, msg, publish, options, meta) => {
|
|
5913
|
-
if (
|
|
5914
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
5914
5915
|
const button = msg.data.movemode === 0 ? '4' : '3';
|
|
5915
5916
|
globalStore.putValue(msg.endpoint, 'button', {button, start: Date.now()});
|
|
5916
5917
|
return {action: `button_${button}_hold`};
|
|
@@ -5920,7 +5921,7 @@ const converters = {
|
|
|
5920
5921
|
cluster: 'lightingColorCtrl',
|
|
5921
5922
|
type: 'commandStepColorTemp',
|
|
5922
5923
|
convert: (model, msg, publish, options, meta) => {
|
|
5923
|
-
if (
|
|
5924
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
5924
5925
|
let action;
|
|
5925
5926
|
if (model.model === 'WXCJKG12LM') {
|
|
5926
5927
|
// for WXCJKG12LM model it's double click event on buttons 3 and 4
|
|
@@ -5937,7 +5938,7 @@ const converters = {
|
|
|
5937
5938
|
type: 'commandMoveColorTemp',
|
|
5938
5939
|
options: [exposes.options.legacy()],
|
|
5939
5940
|
convert: (model, msg, publish, options, meta) => {
|
|
5940
|
-
if (
|
|
5941
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
5941
5942
|
const stop = msg.data.movemode === 0;
|
|
5942
5943
|
let result = null;
|
|
5943
5944
|
if (stop) {
|
|
@@ -7363,7 +7364,7 @@ const converters = {
|
|
|
7363
7364
|
cluster: 'wiserDeviceInfo',
|
|
7364
7365
|
type: 'attributeReport',
|
|
7365
7366
|
convert: (model, msg, publish, options, meta) => {
|
|
7366
|
-
if (
|
|
7367
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
7367
7368
|
|
|
7368
7369
|
const data = msg.data['deviceInfo'].split(',');
|
|
7369
7370
|
if (data[0] === 'UI' && data[1]) {
|
|
@@ -8141,7 +8142,7 @@ const converters = {
|
|
|
8141
8142
|
convert: (model, msg, publish, options, meta) => {
|
|
8142
8143
|
// commandStopMove without params
|
|
8143
8144
|
if (msg.data[2] !== 71) return;
|
|
8144
|
-
if (
|
|
8145
|
+
if (hasAlreadyProcessedMessage(msg)) return;
|
|
8145
8146
|
const movestop = 'stop';
|
|
8146
8147
|
const action = postfixWithEndpointName(`hue_${movestop}`, msg, model);
|
|
8147
8148
|
const payload = {action};
|
package/converters/toZigbee.js
CHANGED
|
@@ -2173,7 +2173,7 @@ const converters = {
|
|
|
2173
2173
|
key: ['led_disabled_night'],
|
|
2174
2174
|
convertSet: async (entity, key, value, meta) => {
|
|
2175
2175
|
if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ14LM', 'QBCZ15LM', 'QBKG19LM', 'QBKG20LM', 'QBKG25LM', 'QBKG26LM',
|
|
2176
|
-
'QBKG34LM', 'DLKZMK11LM'].includes(meta.mapped.model)) {
|
|
2176
|
+
'QBKG31LM', 'QBKG34LM', 'DLKZMK11LM'].includes(meta.mapped.model)) {
|
|
2177
2177
|
await entity.write('aqaraOpple', {0x0203: {value: value ? 1 : 0, type: 0x10}}, manufacturerOptions.xiaomi);
|
|
2178
2178
|
} else if (['ZNCZ11LM'].includes(meta.mapped.model)) {
|
|
2179
2179
|
const payload = value ?
|
|
@@ -2188,13 +2188,24 @@ const converters = {
|
|
|
2188
2188
|
},
|
|
2189
2189
|
convertGet: async (entity, key, meta) => {
|
|
2190
2190
|
if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ15LM', 'QBCZ14LM', 'QBKG19LM', 'QBKG20LM', 'QBKG25LM', 'QBKG26LM',
|
|
2191
|
-
'QBKG34LM', 'DLKZMK11LM'].includes(meta.mapped.model)) {
|
|
2191
|
+
'QBKG31LM', 'QBKG34LM', 'DLKZMK11LM'].includes(meta.mapped.model)) {
|
|
2192
2192
|
await entity.read('aqaraOpple', [0x0203], manufacturerOptions.xiaomi);
|
|
2193
2193
|
} else {
|
|
2194
2194
|
throw new Error('Not supported');
|
|
2195
2195
|
}
|
|
2196
2196
|
},
|
|
2197
2197
|
},
|
|
2198
|
+
xiaomi_flip_indicator_light: {
|
|
2199
|
+
key: ['flip_indicator_light'],
|
|
2200
|
+
convertSet: async (entity, key, value, meta) => {
|
|
2201
|
+
const lookup = {'OFF': 0, 'ON': 1};
|
|
2202
|
+
await entity.write('aqaraOpple', {0x00F0: {value: lookup[value], type: 0x20}}, manufacturerOptions.xiaomi);
|
|
2203
|
+
return {state: {flip_indicator_light: value}};
|
|
2204
|
+
},
|
|
2205
|
+
convertGet: async (entity, key, meta) => {
|
|
2206
|
+
await entity.read('aqaraOpple', [0x00F0], manufacturerOptions.xiaomi);
|
|
2207
|
+
},
|
|
2208
|
+
},
|
|
2198
2209
|
xiaomi_switch_operation_mode_basic: {
|
|
2199
2210
|
key: ['operation_mode'],
|
|
2200
2211
|
convertSet: async (entity, key, value, meta) => {
|
package/devices/casaia.js
CHANGED
|
@@ -3,8 +3,16 @@ const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/lega
|
|
|
3
3
|
const reporting = require('../lib/reporting');
|
|
4
4
|
const e = exposes.presets;
|
|
5
5
|
const tz = require('../converters/toZigbee');
|
|
6
|
+
const extend = require('../lib/extend');
|
|
6
7
|
|
|
7
8
|
module.exports = [
|
|
9
|
+
{
|
|
10
|
+
zigbeeModel: ['CSLC601-D-E'],
|
|
11
|
+
model: 'CSLC601-D-E',
|
|
12
|
+
vendor: 'CASAIA',
|
|
13
|
+
description: 'Dry contact relay switch module in 220v AC for gas boiler',
|
|
14
|
+
extend: extend.switch(),
|
|
15
|
+
},
|
|
8
16
|
{
|
|
9
17
|
zigbeeModel: ['CTHS317ET'],
|
|
10
18
|
model: 'CTHS-317-ET',
|
package/devices/legrand.js
CHANGED
|
@@ -134,11 +134,11 @@ module.exports = [
|
|
|
134
134
|
model: '067774',
|
|
135
135
|
vendor: 'Legrand',
|
|
136
136
|
description: 'Wireless double remote switch',
|
|
137
|
-
fromZigbee: [fz.identify, fz.command_on,
|
|
137
|
+
fromZigbee: [fz.identify, fz.command_on, fzLocal.command_off, fz.command_toggle, fz.command_move, fz.command_stop, fz.battery],
|
|
138
138
|
exposes: [e.battery(),
|
|
139
139
|
e.action(['identify', 'on', 'off', 'toggle', 'brightness_move_up', 'brightness_move_down', 'brightness_stop'])],
|
|
140
140
|
toZigbee: [],
|
|
141
|
-
meta: {
|
|
141
|
+
meta: {multiEndpoint: true, battery: {voltageToPercentage: '3V_2500'}},
|
|
142
142
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
143
143
|
const endpoint = device.getEndpoint(1);
|
|
144
144
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'genOnOff', 'genLevelCtrl']);
|
package/devices/moes.js
CHANGED
|
@@ -203,7 +203,7 @@ module.exports = [
|
|
|
203
203
|
},
|
|
204
204
|
},
|
|
205
205
|
{
|
|
206
|
-
fingerprint: [{modelID: 'TS0222', manufacturerName: '_TYZB01_kvwjujy9'}],
|
|
206
|
+
fingerprint: [{modelID: 'TS0222', manufacturerName: '_TYZB01_kvwjujy9'}, {modelID: 'TS0222', manufacturerName: '_TYZB01_ftdkanlj'}],
|
|
207
207
|
model: 'ZSS-ZK-THL',
|
|
208
208
|
vendor: 'Moes',
|
|
209
209
|
description: 'Smart temperature and humidity meter with display',
|
package/devices/tuya.js
CHANGED
|
@@ -12,7 +12,7 @@ const utils = require('../lib/utils');
|
|
|
12
12
|
|
|
13
13
|
const TS011Fplugs = ['_TZ3000_5f43h46b', '_TZ3000_cphmq0q7', '_TZ3000_dpo1ysak', '_TZ3000_ew3ldmgx', '_TZ3000_gjnozsaz',
|
|
14
14
|
'_TZ3000_jvzvulen', '_TZ3000_mraovvmm', '_TZ3000_nfnmi125', '_TZ3000_ps3dmato', '_TZ3000_w0qqde0g', '_TZ3000_u5u4cakc',
|
|
15
|
-
'_TZ3000_rdtixbnu', '_TZ3000_typdpbpg'
|
|
15
|
+
'_TZ3000_rdtixbnu', '_TZ3000_typdpbpg'];
|
|
16
16
|
|
|
17
17
|
const tzLocal = {
|
|
18
18
|
TS0504B_color: {
|
|
@@ -168,6 +168,7 @@ module.exports = [
|
|
|
168
168
|
{modelID: 'TS0505B', manufacturerName: '_TZ3000_1mtktxdk'},
|
|
169
169
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_remypqqm'},
|
|
170
170
|
{modelID: 'TS0505B', manufacturerName: '_TZ3000_kohbva1f'},
|
|
171
|
+
{modelID: 'TS0505B', manufacturerName: '_TZ3210_wslkvrau'},
|
|
171
172
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_0rn9qhnu'},
|
|
172
173
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_bicjqpg4'},
|
|
173
174
|
{modelID: 'TS0505B', manufacturerName: '_TZ3000_cmaky9gq'},
|
|
@@ -221,6 +222,7 @@ module.exports = [
|
|
|
221
222
|
fingerprint: [{modelID: 'TS0501B', manufacturerName: '_TZ3000_4whigl8i'},
|
|
222
223
|
{modelID: 'TS0501B', manufacturerName: '_TZ3210_4whigl8i'},
|
|
223
224
|
{modelID: 'TS0501B', manufacturerName: '_TZ3210_9q49basr'},
|
|
225
|
+
{modelID: 'TS0501B', manufacturerName: '_TZ3210_i680rtja'},
|
|
224
226
|
{modelID: 'TS0501B', manufacturerName: '_TZ3210_grnwgegn'},
|
|
225
227
|
{modelID: 'TS0501B', manufacturerName: '_TZ3210_wuheofsg'},
|
|
226
228
|
{modelID: 'TS0501B', manufacturerName: '_TZ3210_e5t9bfdv'}],
|
|
@@ -1161,6 +1163,7 @@ module.exports = [
|
|
|
1161
1163
|
{
|
|
1162
1164
|
fingerprint: [
|
|
1163
1165
|
{modelID: 'TS011F', manufacturerName: '_TZ3000_hyfvrar3'},
|
|
1166
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_v1pdxuqq'},
|
|
1164
1167
|
{modelID: 'TS011F', manufacturerName: '_TZ3000_bfn1w0mm'}],
|
|
1165
1168
|
model: 'TS011F_plug_2',
|
|
1166
1169
|
description: 'Smart plug (without power monitoring)',
|
package/devices/xiaomi.js
CHANGED
|
@@ -312,22 +312,22 @@ module.exports = [
|
|
|
312
312
|
model: 'QBKG31LM',
|
|
313
313
|
vendor: 'Xiaomi',
|
|
314
314
|
description: 'Aqara smart wall switch H1 Pro (with neutral, double rocker)',
|
|
315
|
-
extend: extend.switch(),
|
|
316
|
-
exposes: [e.power_outage_memory(), e.action(['single_left', 'double_left', 'single_right', 'double_right']),
|
|
317
|
-
e.switch().withEndpoint('left'), e.switch().withEndpoint('right'), e.power().withAccess(ea.STATE_GET),
|
|
318
|
-
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
|
|
319
|
-
.withDescription('Decoupled mode for left button').withEndpoint('left'),
|
|
320
|
-
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
|
|
321
|
-
.withDescription('Decoupled mode for right button').withEndpoint('right')],
|
|
322
|
-
fromZigbee: [fz.on_off, fz.xiaomi_power, fz.aqara_opple, fz.xiaomi_multistate_action],
|
|
323
|
-
toZigbee: [tz.on_off, tz.xiaomi_power, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_switch_power_outage_memory],
|
|
324
315
|
meta: {multiEndpoint: true},
|
|
325
316
|
endpoint: (device) => {
|
|
326
317
|
return {'left': 1, 'right': 2};
|
|
327
318
|
},
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
319
|
+
fromZigbee: [fz.on_off, fz.xiaomi_power, fz.aqara_opple, fz.xiaomi_multistate_action],
|
|
320
|
+
toZigbee: [tz.on_off, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_switch_power_outage_memory,
|
|
321
|
+
tz.xiaomi_led_disabled_night, tz.xiaomi_flip_indicator_light],
|
|
322
|
+
exposes: [e.switch().withEndpoint('left'), e.switch().withEndpoint('right'),
|
|
323
|
+
e.power(), e.energy(), e.voltage(), e.temperature(), e.power_outage_memory(), e.led_disabled_night(), e.flip_indicator_light(),
|
|
324
|
+
e.action([
|
|
325
|
+
'single_left', 'single_right', 'single_both',
|
|
326
|
+
'double_left', 'double_right', 'double_both']),
|
|
327
|
+
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
|
|
328
|
+
.withDescription('Decoupled mode for left button').withEndpoint('left'),
|
|
329
|
+
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
|
|
330
|
+
.withDescription('Decoupled mode for right button').withEndpoint('right')],
|
|
331
331
|
onEvent: preventReset,
|
|
332
332
|
ota: ota.zigbeeOTA,
|
|
333
333
|
},
|
package/lib/exposes.js
CHANGED
|
@@ -537,6 +537,7 @@ module.exports = {
|
|
|
537
537
|
effect: () => new Enum('effect', access.SET, ['blink', 'breathe', 'okay', 'channel_change', 'finish_effect', 'stop_effect']).withDescription('Triggers an effect on the light (e.g. make light blink for a few seconds)'),
|
|
538
538
|
energy: () => new Numeric('energy', access.STATE).withUnit('kWh').withDescription('Sum of consumed energy'),
|
|
539
539
|
fan: () => new Fan(),
|
|
540
|
+
flip_indicator_light: () => new Binary('flip_indicator_light', access.ALL, 'ON', 'OFF').withDescription('After turn on, the indicator light turns on while switch is off, and vice versa'),
|
|
540
541
|
force: () => new Enum('force', access.STATE_SET, ['normal', 'open', 'close']).withDescription('Force the valve position'),
|
|
541
542
|
formaldehyd: () => new Numeric('formaldehyd', access.STATE).withDescription('The measured formaldehyd value'),
|
|
542
543
|
gas: () => new Binary('gas', access.STATE, true, false).withDescription('Indicates whether the device detected gas'),
|
package/npm-shrinkwrap.json
CHANGED