zigbee-herdsman-converters 14.0.394 → 14.0.398

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.
@@ -1042,7 +1042,7 @@ const converters = {
1042
1042
  cluster: 'genScenes',
1043
1043
  type: 'commandRecall',
1044
1044
  convert: (model, msg, publish, options, meta) => {
1045
- if (hasAlreadyProcessedMessage(msg)) return;
1045
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1046
1046
  const payload = {action: postfixWithEndpointName(`recall_${msg.data.sceneid}`, msg, model)};
1047
1047
  addActionGroup(payload, msg, model);
1048
1048
  return payload;
@@ -1052,7 +1052,7 @@ const converters = {
1052
1052
  cluster: 'ssIasAce',
1053
1053
  type: 'commandPanic',
1054
1054
  convert: (model, msg, publish, options, meta) => {
1055
- if (hasAlreadyProcessedMessage(msg)) return;
1055
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1056
1056
  const payload = {action: postfixWithEndpointName(`panic`, msg, model)};
1057
1057
  addActionGroup(payload, msg, model);
1058
1058
  return payload;
@@ -1062,7 +1062,7 @@ const converters = {
1062
1062
  cluster: 'ssIasAce',
1063
1063
  type: 'commandArm',
1064
1064
  convert: (model, msg, publish, options, meta) => {
1065
- if (hasAlreadyProcessedMessage(msg)) return;
1065
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1066
1066
  const payload = {
1067
1067
  action: postfixWithEndpointName(constants.armMode[msg.data['armmode']], msg, model),
1068
1068
  action_code: msg.data.code,
@@ -1086,7 +1086,7 @@ const converters = {
1086
1086
  cluster: 'closuresWindowCovering',
1087
1087
  type: 'commandStop',
1088
1088
  convert: (model, msg, publish, options, meta) => {
1089
- if (hasAlreadyProcessedMessage(msg)) return;
1089
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1090
1090
  const payload = {action: postfixWithEndpointName('stop', msg, model)};
1091
1091
  addActionGroup(payload, msg, model);
1092
1092
  return payload;
@@ -1096,7 +1096,7 @@ const converters = {
1096
1096
  cluster: 'closuresWindowCovering',
1097
1097
  type: 'commandUpOpen',
1098
1098
  convert: (model, msg, publish, options, meta) => {
1099
- if (hasAlreadyProcessedMessage(msg)) return;
1099
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1100
1100
  const payload = {action: postfixWithEndpointName('open', msg, model)};
1101
1101
  addActionGroup(payload, msg, model);
1102
1102
  return payload;
@@ -1106,7 +1106,7 @@ const converters = {
1106
1106
  cluster: 'closuresWindowCovering',
1107
1107
  type: 'commandDownClose',
1108
1108
  convert: (model, msg, publish, options, meta) => {
1109
- if (hasAlreadyProcessedMessage(msg)) return;
1109
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1110
1110
  const payload = {action: postfixWithEndpointName('close', msg, model)};
1111
1111
  addActionGroup(payload, msg, model);
1112
1112
  return payload;
@@ -1116,7 +1116,7 @@ const converters = {
1116
1116
  cluster: 'genOnOff',
1117
1117
  type: 'commandOn',
1118
1118
  convert: (model, msg, publish, options, meta) => {
1119
- if (hasAlreadyProcessedMessage(msg)) return;
1119
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1120
1120
  const payload = {action: postfixWithEndpointName('on', msg, model)};
1121
1121
  addActionGroup(payload, msg, model);
1122
1122
  return payload;
@@ -1126,7 +1126,7 @@ const converters = {
1126
1126
  cluster: 'genOnOff',
1127
1127
  type: 'commandOff',
1128
1128
  convert: (model, msg, publish, options, meta) => {
1129
- if (hasAlreadyProcessedMessage(msg)) return;
1129
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1130
1130
  const payload = {action: postfixWithEndpointName('off', msg, model)};
1131
1131
  addActionGroup(payload, msg, model);
1132
1132
  return payload;
@@ -1136,7 +1136,7 @@ const converters = {
1136
1136
  cluster: 'genOnOff',
1137
1137
  type: 'commandOffWithEffect',
1138
1138
  convert: (model, msg, publish, options, meta) => {
1139
- if (hasAlreadyProcessedMessage(msg)) return;
1139
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1140
1140
  const payload = {action: postfixWithEndpointName(`off`, msg, model)};
1141
1141
  addActionGroup(payload, msg, model);
1142
1142
  return payload;
@@ -1146,7 +1146,7 @@ const converters = {
1146
1146
  cluster: 'genOnOff',
1147
1147
  type: 'commandToggle',
1148
1148
  convert: (model, msg, publish, options, meta) => {
1149
- if (hasAlreadyProcessedMessage(msg)) return;
1149
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1150
1150
  const payload = {action: postfixWithEndpointName('toggle', msg, model)};
1151
1151
  addActionGroup(payload, msg, model);
1152
1152
  return payload;
@@ -1157,7 +1157,7 @@ const converters = {
1157
1157
  type: ['commandMoveToLevel', 'commandMoveToLevelWithOnOff'],
1158
1158
  options: [exposes.options.simulated_brightness()],
1159
1159
  convert: (model, msg, publish, options, meta) => {
1160
- if (hasAlreadyProcessedMessage(msg)) return;
1160
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1161
1161
  const payload = {
1162
1162
  action: postfixWithEndpointName(`brightness_move_to_level`, msg, model),
1163
1163
  action_level: msg.data.level,
@@ -1179,7 +1179,7 @@ const converters = {
1179
1179
  type: ['commandMove', 'commandMoveWithOnOff'],
1180
1180
  options: [exposes.options.simulated_brightness()],
1181
1181
  convert: (model, msg, publish, options, meta) => {
1182
- if (hasAlreadyProcessedMessage(msg)) return;
1182
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1183
1183
  const direction = msg.data.movemode === 1 ? 'down' : 'up';
1184
1184
  const action = postfixWithEndpointName(`brightness_move_${direction}`, msg, model);
1185
1185
  const payload = {action, action_rate: msg.data.rate};
@@ -1215,7 +1215,7 @@ const converters = {
1215
1215
  type: ['commandStep', 'commandStepWithOnOff'],
1216
1216
  options: [exposes.options.simulated_brightness()],
1217
1217
  convert: (model, msg, publish, options, meta) => {
1218
- if (hasAlreadyProcessedMessage(msg)) return;
1218
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1219
1219
  const direction = msg.data.stepmode === 1 ? 'down' : 'up';
1220
1220
  const payload = {
1221
1221
  action: postfixWithEndpointName(`brightness_step_${direction}`, msg, model),
@@ -1242,7 +1242,7 @@ const converters = {
1242
1242
  type: ['commandStop', 'commandStopWithOnOff'],
1243
1243
  options: [exposes.options.simulated_brightness()],
1244
1244
  convert: (model, msg, publish, options, meta) => {
1245
- if (hasAlreadyProcessedMessage(msg)) return;
1245
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1246
1246
  if (options.simulated_brightness) {
1247
1247
  clearInterval(globalStore.getValue(msg.endpoint, 'simulated_brightness_timer'));
1248
1248
  globalStore.putValue(msg.endpoint, 'simulated_brightness_timer', undefined);
@@ -1257,7 +1257,7 @@ const converters = {
1257
1257
  cluster: 'lightingColorCtrl',
1258
1258
  type: ['commandMoveColorTemp'],
1259
1259
  convert: (model, msg, publish, options, meta) => {
1260
- if (hasAlreadyProcessedMessage(msg)) return;
1260
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1261
1261
  const direction = msg.data.movemode === 1 ? 'down' : 'up';
1262
1262
  const action = postfixWithEndpointName(`color_temperature_move_${direction}`, msg, model);
1263
1263
  const payload = {action, action_rate: msg.data.rate, action_minimum: msg.data.minimum, action_maximum: msg.data.maximum};
@@ -1269,7 +1269,7 @@ const converters = {
1269
1269
  cluster: 'lightingColorCtrl',
1270
1270
  type: 'commandStepColorTemp',
1271
1271
  convert: (model, msg, publish, options, meta) => {
1272
- if (hasAlreadyProcessedMessage(msg)) return;
1272
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1273
1273
  const direction = msg.data.stepmode === 1 ? 'up' : 'down';
1274
1274
  const payload = {
1275
1275
  action: postfixWithEndpointName(`color_temperature_step_${direction}`, msg, model),
@@ -1288,7 +1288,7 @@ const converters = {
1288
1288
  cluster: 'lightingColorCtrl',
1289
1289
  type: 'commandEnhancedMoveToHueAndSaturation',
1290
1290
  convert: (model, msg, publish, options, meta) => {
1291
- if (hasAlreadyProcessedMessage(msg)) return;
1291
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1292
1292
  const payload = {
1293
1293
  action: postfixWithEndpointName(`enhanced_move_to_hue_and_saturation`, msg, model),
1294
1294
  action_enhanced_hue: msg.data.enhancehue,
@@ -1305,7 +1305,7 @@ const converters = {
1305
1305
  cluster: 'lightingColorCtrl',
1306
1306
  type: ['commandStepHue'],
1307
1307
  convert: (model, msg, publish, options, meta) => {
1308
- if (hasAlreadyProcessedMessage(msg)) return;
1308
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1309
1309
  const direction = msg.data.stepmode === 1 ? 'up' : 'down';
1310
1310
  const payload = {
1311
1311
  action: postfixWithEndpointName(`color_hue_step_${direction}`, msg, model),
@@ -1320,7 +1320,7 @@ const converters = {
1320
1320
  cluster: 'lightingColorCtrl',
1321
1321
  type: ['commandStepSaturation'],
1322
1322
  convert: (model, msg, publish, options, meta) => {
1323
- if (hasAlreadyProcessedMessage(msg)) return;
1323
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1324
1324
  const direction = msg.data.stepmode === 1 ? 'up' : 'down';
1325
1325
  const payload = {
1326
1326
  action: postfixWithEndpointName(`color_saturation_step_${direction}`, msg, model),
@@ -1335,7 +1335,7 @@ const converters = {
1335
1335
  cluster: 'lightingColorCtrl',
1336
1336
  type: 'commandColorLoopSet',
1337
1337
  convert: (model, msg, publish, options, meta) => {
1338
- if (hasAlreadyProcessedMessage(msg)) return;
1338
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1339
1339
  const updateFlags = msg.data.updateflags;
1340
1340
  const actionLookup = {
1341
1341
  0x00: 'deactivate',
@@ -1365,7 +1365,7 @@ const converters = {
1365
1365
  cluster: 'lightingColorCtrl',
1366
1366
  type: 'commandMoveToColorTemp',
1367
1367
  convert: (model, msg, publish, options, meta) => {
1368
- if (hasAlreadyProcessedMessage(msg)) return;
1368
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1369
1369
  const payload = {
1370
1370
  action: postfixWithEndpointName(`color_temperature_move`, msg, model),
1371
1371
  action_color_temperature: msg.data.colortemp,
@@ -1379,7 +1379,7 @@ const converters = {
1379
1379
  cluster: 'lightingColorCtrl',
1380
1380
  type: 'commandMoveToColor',
1381
1381
  convert: (model, msg, publish, options, meta) => {
1382
- if (hasAlreadyProcessedMessage(msg)) return;
1382
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1383
1383
  const payload = {
1384
1384
  action: postfixWithEndpointName(`color_move`, msg, model),
1385
1385
  action_color: {
@@ -1396,7 +1396,7 @@ const converters = {
1396
1396
  cluster: 'lightingColorCtrl',
1397
1397
  type: 'commandMoveHue',
1398
1398
  convert: (model, msg, publish, options, meta) => {
1399
- if (hasAlreadyProcessedMessage(msg)) return;
1399
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1400
1400
  const movestop = msg.data.movemode == 1 ? 'move' : 'stop';
1401
1401
  const action = postfixWithEndpointName(`hue_${movestop}`, msg, model);
1402
1402
  const payload = {action, action_rate: msg.data.rate};
@@ -1408,7 +1408,7 @@ const converters = {
1408
1408
  cluster: 'lightingColorCtrl',
1409
1409
  type: 'commandMoveToSaturation',
1410
1410
  convert: (model, msg, publish, options, meta) => {
1411
- if (hasAlreadyProcessedMessage(msg)) return;
1411
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1412
1412
  const payload = {
1413
1413
  action: postfixWithEndpointName('move_to_saturation', msg, model),
1414
1414
  action_saturation: msg.data.saturation,
@@ -1422,7 +1422,7 @@ const converters = {
1422
1422
  cluster: 'lightingColorCtrl',
1423
1423
  type: 'commandMoveToHue',
1424
1424
  convert: (model, msg, publish, options, meta) => {
1425
- if (hasAlreadyProcessedMessage(msg)) return;
1425
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1426
1426
  const payload = {
1427
1427
  action: postfixWithEndpointName(`move_to_hue`, msg, model),
1428
1428
  action_hue: msg.data.hue,
@@ -1437,7 +1437,7 @@ const converters = {
1437
1437
  cluster: 'ssIasAce',
1438
1438
  type: 'commandEmergency',
1439
1439
  convert: (model, msg, publish, options, meta) => {
1440
- if (hasAlreadyProcessedMessage(msg)) return;
1440
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1441
1441
  const payload = {action: postfixWithEndpointName(`emergency`, msg, model)};
1442
1442
  addActionGroup(payload, msg, model);
1443
1443
  return payload;
@@ -1447,7 +1447,7 @@ const converters = {
1447
1447
  cluster: 'genOnOff',
1448
1448
  type: 'commandOn',
1449
1449
  convert: (model, msg, publish, options, meta) => {
1450
- if (hasAlreadyProcessedMessage(msg)) return;
1450
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1451
1451
  const property = postfixWithEndpointName('state', msg, model);
1452
1452
  return {[property]: 'ON'};
1453
1453
  },
@@ -1456,7 +1456,7 @@ const converters = {
1456
1456
  cluster: 'genOnOff',
1457
1457
  type: 'commandOff',
1458
1458
  convert: (model, msg, publish, options, meta) => {
1459
- if (hasAlreadyProcessedMessage(msg)) return;
1459
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
1460
1460
  const property = postfixWithEndpointName('state', msg, model);
1461
1461
  return {[property]: 'OFF'};
1462
1462
  },
@@ -2181,7 +2181,7 @@ const converters = {
2181
2181
  cluster: 'ssIasZone',
2182
2182
  type: 'commandStatusChangeNotification',
2183
2183
  convert: (model, msg, publish, options, meta) => {
2184
- if (hasAlreadyProcessedMessage(msg)) return;
2184
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
2185
2185
  const lookup = {1: 'pressed'};
2186
2186
  const zoneStatus = msg.data.zonestatus;
2187
2187
  return {
@@ -4515,7 +4515,7 @@ const converters = {
4515
4515
  cluster: 'genScenes',
4516
4516
  type: 'commandTradfriArrowSingle',
4517
4517
  convert: (model, msg, publish, options, meta) => {
4518
- if (hasAlreadyProcessedMessage(msg)) return;
4518
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
4519
4519
  if (msg.data.value === 2) {
4520
4520
  // This is send on toggle hold, ignore it as a toggle_hold is already handled above.
4521
4521
  return;
@@ -4529,7 +4529,7 @@ const converters = {
4529
4529
  cluster: 'genScenes',
4530
4530
  type: 'commandTradfriArrowHold',
4531
4531
  convert: (model, msg, publish, options, meta) => {
4532
- if (hasAlreadyProcessedMessage(msg)) return;
4532
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
4533
4533
  const direction = msg.data.value === 3329 ? 'left' : 'right';
4534
4534
  globalStore.putValue(msg.endpoint, 'direction', direction);
4535
4535
  return {action: `arrow_${direction}_hold`};
@@ -4540,7 +4540,7 @@ const converters = {
4540
4540
  type: 'commandTradfriArrowRelease',
4541
4541
  options: [exposes.options.legacy()],
4542
4542
  convert: (model, msg, publish, options, meta) => {
4543
- if (hasAlreadyProcessedMessage(msg)) return;
4543
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
4544
4544
  const direction = globalStore.getValue(msg.endpoint, 'direction');
4545
4545
  if (direction) {
4546
4546
  globalStore.clearValue(msg.endpoint, 'direction');
@@ -5379,7 +5379,7 @@ const converters = {
5379
5379
  cluster: 'genMultistateInput',
5380
5380
  type: ['attributeReport'],
5381
5381
  convert: (model, msg, publish, options, meta) => {
5382
- if (hasAlreadyProcessedMessage(msg)) return;
5382
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
5383
5383
  let actionLookup = {0: 'hold', 1: 'single', 2: 'double', 3: 'triple', 255: 'release'};
5384
5384
  if (model.model === 'WXKG12LM') {
5385
5385
  actionLookup = {...actionLookup, 16: 'hold', 17: 'release', 18: 'shake'};
@@ -5525,7 +5525,7 @@ const converters = {
5525
5525
  `increase it with this option (value is in ms).`),
5526
5526
  ],
5527
5527
  convert: (model, msg, publish, options, meta) => {
5528
- if (hasAlreadyProcessedMessage(msg)) return;
5528
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
5529
5529
  const state = msg.data['onOff'];
5530
5530
 
5531
5531
  // 0 = click down, 1 = click up, else = multiple clicks
@@ -5831,7 +5831,7 @@ const converters = {
5831
5831
  cluster: 'genMultistateInput',
5832
5832
  type: ['attributeReport', 'readResponse'],
5833
5833
  convert: (model, msg, publish, options, meta) => {
5834
- if (hasAlreadyProcessedMessage(msg)) return;
5834
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
5835
5835
  const actionLookup = {0: 'hold', 255: 'release', 1: 'single', 2: 'double', 3: 'triple', 5: 'quintuple', 6: 'many'};
5836
5836
  const button = msg.endpoint.ID;
5837
5837
  const value = msg.data.presentValue;
@@ -5854,7 +5854,7 @@ const converters = {
5854
5854
  cluster: 'genOnOff',
5855
5855
  type: 'commandOn',
5856
5856
  convert: (model, msg, publish, options, meta) => {
5857
- if (hasAlreadyProcessedMessage(msg)) return;
5857
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
5858
5858
  return {action: 'button_2_single'};
5859
5859
  },
5860
5860
  },
@@ -5862,7 +5862,7 @@ const converters = {
5862
5862
  cluster: 'genOnOff',
5863
5863
  type: 'commandOff',
5864
5864
  convert: (model, msg, publish, options, meta) => {
5865
- if (hasAlreadyProcessedMessage(msg)) return;
5865
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
5866
5866
  return {action: 'button_1_single'};
5867
5867
  },
5868
5868
  },
@@ -5870,7 +5870,7 @@ const converters = {
5870
5870
  cluster: 'genLevelCtrl',
5871
5871
  type: 'commandStep',
5872
5872
  convert: (model, msg, publish, options, meta) => {
5873
- if (hasAlreadyProcessedMessage(msg)) return;
5873
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
5874
5874
  const button = msg.data.stepmode === 0 ? '4' : '3';
5875
5875
  return {action: `button_${button}_single`};
5876
5876
  },
@@ -5880,7 +5880,7 @@ const converters = {
5880
5880
  type: 'commandStop',
5881
5881
  options: [exposes.options.legacy()],
5882
5882
  convert: (model, msg, publish, options, meta) => {
5883
- if (hasAlreadyProcessedMessage(msg)) return;
5883
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
5884
5884
  if (globalStore.hasValue(msg.endpoint, 'button')) {
5885
5885
  const value = globalStore.getValue(msg.endpoint, 'button');
5886
5886
  const duration = Date.now() - value.start;
@@ -5894,7 +5894,7 @@ const converters = {
5894
5894
  cluster: 'genLevelCtrl',
5895
5895
  type: 'commandMove',
5896
5896
  convert: (model, msg, publish, options, meta) => {
5897
- if (hasAlreadyProcessedMessage(msg)) return;
5897
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
5898
5898
  const button = msg.data.movemode === 0 ? '4' : '3';
5899
5899
  globalStore.putValue(msg.endpoint, 'button', {button, start: Date.now()});
5900
5900
  return {action: `button_${button}_hold`};
@@ -5904,7 +5904,7 @@ const converters = {
5904
5904
  cluster: 'lightingColorCtrl',
5905
5905
  type: 'commandStepColorTemp',
5906
5906
  convert: (model, msg, publish, options, meta) => {
5907
- if (hasAlreadyProcessedMessage(msg)) return;
5907
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
5908
5908
  let action;
5909
5909
  if (model.model === 'WXCJKG12LM') {
5910
5910
  // for WXCJKG12LM model it's double click event on buttons 3 and 4
@@ -5921,7 +5921,7 @@ const converters = {
5921
5921
  type: 'commandMoveColorTemp',
5922
5922
  options: [exposes.options.legacy()],
5923
5923
  convert: (model, msg, publish, options, meta) => {
5924
- if (hasAlreadyProcessedMessage(msg)) return;
5924
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
5925
5925
  const stop = msg.data.movemode === 0;
5926
5926
  let result = null;
5927
5927
  if (stop) {
@@ -7327,7 +7327,7 @@ const converters = {
7327
7327
  cluster: 'wiserDeviceInfo',
7328
7328
  type: 'attributeReport',
7329
7329
  convert: (model, msg, publish, options, meta) => {
7330
- if (hasAlreadyProcessedMessage(msg)) return;
7330
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
7331
7331
 
7332
7332
  const data = msg.data['deviceInfo'].split(',');
7333
7333
  if (data[0] === 'UI' && data[1]) {
@@ -8105,7 +8105,7 @@ const converters = {
8105
8105
  convert: (model, msg, publish, options, meta) => {
8106
8106
  // commandStopMove without params
8107
8107
  if (msg.data[2] !== 71) return;
8108
- if (hasAlreadyProcessedMessage(msg)) return;
8108
+ if ((!model.meta || !model.meta.handleDuplicateTransaction) && hasAlreadyProcessedMessage(msg)) return;
8109
8109
  const movestop = 'stop';
8110
8110
  const action = postfixWithEndpointName(`hue_${movestop}`, msg, model);
8111
8111
  const payload = {action};
@@ -2336,7 +2336,7 @@ const converters = {
2336
2336
  matsee_garage_door_opener: {
2337
2337
  key: ['trigger'],
2338
2338
  convertSet: (entity, key, value, meta) => {
2339
- tuya.sendDataPointBool(entity, tuya.dataPoints.action, true);
2339
+ tuya.sendDataPointBool(entity, tuya.dataPoints.garageDoorTrigger, true);
2340
2340
  },
2341
2341
  },
2342
2342
  SPZ01_power_outage_memory: {
@@ -5096,7 +5096,7 @@ const converters = {
5096
5096
  await tuya.sendDataPointEnum(
5097
5097
  entity,
5098
5098
  tuya.dataPoints.neoAOVolume,
5099
- {'low': 2, 'medium': 1, 'high': 0}[value]);
5099
+ {'low': 0, 'medium': 1, 'high': 2}[value]);
5100
5100
  break;
5101
5101
  case 'duration':
5102
5102
  await tuya.sendDataPointValue(entity, tuya.dataPoints.neoAODuration, value);
@@ -332,4 +332,47 @@ module.exports = [
332
332
  },
333
333
  exposes: [e.soil_moisture(), e.battery(), e.illuminance(), e.temperature(), e.humidity()],
334
334
  },
335
+ {
336
+ zigbeeModel: ['EFEKTA_PWS_MaxPro'],
337
+ model: 'EFEKTA_PWS_MaxPro',
338
+ vendor: 'Custom devices (DiY)',
339
+ description: '[Plant watering sensor EFEKTA PWS Max Pro, long battery life](http://efektalab.com/PWS_MaxPro)',
340
+ fromZigbee: [fz.temperature, fz.humidity, fz.illuminance, fz.soil_moisture, fz.battery],
341
+ toZigbee: [tz.factory_reset],
342
+ configure: async (device, coordinatorEndpoint, logger) => {
343
+ const firstEndpoint = device.getEndpoint(1);
344
+ await reporting.bind(firstEndpoint, coordinatorEndpoint, [
345
+ 'genPowerCfg', 'msTemperatureMeasurement', 'msRelativeHumidity', 'msIlluminanceMeasurement', 'msSoilMoisture']);
346
+ const overides = {min: 0, max: 21600, change: 0};
347
+ await reporting.batteryVoltage(firstEndpoint, overides);
348
+ await reporting.batteryPercentageRemaining(firstEndpoint, overides);
349
+ await reporting.temperature(firstEndpoint, overides);
350
+ await reporting.humidity(firstEndpoint, overides);
351
+ await reporting.illuminance(firstEndpoint, overides);
352
+ await reporting.soil_moisture(firstEndpoint, overides);
353
+ },
354
+ exposes: [e.soil_moisture(), e.battery(), e.illuminance(), e.temperature(), e.humidity()],
355
+ },
356
+ {
357
+ zigbeeModel: ['EFEKTA_eON29wz'],
358
+ model: 'EFEKTA_eON29wz',
359
+ vendor: 'Custom devices (DiY)',
360
+ description: '[Mini weather station, barometer, forecast, charts, temperature, humidity, light](http://efektalab.com/eON290wz)',
361
+ fromZigbee: [fz.temperature, fz.humidity, fz.pressure, fz.illuminance, fz.battery],
362
+ toZigbee: [tz.factory_reset],
363
+ configure: async (device, coordinatorEndpoint, logger) => {
364
+ const endpoint = device.getEndpoint(1);
365
+ await reporting.bind(endpoint, coordinatorEndpoint, [
366
+ 'genPowerCfg', 'msTemperatureMeasurement', 'msRelativeHumidity', 'msPressureMeasurement', 'msIlluminanceMeasurement']);
367
+ const overides = {min: 0, max: 21600, change: 0};
368
+ await reporting.batteryVoltage(endpoint, overides);
369
+ await reporting.batteryPercentageRemaining(endpoint, overides);
370
+ await reporting.temperature(endpoint, overides);
371
+ await reporting.humidity(endpoint, overides);
372
+ await reporting.illuminance(endpoint, overides);
373
+ await reporting.pressureExtended(endpoint, overides);
374
+ await endpoint.read('msPressureMeasurement', ['scale']);
375
+ },
376
+ exposes: [e.battery(), e.illuminance(), e.temperature(), e.humidity(), e.pressure()],
377
+ },
335
378
  ];
package/devices/ecodim.js CHANGED
@@ -98,7 +98,6 @@ module.exports = [
98
98
  model: 'ED-10014',
99
99
  vendor: 'EcoDim',
100
100
  description: 'Zigbee 8 button wall switch - white',
101
- supports: '',
102
101
  fromZigbee: [fz.command_on, fz.command_off, fz.command_move, fz.command_stop, fz.battery],
103
102
  exposes: [e.battery(), e.action(['on_1', 'off_1', 'brightness_move_up_1', 'brightness_move_down_1', 'brightness_stop_1',
104
103
  'on_2', 'off_2', 'brightness_move_up_2', 'brightness_move_down_2', 'brightness_stop_2', 'on_3', 'off_3',
@@ -112,7 +111,6 @@ module.exports = [
112
111
  model: 'ED-10015',
113
112
  vendor: 'EcoDim',
114
113
  description: 'Zigbee 8 button wall switch - black',
115
- supports: '',
116
114
  fromZigbee: [fz.command_on, fz.command_off, fz.command_move, fz.command_stop, fz.battery],
117
115
  exposes: [e.battery(), e.action(['on_1', 'off_1', 'brightness_move_up_1', 'brightness_move_down_1', 'brightness_stop_1',
118
116
  'on_2', 'off_2', 'brightness_move_up_2', 'brightness_move_down_2', 'brightness_stop_2', 'on_3', 'off_3', 'brightness_move_up_3',
package/devices/jxuan.js CHANGED
@@ -38,7 +38,6 @@ module.exports = [
38
38
  model: 'SPZ01',
39
39
  vendor: 'J.XUAN',
40
40
  description: 'plug',
41
- supports: 'plug',
42
41
  fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering],
43
42
  exposes: [e.switch(), e.power(), e.power_outage_memory().withAccess(ea.STATE_SET)],
44
43
  toZigbee: [tz.on_off, tz.SPZ01_power_outage_memory],
@@ -111,7 +111,7 @@ module.exports = [
111
111
  exposes: [e.battery(), e.action(['identify', 'on', 'off', 'toggle', 'brightness_move_up',
112
112
  'brightness_move_down', 'brightness_stop'])],
113
113
  toZigbee: [],
114
- meta: {battery: {voltageToPercentage: '3V_2500'}},
114
+ meta: {handleDuplicateTransaction: true, battery: {voltageToPercentage: '3V_2500'}},
115
115
  configure: async (device, coordinatorEndpoint, logger) => {
116
116
  const endpoint = device.getEndpoint(1);
117
117
  await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'genOnOff', 'genLevelCtrl']);
@@ -127,7 +127,7 @@ module.exports = [
127
127
  exposes: [e.battery(),
128
128
  e.action(['identify', 'on', 'off', 'toggle', 'brightness_move_up', 'brightness_move_down', 'brightness_stop'])],
129
129
  toZigbee: [],
130
- meta: {multiEndpoint: true, battery: {voltageToPercentage: '3V_2500'}},
130
+ meta: {handleDuplicateTransaction: true, multiEndpoint: true, battery: {voltageToPercentage: '3V_2500'}},
131
131
  configure: async (device, coordinatorEndpoint, logger) => {
132
132
  const endpoint = device.getEndpoint(1);
133
133
  await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'genOnOff', 'genLevelCtrl']);
package/devices/lidl.js CHANGED
@@ -394,7 +394,7 @@ module.exports = [
394
394
  },
395
395
  {
396
396
  fingerprint: [{modelID: 'TY0202', manufacturerName: '_TZ1800_fcdjzz3s'}],
397
- model: 'HG06335',
397
+ model: 'HG06335/HG07310',
398
398
  vendor: 'Lidl',
399
399
  description: 'Silvercrest smart motion sensor',
400
400
  fromZigbee: [fz.ias_occupancy_alarm_1, fz.battery],
package/devices/moes.js CHANGED
@@ -303,7 +303,6 @@ module.exports = [
303
303
  model: 'MS-108ZR',
304
304
  vendor: 'Moes',
305
305
  description: 'Zigbee + RF curtain switch module',
306
- supports: 'open, close, stop, position',
307
306
  fromZigbee: [fz.tuya_cover_options, fz.cover_position_tilt],
308
307
  toZigbee: [tz.cover_state, tz.moes_cover_calibration, tz.cover_position_tilt, tz.tuya_cover_reversal],
309
308
  exposes: [e.cover_position(), exposes.numeric('calibration_time', ea.ALL).withValueMin(0).withValueMax(100),
package/devices/owon.js CHANGED
@@ -27,7 +27,6 @@ module.exports = [
27
27
  model: 'CB432',
28
28
  vendor: 'OWON',
29
29
  description: '32A/63A power circuit breaker',
30
- supports: 'on/off, power measurement',
31
30
  fromZigbee: [fz.on_off, fz.metering, fz.electrical_measurement],
32
31
  toZigbee: [tz.on_off],
33
32
  exposes: [e.switch(), e.power(), e.energy()],
@@ -321,6 +321,14 @@ module.exports = [
321
321
  extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
322
322
  ota: ota.zigbeeOTA,
323
323
  },
324
+ {
325
+ zigbeeModel: ['929003055901'],
326
+ model: '929003055901',
327
+ vendor: 'Philips',
328
+ description: 'Hue white ambiance bathroom ceiling light Adore with Bluetooth',
329
+ extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 454]}),
330
+ ota: ota.zigbeeOTA,
331
+ },
324
332
  {
325
333
  zigbeeModel: ['LLC020'],
326
334
  model: '7146060PH',
@@ -555,6 +563,15 @@ module.exports = [
555
563
  extend: hueExtend.light_onoff_brightness(),
556
564
  ota: ota.zigbeeOTA,
557
565
  },
566
+ {
567
+ zigbeeModel: ['LWO002'],
568
+ model: '9290022415',
569
+ vendor: 'Philips',
570
+ description: 'Hue White G25 E26 Edison Filament Globe Bluetooth',
571
+ meta: {turnsOffAtBrightness1: true},
572
+ extend: hueExtend.light_onoff_brightness(),
573
+ ota: ota.zigbeeOTA,
574
+ },
558
575
  {
559
576
  zigbeeModel: ['LWA004'],
560
577
  model: '8718699688820',
@@ -1021,7 +1038,7 @@ module.exports = [
1021
1038
  ota: ota.zigbeeOTA,
1022
1039
  },
1023
1040
  {
1024
- zigbeeModel: ['3417931P6'],
1041
+ zigbeeModel: ['3417931P6', '929003056201'],
1025
1042
  model: '3417931P6',
1026
1043
  vendor: 'Philips',
1027
1044
  description: 'Hue white ambiance Adore GU10 with Bluetooth (2 spots)',
@@ -1210,7 +1227,7 @@ module.exports = [
1210
1227
  ota: ota.zigbeeOTA,
1211
1228
  },
1212
1229
  {
1213
- zigbeeModel: ['3261031P6', '929003055001'],
1230
+ zigbeeModel: ['3261031P6', '929003055001', '929003055101'],
1214
1231
  model: '3261031P6',
1215
1232
  vendor: 'Philips',
1216
1233
  description: 'Hue Being white',
@@ -1344,7 +1361,7 @@ module.exports = [
1344
1361
  ota: ota.zigbeeOTA,
1345
1362
  },
1346
1363
  {
1347
- zigbeeModel: ['929003099001'],
1364
+ zigbeeModel: ['929003099001', '929003099201'],
1348
1365
  model: '929003099001',
1349
1366
  vendor: 'Philips',
1350
1367
  description: 'Hue white ambiance Aurelle square panel light',
@@ -2652,4 +2669,13 @@ module.exports = [
2652
2669
  extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
2653
2670
  ota: ota.zigbeeOTA,
2654
2671
  },
2672
+ {
2673
+ zigbeeModel: ['3417611P6', '3417511P9'],
2674
+ model: '3417511P9',
2675
+ vendor: 'Philips',
2676
+ description: 'Hue white ambiance bathroom recessed downlight Adore with Bluetooth',
2677
+ meta: {turnsOffAtBrightness1: true},
2678
+ extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
2679
+ ota: ota.zigbeeOTA,
2680
+ },
2655
2681
  ];
@@ -15,6 +15,13 @@ module.exports = [
15
15
  description: 'E27 filament bulb dimmable',
16
16
  extend: extend.light_onoff_brightness(),
17
17
  },
18
+ {
19
+ zigbeeModel: ['PROLIGHT E27 WARM WHITE'],
20
+ model: '5412748727364',
21
+ vendor: 'Prolight',
22
+ description: 'E27 bulb dimmable',
23
+ extend: extend.light_onoff_brightness(),
24
+ },
18
25
  {
19
26
  zigbeeModel: ['PROLIGHT GU10 WHITE AND COLOUR'],
20
27
  model: '5412748727401',
@@ -1,5 +1,5 @@
1
- const reporting = require('zigbee-herdsman-converters/lib/reporting');
2
- const extend = require('zigbee-herdsman-converters/lib/extend');
1
+ const reporting = require('../lib/reporting');
2
+ const extend = require('../lib/extend');
3
3
 
4
4
  module.exports = [
5
5
  {
@@ -46,7 +46,7 @@ module.exports = [
46
46
  toZigbee: [tz.tuya_dimmer_state, tz.tuya_light_wz5],
47
47
  exposes: [
48
48
  exposes.light().withBrightness().setAccess('state', ea.STATE_SET).setAccess('brightness',
49
- ea.STATE_SET).withColor('hs'),
49
+ ea.STATE_SET).withColor(['hs']),
50
50
  ],
51
51
  },
52
52
  {
@@ -61,7 +61,7 @@ module.exports = [
61
61
  toZigbee: [tz.tuya_dimmer_state, tz.tuya_light_wz5],
62
62
  exposes: [
63
63
  exposes.light().withBrightness().setAccess('state', ea.STATE_SET).setAccess('brightness',
64
- ea.STATE_SET).withColor('hs'),
64
+ ea.STATE_SET).withColor(['hs']),
65
65
  exposes.numeric('white_brightness', ea.STATE_SET).withValueMin(0).withValueMax(254).withDescription(
66
66
  'White brightness of this light'),
67
67
  ],
@@ -79,7 +79,7 @@ module.exports = [
79
79
  toZigbee: [tz.tuya_dimmer_state, tz.tuya_light_wz5],
80
80
  exposes: [
81
81
  exposes.light().withBrightness().setAccess('state', ea.STATE_SET).setAccess('brightness',
82
- ea.STATE_SET).withColor('hs').withColorTemp([250, 454]).setAccess('color_temp',
82
+ ea.STATE_SET).withColor(['hs']).withColorTemp([250, 454]).setAccess('color_temp',
83
83
  ea.STATE_SET),
84
84
  exposes.numeric('white_brightness', ea.STATE_SET).withValueMin(0).withValueMax(254).withDescription(
85
85
  'White brightness of this light'),