zigbee-herdsman-converters 14.0.278 → 14.0.282

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.
@@ -4416,11 +4416,11 @@ const converters = {
4416
4416
  const data = msg.data['247'];
4417
4417
  // Xiaomi struct parsing
4418
4418
  const length = data.length;
4419
- // if (meta.logger) meta.logger.debug(`plug.mmeu01: Xiaomi struct: length ${length}`);
4419
+ // if (meta.logger) meta.logger.debug(`${model.zigbeeModel}: Xiaomi struct: length ${length}`);
4420
4420
  for (let i=0; i < length; i++) {
4421
4421
  const index = data[i];
4422
4422
  let value = null;
4423
- // if (meta.logger) meta.logger.debug(`plug.mmeu01: pos=${i}, ind=${data[i]}, vtype=${data[i+1]}`);
4423
+ // if (meta.logger) meta.logger.debug(`${model.zigbeeModel}: pos=${i}, ind=${data[i]}, vtype=${data[i+1]}`);
4424
4424
  switch (data[i+1]) {
4425
4425
  case 16:
4426
4426
  // 0x10 ZclBoolean
@@ -4437,8 +4437,14 @@ const converters = {
4437
4437
  value = data.readUInt16LE(i+2);
4438
4438
  i += 3;
4439
4439
  break;
4440
+ case 35:
4441
+ // 0x23 Zcl32BitUint
4442
+ value = data.readUInt32LE(i+2);
4443
+ i += 5;
4444
+ break;
4440
4445
  case 39:
4441
4446
  // 0x27 Zcl64BitUint
4447
+ value = data.readBigUInt64BE(i+2);
4442
4448
  i += 9;
4443
4449
  break;
4444
4450
  case 40:
@@ -4446,11 +4452,31 @@ const converters = {
4446
4452
  value = data.readInt8(i+2);
4447
4453
  i += 2;
4448
4454
  break;
4455
+ case 41:
4456
+ // 0x29 Zcl16BitInt
4457
+ value = data.readInt16LE(i+2);
4458
+ i += 3;
4459
+ break;
4460
+ case 43:
4461
+ // 0x2B Zcl32BitInt
4462
+ value = data.readInt32LE(i+2);
4463
+ i += 5;
4464
+ break;
4465
+ case 47:
4466
+ // 0x2F Zcl64BitInt
4467
+ value = data.readBigInt64BE(i+2);
4468
+ i += 9;
4469
+ break;
4449
4470
  case 57:
4450
4471
  // 0x39 ZclSingleFloat
4451
4472
  value = data.readFloatLE(i+2);
4452
4473
  i += 5;
4453
4474
  break;
4475
+ case 58:
4476
+ // 0x3a ZclDoubleFloat
4477
+ value = data.readDoubleLE(i+2);
4478
+ i += 5;
4479
+ break;
4454
4480
  default:
4455
4481
  if (meta.logger) meta.logger.debug(`${model.zigbeeModel}: unknown vtype=${data[i+1]}, pos=${i+1}`);
4456
4482
  }
@@ -4466,6 +4492,10 @@ const converters = {
4466
4492
  else if (meta.logger) meta.logger.debug(`${model.zigbeeModel}: unknown index ${index} with value ${value}`);
4467
4493
  }
4468
4494
  }
4495
+ if (msg.data.hasOwnProperty('4')) {
4496
+ const lookup = {4: 'anti_flicker_mode', 1: 'quick_mode'};
4497
+ payload.mode_switch = lookup[msg.data['4']];
4498
+ }
4469
4499
  if (msg.data.hasOwnProperty('512')) {
4470
4500
  if (['ZNCZ15LM', 'QBCZ14LM', 'QBCZ15LM'].includes(model.model)) {
4471
4501
  payload.button_lock = msg.data['512'] === 1 ? 'OFF' : 'ON';
@@ -4557,7 +4587,7 @@ const converters = {
4557
4587
  if (['WXKG02LM_rev2', 'WXKG07LM'].includes(model.model)) buttonLookup = {1: 'left', 2: 'right', 3: 'both'};
4558
4588
  if (['QBKG12LM', 'QBKG24LM'].includes(model.model)) buttonLookup = {5: 'left', 6: 'right', 7: 'both'};
4559
4589
  if (['QBKG25LM', 'QBKG26LM'].includes(model.model)) buttonLookup = {41: 'left', 42: 'center', 43: 'right'};
4560
- if (['QBKG39LM', 'QBKG41LM', 'WS-EUK02', 'WS-EUK04', 'QBKG31LM'].includes(model.model)) {
4590
+ if (['QBKG39LM', 'QBKG41LM', 'WS-EUK02', 'WS-EUK04', 'QBKG20LM', 'QBKG31LM'].includes(model.model)) {
4561
4591
  buttonLookup = {41: 'left', 42: 'right', 51: 'both'};
4562
4592
  }
4563
4593
 
@@ -6708,6 +6738,13 @@ const converters = {
6708
6738
  }
6709
6739
  },
6710
6740
  },
6741
+ sihas_people_cnt: {
6742
+ cluster: 'genAnalogInput',
6743
+ type: ['attributeReport', 'readResponse'],
6744
+ convert: (model, msg, publish, options, meta) => {
6745
+ return {people: msg.data.presentValue};
6746
+ },
6747
+ },
6711
6748
  // #endregion
6712
6749
 
6713
6750
  // #region Ignore converters (these message dont need parsing).
@@ -1912,7 +1912,7 @@ const converters = {
1912
1912
  key: ['power_outage_memory'],
1913
1913
  convertSet: async (entity, key, value, meta) => {
1914
1914
  if (['ZNCZ04LM', 'QBKG25LM', 'SSM-U01', 'SSM-U02', 'DLKZMK11LM', 'QBKG39LM', 'QBKG41LM', 'ZNCZ15LM',
1915
- 'WS-EUK01', 'WS-EUK02', 'WS-EUK03', 'WS-EUK04', 'QBKG31LM', 'QBCZ15LM',
1915
+ 'WS-EUK01', 'WS-EUK02', 'WS-EUK03', 'WS-EUK04', 'QBKG31LM', 'QBCZ15LM', 'QBKG20LM',
1916
1916
  'QBCZ14LM'].includes(meta.mapped.model)) {
1917
1917
  await entity.write('aqaraOpple', {0x0201: {value: value ? 1 : 0, type: 0x10}}, manufacturerOptions.xiaomi);
1918
1918
  } else if (['ZNCZ02LM', 'QBCZ11LM'].includes(meta.mapped.model)) {
@@ -1935,7 +1935,7 @@ const converters = {
1935
1935
  },
1936
1936
  convertGet: async (entity, key, meta) => {
1937
1937
  if (['ZNCZ04LM', 'QBKG25LM', 'SSM-U01', 'SSM-U02', 'DLKZMK11LM', 'QBKG39LM', 'QBKG41LM', 'ZNCZ15LM',
1938
- 'WS-EUK02', 'WS-EUK01', 'QBKG31LM', 'QBCZ15LM', 'QBCZ14LM'].includes(meta.mapped.model)) {
1938
+ 'WS-EUK02', 'WS-EUK01', 'QBKG31LM', 'QBCZ15LM', 'QBCZ14LM', 'QBKG20LM'].includes(meta.mapped.model)) {
1939
1939
  await entity.read('aqaraOpple', [0x0201]);
1940
1940
  } else if (['ZNCZ02LM', 'QBCZ11LM', 'ZNCZ11LM'].includes(meta.mapped.model)) {
1941
1941
  await entity.read('aqaraOpple', [0xFFF0]);
@@ -1997,6 +1997,17 @@ const converters = {
1997
1997
  await entity.read('aqaraOpple', [0x020b], manufacturerOptions.xiaomi);
1998
1998
  },
1999
1999
  },
2000
+ aqara_switch_mode_switch: {
2001
+ key: ['mode_switch'],
2002
+ convertSet: async (entity, key, value, meta) => {
2003
+ const lookup = {'anti_flicker_mode': 4, 'quick_mode': 1};
2004
+ await entity.write('aqaraOpple', {0x0004: {value: lookup[value], type: 0x21}}, manufacturerOptions.xiaomi);
2005
+ return {state: {mode_switch: value}};
2006
+ },
2007
+ convertGet: async (entity, key, meta) => {
2008
+ await entity.read('aqaraOpple', [0x0004], manufacturerOptions.xiaomi);
2009
+ },
2010
+ },
2000
2011
  xiaomi_button_switch_mode: {
2001
2012
  key: ['button_switch_mode'],
2002
2013
  convertSet: async (entity, key, value, meta) => {
@@ -2022,7 +2033,7 @@ const converters = {
2022
2033
  xiaomi_led_disabled_night: {
2023
2034
  key: ['led_disabled_night'],
2024
2035
  convertSet: async (entity, key, value, meta) => {
2025
- if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ15LM', 'QBCZ14LM', 'QBKG25LM'].includes(meta.mapped.model)) {
2036
+ if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ15LM', 'QBCZ14LM', 'QBKG20LM', 'QBKG25LM'].includes(meta.mapped.model)) {
2026
2037
  await entity.write('aqaraOpple', {0x0203: {value: value ? 1 : 0, type: 0x10}}, manufacturerOptions.xiaomi);
2027
2038
  } else if (['ZNCZ11LM'].includes(meta.mapped.model)) {
2028
2039
  const payload = value ?
@@ -2036,7 +2047,7 @@ const converters = {
2036
2047
  return {state: {led_disabled_night: value}};
2037
2048
  },
2038
2049
  convertGet: async (entity, key, meta) => {
2039
- if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ15LM', 'QBCZ14LM', 'QBKG25LM'].includes(meta.mapped.model)) {
2050
+ if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ15LM', 'QBCZ14LM', 'QBKG20LM', 'QBKG25LM'].includes(meta.mapped.model)) {
2040
2051
  await entity.read('aqaraOpple', [0x0203], manufacturerOptions.xiaomi);
2041
2052
  } else {
2042
2053
  throw new Error('Not supported');
@@ -5825,6 +5836,18 @@ const converters = {
5825
5836
  }
5826
5837
  },
5827
5838
  },
5839
+ sihas_set_people: {
5840
+ key: ['people'],
5841
+ convertSet: async (entity, key, value, meta) => {
5842
+ const payload = {'presentValue': value};
5843
+ const endpoint = meta.device.endpoints.find((e) => e.supportsInputCluster('genAnalogInput'));
5844
+ await endpoint.write('genAnalogInput', payload);
5845
+ },
5846
+ convertGet: async (entity, key, meta) => {
5847
+ const endpoint = meta.device.endpoints.find((e) => e.supportsInputCluster('genAnalogInput'));
5848
+ await endpoint.read('genAnalogInput', ['presentValue']);
5849
+ },
5850
+ },
5828
5851
  // #endregion
5829
5852
 
5830
5853
  // #region Ignore converters
@@ -36,32 +36,48 @@ module.exports = [
36
36
  'row_4_on', 'row_4_off', 'row_4_up', 'row_4_down', 'row_4_stop'])],
37
37
  meta: {multiEndpoint: true},
38
38
  configure: async (device, coordinatorEndpoint, logger) => {
39
- let firstEndpoint = 0x0a;
39
+ const endpoint10 = device.getEndpoint(0x0a);
40
+ if (endpoint10 != null) {
41
+ // The total number of bindings seems to be severely limited with these devices.
42
+ // In order to be able to toggle groups, we need to remove the scenes cluster
40
43
 
41
- const switchEndpoint10 = device.getEndpoint(10);
42
- if (switchEndpoint10 != null && switchEndpoint10.supportsOutputCluster('genOnOff')) {
43
- // https://github.com/Koenkk/zigbee2mqtt/issues/3027#issuecomment-606169628
44
- await reporting.bind(switchEndpoint10, coordinatorEndpoint, ['genOnOff']);
44
+ await reporting.bind(endpoint10, coordinatorEndpoint, ['genLevelCtrl']);
45
45
  }
46
-
47
- const switchEndpoint12 = device.getEndpoint(0x12);
48
- if (switchEndpoint12 != null) {
49
- firstEndpoint++;
50
- await reporting.bind(switchEndpoint12, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
51
- }
52
-
53
46
  // Depending on the actual devices - 6735, 6736, or 6737 - there are 1, 2, or 4 endpoints.
54
- for (let i = firstEndpoint; i <= 0x0d; i++) {
55
- const endpoint = device.getEndpoint(i);
56
- if (endpoint != null) {
57
- // The total number of bindings seems to be severely limited with these devices.
58
- // In order to be able to toggle groups, we need to remove the scenes cluster
59
- const index = endpoint.outputClusters.indexOf(5);
60
- if (index > -1) {
61
- endpoint.outputClusters.splice(index, 1);
62
- }
63
- await reporting.bind(endpoint, coordinatorEndpoint, ['genLevelCtrl']);
47
+ // Thef 1st endpoint ist most bound to hardware switch
48
+ const endpoint11 = device.getEndpoint(0x0b);
49
+ if (endpoint11 != null) {
50
+ // The total number of bindings seems to be severely limited with these devices.
51
+ // In order to be able to toggle groups, we need to remove the scenes cluster
52
+ const index = endpoint11.outputClusters.indexOf(5);
53
+ if (index > -1) {
54
+ endpoint11.outputClusters.splice(index, 1);
55
+ }
56
+ await reporting.bind(endpoint11, coordinatorEndpoint, ['genLevelCtrl']);
57
+ }
58
+ const endpoint12 = device.getEndpoint(0x0c);
59
+ if (endpoint12 != null) {
60
+ // The total number of bindings seems to be severely limited with these devices.
61
+ // In order to be able to toggle groups, we need to remove the scenes cluster
62
+ const index = endpoint12.outputClusters.indexOf(5);
63
+ if (index > -1) {
64
+ endpoint12.outputClusters.splice(index, 1);
65
+ }
66
+ await reporting.bind(endpoint12, coordinatorEndpoint, ['genLevelCtrl']);
67
+ }
68
+ const endpoint13 = device.getEndpoint(0x0d);
69
+ if (endpoint13 != null) {
70
+ // The total number of bindings seems to be severely limited with these devices.
71
+ // In order to be able to toggle groups, we need to remove the scenes cluster
72
+ const index = endpoint13.outputClusters.indexOf(5);
73
+ if (index > -1) {
74
+ endpoint13.outputClusters.splice(index, 1);
64
75
  }
76
+ await reporting.bind(endpoint13, coordinatorEndpoint, ['genLevelCtrl']);
77
+ }
78
+ const endpoint18 = device.getEndpoint(0x12);
79
+ if (endpoint18 != null) {
80
+ await reporting.bind(endpoint18, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
65
81
  }
66
82
  },
67
83
  fromZigbee: [fz.ignore_basic_report, fz.on_off, fz.brightness, fz.legacy.RM01_on_click, fz.legacy.RM01_off_click,
@@ -72,7 +88,6 @@ module.exports = [
72
88
  if (switchEndpoint == null) {
73
89
  return;
74
90
  }
75
-
76
91
  // This device doesn't support reporting.
77
92
  // Therefore we read the on/off state every 5 seconds.
78
93
  // This is the same way as the Hue bridge does it.
@@ -0,0 +1,19 @@
1
+ const reporting = require('../lib/reporting');
2
+ const extend = require('../lib/extend');
3
+
4
+ module.exports = [
5
+ {
6
+ zigbeeModel: ['HK-DIM-A'],
7
+ model: 'HK-DIM-A',
8
+ vendor: 'Candeo',
9
+ description: 'Zigbee LED dimmer smart switch',
10
+ extend: extend.light_onoff_brightness({noConfigure: true, disableEffect: true}),
11
+ configure: async (device, coordinatorEndpoint, logger) => {
12
+ await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
13
+ const endpoint = device.getEndpoint(1);
14
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
15
+ await reporting.onOff(endpoint);
16
+ await reporting.brightness(endpoint, {min: 1});
17
+ },
18
+ },
19
+ ];
@@ -216,4 +216,23 @@ module.exports = [
216
216
  },
217
217
  exposes: [e.battery(), e.temperature(), e.humidity(), e.pressure()],
218
218
  },
219
+ {
220
+ zigbeeModel: ['EFEKTA_ePWS'],
221
+ model: 'EFEKTA_ePWS',
222
+ vendor: 'Custom devices (DiY)',
223
+ description: '[Plant wattering sensor with e-ink display](https://efektalab.com/epws102)',
224
+ fromZigbee: [fz.temperature, fz.soil_moisture, fz.battery],
225
+ toZigbee: [tz.factory_reset],
226
+ meta: {disableDefaultResponse: true},
227
+ configure: async (device, coordinatorEndpoint, logger) => {
228
+ const firstEndpoint = device.getEndpoint(1);
229
+ await reporting.bind(firstEndpoint, coordinatorEndpoint, ['genPowerCfg', 'msTemperatureMeasurement', 'msSoilMoisture']);
230
+ const overides = {min: 0, max: 21600, change: 0};
231
+ await reporting.batteryVoltage(firstEndpoint, overides);
232
+ await reporting.batteryPercentageRemaining(firstEndpoint, overides);
233
+ await reporting.temperature(firstEndpoint, overides);
234
+ await reporting.soil_moisture(firstEndpoint, overides);
235
+ },
236
+ exposes: [e.soil_moisture(), e.battery(), e.temperature()],
237
+ },
219
238
  ];
@@ -36,7 +36,7 @@ module.exports = [
36
36
  .withDescription('Not clear how this affects operation. `false` No Heat Available or `true` Heat Available'),
37
37
  exposes.binary('heat_required', ea.STATE_GET, true, false)
38
38
  .withDescription('Whether or not the unit needs warm water. `false` No Heat Request or `true` Heat Request'),
39
- exposes.binary('setpoint_change_source', ea.STATE, 0, 1)
39
+ exposes.enum('setpoint_change_source', ea.STATE, ['manual', 'schedule', 'externally'])
40
40
  .withDescription('Values observed are `0` (set locally) or `2` (set via Zigbee)'),
41
41
  exposes.climate().withSetpoint('occupied_heating_setpoint', 5, 32, 0.5).withLocalTemperature().withPiHeatingDemand()
42
42
  .withSystemMode(['heat']).withRunningState(['idle', 'heat'], ea.STATE),
package/devices/nyce.js CHANGED
@@ -4,6 +4,20 @@ const reporting = require('../lib/reporting');
4
4
  const e = exposes.presets;
5
5
 
6
6
  module.exports = [
7
+ {
8
+ zigbeeModel: ['3010'],
9
+ model: 'NCZ-3010',
10
+ vendor: 'Nyce',
11
+ description: 'Door hinge sensor',
12
+ fromZigbee: [fz.ias_contact_alarm_1, fz.battery],
13
+ toZigbee: [],
14
+ configure: async (device, coordinatorEndpoint, logger) => {
15
+ const endpoint = device.getEndpoint(1);
16
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
17
+ await reporting.batteryPercentageRemaining(endpoint);
18
+ },
19
+ exposes: [e.contact(), e.battery_low(), e.battery()],
20
+ },
7
21
  {
8
22
  zigbeeModel: ['3011'],
9
23
  model: 'NCZ-3011-HA',
@@ -297,7 +297,7 @@ module.exports = [
297
297
  ota: ota.zigbeeOTA,
298
298
  },
299
299
  {
300
- zigbeeModel: ['LCT026'],
300
+ zigbeeModel: ['LCT026', '7602031P7'],
301
301
  model: '7602031P7',
302
302
  vendor: 'Philips',
303
303
  description: 'Hue Go with Bluetooth',
@@ -501,6 +501,15 @@ module.exports = [
501
501
  extend: hueExtend.light_onoff_brightness(),
502
502
  ota: ota.zigbeeOTA,
503
503
  },
504
+ {
505
+ zigbeeModel: ['LWA012'],
506
+ model: '9290018217',
507
+ vendor: 'Philips',
508
+ description: 'Hue white A60 bulb B22 bluetooth',
509
+ meta: {turnsOffAtBrightness1: true},
510
+ extend: hueExtend.light_onoff_brightness(),
511
+ ota: ota.zigbeeOTA,
512
+ },
504
513
  {
505
514
  zigbeeModel: ['LWA017'],
506
515
  model: '‎929002469202',
@@ -528,6 +537,15 @@ module.exports = [
528
537
  extend: hueExtend.light_onoff_brightness_colortemp(),
529
538
  ota: ota.zigbeeOTA,
530
539
  },
540
+ {
541
+ zigbeeModel: ['LTA009'],
542
+ model: '9290024684',
543
+ vendor: 'Philips',
544
+ description: 'Hue white ambiance E27 1100lm with Bluetooth',
545
+ meta: {turnsOffAtBrightness1: true},
546
+ extend: hueExtend.light_onoff_brightness_colortemp(),
547
+ ota: ota.zigbeeOTA,
548
+ },
531
549
  {
532
550
  zigbeeModel: ['LTA008'],
533
551
  model: '9290022267A',
@@ -2078,9 +2096,27 @@ module.exports = [
2078
2096
  zigbeeModel: ['929002966401'],
2079
2097
  model: '929002966401',
2080
2098
  vendor: 'Philips',
2081
- description: 'Hue white & color ambiance Surimu square panel',
2099
+ description: 'Hue White & Color Ambiance Surimu square panel',
2082
2100
  meta: {turnsOffAtBrightness1: true},
2083
2101
  extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
2084
2102
  ota: ota.zigbeeOTA,
2085
2103
  },
2104
+ {
2105
+ zigbeeModel: ['929002966501'],
2106
+ model: '929002966501',
2107
+ vendor: 'Philips',
2108
+ description: 'Hue White and Color Ambiance Surimu rectangle panel',
2109
+ extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
2110
+ meta: {turnsOffAtBrightness1: true},
2111
+ ota: ota.zigbeeOTA,
2112
+ },
2113
+ {
2114
+ zigbeeModel: ['5060931P7_01', '5060931P7_02', '5060931P7_03', '5060931P7_04'],
2115
+ model: '5060931P7',
2116
+ vendor: 'Philips',
2117
+ description: 'Hue White & Color Ambiance Centris ceiling light (3 spots)',
2118
+ extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
2119
+ meta: {turnsOffAtBrightness1: true},
2120
+ ota: ota.zigbeeOTA,
2121
+ },
2086
2122
  ];
package/devices/popp.js CHANGED
@@ -37,7 +37,7 @@ module.exports = [
37
37
  .withDescription('Not clear how this affects operation. `false` No Heat Available or `true` Heat Available'),
38
38
  exposes.binary('heat_required', ea.STATE_GET, true, false)
39
39
  .withDescription('Whether or not the unit needs warm water. `false` No Heat Request or `true` Heat Request'),
40
- exposes.binary('setpoint_change_source', ea.STATE, 0, 1)
40
+ exposes.enum('setpoint_change_source', ea.STATE, ['manual', 'schedule', 'externally'])
41
41
  .withDescription('Values observed are `0` (set locally) or `2` (set via Zigbee)'),
42
42
  exposes.climate().withSetpoint('occupied_heating_setpoint', 5, 32, 0.5).withLocalTemperature().withPiHeatingDemand()
43
43
  .withSystemMode(['heat']).withRunningState(['idle', 'heat'], ea.STATE),
package/devices/robb.js CHANGED
@@ -80,6 +80,20 @@ module.exports = [
80
80
  meta: {multiEndpoint: true, battery: {dontDividePercentage: true}},
81
81
  whiteLabel: [{vendor: 'Sunricher', model: 'SR-ZG9001K8-DIM'}],
82
82
  },
83
+ {
84
+ zigbeeModel: ['ROB_200-025-0'],
85
+ model: 'ROB_200-025-0',
86
+ vendor: 'ROBB',
87
+ description: 'Zigbee 8 button wall switch',
88
+ fromZigbee: [fz.command_on, fz.command_off, fz.command_move, fz.command_stop, fz.battery, fz.ignore_genOta],
89
+ exposes: [e.battery(), e.action([
90
+ 'on_1', 'off_1', 'brightness_move_up_1', 'brightness_move_down_1', 'brightness_stop_1',
91
+ 'on_2', 'off_2', 'brightness_move_up_2', 'brightness_move_down_2', 'brightness_stop_2',
92
+ 'on_3', 'off_3', 'brightness_move_up_3', 'brightness_move_down_3', 'brightness_stop_3',
93
+ 'on_4', 'off_4', 'brightness_move_up_4', 'brightness_move_down_4', 'brightness_stop_4'])],
94
+ toZigbee: [],
95
+ meta: {multiEndpoint: true, battery: {dontDividePercentage: true}},
96
+ },
83
97
  {
84
98
  zigbeeModel: ['ZG2833K4_EU06', 'ROB_200-008', 'ROB_200-008-0'],
85
99
  model: 'ROB_200-008-0',
@@ -517,4 +517,20 @@ module.exports = [
517
517
  await reporting.thermostatOccupiedHeatingSetpoint(endpoint, {min: 0, max: constants.repInterval.MINUTES_15, change: 25});
518
518
  },
519
519
  },
520
+ {
521
+ zigbeeModel: ['FLS/SYSTEM-M/4'],
522
+ model: 'WDE002906',
523
+ vendor: 'Schneider Electric',
524
+ description: 'Wiser wireless switch 1-gang',
525
+ fromZigbee: [fz.command_on, fz.command_off, fz.command_move, fz.command_stop, fz.battery],
526
+ toZigbee: [],
527
+ exposes: [e.action(['on', 'off', 'brightness_move_up', 'brightness_move_down', 'brightness_stop']),
528
+ e.battery()],
529
+ meta: {disableActionGroup: true},
530
+ configure: async (device, coordinatorEndpoint, logger) => {
531
+ const endpoint = device.getEndpoint(21);
532
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl', 'genPowerCfg']);
533
+ await reporting.batteryPercentageRemaining(endpoint);
534
+ },
535
+ },
520
536
  ];
@@ -0,0 +1,28 @@
1
+ const exposes = require('../lib/exposes');
2
+ const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
3
+ const tz = require('../converters/toZigbee');
4
+ const reporting = require('../lib/reporting');
5
+ const e = exposes.presets;
6
+ const ea = exposes.access;
7
+
8
+ module.exports = [
9
+ {
10
+ zigbeeModel: ['CSM-300Z'],
11
+ model: 'CSM-300ZB',
12
+ vendor: 'ShinaSystem',
13
+ description: 'Sihas multipurpose sensor',
14
+ meta: {battery: {voltageToPercentage: '3V_2100'}},
15
+ fromZigbee: [fz.battery, fz.sihas_people_cnt],
16
+ toZigbee: [tz.sihas_set_people],
17
+ configure: async (device, coordinatorEndpoint, logger) => {
18
+ const endpoint = device.getEndpoint(1);
19
+ const binds = ['genPowerCfg', 'genAnalogInput'];
20
+ await reporting.bind(endpoint, coordinatorEndpoint, binds);
21
+ await reporting.batteryVoltage(endpoint);
22
+ const payload = reporting.payload('presentValue', 1, 600, 0);
23
+ await endpoint.configureReporting('genAnalogInput', payload);
24
+ },
25
+ exposes: [e.battery(), e.battery_voltage(),
26
+ exposes.numeric('people', ea.ALL).withValueMin(0).withValueMax(50).withDescription('People count')],
27
+ },
28
+ ];
package/devices/tuya.js CHANGED
@@ -30,7 +30,7 @@ module.exports = [
30
30
  {
31
31
  fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_bq5c8xfe'}],
32
32
  model: 'TS0601_temperature_humidity_sensor',
33
- vendor: 'Tuya',
33
+ vendor: 'TuYa',
34
34
  description: 'Temperature & humidity sensor',
35
35
  fromZigbee: [fz.tuya_temperature_humidity_sensor],
36
36
  toZigbee: [],
@@ -40,7 +40,7 @@ module.exports = [
40
40
  fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_8ygsuhe1'},
41
41
  {modelID: 'TS0601', manufacturerName: '_TZE200_yvx5lh6k'}, {modelID: 'TS0601', manufacturerName: '_TZE200_ryfmq5rl'}],
42
42
  model: 'TS0601_air_quality_sensor',
43
- vendor: 'Tuya',
43
+ vendor: 'TuYa',
44
44
  description: 'Air quality sensor',
45
45
  fromZigbee: [fz.tuya_air_quality],
46
46
  toZigbee: [],
@@ -105,14 +105,15 @@ module.exports = [
105
105
  {modelID: 'TS0505B', manufacturerName: '_TZ3000_jtmhndw2'},
106
106
  {modelID: 'TS0505B', manufacturerName: '_TZ3210_5snkkrxw'},
107
107
  {modelID: 'TS0505B', manufacturerName: '_TZ3000_12sxjap4'},
108
+ {modelID: 'TS0505B', manufacturerName: '_TZ3000_x2fqbdun'},
108
109
  {modelID: 'TS0505B', manufacturerName: '_TZ3000_589kq4ul'},
109
110
  {modelID: 'TS0505B', manufacturerName: '_TZ3000_1mtktxdk'}],
110
111
  model: 'TS0505B',
111
112
  vendor: 'TuYa',
112
113
  description: 'Zigbee RGB+CCT light',
113
114
  whiteLabel: [{vendor: 'Mercator ikuü', model: 'SMD4106W-RGB-ZB'},
114
- {vendor: 'Tuya', model: 'A5C-21F7-01'}],
115
- extend: extend.light_onoff_brightness_colortemp_color(),
115
+ {vendor: 'TuYa', model: 'A5C-21F7-01'}, {vendor: 'Mercator ikuü', model: 'S9E27LED9W-RGB-Z'}],
116
+ extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
116
117
  meta: {applyRedFix: true, enhancedHue: false},
117
118
  },
118
119
  {
@@ -134,7 +135,7 @@ module.exports = [
134
135
  },
135
136
  {
136
137
  fingerprint: [{modelID: 'TS0501B', manufacturerName: '_TZ3000_4whigl8i'},
137
- {modelID: 'TS0501B', manufacturerName: '_TZ3210_4whigl8i'}],
138
+ {modelID: 'TS0501B', manufacturerName: '_TZ3210_4whigl8i'}, {modelID: 'TS0501B', manufacturerName: '_TZ3210_9q49basr'}],
138
139
  model: 'TS0501B',
139
140
  description: 'Zigbee light',
140
141
  vendor: 'TuYa',
@@ -469,7 +470,7 @@ module.exports = [
469
470
  {
470
471
  fingerprint: [{modelID: 'SM0201', manufacturerName: '_TYZB01_cbiezpds'}],
471
472
  model: 'SM0201',
472
- vendor: 'Tuya',
473
+ vendor: 'TuYa',
473
474
  description: 'Temperature & humidity sensor with LED screen',
474
475
  fromZigbee: [fz.battery, fz.temperature, fz.humidity],
475
476
  toZigbee: [],
@@ -661,7 +662,7 @@ module.exports = [
661
662
  {vendor: 'Binthen', model: 'BCM100D'},
662
663
  {vendor: 'Binthen', model: 'CV01A'},
663
664
  {vendor: 'Zemismart', model: 'M515EGB'},
664
- {vendor: 'Tuya', model: 'M515EGZT'},
665
+ {vendor: 'TuYa', model: 'M515EGZT'},
665
666
  {vendor: 'TuYa', model: 'DT82LEMA-1.2N'},
666
667
  {vendor: 'Moes', model: 'AM43-0.45/40-ES-EB'},
667
668
  {vendor: 'Larkkey', model: 'ZSTY-SM-1SRZG-EU'},
@@ -684,11 +685,12 @@ module.exports = [
684
685
  {
685
686
  zigbeeModel: ['kud7u2l'],
686
687
  fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_ckud7u2l'}, {modelID: 'TS0601', manufacturerName: '_TZE200_ywdxldoj'},
687
- {modelID: 'TS0601', manufacturerName: '_TZE200_cwnjrr72'}],
688
+ {modelID: 'TS0601', manufacturerName: '_TZE200_cwnjrr72'}, {modelID: 'TS0601', manufacturerName: '_TZE200_chyvmhay'}],
688
689
  model: 'TS0601_thermostat',
689
690
  vendor: 'TuYa',
690
691
  description: 'Radiator valve with thermostat',
691
- whiteLabel: [{vendor: 'Moes', model: 'HY368'}, {vendor: 'Moes', model: 'HY369RT'}, {vendor: 'SHOJZJ', model: '378RT'}],
692
+ whiteLabel: [{vendor: 'Moes', model: 'HY368'}, {vendor: 'Moes', model: 'HY369RT'}, {vendor: 'SHOJZJ', model: '378RT'},
693
+ {vendor: 'Silvercrest', model: 'TVR01'}],
692
694
  meta: {tuyaThermostatPreset: tuya.thermostatPresets, tuyaThermostatSystemMode: tuya.thermostatSystemModes3},
693
695
  ota: ota.zigbeeOTA,
694
696
  onEvent: tuya.onEventSetLocalTime,
package/devices/xiaomi.js CHANGED
@@ -176,8 +176,12 @@ module.exports = [
176
176
  onEvent: preventReset,
177
177
  meta: {battery: {voltageToPercentage: '3V_2100'}},
178
178
  configure: async (device, coordinatorEndpoint, logger) => {
179
- const endpoint = device.endpoints[1];
180
- await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genPowerCfg']);
179
+ try {
180
+ const endpoint = device.endpoints[1];
181
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genPowerCfg']);
182
+ } catch (error) {
183
+ // fails for some but device works as expected: https://github.com/Koenkk/zigbee2mqtt/issues/9136
184
+ }
181
185
  },
182
186
  },
183
187
  {
@@ -563,7 +567,8 @@ module.exports = [
563
567
  vendor: 'Xiaomi',
564
568
  description: 'Aqara D1 3 gang smart wall switch (no neutral wire)',
565
569
  fromZigbee: [fz.on_off, fz.legacy.QBKG25LM_click, fz.xiaomi_operation_mode_opple, fz.xiaomi_switch_opple_basic],
566
- toZigbee: [tz.on_off, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_switch_power_outage_memory, tz.xiaomi_led_disabled_night],
570
+ toZigbee: [tz.on_off, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_switch_power_outage_memory, tz.xiaomi_led_disabled_night,
571
+ tz.aqara_switch_mode_switch],
567
572
  meta: {multiEndpoint: true},
568
573
  endpoint: (device) => {
569
574
  return {'left': 1, 'center': 2, 'right': 3};
@@ -579,6 +584,9 @@ module.exports = [
579
584
  exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
580
585
  .withDescription('Decoupled mode for right button')
581
586
  .withEndpoint('right'),
587
+ exposes.enum('mode_switch', ea.ALL, ['anti_flicker_mode', 'quick_mode'])
588
+ .withDescription('Anti flicker mode can be used to solve blinking issues of some lights.' +
589
+ 'Quick mode makes the device respond faster.'),
582
590
  e.power_outage_memory(), e.led_disabled_night(), e.temperature().withAccess(ea.STATE),
583
591
  e.action([
584
592
  'left_single', 'left_double', 'left_triple', 'left_hold', 'left_release',
@@ -680,6 +688,37 @@ module.exports = [
680
688
  onEvent: preventReset,
681
689
  ota: ota.zigbeeOTA,
682
690
  },
691
+ {
692
+ zigbeeModel: ['lumi.switch.b2nacn01'],
693
+ model: 'QBKG20LM',
694
+ vendor: 'Xiaomi',
695
+ description: 'Aqara smart wall switch T1 (with neutral, double rocker)',
696
+ fromZigbee: [fz.on_off, fz.xiaomi_power, fz.xiaomi_multistate_action, fz.xiaomi_switch_opple_basic],
697
+ toZigbee: [tz.on_off, tz.xiaomi_power, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_switch_power_outage_memory,
698
+ tz.xiaomi_led_disabled_night],
699
+ meta: {multiEndpoint: true},
700
+ endpoint: (device) => {
701
+ return {'left': 1, 'right': 2};
702
+ },
703
+ exposes: [
704
+ e.switch().withEndpoint('left'), e.switch().withEndpoint('right'),
705
+ e.power().withAccess(ea.STATE_GET), e.energy(), e.voltage().withAccess(ea.STATE),
706
+ e.power_outage_memory(), e.led_disabled_night(), e.temperature().withAccess(ea.STATE),
707
+ e.action([
708
+ 'single_left', 'double_left', 'single_right', 'double_right', 'single_both', 'double_both']),
709
+ exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
710
+ .withDescription('Decoupled mode for left button')
711
+ .withEndpoint('left'),
712
+ exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
713
+ .withDescription('Decoupled mode for right button')
714
+ .withEndpoint('right'),
715
+ ],
716
+ configure: async (device, coordinatorEndpoint, logger) => {
717
+ await device.getEndpoint(1).write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f, disableResponse: true});
718
+ },
719
+ onEvent: preventReset,
720
+ ota: ota.zigbeeOTA,
721
+ },
683
722
  {
684
723
  zigbeeModel: ['lumi.sens', 'lumi.sensor_ht'],
685
724
  model: 'WSDCGQ01LM',
@@ -1422,11 +1461,15 @@ module.exports = [
1422
1461
  model: 'QBKG38LM',
1423
1462
  vendor: 'Xiaomi',
1424
1463
  description: 'Aqara E1 1 gang switch (without neutral)',
1425
- fromZigbee: [fz.on_off, fz.xiaomi_multistate_action],
1426
- toZigbee: [tz.on_off, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_switch_power_outage_memory],
1464
+ fromZigbee: [fz.on_off, fz.xiaomi_multistate_action, fz.xiaomi_switch_opple_basic],
1465
+ toZigbee: [tz.on_off, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_switch_power_outage_memory,
1466
+ tz.aqara_switch_mode_switch],
1427
1467
  exposes: [e.switch(), e.power_outage_memory(), e.action(['single', 'double']),
1428
1468
  exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
1429
- .withDescription('Decoupled mode for button')],
1469
+ .withDescription('Decoupled mode for button'),
1470
+ exposes.enum('mode_switch', ea.ALL, ['anti_flicker_mode', 'quick_mode'])
1471
+ .withDescription('Anti flicker mode can be used to solve blinking issues of some lights.' +
1472
+ 'Quick mode makes the device respond faster.')],
1430
1473
  onEvent: preventReset,
1431
1474
  configure: async (device, coordinatorEndpoint, logger) => {
1432
1475
  const endpoint1 = device.getEndpoint(1);
@@ -1441,7 +1484,8 @@ module.exports = [
1441
1484
  vendor: 'Xiaomi',
1442
1485
  description: 'Aqara E1 2 gang switch (without neutral)',
1443
1486
  fromZigbee: [fz.on_off, fz.xiaomi_multistate_action, fz.xiaomi_switch_opple_basic],
1444
- toZigbee: [tz.on_off, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_switch_power_outage_memory],
1487
+ toZigbee: [tz.on_off, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_switch_power_outage_memory,
1488
+ tz.aqara_switch_mode_switch],
1445
1489
  meta: {multiEndpoint: true},
1446
1490
  endpoint: (device) => {
1447
1491
  return {'left': 1, 'right': 2};
@@ -1454,6 +1498,9 @@ module.exports = [
1454
1498
  exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
1455
1499
  .withDescription('Decoupled mode for right button')
1456
1500
  .withEndpoint('right'),
1501
+ exposes.enum('mode_switch', ea.ALL, ['anti_flicker_mode', 'quick_mode'])
1502
+ .withDescription('Anti flicker mode can be used to solve blinking issues of some lights.' +
1503
+ 'Quick mode makes the device respond faster.'),
1457
1504
  e.action(['single_left', 'double_left', 'single_right', 'double_right', 'single_both', 'double_both']),
1458
1505
  e.power_outage_memory(),
1459
1506
  ],
package/lib/constants.js CHANGED
@@ -85,7 +85,7 @@ const temperatureDisplayMode = {
85
85
 
86
86
  const danfossWindowOpen = {
87
87
  0: 'quarantine',
88
- 1: 'closing',
88
+ 1: 'closed',
89
89
  2: 'hold',
90
90
  3: 'open',
91
91
  4: 'external_open',
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.278",
3
+ "version": "14.0.282",
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.278",
3
+ "version": "14.0.282",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [