zigbee-herdsman-converters 14.0.398 → 14.0.402

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.
@@ -719,6 +719,7 @@ const converters = {
719
719
  {key: 'rmsVoltage', name: 'voltage', factor: 'acVoltage'},
720
720
  {key: 'rmsVoltagePhB', name: 'voltage_phase_b', factor: 'acVoltage'},
721
721
  {key: 'rmsVoltagePhC', name: 'voltage_phase_c', factor: 'acVoltage'},
722
+ {key: 'acFrequency', name: 'ac_frequency', factor: 'acFrequency'},
722
723
  ];
723
724
 
724
725
  const payload = {};
@@ -730,6 +731,9 @@ const converters = {
730
731
  payload[property] = calibrateAndPrecisionRoundOptions(value, options, entry.name);
731
732
  }
732
733
  }
734
+ if (msg.data.hasOwnProperty('powerFactor')) {
735
+ payload.power_factor = precisionRound(msg.data['powerFactor'] / 100, 2);
736
+ }
733
737
  return payload;
734
738
  },
735
739
  },
@@ -4045,7 +4049,8 @@ const converters = {
4045
4049
  exposes.options.precision('humidity'), exposes.options.calibration('humidity'),
4046
4050
  exposes.options.precision('co2'), exposes.options.calibration('co2'),
4047
4051
  exposes.options.precision('voc'), exposes.options.calibration('voc'),
4048
- exposes.options.precision('formaldehyd'), exposes.options.calibration('formaldehyd')],
4052
+ exposes.options.precision('formaldehyd'), exposes.options.calibration('formaldehyd'),
4053
+ exposes.options.precision('pm25'), exposes.options.calibration('pm25')],
4049
4054
  convert: (model, msg, publish, options, meta) => {
4050
4055
  const dpValue = tuya.firstDpValue(msg, meta, 'tuya_air_quality');
4051
4056
  const dp = dpValue.dp;
@@ -4062,6 +4067,8 @@ const converters = {
4062
4067
  case tuya.dataPoints.tuyaSabFormaldehyd:
4063
4068
  // Not sure which unit this is, supposedly mg/m³, but the value seems way too high.
4064
4069
  return {formaldehyd: calibrateAndPrecisionRoundOptions(value, options, 'formaldehyd')};
4070
+ case tuya.dataPoints.tuyaSahkMP25:
4071
+ return {pm25: calibrateAndPrecisionRoundOptions(value, options, 'pm25')};
4065
4072
  default:
4066
4073
  meta.logger.warn(`zigbee-herdsman-converters:TuyaSmartAirBox: Unrecognized DP #${
4067
4074
  dp} with data ${JSON.stringify(dpValue)}`);
@@ -5250,9 +5257,11 @@ const converters = {
5250
5257
  else if (index === 5) {
5251
5258
  if (['JT-BZ-01AQ/A'].includes(model.model)) payload.power_outage_count = value;
5252
5259
  } else if (index === 100) {
5253
- if (['QBKG19LM', 'QBKG20LM', 'QBKG39LM', 'QBKG41LM', 'QBCZ15LM'].includes(model.model)) {
5260
+ if (['QBKG20LM', 'QBKG39LM', 'QBKG41LM', 'QBCZ15LM'].includes(model.model)) {
5254
5261
  const mapping = model.model === 'QBCZ15LM' ? 'relay' : 'left';
5255
5262
  payload[`state_${mapping}`] = value === 1 ? 'ON' : 'OFF';
5263
+ } else if (['WXKG14LM', 'WXKG16LM', 'WXKG17LM'].includes(model.model)) {
5264
+ payload.click_mode = {1: 'fast', 2: 'multi'}[value];
5256
5265
  } else {
5257
5266
  payload.state = value === 1 ? 'ON' : 'OFF';
5258
5267
  }
@@ -5260,10 +5269,17 @@ const converters = {
5260
5269
  if (['QBKG19LM', 'QBKG20LM', 'QBKG39LM', 'QBKG41LM', 'QBCZ15LM'].includes(model.model)) {
5261
5270
  const mapping = model.model === 'QBCZ15LM' ? 'usb' : 'right';
5262
5271
  payload[`state_${mapping}`] = value === 1 ? 'ON' : 'OFF';
5272
+ } else if (['QBKG25LM', 'QBKG34LM'].includes(model.model)) {
5273
+ payload.state_center = value === 1 ? 'ON' : 'OFF';
5263
5274
  } else if (['RTCGQ12LM'].includes(model.model)) {
5264
5275
  payload.illuminance = calibrateAndPrecisionRoundOptions(value, options, 'illuminance');
5265
5276
  }
5266
- } else if (index === 149) {
5277
+ } else if (index ===102 ) {
5278
+ if (['QBKG25LM', 'QBKG34LM'].includes(model.model)) {
5279
+ payload.state_right = value === 1 ? 'ON' : 'OFF';
5280
+ }
5281
+ } else if (index === 105) payload.motion_sensitivity = {1: 'low', 2: 'medium', 3: 'high'}[value]; // RTCGQ13LM
5282
+ else if (index === 149) {
5267
5283
  payload.energy = precisionRound(value, 2); // 0x95
5268
5284
  // Consumption is deprecated
5269
5285
  payload.consumption = payload.energy;
@@ -7228,6 +7244,26 @@ const converters = {
7228
7244
  return {occupancy: (zoneStatus & 1) > 0, tamper: (zoneStatus & 4) > 0};
7229
7245
  },
7230
7246
  },
7247
+ ZM35HQ_attr: {
7248
+ cluster: 'ssIasZone',
7249
+ type: ['attributeReport', 'readResponse'],
7250
+ convert: (model, msg, publish, options, meta) => {
7251
+ let result = {};
7252
+ const data = msg.data;
7253
+ if (data && data.hasOwnProperty('zoneStatus')) {
7254
+ result = converters.ias_occupancy_alarm_1_report.convert(model, msg, publish, options, meta);
7255
+ }
7256
+ if (data && data.hasOwnProperty('currentZoneSensitivityLevel')) {
7257
+ const senslookup = {'0': 'low', '1': 'medium', '2': 'high'};
7258
+ result.sensitivity = senslookup[data.currentZoneSensitivityLevel];
7259
+ }
7260
+ if (data && data.hasOwnProperty('61441')) {
7261
+ const keeptimelookup = {'0': 30, '1': 60, '2': 120};
7262
+ result.keep_time = keeptimelookup[data['61441']];
7263
+ }
7264
+ return result;
7265
+ },
7266
+ },
7231
7267
  tuya_gas: {
7232
7268
  cluster: 'manuSpecificTuya',
7233
7269
  type: ['commandDataResponse'],
@@ -1409,6 +1409,42 @@ const converters = {
1409
1409
  await entity.read('seMetering', ['instantaneousDemand']);
1410
1410
  },
1411
1411
  },
1412
+ currentsummdelivered: {
1413
+ key: ['energy'],
1414
+ convertGet: async (entity, key, meta) => {
1415
+ await entity.read('seMetering', ['currentSummDelivered']);
1416
+ },
1417
+ },
1418
+ frequency: {
1419
+ key: ['ac_frequency'],
1420
+ convertGet: async (entity, key, meta) => {
1421
+ await entity.read('haElectricalMeasurement', ['acFrequency']);
1422
+ },
1423
+ },
1424
+ powerfactor: {
1425
+ key: ['power_factor'],
1426
+ convertGet: async (entity, key, meta) => {
1427
+ await entity.read('haElectricalMeasurement', ['powerFactor']);
1428
+ },
1429
+ },
1430
+ acvoltage: {
1431
+ key: ['voltage'],
1432
+ convertGet: async (entity, key, meta) => {
1433
+ await entity.read('haElectricalMeasurement', ['rmsVoltage']);
1434
+ },
1435
+ },
1436
+ accurrent: {
1437
+ key: ['current'],
1438
+ convertGet: async (entity, key, meta) => {
1439
+ await entity.read('haElectricalMeasurement', ['rmsCurrent']);
1440
+ },
1441
+ },
1442
+ temperature: {
1443
+ key: ['temperature'],
1444
+ convertGet: async (entity, key, meta) => {
1445
+ await entity.read('msTemperatureMeasurement', ['measuredValue']);
1446
+ },
1447
+ },
1412
1448
  // #endregion
1413
1449
 
1414
1450
  // #region Non-generic converters
@@ -5961,6 +5997,29 @@ const converters = {
5961
5997
  }
5962
5998
  },
5963
5999
  },
6000
+ ZM35HQ_attr: {
6001
+ key: [
6002
+ 'sensitivity', 'keep_time',
6003
+ ],
6004
+ convertSet: async (entity, key, value, meta) => {
6005
+ switch (key) {
6006
+ case 'sensitivity':
6007
+ await entity.write('ssIasZone', {currentZoneSensitivityLevel: {'low': 0, 'medium': 1, 'high': 2}[value]},
6008
+ {sendWhen: 'active'});
6009
+ break;
6010
+ case 'keep_time':
6011
+ await entity.write('ssIasZone', {61441: {value: {'30': 0, '60': 1, '120': 2}[value], type: 0x20}}, {sendWhen: 'active'});
6012
+ break;
6013
+ default: // Unknown key
6014
+ throw new Error(`Unhandled key ${key}`);
6015
+ }
6016
+ },
6017
+ convertGet: async (entity, key, meta) => {
6018
+ // Apparently, reading values may interfere with a commandStatusChangeNotification for changed occupancy.
6019
+ // Therefore, read "zoneStatus" as well.
6020
+ await entity.read('ssIasZone', ['currentZoneSensitivityLevel', 61441, 'zoneStatus'], {sendWhen: 'active'});
6021
+ },
6022
+ },
5964
6023
  TS0210_sensitivity: {
5965
6024
  key: ['sensitivity'],
5966
6025
  convertSet: async (entity, key, value, meta) => {
package/devices/edp.js CHANGED
@@ -16,8 +16,10 @@ module.exports = [
16
16
  configure: async (device, coordinatorEndpoint, logger) => {
17
17
  const endpoint = device.getEndpoint(85);
18
18
  await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'seMetering']);
19
+ // await reporting.readMeteringMultiplierDivisor(endpoint);
20
+ // Fix for UNSUPPORTED_ATTRIBUTE
21
+ endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 1000, multiplier: 1});
19
22
  await reporting.onOff(endpoint);
20
- await reporting.readMeteringMultiplierDivisor(endpoint);
21
23
  await reporting.instantaneousDemand(endpoint);
22
24
  },
23
25
  exposes: [e.switch(), e.power(), e.energy()],
package/devices/ikea.js CHANGED
@@ -746,10 +746,10 @@ module.exports = [
746
746
  extend: tradfriExtend.light_onoff_brightness_colortemp_color(),
747
747
  },
748
748
  {
749
- zigbeeModel: ['TRADFRIbulbE14WWclear250lm'],
749
+ zigbeeModel: ['TRADFRIbulbE14WWclear250lm', 'TRADFRIbulbE12WWclear250lm'],
750
750
  model: 'LED1935C3',
751
751
  vendor: 'IKEA',
752
- description: 'TRADFRI LED bulb E14 WW clear 250 lumen, dimmable',
752
+ description: 'TRADFRI LED bulb E12/E14 WW clear 250 lumen, dimmable',
753
753
  extend: tradfriExtend.light_onoff_brightness(),
754
754
  },
755
755
  {
@@ -15,6 +15,16 @@ const readInitialBatteryState = async (type, data, device) => {
15
15
  }
16
16
  };
17
17
 
18
+ const fzLocal = {
19
+ command_off: {
20
+ cluster: 'genOnOff',
21
+ type: 'commandOff',
22
+ convert: (model, msg, publish, options, meta) => {
23
+ return {action: 'off'};
24
+ },
25
+ },
26
+ };
27
+
18
28
  module.exports = [
19
29
  {
20
30
  zigbeeModel: [' Contactor\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'+
@@ -107,11 +117,12 @@ module.exports = [
107
117
  vendor: 'Legrand',
108
118
  // led blink RED when battery is low
109
119
  description: 'Wireless remote switch',
110
- fromZigbee: [fz.identify, fz.command_on, fz.command_off, fz.command_toggle, fz.legacy.cmd_move, fz.legacy.cmd_stop, fz.battery],
120
+ fromZigbee: [fz.identify, fz.command_on, fzLocal.command_off, fz.command_toggle, fz.legacy.cmd_move, fz.legacy.cmd_stop,
121
+ fz.battery],
111
122
  exposes: [e.battery(), e.action(['identify', 'on', 'off', 'toggle', 'brightness_move_up',
112
123
  'brightness_move_down', 'brightness_stop'])],
113
124
  toZigbee: [],
114
- meta: {handleDuplicateTransaction: true, battery: {voltageToPercentage: '3V_2500'}},
125
+ meta: {battery: {voltageToPercentage: '3V_2500'}},
115
126
  configure: async (device, coordinatorEndpoint, logger) => {
116
127
  const endpoint = device.getEndpoint(1);
117
128
  await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'genOnOff', 'genLevelCtrl']);
@@ -32,6 +32,26 @@ module.exports = [
32
32
  exposes.enum('backlight_mode', ea.ALL, ['LOW', 'MEDIUM', 'HIGH']),
33
33
  exposes.numeric('calibration_time', ea.STATE).withUnit('S').withDescription('Calibration time')],
34
34
  },
35
+ {
36
+ fingerprint: [{modelID: 'TS130F', manufacturerName: '_TZ3000_j1xl73iw'}],
37
+ model: 'TS130F_dual',
38
+ vendor: 'Lonsonho',
39
+ description: 'Dual curtain/blind module',
40
+ fromZigbee: [fz.cover_position_tilt, fz.tuya_cover_options],
41
+ toZigbee: [tz.cover_state, tz.cover_position_tilt, tz.tuya_cover_calibration, tz.tuya_cover_reversal],
42
+ meta: {multiEndpoint: true},
43
+ endpoint: (device) => {
44
+ return {'left': 1, 'right': 2};
45
+ },
46
+ exposes: [
47
+ exposes.enum('moving', ea.STATE, ['UP', 'STOP', 'DOWN']),
48
+ exposes.numeric('calibration_time', ea.STATE).withUnit('S').withDescription('Calibration time'),
49
+ e.cover_position().withEndpoint('left'), exposes.binary('calibration', ea.ALL, 'ON', 'OFF')
50
+ .withEndpoint('left'), exposes.binary('motor_reversal', ea.ALL, 'ON', 'OFF').withEndpoint('left'),
51
+ e.cover_position().withEndpoint('right'), exposes.binary('calibration', ea.ALL, 'ON', 'OFF')
52
+ .withEndpoint('right'), exposes.binary('motor_reversal', ea.ALL, 'ON', 'OFF').withEndpoint('right'),
53
+ ],
54
+ },
35
55
  {
36
56
  fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_8vxj8khv'}, {modelID: 'TS0601', manufacturerName: '_TZE200_7tdtqgwv'}],
37
57
  model: 'X711A',
@@ -177,4 +197,28 @@ module.exports = [
177
197
  await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
178
198
  },
179
199
  },
200
+ {
201
+ fingerprint: [{modelID: 'TS110E', manufacturerName: '_TZ3210_zxbtub8r'}],
202
+ model: 'TS110E_1gang',
203
+ vendor: 'Lonsonho',
204
+ description: 'Zigbee smart dimmer module 1 gang with neutral',
205
+ extend: extend.light_onoff_brightness(),
206
+ },
207
+ {
208
+ fingerprint: [{modelID: 'TS110E', manufacturerName: '_TZ3210_wdexaypg'}],
209
+ model: 'TS110E_2gang',
210
+ vendor: 'Lonsonho',
211
+ description: 'Zigbee smart dimmer module 2 gang with neutral',
212
+ extend: extend.light_onoff_brightness({noConfigure: true}),
213
+ meta: {multiEndpoint: true},
214
+ exposes: [e.light_brightness().withEndpoint('l1'), e.light_brightness().withEndpoint('l2')],
215
+ configure: async (device, coordinatorEndpoint, logger) => {
216
+ await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
217
+ await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
218
+ await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
219
+ },
220
+ endpoint: (device) => {
221
+ return {l1: 1, l2: 2};
222
+ },
223
+ },
180
224
  ];
package/devices/namron.js CHANGED
@@ -220,6 +220,13 @@ module.exports = [
220
220
  description: 'LED 5,3W CCT E14',
221
221
  extend: extend.light_onoff_brightness_colortemp(),
222
222
  },
223
+ {
224
+ zigbeeModel: ['3802965'],
225
+ model: '3802965',
226
+ vendor: 'Namron',
227
+ description: 'LED 4,8W DIM GU10',
228
+ extend: extend.light_onoff_brightness(),
229
+ },
223
230
  {
224
231
  zigbeeModel: ['3802966'],
225
232
  model: '3802966',
@@ -40,7 +40,6 @@ module.exports = [
40
40
  description: 'Motion sensor',
41
41
  fromZigbee: [fz.battery, fz.ias_occupancy_alarm_1],
42
42
  toZigbee: [],
43
- meta: {battery: {dontDividePercentage: true}},
44
43
  exposes: [e.occupancy(), e.battery_low(), e.tamper(), e.battery()],
45
44
  configure: async (device, coordinatorEndpoint, logger) => {
46
45
  const endpoint = device.getEndpoint(1);
@@ -36,6 +36,15 @@ module.exports = [
36
36
  description: 'Hue white ambiance bathroom ceiling light Adore with Bluetooth',
37
37
  extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
38
38
  },
39
+ {
40
+ zigbeeModel: ['929003045301_01', '929003045301_02', '929003045301_03'],
41
+ model: '929003045301',
42
+ vendor: 'Philips',
43
+ description: 'Hue White and Color Ambiance GU10 (Centura)',
44
+ meta: {turnsOffAtBrightness1: true},
45
+ extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
46
+ ota: ota.zigbeeOTA,
47
+ },
39
48
  {
40
49
  zigbeeModel: ['929003056901'],
41
50
  model: '929003056901',
@@ -186,6 +186,18 @@ module.exports = [
186
186
  await reporting.brightness(endpoint);
187
187
  },
188
188
  },
189
+ {
190
+ zigbeeModel: ['CH2AX/SWITCH/1'],
191
+ model: '41E2PBSWMZ/356PB2MBTZ',
192
+ vendor: 'Schneider Electric',
193
+ description: 'Wiser 40/300-Series module switch 2A',
194
+ extend: extend.switch(),
195
+ configure: async (device, coordinatorEndpoint, logger) => {
196
+ const endpoint = device.getEndpoint(1);
197
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
198
+ await reporting.onOff(endpoint);
199
+ },
200
+ },
189
201
  {
190
202
  zigbeeModel: ['SMARTPLUG/1'],
191
203
  model: 'CCT711119',
@@ -630,4 +642,35 @@ module.exports = [
630
642
  await reporting.currentSummDelivered(endpoint, {min: 60, change: 1});
631
643
  },
632
644
  },
645
+ {
646
+ zigbeeModel: ['NHMOTION/SWITCH/1'],
647
+ model: '545D6306',
648
+ vendor: 'Schneider Electric',
649
+ description: 'LK FUGA Wiser wireless PIR with relay',
650
+ fromZigbee: [fz.on_off, fz.illuminance, fz.occupancy, fz.occupancy_timeout],
651
+ exposes: [e.switch().withEndpoint('l1'), e.occupancy(), e.illuminance_lux(), e.illuminance(),
652
+ exposes.numeric('occupancy_timeout', ea.ALL).withUnit('second').withValueMin(0).withValueMax(3600)
653
+ .withDescription('Time in seconds after which occupancy is cleared after detecting it')],
654
+ toZigbee: [tz.on_off, tz.occupancy_timeout],
655
+ endpoint: (device) => {
656
+ return {'default': 37, 'l1': 1, 'l2': 37};
657
+ },
658
+ meta: {multiEndpoint: true},
659
+ configure: async (device, coordinatorEndpoint, logger) => {
660
+ const endpoint1 = device.getEndpoint(1);
661
+ const binds1 = ['genBasic', 'genIdentify', 'genOnOff'];
662
+ await reporting.bind(endpoint1, coordinatorEndpoint, binds1);
663
+ await reporting.onOff(endpoint1);
664
+ // read switch state
665
+ await endpoint1.read('genOnOff', ['onOff']);
666
+
667
+ const endpoint37 = device.getEndpoint(37);
668
+ const binds37 = ['msIlluminanceMeasurement', 'msOccupancySensing'];
669
+ await reporting.bind(endpoint37, coordinatorEndpoint, binds37);
670
+ await reporting.occupancy(endpoint37);
671
+ await reporting.illuminance(endpoint37);
672
+ // read occupancy_timeout
673
+ await endpoint37.read('msOccupancySensing', ['pirOToUDelay']);
674
+ },
675
+ },
633
676
  ];
@@ -183,7 +183,7 @@ module.exports = [
183
183
  toZigbee: [],
184
184
  configure: async (device, coordinatorEndpoint, logger) => {
185
185
  const endpoint = device.getEndpoint(1);
186
- await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
186
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genPowerCfg']);
187
187
  await reporting.batteryVoltage(endpoint);
188
188
  },
189
189
  exposes: [e.battery(), e.battery_voltage(), e.action(['single', 'double', 'long'])],
@@ -230,11 +230,14 @@ module.exports = [
230
230
  toZigbee: [],
231
231
  exposes: [e.action(['1_single', '1_double', '1_long', '2_single', '2_double', '2_long',
232
232
  '3_single', '3_double', '3_long', '4_single', '4_double', '4_long']), e.battery(), e.battery_voltage()],
233
- meta: {battery: {voltageToPercentage: '3V_2100'}},
233
+ meta: {battery: {voltageToPercentage: '3V_2100'}, multiEndpoint: true},
234
234
  configure: async (device, coordinatorEndpoint, logger) => {
235
235
  const endpoint = device.getEndpoint(1);
236
- await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
236
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genPowerCfg']);
237
237
  await reporting.batteryVoltage(endpoint, {min: 30, max: 21600, change: 1});
238
+ await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
239
+ await reporting.bind(device.getEndpoint(3), coordinatorEndpoint, ['genOnOff']);
240
+ await reporting.bind(device.getEndpoint(4), coordinatorEndpoint, ['genOnOff']);
238
241
  },
239
242
  },
240
243
  {
@@ -247,7 +250,7 @@ module.exports = [
247
250
  toZigbee: [],
248
251
  configure: async (device, coordinatorEndpoint, logger) => {
249
252
  const endpoint = device.getEndpoint(1);
250
- await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
253
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genPowerCfg']);
251
254
  await reporting.batteryVoltage(endpoint);
252
255
  },
253
256
  exposes: [e.battery(), e.battery_voltage(), e.action(['single', 'double', 'long'])],
@@ -260,12 +263,14 @@ module.exports = [
260
263
  fromZigbee: [fz.sihas_action, fz.battery],
261
264
  toZigbee: [],
262
265
  exposes: [e.action(['1_single', '1_double', '1_long', '2_single', '2_double', '2_long']), e.battery(), e.battery_voltage()],
263
- meta: {battery: {voltageToPercentage: '3V_2100'}},
266
+ meta: {battery: {voltageToPercentage: '3V_2100'}, multiEndpoint: true},
264
267
  configure: async (device, coordinatorEndpoint, logger) => {
265
268
  const endpoint = device.getEndpoint(1);
266
- await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
269
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genPowerCfg']);
267
270
  await reporting.batteryVoltage(endpoint, {min: 30, max: 21600, change: 1});
271
+ await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
268
272
  },
273
+
269
274
  },
270
275
  {
271
276
  zigbeeModel: ['SBM300ZB3'],
@@ -276,11 +281,13 @@ module.exports = [
276
281
  toZigbee: [],
277
282
  exposes: [e.action(['1_single', '1_double', '1_long', '2_single', '2_double', '2_long',
278
283
  '3_single', '3_double', '3_long']), e.battery(), e.battery_voltage()],
279
- meta: {battery: {voltageToPercentage: '3V_2100'}},
284
+ meta: {battery: {voltageToPercentage: '3V_2100'}, multiEndpoint: true},
280
285
  configure: async (device, coordinatorEndpoint, logger) => {
281
286
  const endpoint = device.getEndpoint(1);
282
- await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
287
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genPowerCfg']);
283
288
  await reporting.batteryVoltage(endpoint, {min: 30, max: 21600, change: 1});
289
+ await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
290
+ await reporting.bind(device.getEndpoint(3), coordinatorEndpoint, ['genOnOff']);
284
291
  },
285
292
  },
286
293
  {
@@ -300,4 +307,38 @@ module.exports = [
300
307
  await reporting.currentSummDelivered(endpoint, {min: 1, max: 600, change: 5});
301
308
  },
302
309
  },
310
+ {
311
+ zigbeeModel: ['PMM-300Z2'],
312
+ model: 'PMM-300Z2',
313
+ vendor: 'ShinaSystem',
314
+ description: 'SiHAS energy monitor',
315
+ fromZigbee: [fz.electrical_measurement, fz.metering, fz.temperature],
316
+ toZigbee: [tz.metering_power, tz.currentsummdelivered, tz.frequency, tz.powerfactor, tz.acvoltage, tz.accurrent, tz.temperature],
317
+ exposes: [e.power().withAccess(ea.STATE_GET), e.energy().withAccess(ea.STATE_GET),
318
+ e.current().withAccess(ea.STATE_GET), e.voltage().withAccess(ea.STATE_GET),
319
+ e.temperature().withAccess(ea.STATE_GET).withDescription('temperature of device internal mcu'),
320
+ exposes.numeric('power_factor', ea.STATE_GET).withDescription('Measured electrical power factor'),
321
+ exposes.numeric('ac_frequency', ea.STATE_GET).withUnit('Hz').withDescription('Measured electrical ac frequency')],
322
+ configure: async (device, coordinatorEndpoint, logger) => {
323
+ const endpoint = device.getEndpoint(1);
324
+ await reporting.bind(endpoint, coordinatorEndpoint, ['haElectricalMeasurement', 'seMetering', 'msTemperatureMeasurement']);
325
+ await endpoint.read('haElectricalMeasurement', ['acVoltageMultiplier', 'acVoltageDivisor', 'acCurrentMultiplier',
326
+ 'acCurrentDivisor']);
327
+ await endpoint.read('seMetering', ['multiplier', 'divisor']);
328
+ // await reporting.activePower(endpoint, {min: 1, max: 600, change: 5}); // no need, duplicate for power value.
329
+ await reporting.instantaneousDemand(endpoint, {min: 1, max: 600, change: 5});
330
+ await reporting.powerFactor(endpoint, {min: 10, max: 600, change: 1});
331
+ await reporting.rmsVoltage(endpoint, {min: 5, max: 600, change: 1});
332
+ await reporting.rmsCurrent(endpoint, {min: 5, max: 600, change: 1});
333
+ await reporting.currentSummDelivered(endpoint, {min: 1, max: 600, change: 5});
334
+ await reporting.temperature(endpoint, {min: 20, max: 300, change: 10});
335
+ endpoint.saveClusterAttributeKeyValue('haElectricalMeasurement', {acFrequencyMultiplier: 1, acFrequencyDivisor: 10});
336
+ await endpoint.configureReporting('haElectricalMeasurement', [{
337
+ attribute: 'acFrequency',
338
+ minimumReportInterval: 10,
339
+ maximumReportInterval: 600,
340
+ reportableChange: 3,
341
+ }]);
342
+ },
343
+ },
303
344
  ];
@@ -260,7 +260,8 @@ module.exports = [
260
260
  exposes: [e.action(['press_on', 'press_off', 'hold_on', 'hold_off', 'release'])],
261
261
  },
262
262
  {
263
- fingerprint: [{modelID: 'GreenPower_2', ieeeAddr: /^0x000000005d5.....$/}],
263
+ fingerprint: [{modelID: 'GreenPower_2', ieeeAddr: /^0x000000005d5.....$/},
264
+ {modelID: 'GreenPower_2', ieeeAddr: /^0x0000000057e.....$/}],
264
265
  model: 'SR-ZGP2801K4-DIM',
265
266
  vendor: 'Sunricher',
266
267
  description: 'Pushbutton transmitter module',
package/devices/tuya.js CHANGED
@@ -89,6 +89,15 @@ module.exports = [
89
89
  toZigbee: [],
90
90
  exposes: [e.temperature(), e.humidity(), e.co2(), e.voc(), e.formaldehyd()],
91
91
  },
92
+ {
93
+ fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_dwcarsat'}],
94
+ model: 'TS0601_smart_air_house_keeper',
95
+ vendor: 'TuYa',
96
+ description: 'Smart air house keeper',
97
+ fromZigbee: [fz.tuya_air_quality],
98
+ toZigbee: [],
99
+ exposes: [e.temperature(), e.humidity(), e.co2(), e.voc(), e.formaldehyd(), e.pm25()],
100
+ },
92
101
  {
93
102
  fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_ggev5fsl'}],
94
103
  model: 'TS0601_gas_sensor',
@@ -201,6 +210,13 @@ module.exports = [
201
210
  toZigbee: utils.replaceInArray(extend.light_onoff_brightness_color().toZigbee, [tz.light_color], [tzLocal.TS0504B_color]),
202
211
  meta: {applyRedFix: true},
203
212
  },
213
+ {
214
+ fingerprint: [{modelID: 'TS0501A', manufacturerName: '_TZ3000_yeg1e5eh'}],
215
+ model: 'TS0501A',
216
+ description: 'Zigbee light',
217
+ vendor: 'TuYa',
218
+ extend: extend.light_onoff_brightness(),
219
+ },
204
220
  {
205
221
  fingerprint: [{modelID: 'TS0501B', manufacturerName: '_TZ3000_4whigl8i'},
206
222
  {modelID: 'TS0501B', manufacturerName: '_TZ3210_4whigl8i'},
@@ -223,9 +239,7 @@ module.exports = [
223
239
  {modelID: 'TS0202', manufacturerName: '_TZ3000_mmtwjmaq'},
224
240
  {modelID: 'TS0202', manufacturerName: '_TZ3000_kmh5qpmb'},
225
241
  {modelID: 'TS0202', manufacturerName: '_TYZB01_zwvaj5wy'},
226
- {modelID: 'TS0202', manufacturerName: '_TZ3000_mcxw5ehu'},
227
242
  {modelID: 'TS0202', manufacturerName: '_TZ3000_bsvqrxru'},
228
- {modelID: 'TS0202', manufacturerName: '_TZ3000_msl6wxk9'},
229
243
  {modelID: 'TS0202', manufacturerName: '_TYZB01_tv3wxhcz'},
230
244
  {modelID: 'TS0202', manufacturerName: '_TYZB01_hqbdru35'},
231
245
  {modelID: 'TS0202', manufacturerName: '_TZ3000_tiwq83wk'},
@@ -238,6 +252,19 @@ module.exports = [
238
252
  toZigbee: [],
239
253
  exposes: [e.occupancy(), e.battery_low(), e.tamper(), e.battery()],
240
254
  },
255
+ {
256
+ fingerprint: [{modelID: 'TS0202', manufacturerName: '_TZ3000_mcxw5ehu'},
257
+ {modelID: 'TS0202', manufacturerName: '_TZ3000_msl6wxk9'}],
258
+ model: 'ZM-35H-Q',
259
+ vendor: 'TuYa',
260
+ description: 'Motion Sensor',
261
+ fromZigbee: [fz.ias_occupancy_alarm_1, fz.battery, fz.ignore_basic_report, fz.ZM35HQ_attr],
262
+ toZigbee: [tz.ZM35HQ_attr],
263
+ exposes: [e.occupancy(), e.battery_low(), e.tamper(), e.battery(),
264
+ exposes.enum('sensitivity', ea.ALL, ['low', 'medium', 'high']).withDescription('PIR sensor sensitivity'),
265
+ exposes.enum('keep_time', ea.ALL, ['30', '60', '120']).withDescription('PIR keep time in seconds'),
266
+ ],
267
+ },
241
268
  {
242
269
  fingerprint: [{modelID: 'TS0207', manufacturerName: '_TZ3000_m0vaazab'},
243
270
  {modelID: 'TS0207', manufacturerName: '_TZ3000_ufttklsz'},
@@ -319,8 +346,7 @@ module.exports = [
319
346
  ],
320
347
  },
321
348
  {
322
- fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_oiymh3qu'},
323
- {modelID: 'TS011F', manufacturerName: '_TZ3000_o1jzcxou'}],
349
+ fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_oiymh3qu'}],
324
350
  model: 'TS011F_socket_module',
325
351
  vendor: 'TuYa',
326
352
  description: 'Socket module',
@@ -329,12 +355,15 @@ module.exports = [
329
355
  },
330
356
  {
331
357
  fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_wxtp7c5y'},
332
- {modelID: 'TS011F', manufacturerName: '_TYZB01_mtunwanm'}],
358
+ {modelID: 'TS011F', manufacturerName: '_TYZB01_mtunwanm'},
359
+ {modelID: 'TS011F', manufacturerName: '_TZ3000_o1jzcxou'}],
333
360
  model: 'TS011F_wall_outlet',
334
361
  vendor: 'TuYa',
335
362
  description: 'In-wall outlet',
336
363
  extend: extend.switch(),
337
- whiteLabel: [{vendor: 'Teekar', model: 'SWP86-01OG'}, {vendor: 'ClickSmart+', model: 'CMA30035'}],
364
+ whiteLabel: [{vendor: 'Teekar', model: 'SWP86-01OG'},
365
+ {vendor: 'ClickSmart+', model: 'CMA30035'},
366
+ {vendor: 'BSEED', model: 'Zigbee Socket'}],
338
367
  },
339
368
  {
340
369
  fingerprint: [{modelID: 'isltm67\u0000', manufacturerName: '_TYST11_pisltm67'}],
@@ -848,6 +877,7 @@ module.exports = [
848
877
  {modelID: 'TS0601', manufacturerName: '_TZE200_fzo2pocs'},
849
878
  {modelID: 'TS0601', manufacturerName: '_TZE200_5sbebbzs'},
850
879
  {modelID: 'TS0601', manufacturerName: '_TZE200_zuz7f94z'},
880
+ {modelID: 'TS0601', manufacturerName: '_TZE200_zyrdrmno'},
851
881
  ],
852
882
  model: 'TS0601_cover',
853
883
  vendor: 'TuYa',
@@ -867,6 +897,7 @@ module.exports = [
867
897
  {vendor: 'Zemismart', model: 'M2805EGBZTN', description: 'Tubular motor'},
868
898
  {vendor: 'Zemismart', model: 'BCM500DS-TYZ', description: 'Curtain motor'},
869
899
  {vendor: 'A-OK', model: 'AM25', description: 'Tubular motor'},
900
+ {vendor: 'Alutech', model: 'AM/R-Sm', description: 'Tubular motor'},
870
901
  ],
871
902
  fromZigbee: [fz.tuya_cover, fz.ignore_basic_report],
872
903
  toZigbee: [tz.tuya_cover_control, tz.tuya_cover_options],
@@ -1434,7 +1465,8 @@ module.exports = [
1434
1465
  {
1435
1466
  fingerprint: [{modelID: 'TS0014', manufacturerName: '_TZ3000_jr2atpww'}, {modelID: 'TS0014', manufacturerName: '_TYZB01_dvakyzhd'},
1436
1467
  {modelID: 'TS0014', manufacturerName: '_TZ3210_w3hl6rao'}, {modelID: 'TS0014', manufacturerName: '_TYZB01_bagt1e4o'},
1437
- {modelID: 'TS0014', manufacturerName: '_TZ3000_r0pmi2p3'}, {modelID: 'TS0014', manufacturerName: '_TZ3000_fxjdcikv'}],
1468
+ {modelID: 'TS0014', manufacturerName: '_TZ3000_r0pmi2p3'}, {modelID: 'TS0014', manufacturerName: '_TZ3000_fxjdcikv'},
1469
+ {modelID: 'TS0014', manufacturerName: '_TZ3000_q6vxaod1'}],
1438
1470
  model: 'TS0014',
1439
1471
  vendor: 'TuYa',
1440
1472
  description: 'Smart light switch - 4 gang without neutral wire',
@@ -1580,6 +1612,7 @@ module.exports = [
1580
1612
  vendor: 'TuYa',
1581
1613
  description: 'Multiprise with 4 AC outlets and 2 USB super charging ports (16A)',
1582
1614
  extend: extend.switch(),
1615
+ fromZigbee: [fz.on_off_skip_duplicate_transaction],
1583
1616
  exposes: [e.switch().withEndpoint('l1'), e.switch().withEndpoint('l2'), e.switch().withEndpoint('l3'),
1584
1617
  e.switch().withEndpoint('l4')],
1585
1618
  whiteLabel: [{vendor: 'LEELKI', model: 'WP33-EU'}],
package/devices/xiaomi.js CHANGED
@@ -736,9 +736,6 @@ module.exports = [
736
736
  exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
737
737
  .withDescription('Decoupled mode for left button'),
738
738
  ],
739
- configure: async (device, coordinatorEndpoint, logger) => {
740
- await device.getEndpoint(1).write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f, disableResponse: true});
741
- },
742
739
  onEvent: preventReset,
743
740
  ota: ota.zigbeeOTA,
744
741
  },
@@ -767,9 +764,6 @@ module.exports = [
767
764
  .withDescription('Decoupled mode for right button')
768
765
  .withEndpoint('right'),
769
766
  ],
770
- configure: async (device, coordinatorEndpoint, logger) => {
771
- await device.getEndpoint(1).write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f, disableResponse: true});
772
- },
773
767
  onEvent: preventReset,
774
768
  ota: ota.zigbeeOTA,
775
769
  },
@@ -804,10 +798,8 @@ module.exports = [
804
798
  .withDescription('Decoupled mode for right button')
805
799
  .withEndpoint('right'),
806
800
  ],
807
- configure: async (device, coordinatorEndpoint, logger) => {
808
- await device.getEndpoint(1).write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f, disableResponse: true});
809
- },
810
801
  onEvent: preventReset,
802
+ ota: ota.zigbeeOTA,
811
803
  },
812
804
  {
813
805
  zigbeeModel: ['lumi.sens', 'lumi.sensor_ht'],
@@ -997,7 +989,7 @@ module.exports = [
997
989
  e.voltage().withAccess(ea.STATE), e.current(), e.consumer_connected(), e.led_disabled_night(),
998
990
  e.power_outage_memory(), exposes.binary('auto_off', ea.STATE_SET, true, false)
999
991
  .withDescription('Turn the device automatically off when attached device consumes less than 2W for 20 minutes'),
1000
- exposes.numeric('overload_protection', exposes.access.ALL).withValueMin(100).withValueMax(2200).withUnit('W')
992
+ exposes.numeric('overload_protection', exposes.access.ALL).withValueMin(100).withValueMax(2300).withUnit('W')
1001
993
  .withDescription('Maximum allowed load, turns off if exceeded')],
1002
994
  ota: ota.zigbeeOTA,
1003
995
  },
@@ -1691,7 +1683,7 @@ module.exports = [
1691
1683
  zigbeeModel: ['lumi.plug.macn01'],
1692
1684
  model: 'ZNCZ15LM',
1693
1685
  vendor: 'Xiaomi',
1694
- description: 'Aqara T1 power plug ZigBee',
1686
+ description: 'Aqara smart plug T1 (china standard)',
1695
1687
  fromZigbee: [fz.on_off, fz.xiaomi_power, fz.aqara_opple],
1696
1688
  toZigbee: [tz.on_off, tz.xiaomi_switch_power_outage_memory, tz.xiaomi_led_disabled_night,
1697
1689
  tz.xiaomi_overload_protection, tz.xiaomi_socket_button_lock],
@@ -1700,9 +1692,6 @@ module.exports = [
1700
1692
  e.power_outage_memory(), e.led_disabled_night(), e.button_lock(),
1701
1693
  exposes.numeric('overload_protection', exposes.access.ALL).withValueMin(100).withValueMax(2500).withUnit('W')
1702
1694
  .withDescription('Maximum allowed load, turns off if exceeded')],
1703
- configure: async (device, coordinatorEndpoint, logger) => {
1704
- await device.getEndpoint(1).write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f, disableResponse: true});
1705
- },
1706
1695
  ota: ota.zigbeeOTA,
1707
1696
  },
1708
1697
  {
@@ -1755,7 +1744,7 @@ module.exports = [
1755
1744
  zigbeeModel: ['lumi.plug.sacn03'],
1756
1745
  model: 'QBCZ15LM',
1757
1746
  vendor: 'Xiaomi',
1758
- description: 'Aqara smart wall outlet H1 usb',
1747
+ description: 'Aqara smart wall outlet H1 (USB)',
1759
1748
  fromZigbee: [fz.on_off, fz.xiaomi_power, fz.aqara_opple],
1760
1749
  toZigbee: [tz.on_off, tz.xiaomi_switch_power_outage_memory, tz.xiaomi_led_disabled_night,
1761
1750
  tz.xiaomi_button_switch_mode, tz.xiaomi_overload_protection, tz.xiaomi_socket_button_lock],
@@ -1771,9 +1760,6 @@ module.exports = [
1771
1760
  .withDescription('Control both relay and usb or only the relay with the physical switch button'),
1772
1761
  exposes.numeric('overload_protection', exposes.access.ALL).withValueMin(100).withValueMax(2500).withUnit('W')
1773
1762
  .withDescription('Maximum allowed load, turns off if exceeded')],
1774
- configure: async (device, coordinatorEndpoint, logger) => {
1775
- await device.getEndpoint(1).write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f, disableResponse: true});
1776
- },
1777
1763
  ota: ota.zigbeeOTA,
1778
1764
  },
1779
1765
  {
@@ -1805,9 +1791,6 @@ module.exports = [
1805
1791
  e.current(), e.power_outage_memory(), e.led_disabled_night(), e.button_lock(),
1806
1792
  exposes.numeric('overload_protection', exposes.access.ALL).withValueMin(100).withValueMax(2500).withUnit('W')
1807
1793
  .withDescription('Maximum allowed load, turns off if exceeded')],
1808
- configure: async (device, coordinatorEndpoint, logger) => {
1809
- await device.getEndpoint(1).write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f, disableResponse: true});
1810
- },
1811
1794
  ota: ota.zigbeeOTA,
1812
1795
  },
1813
1796
  {
@@ -1873,7 +1856,7 @@ module.exports = [
1873
1856
  model: 'WXKG14LM',
1874
1857
  vendor: 'Xiaomi',
1875
1858
  description: 'Aqara wireless remote switch H1 (single rocker)',
1876
- fromZigbee: [fz.xiaomi_multistate_action, fz.aqara_opple],
1859
+ fromZigbee: [fz.xiaomi_multistate_action, fz.aqara_opple, fz.command_toggle],
1877
1860
  toZigbee: [tz.xiaomi_switch_click_mode, tz.aqara_opple_operation_mode],
1878
1861
  exposes: [e.battery(), e.battery_voltage(), e.action(['single', 'double', 'triple', 'hold']),
1879
1862
  exposes.enum('click_mode', ea.ALL, ['fast', 'multi'])
package/lib/tuya.js CHANGED
@@ -418,6 +418,9 @@ const dataPoints = {
418
418
  tuyaSabHumidity: 19,
419
419
  tuyaSabVOC: 21,
420
420
  tuyaSabFormaldehyd: 22,
421
+ // tuya Smart Air House Keeper, Multifunctionale air quality detector.
422
+ // CO2, Temp, Humidity, VOC and Formaldehyd same as Smart Air Box
423
+ tuyaSahkMP25: 20,
421
424
  lidlTimer: 5,
422
425
  // Moes MS-105 Dimmer
423
426
  moes105DimmerState1: 1,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.398",
3
+ "version": "14.0.402",
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.398",
3
+ "version": "14.0.402",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [