zigbee-herdsman-converters 14.0.353 → 14.0.357

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.
@@ -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
  },
@@ -1771,7 +1798,7 @@ const converters = {
1771
1798
  },
1772
1799
  nous_lcd_temperature_humidity_sensor: {
1773
1800
  cluster: 'manuSpecificTuya',
1774
- type: ['commandGetData'],
1801
+ type: ['commandDataResponse'],
1775
1802
  options: [exposes.options.precision('temperature'), exposes.options.calibration('temperature'),
1776
1803
  exposes.options.precision('humidity'), exposes.options.calibration('humidity')],
1777
1804
  convert: (model, msg, publish, options, meta) => {
@@ -4317,6 +4344,7 @@ const converters = {
4317
4344
  cluster: 'genScenes',
4318
4345
  type: 'commandTradfriArrowSingle',
4319
4346
  convert: (model, msg, publish, options, meta) => {
4347
+ if (hasAlreadyProcessedMessage(msg)) return;
4320
4348
  if (msg.data.value === 2) {
4321
4349
  // This is send on toggle hold, ignore it as a toggle_hold is already handled above.
4322
4350
  return;
@@ -4330,6 +4358,7 @@ const converters = {
4330
4358
  cluster: 'genScenes',
4331
4359
  type: 'commandTradfriArrowHold',
4332
4360
  convert: (model, msg, publish, options, meta) => {
4361
+ if (hasAlreadyProcessedMessage(msg)) return;
4333
4362
  const direction = msg.data.value === 3329 ? 'left' : 'right';
4334
4363
  globalStore.putValue(msg.endpoint, 'direction', direction);
4335
4364
  return {action: `arrow_${direction}_hold`};
@@ -4340,6 +4369,7 @@ const converters = {
4340
4369
  type: 'commandTradfriArrowRelease',
4341
4370
  options: [exposes.options.legacy()],
4342
4371
  convert: (model, msg, publish, options, meta) => {
4372
+ if (hasAlreadyProcessedMessage(msg)) return;
4343
4373
  const direction = globalStore.getValue(msg.endpoint, 'direction');
4344
4374
  if (direction) {
4345
4375
  globalStore.clearValue(msg.endpoint, 'direction');
@@ -5114,11 +5144,10 @@ const converters = {
5114
5144
  let buttonLookup = null;
5115
5145
  if (['WXKG02LM_rev2', 'WXKG07LM', 'WXKG17LM'].includes(model.model)) buttonLookup = {1: 'left', 2: 'right', 3: 'both'};
5116
5146
  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
5147
  if (['QBKG39LM', 'QBKG41LM', 'WS-EUK02', 'WS-EUK04', 'QBKG20LM', 'QBKG31LM'].includes(model.model)) {
5119
5148
  buttonLookup = {41: 'left', 42: 'right', 51: 'both'};
5120
5149
  }
5121
- if (['QBKG26LM', 'QBKG34LM'].includes(model.model)) {
5150
+ if (['QBKG25LM', 'QBKG26LM', 'QBKG34LM'].includes(model.model)) {
5122
5151
  buttonLookup = {
5123
5152
  41: 'left', 42: 'center', 43: 'right',
5124
5153
  51: 'left_center', 52: 'left_right', 53: 'center_right',
@@ -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', 'QBKG25LM', 'SSM-U01', 'SSM-U02', 'DLKZMK11LM', 'DLKZMK12LM', 'QBKG39LM', 'QBKG41LM', 'ZNCZ15LM',
1986
- 'WS-EUK01', 'WS-EUK02', 'WS-EUK03', 'WS-EUK04', 'QBKG31LM', 'QBCZ15LM', 'QBKG20LM', 'QBKG38LM',
1987
- 'QBKG34LM', 'QBCZ14LM', 'QBKG19LM', 'QBKG40LM', 'QBKG41LM'].includes(meta.mapped.model)) {
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', 'QBKG25LM', 'SSM-U01', 'SSM-U02', 'DLKZMK11LM', 'DLKZMK12LM', 'QBKG39LM', 'QBKG41LM', 'ZNCZ15LM',
2009
- 'WS-EUK02', 'WS-EUK01', 'QBKG31LM', 'QBCZ15LM', 'QBCZ14LM', 'QBKG20LM', 'QBKG34LM', 'QBKG19LM',
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', 'QBCZ15LM', 'QBCZ14LM', 'QBKG20LM', 'QBKG25LM', 'QBKG19LM', 'DLKZMK11LM',
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', 'QBKG20LM', 'QBKG25LM', 'QBKG19LM', 'DLKZMK11LM',
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/acova.js CHANGED
@@ -28,6 +28,7 @@ module.exports = [{
28
28
  const endpoint = device.getEndpoint(1);
29
29
  await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'hvacThermostat']);
30
30
  await reporting.thermostatTemperature(endpoint);
31
+ await reporting.thermostatRunningState(endpoint);
31
32
  await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
32
33
  await reporting.thermostatUnoccupiedHeatingSetpoint(endpoint);
33
34
  },
package/devices/ikea.js CHANGED
@@ -443,27 +443,21 @@ module.exports = [
443
443
  model: 'ICPSHC24-10EU-IL-1',
444
444
  vendor: 'IKEA',
445
445
  description: 'TRADFRI driver for wireless control (10 watt)',
446
- extend: extend.light_onoff_brightness(),
447
- ota: ota.tradfri,
448
- onEvent: bulbOnEvent,
446
+ extend: tradfriExtend.light_onoff_brightness(),
449
447
  },
450
448
  {
451
449
  zigbeeModel: ['TRADFRI transformer 30W', 'TRADFRI Driver 30W'],
452
450
  model: 'ICPSHC24-30EU-IL-1',
453
451
  vendor: 'IKEA',
454
452
  description: 'TRADFRI driver for wireless control (30 watt)',
455
- extend: extend.light_onoff_brightness(),
456
- ota: ota.tradfri,
457
- onEvent: bulbOnEvent,
453
+ extend: tradfriExtend.light_onoff_brightness(),
458
454
  },
459
455
  {
460
456
  zigbeeModel: ['SILVERGLANS IP44 LED driver'],
461
457
  model: 'ICPSHC24-30-IL44-1',
462
458
  vendor: 'IKEA',
463
459
  description: 'SILVERGLANS IP44 LED driver for wireless control (30 watt)',
464
- extend: extend.light_onoff_brightness(),
465
- ota: ota.tradfri,
466
- onEvent: bulbOnEvent,
460
+ extend: tradfriExtend.light_onoff_brightness(),
467
461
  },
468
462
  {
469
463
  zigbeeModel: ['FLOALT panel WS 30x30'],
@@ -546,7 +540,12 @@ module.exports = [
546
540
  toZigbee: [],
547
541
  ota: ota.tradfri,
548
542
  meta: {battery: {dontDividePercentage: true}},
549
- configure: configureRemote,
543
+ configure: async (device, coordinatorEndpoint, logger) => {
544
+ // Binding genOnOff is not required to make device send events.
545
+ const endpoint = device.getEndpoint(1);
546
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
547
+ await reporting.batteryPercentageRemaining(endpoint);
548
+ },
550
549
  },
551
550
  {
552
551
  zigbeeModel: ['TRADFRI on/off switch'],
@@ -596,7 +595,12 @@ module.exports = [
596
595
  toZigbee: [],
597
596
  ota: ota.tradfri,
598
597
  meta: {disableActionGroup: true, battery: {dontDividePercentage: true}},
599
- configure: configureRemote,
598
+ configure: async (device, coordinatorEndpoint, logger) => {
599
+ // Binding genOnOff is not required to make device send events.
600
+ const endpoint = device.getEndpoint(1);
601
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
602
+ await reporting.batteryPercentageRemaining(endpoint);
603
+ },
600
604
  },
601
605
  {
602
606
  zigbeeModel: ['SYMFONISK Sound Controller'],
@@ -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
  {
@@ -1516,6 +1525,15 @@ module.exports = [
1516
1525
  extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
1517
1526
  ota: ota.zigbeeOTA,
1518
1527
  },
1528
+ {
1529
+ zigbeeModel: ['915005986901'],
1530
+ model: '915005986901',
1531
+ vendor: 'Philips',
1532
+ description: 'Hue White and color ambiance Gradient Signe table lamp (white)',
1533
+ meta: {turnsOffAtBrightness1: true},
1534
+ extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
1535
+ ota: ota.zigbeeOTA,
1536
+ },
1519
1537
  {
1520
1538
  zigbeeModel: ['5060730P7_01', '5060730P7_02', '5060730P7_03', '5060730P7_04', '5060730P7_05'],
1521
1539
  model: '5060730P7',
@@ -1715,7 +1733,7 @@ module.exports = [
1715
1733
  ota: ota.zigbeeOTA,
1716
1734
  },
1717
1735
  {
1718
- zigbeeModel: ['RDM001'],
1736
+ zigbeeModel: ['RDM001', '9290030171'],
1719
1737
  model: '929003017102',
1720
1738
  vendor: 'Philips',
1721
1739
  description: 'Hue wall switch module',
@@ -1739,7 +1757,8 @@ module.exports = [
1739
1757
  fromZigbee: [fz.ignore_command_on, fz.ignore_command_off, fz.ignore_command_step, fz.ignore_command_stop,
1740
1758
  fz.legacy.hue_dimmer_switch, fz.battery],
1741
1759
  exposes: [e.battery(), e.action(['on-press', 'on-hold', 'on-hold-release', 'up-press', 'up-hold', 'up-hold-release',
1742
- 'down-press', 'down-hold', 'down-hold-release', 'off-press', 'off-hold', 'off-hold-release'])],
1760
+ 'down-press', 'down-hold', 'down-hold-release', 'off-press', 'off-hold', 'off-hold-release']),
1761
+ exposes.numeric('action_duration', ea.STATE).withUnit('second')],
1743
1762
  toZigbee: [],
1744
1763
  configure: async (device, coordinatorEndpoint, logger) => {
1745
1764
  const endpoint1 = device.getEndpoint(1);
@@ -86,6 +86,20 @@ module.exports = [
86
86
  exposes: [e.contact(), e.battery_low(), e.tamper()],
87
87
  ota: ota.salus,
88
88
  },
89
+ {
90
+ zigbeeModel: ['SS909ZB'],
91
+ model: 'PS600',
92
+ vendor: 'Salus Controls',
93
+ description: 'Pipe temperature sensor',
94
+ fromZigbee: [fz.temperature],
95
+ toZigbee: [],
96
+ exposes: [e.temperature()],
97
+ configure: async (device, coordinatorEndpoint, logger) => {
98
+ const endpoint = device.getEndpoint(9);
99
+ await reporting.bind(endpoint, coordinatorEndpoint, ['msTemperatureMeasurement']);
100
+ },
101
+ ota: ota.salus,
102
+ },
89
103
  {
90
104
  zigbeeModel: ['RE600'],
91
105
  model: 'RE600',
@@ -8,6 +8,36 @@ const e = exposes.presets;
8
8
  const ea = exposes.access;
9
9
 
10
10
  module.exports = [
11
+ {
12
+ zigbeeModel: ['PUCK/SHUTTER/1'],
13
+ model: 'CCT5015-0001',
14
+ vendor: 'Schneider Electric',
15
+ description: 'Roller shutter module',
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
+ },
26
+ {
27
+ zigbeeModel: ['NHPB/SHUTTER/1'],
28
+ model: 'S520567',
29
+ vendor: 'Schneider Electric',
30
+ description: 'Roller shutter',
31
+ fromZigbee: [fz.cover_position_tilt],
32
+ toZigbee: [tz.cover_position_tilt, tz.cover_state],
33
+ exposes: [e.cover_position()],
34
+ meta: {coverInverted: true},
35
+ configure: async (device, coordinatorEndpoint, logger) => {
36
+ const endpoint = device.getEndpoint(5);
37
+ await reporting.bind(endpoint, coordinatorEndpoint, ['closuresWindowCovering']);
38
+ await reporting.currentPositionLiftPercentage(endpoint);
39
+ },
40
+ },
11
41
  {
12
42
  zigbeeModel: ['iTRV'],
13
43
  model: 'WV704R0A0902',
package/devices/siglis.js CHANGED
@@ -1,9 +1,46 @@
1
- const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
2
- const tz = require('zigbee-herdsman-converters/converters/toZigbee');
3
- const exposes = require('zigbee-herdsman-converters/lib/exposes');
4
- const reporting = require('zigbee-herdsman-converters/lib/reporting');
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
- fromZigbee: [fz.color_colortemp, fz.on_off, fz.brightness, fz.level_config, fz.power_on_behavior, fz.ignore_basic_report],
16
- toZigbee: [tz.light_onoff_brightness, tz.light_color, tz.ignore_transition, tz.ignore_rate, tz.light_brightness_move,
17
- tz.light_brightness_step, tz.level_config, tz.power_on_behavior, tz.light_hue_saturation_move,
18
- tz.light_hue_saturation_step, tz.light_color_options, tz.light_color_mode],
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 {'l1': 5, 'l2': 6, 'l3': 7};
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(5);
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/tuya.js CHANGED
@@ -11,7 +11,7 @@ const ea = exposes.access;
11
11
 
12
12
  const TS011Fplugs = ['_TZ3000_5f43h46b', '_TZ3000_cphmq0q7', '_TZ3000_dpo1ysak', '_TZ3000_ew3ldmgx', '_TZ3000_gjnozsaz',
13
13
  '_TZ3000_jvzvulen', '_TZ3000_mraovvmm', '_TZ3000_nfnmi125', '_TZ3000_ps3dmato', '_TZ3000_w0qqde0g', '_TZ3000_u5u4cakc',
14
- '_TZ3000_rdtixbnu'];
14
+ '_TZ3000_rdtixbnu', '_TZ3000_typdpbpg'];
15
15
 
16
16
  module.exports = [
17
17
  {
@@ -175,6 +175,7 @@ module.exports = [
175
175
  {modelID: 'TS0202', manufacturerName: '_TYZB01_dl7cejts'},
176
176
  {modelID: 'TS0202', manufacturerName: '_TYZB01_qjqgmqxr'},
177
177
  {modelID: 'TS0202', manufacturerName: '_TZ3000_mmtwjmaq'},
178
+ {modelID: 'TS0202', manufacturerName: '_TZ3000_kmh5qpmb'},
178
179
  {modelID: 'TS0202', manufacturerName: '_TZ3000_mcxw5ehu'},
179
180
  {modelID: 'TS0202', manufacturerName: '_TZ3000_msl6wxk9'},
180
181
  {modelID: 'TS0202', manufacturerName: '_TYZB01_hqbdru35'},
@@ -570,6 +571,13 @@ module.exports = [
570
571
  exposes: [e.battery(), e.action(['1_single', '1_double', '1_hold', '2_single', '2_double', '2_hold',
571
572
  '3_single', '3_double', '3_hold', '4_single', '4_double', '4_hold'])],
572
573
  toZigbee: [],
574
+ configure: async (device, coordinatorEndpoint, logger) => {
575
+ const endpoint = device.getEndpoint(1);
576
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
577
+ try {
578
+ await reporting.batteryPercentageRemaining(endpoint);
579
+ } catch (error) {/* Fails for some*/}
580
+ },
573
581
  },
574
582
  {
575
583
  fingerprint: [{modelID: 'TS004F', manufacturerName: '_TZ3000_xabckq1v'}],
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.legacy.QBKG25LM_click, fz.aqara_opple],
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', 'left_triple', 'left_hold', 'left_release',
611
- 'center_single', 'center_double', 'center_triple', 'center_hold', 'center_release',
612
- 'right_single', 'right_double', 'right_triple', 'right_hold', 'right_release']),
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.action([
640
- 'hold_left', 'single_left', 'double_left', 'triple_left', 'release_left',
641
- 'hold_center', 'single_center', 'double_center', 'triple_center', 'release_center',
642
- 'hold_right', 'single_right', 'double_right', 'triple_right', 'release_right',
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.aqara_opple, fz.xiaomi_multistate_action, fz.xiaomi_power],
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, 'system': 1};
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
  },
@@ -4,6 +4,21 @@ const tz = require('../converters/toZigbee');
4
4
  const reporting = require('../lib/reporting');
5
5
  const extend = require('../lib/extend');
6
6
  const e = exposes.presets;
7
+ const tuya = require('../lib/tuya');
8
+
9
+ const fzLocal = {
10
+ ZMRM02: {
11
+ cluster: 'manuSpecificTuya',
12
+ type: ['commandGetData', 'commandSetDataResponse'],
13
+ convert: (model, msg, publish, options, meta) => {
14
+ const button = msg.data.dp;
15
+ const actionValue = tuya.getDataValue(msg.data.datatype, msg.data.data);
16
+ const lookup = {0: 'single', 1: 'double', 2: 'hold'};
17
+ const action = lookup[actionValue];
18
+ return {action: `button_${button}_${action}`};
19
+ },
20
+ },
21
+ };
7
22
 
8
23
  module.exports = [
9
24
  {
@@ -66,4 +81,20 @@ module.exports = [
66
81
  await reporting.onOff(endpoint);
67
82
  },
68
83
  },
84
+ {
85
+ fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_zqtiam4u'}],
86
+ model: 'ZM-RM02',
87
+ vendor: 'Zemismart',
88
+ description: 'Smart 6 key scene switch',
89
+ fromZigbee: [fzLocal.ZMRM02],
90
+ toZigbee: [],
91
+ onEvent: tuya.onEventSetTime,
92
+ exposes: [e.battery(), e.action([
93
+ 'button_1_hold', 'button_1_single', 'button_1_double',
94
+ 'button_2_hold', 'button_2_single', 'button_2_double',
95
+ 'button_3_hold', 'button_3_single', 'button_3_double',
96
+ 'button_4_hold', 'button_4_single', 'button_4_double',
97
+ 'button_5_hold', 'button_5_single', 'button_5_double',
98
+ 'button_6_hold', 'button_6_single', 'button_6_double'])],
99
+ },
69
100
  ];
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/lib/exposes.js CHANGED
@@ -516,7 +516,7 @@ module.exports = {
516
516
  carbon_monoxide: () => new Binary('carbon_monoxide', access.STATE, true, false).withDescription('Indicates if CO (carbon monoxide) is detected'),
517
517
  child_lock: () => new Lock().withState('child_lock', 'LOCK', 'UNLOCK', 'Enables/disables physical input on the device', access.STATE_SET),
518
518
  co2: () => new Numeric('co2', access.STATE).withUnit('ppm').withDescription('The measured CO2 (carbon dioxide) value'),
519
- comfort_temperature: () => new Numeric('comfort_temperature', access.STATE_SET).withUnit('°C').withDescription('Comfort temperature').withValueMin(-10).withValueMax(35),
519
+ comfort_temperature: () => new Numeric('comfort_temperature', access.STATE_SET).withUnit('°C').withDescription('Comfort temperature').withValueMin(0).withValueMax(30),
520
520
  consumer_connected: () => new Binary('consumer_connected', access.STATE, true, false).withDescription('Indicates whether a plug is physically attached. Device does not have to pull power or even be connected electrically (state of this binary switch can be ON even if main power switch is OFF)'),
521
521
  contact: () => new Binary('contact', access.STATE, false, true).withDescription('Indicates if the contact is closed (= true) or open (= false)'),
522
522
  cover_position: () => new Cover().withPosition(),
@@ -531,7 +531,7 @@ module.exports = {
531
531
  device_temperature: () => new Numeric('device_temperature', access.STATE).withUnit('°C').withDescription('Temperature of the device'),
532
532
  eco2: () => new Numeric('eco2', access.STATE).withUnit('ppm').withDescription('Measured eCO2 value'),
533
533
  eco_mode: () => new Binary('eco_mode', access.STATE_SET, 'ON', 'OFF').withDescription('ECO mode (energy saving mode)'),
534
- eco_temperature: () => new Numeric('eco_temperature', access.STATE_SET).withUnit('°C').withDescription('Eco temperature').withValueMin(-10).withValueMax(35),
534
+ eco_temperature: () => new Numeric('eco_temperature', access.STATE_SET).withUnit('°C').withDescription('Eco temperature').withValueMin(0).withValueMax(35),
535
535
  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)'),
536
536
  energy: () => new Numeric('energy', access.STATE).withUnit('kWh').withDescription('Sum of consumed energy'),
537
537
  fan: () => new Fan(),
@@ -539,7 +539,7 @@ module.exports = {
539
539
  formaldehyd: () => new Numeric('formaldehyd', access.STATE).withDescription('The measured formaldehyd value'),
540
540
  gas: () => new Binary('gas', access.STATE, true, false).withDescription('Indicates whether the device detected gas'),
541
541
  hcho: () => new Numeric('hcho', access.STATE).withUnit('mg/m³').withDescription('Measured Hcho value'),
542
- holiday_temperature: () => new Numeric('holiday_temperature', access.STATE_SET).withUnit('°C').withDescription('Holiday temperature').withValueMin(-10).withValueMax(35),
542
+ holiday_temperature: () => new Numeric('holiday_temperature', access.STATE_SET).withUnit('°C').withDescription('Holiday temperature').withValueMin(0).withValueMax(30),
543
543
  humidity: () => new Numeric('humidity', access.STATE).withUnit('%').withDescription('Measured relative humidity'),
544
544
  illuminance: () => new Numeric('illuminance', access.STATE).withDescription('Raw measured illuminance'),
545
545
  illuminance_lux: () => new Numeric('illuminance_lux', access.STATE).withUnit('lx').withDescription('Measured illuminance in lux'),
@@ -557,15 +557,15 @@ module.exports = {
557
557
  linkquality: () => new Numeric('linkquality', access.STATE).withUnit('lqi').withDescription('Link quality (signal strength)').withValueMin(0).withValueMax(255),
558
558
  local_temperature: () => new Numeric('local_temperature', access.STATE_GET).withUnit('°C').withDescription('Current temperature measured on the device'),
559
559
  lock: () => new Lock().withState('state', 'LOCK', 'UNLOCK', 'State of the lock').withLockState('lock_state', 'Actual state of the lock'),
560
- max_temperature: () => new Numeric('max_temperature', access.STATE_SET).withUnit('°C').withDescription('Maximum temperature').withValueMin(-10).withValueMax(35),
561
- max_temperature_limit: () => new Numeric('max_temperature_limit', access.STATE_SET).withUnit('°C').withDescription('Maximum temperature limit').withValueMin(-10).withValueMax(35),
562
- min_temperature: () => new Numeric('min_temperature', access.STATE_SET).withUnit('°C').withDescription('Minimum temperature').withValueMin(-10).withValueMax(35),
560
+ max_temperature: () => new Numeric('max_temperature', access.STATE_SET).withUnit('°C').withDescription('Maximum temperature').withValueMin(15).withValueMax(35),
561
+ max_temperature_limit: () => new Numeric('max_temperature_limit', access.STATE_SET).withUnit('°C').withDescription('Maximum temperature limit').withValueMin(0).withValueMax(35),
562
+ min_temperature: () => new Numeric('min_temperature', access.STATE_SET).withUnit('°C').withDescription('Minimum temperature').withValueMin(5).withValueMax(15),
563
563
  noise: () => new Numeric('noise', access.STATE).withUnit('dBA').withDescription('The measured noise value'),
564
564
  noise_detected: () => new Binary('noise_detected', access.STATE, true, false).withDescription('Indicates whether the device detected noise'),
565
565
  occupancy: () => new Binary('occupancy', access.STATE, true, false).withDescription('Indicates whether the device detected occupancy'),
566
566
  occupancy_level: () => new Numeric('occupancy_level', access.STATE).withDescription('The measured occupancy value'),
567
567
  open_window: () => new Binary('open_window', access.STATE_SET, 'ON', 'OFF').withDescription('Enables/disables the status on the device'),
568
- open_window_temperature: () => new Numeric('open_window_temperature', access.STATE_SET).withUnit('°C').withDescription('Open window temperature').withValueMin(-10).withValueMax(35),
568
+ open_window_temperature: () => new Numeric('open_window_temperature', access.STATE_SET).withUnit('°C').withDescription('Open window temperature').withValueMin(0).withValueMax(35),
569
569
  pm10: () => new Numeric('pm10', access.STATE).withUnit('µg/m³').withDescription('Measured PM10 (particulate matter) concentration'),
570
570
  pm25: () => new Numeric('pm25', access.STATE).withUnit('µg/m³').withDescription('Measured PM2.5 (particulate matter) concentration'),
571
571
  position: () => new Numeric('position', access.STATE).withUnit('%').withDescription('Position'),
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.353",
3
+ "version": "14.0.357",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.353",
3
+ "version": "14.0.357",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [