zigbee-herdsman-converters 14.0.448 → 14.0.451

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.
@@ -4176,15 +4176,24 @@ const converters = {
4176
4176
  return {temperature: calibrateAndPrecisionRoundOptions(value / 10, options, 'temperature')};
4177
4177
  case tuya.dataPoints.tuyaSabHumidity:
4178
4178
  return {humidity: calibrateAndPrecisionRoundOptions(value / 10, options, 'humidity')};
4179
+ // DP22: Smart Air Box: Formaldehyd, Smart Air Housekeeper: co2
4180
+ case tuya.dataPoints.tuyaSabFormaldehyd:
4181
+ if (meta.device.manufacturerName === '_TZE200_dwcarsat') {
4182
+ return {co2: calibrateAndPrecisionRoundOptions(value, options, 'co2')};
4183
+ } else {
4184
+ return {formaldehyd: calibrateAndPrecisionRoundOptions(value, options, 'formaldehyd')};
4185
+ }
4186
+ // DP2: Smart Air Box: co2, Smart Air Housekeeper: MP25
4179
4187
  case tuya.dataPoints.tuyaSabCO2:
4180
- return {co2: calibrateAndPrecisionRoundOptions(value, options, 'co2')};
4188
+ if (meta.device.manufacturerName === '_TZE200_dwcarsat') {
4189
+ return {pm25: calibrateAndPrecisionRoundOptions(value, options, 'pm25')};
4190
+ } else {
4191
+ return {co2: calibrateAndPrecisionRoundOptions(value, options, 'co2')};
4192
+ }
4181
4193
  case tuya.dataPoints.tuyaSabVOC:
4182
4194
  return {voc: calibrateAndPrecisionRoundOptions(value, options, 'voc')};
4183
- case tuya.dataPoints.tuyaSabFormaldehyd:
4184
- // Not sure which unit this is, supposedly mg/m³, but the value seems way too high.
4195
+ case tuya.dataPoints.tuyaSahkCH2O:
4185
4196
  return {formaldehyd: calibrateAndPrecisionRoundOptions(value, options, 'formaldehyd')};
4186
- case tuya.dataPoints.tuyaSahkMP25:
4187
- return {pm25: calibrateAndPrecisionRoundOptions(value, options, 'pm25')};
4188
4197
  default:
4189
4198
  meta.logger.warn(`zigbee-herdsman-converters:TuyaSmartAirBox: Unrecognized DP #${
4190
4199
  dp} with data ${JSON.stringify(dpValue)}`);
@@ -4437,8 +4446,9 @@ const converters = {
4437
4446
  const dpValue = tuya.firstDpValue(msg, meta, 'tuya_thermostat');
4438
4447
  const dp = dpValue.dp;
4439
4448
  const value = tuya.getDataValue(dpValue);
4440
-
4441
4449
  switch (dp) {
4450
+ case tuya.dataPoints.windowOpen:
4451
+ return {window_open: value};
4442
4452
  case tuya.dataPoints.windowDetection:
4443
4453
  return {
4444
4454
  window_detection: value[0] ? 'ON' : 'OFF',
@@ -2116,7 +2116,7 @@ const converters = {
2116
2116
  'WS-EUK01', 'WS-EUK02', 'WS-EUK03', 'WS-EUK04', 'QBKG19LM', 'QBKG20LM', 'QBKG25LM', 'QBKG26LM',
2117
2117
  'QBKG31LM', 'QBKG34LM', 'QBKG38LM', 'QBKG39LM', 'QBKG40LM', 'QBKG41LM', 'ZNDDMK11LM'].includes(meta.mapped.model)) {
2118
2118
  await entity.write('aqaraOpple', {0x0201: {value: value ? 1 : 0, type: 0x10}}, manufacturerOptions.xiaomi);
2119
- } else if (['ZNCZ02LM', 'QBCZ11LM'].includes(meta.mapped.model)) {
2119
+ } else if (['ZNCZ02LM', 'QBCZ11LM', 'LLKZMK11LM'].includes(meta.mapped.model)) {
2120
2120
  const payload = value ?
2121
2121
  [[0xaa, 0x80, 0x05, 0xd1, 0x47, 0x07, 0x01, 0x10, 0x01], [0xaa, 0x80, 0x03, 0xd3, 0x07, 0x08, 0x01]] :
2122
2122
  [[0xaa, 0x80, 0x05, 0xd1, 0x47, 0x09, 0x01, 0x10, 0x00], [0xaa, 0x80, 0x03, 0xd3, 0x07, 0x0a, 0x01]];
@@ -185,4 +185,14 @@ module.exports = [
185
185
  description: 'Zigbee 3.0 LED-controller 1x 8A',
186
186
  extend: extend.light_onoff_brightness(),
187
187
  },
188
+ {
189
+ zigbeeModel: ['ZGRC-TEUR-001'],
190
+ model: '511.544',
191
+ vendor: 'Iluminize',
192
+ description: 'Zigbee 3.0 wall dimmer RGBW 4 zone',
193
+ fromZigbee: [fz.command_move_to_color, fz.command_move_hue, fz.command_on, fz.command_off, fz.command_move],
194
+ toZigbee: [],
195
+ exposes: [e.action(['recall_*', 'on', 'off', 'color_move', 'color_temperature_move',
196
+ 'hue_move', 'brightness_step_down', 'brightness_step_up', 'brightness_move_down', 'brightness_move_up', 'brightness_stop'])],
197
+ },
188
198
  ];
@@ -55,6 +55,22 @@ module.exports = [
55
55
  extend: extend.ledvance.light_onoff_brightness_colortemp_color(),
56
56
  ota: ota.ledvance,
57
57
  },
58
+ {
59
+ zigbeeModel: ['PAR16S RGBW'],
60
+ model: 'AC33906',
61
+ vendor: 'LEDVANCE',
62
+ description: 'SMART+ spot GU10 multicolor RGBW',
63
+ extend: extend.ledvance.light_onoff_brightness_colortemp_color({colorTempRange: [153, 370]}),
64
+ ota: ota.ledvance,
65
+ },
66
+ {
67
+ zigbeeModel: ['PAR16S TW'],
68
+ model: 'AC33905',
69
+ vendor: 'LEDVANCE',
70
+ description: 'SMART+ spot GU10 tunable white',
71
+ extend: extend.ledvance.light_onoff_brightness_colortemp_color({colorTempRange: [153, 370]}),
72
+ ota: ota.ledvance,
73
+ },
58
74
  {
59
75
  zigbeeModel: ['B40 TW Z3'],
60
76
  model: '4058075208414',
@@ -63,6 +79,14 @@ module.exports = [
63
79
  extend: extend.ledvance.light_onoff_brightness_colortemp({colorTempRange: [153, 370]}),
64
80
  ota: ota.ledvance,
65
81
  },
82
+ {
83
+ zigbeeModel: ['P40S TW'],
84
+ model: 'AC33903',
85
+ vendor: 'LEDVANCE',
86
+ description: 'SMART+ classic P 40 E14 tunable white',
87
+ extend: extend.ledvance.light_onoff_brightness_colortemp({colorTempRange: [153, 370]}),
88
+ ota: ota.ledvance,
89
+ },
66
90
  {
67
91
  zigbeeModel: ['FLEX RGBW Z3'],
68
92
  model: '4058075208339',
package/devices/lixee.js CHANGED
@@ -509,6 +509,14 @@ function getCurrentConfig(device, options, logger=console) {
509
509
  break;
510
510
  }
511
511
 
512
+ // Filter exposed attributes with user whitelist
513
+ if (options && options.hasOwnProperty('tic_command_whitelist')) {
514
+ const tic_commands_str = options['tic_command_whitelist'].toUpperCase();
515
+ if (tic_commands_str !== 'ALL') {
516
+ const tic_commands = tic_commands_str.split(',').map((a) => a.trim());
517
+ myExpose = myExpose.filter((a) => tic_commands.includes(a.exposes.name));
518
+ }
519
+ }
512
520
 
513
521
  return myExpose;
514
522
  }
@@ -547,6 +555,7 @@ const definition = {
547
555
  .withDescription(`Overrides the automatic current tarif. This option will exclude unnecesary attributes. Open a issue to support more of them. Default: auto`),
548
556
  exposes.options.precision(`kWh`),
549
557
  exposes.numeric(`measurement_poll_chunk`, ea.SET).withValueMin(1).withDescription(`During the poll, request multiple exposes to the Zlinky at once for reducing Zigbee network overload. Too much request at once could exceed device limit. Requieres Z2M restart. Default: 1`),
558
+ exposes.text(`tic_command_whitelist`, ea.SET).withDescription(`List of TIC commands to be exposed (separated by comma). Reconfigure device after change. Default: all`),
550
559
  ],
551
560
  configure: async (device, coordinatorEndpoint, logger, options) => {
552
561
  const endpoint = device.getEndpoint(1);
@@ -621,7 +630,11 @@ const definition = {
621
630
  // Split array by chunks
622
631
  for (i = 0, j = targ.length; i < j; i += measurement_poll_chunk) {
623
632
  await endpoint
624
- .read(cluster, targ.slice(i, i + measurement_poll_chunk), {manufacturerCode: null});
633
+ .read(cluster, targ.slice(i, i + measurement_poll_chunk), {manufacturerCode: null})
634
+ .catch((e) => {
635
+ // https://github.com/Koenkk/zigbee2mqtt/issues/11674
636
+ console.warn(`Failed to read zigbee attributes: ${e}`);
637
+ });
625
638
  }
626
639
  }
627
640
  }
@@ -2508,7 +2508,7 @@ module.exports = [
2508
2508
  ota: ota.zigbeeOTA,
2509
2509
  },
2510
2510
  {
2511
- zigbeeModel: ['5309331P6', '5309330P6', '929003046301_03'],
2511
+ zigbeeModel: ['5309331P6', '5309330P6', '929003046301_03', '929003046301_02'],
2512
2512
  model: '5309331P6',
2513
2513
  vendor: 'Philips',
2514
2514
  description: 'Hue White ambiance Runner triple spotlight',
@@ -2776,7 +2776,7 @@ module.exports = [
2776
2776
  ota: ota.zigbeeOTA,
2777
2777
  },
2778
2778
  {
2779
- zigbeeModel: ['915005997501'],
2779
+ zigbeeModel: ['915005997501', '915005997401'],
2780
2780
  model: '915005997501',
2781
2781
  vendor: 'Philips',
2782
2782
  description: 'Hue Bluetooth white & color ambiance ceiling lamp Infuse large',
@@ -2810,4 +2810,13 @@ module.exports = [
2810
2810
  extend: hueExtend.light_onoff_brightness(),
2811
2811
  ota: ota.zigbeeOTA,
2812
2812
  },
2813
+ {
2814
+ zigbeeModel: ['LTO005', '929002980901'],
2815
+ model: '929002980901',
2816
+ vendor: 'Philips',
2817
+ description: 'Hue white ambiance G40 E26 filament globe with Bluetooth',
2818
+ meta: {turnsOffAtBrightness1: true},
2819
+ extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [222, 454]}),
2820
+ ota: ota.zigbeeOTA,
2821
+ },
2813
2822
  ];
@@ -20,9 +20,10 @@ module.exports = [
20
20
  model: '3RSS008Z',
21
21
  vendor: 'Third Reality',
22
22
  description: 'RealitySwitch Plus',
23
- fromZigbee: [fz.on_off],
23
+ fromZigbee: [fz.on_off, fz.battery],
24
24
  toZigbee: [tz.on_off, tz.ignore_transition],
25
- exposes: [e.switch()],
25
+ meta: {battery: {voltageToPercentage: '3V_2100'}},
26
+ exposes: [e.switch(), e.battery(), e.battery_voltage()],
26
27
  },
27
28
  {
28
29
  zigbeeModel: ['3RSS007Z'],
package/devices/tuya.js CHANGED
@@ -143,7 +143,8 @@ module.exports = [
143
143
  description: 'Smart air house keeper',
144
144
  fromZigbee: [fz.tuya_air_quality],
145
145
  toZigbee: [],
146
- exposes: [e.temperature(), e.humidity(), e.co2(), e.voc(), e.formaldehyd(), e.pm25()],
146
+ exposes: [e.temperature(), e.humidity(), e.co2(), e.voc(), e.formaldehyd().withUnit('ppm'),
147
+ e.pm25().withValueMin(0).withValueMax(999).withValueStep(1)],
147
148
  },
148
149
  {
149
150
  fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_7bztmfm1'}],
@@ -235,7 +236,8 @@ module.exports = [
235
236
  {modelID: 'TS0505B', manufacturerName: '_TZ3210_k1pe6ibm'},
236
237
  {modelID: 'TS0505B', manufacturerName: '_TZ3210_bfwvfyx1'},
237
238
  {modelID: 'TS0505B', manufacturerName: '_TZ3210_leyz4rju'},
238
- {modelID: 'TS0505B', manufacturerName: '_TZ3210_jd3z4yig'}],
239
+ {modelID: 'TS0505B', manufacturerName: '_TZ3210_jd3z4yig'},
240
+ {modelID: 'TS0505B', manufacturerName: '_TZ3210_dgdjiw1c'}],
239
241
  model: 'TS0505B',
240
242
  vendor: 'TuYa',
241
243
  description: 'Zigbee RGB+CCT light',
@@ -999,6 +1001,8 @@ module.exports = [
999
1001
  toZigbee: [tz.tuya_cover_control, tz.tuya_cover_options],
1000
1002
  exposes: [
1001
1003
  e.cover_position().setAccess('position', ea.STATE_SET),
1004
+ exposes.binary('running', ea.STATE, true, false)
1005
+ .withDescription('Whether the motor is moving or not'),
1002
1006
  exposes.composite('options', 'options')
1003
1007
  .withFeature(exposes.numeric('motor_speed', ea.STATE_SET)
1004
1008
  .withValueMin(0)
@@ -1036,7 +1040,9 @@ module.exports = [
1036
1040
  tz.tuya_thermostat_window_detect, tz.tuya_thermostat_schedule, tz.tuya_thermostat_week, tz.tuya_thermostat_away_preset,
1037
1041
  tz.tuya_thermostat_schedule_programming_mode],
1038
1042
  exposes: [
1039
- e.child_lock(), e.window_detection(), e.battery_low(), e.valve_detection(), e.position(),
1043
+ e.child_lock(), e.window_detection(),
1044
+ exposes.binary('window_open', ea.STATE).withDescription('Window open?'),
1045
+ e.battery_low(), e.valve_detection(), e.position(),
1040
1046
  exposes.climate().withSetpoint('current_heating_setpoint', 5, 35, 0.5, ea.STATE_SET)
1041
1047
  .withLocalTemperature(ea.STATE).withSystemMode(['heat', 'auto', 'off'], ea.STATE_SET,
1042
1048
  'Mode of this device, in the `heat` mode the TS0601 will remain continuously heating, i.e. it does not regulate ' +
package/devices/xiaomi.js CHANGED
@@ -914,7 +914,7 @@ module.exports = [
914
914
  fromZigbee: [fz.aqara_opple],
915
915
  toZigbee: [tz.RTCZCGQ11LM_presence, tz.RTCZCGQ11LM_monitoring_mode, tz.RTCZCGQ11LM_approach_distance,
916
916
  tz.aqara_motion_sensitivity, tz.RTCZCGQ11LM_reset_nopresence_status],
917
- exposes: [e.presence().withAccess(ea.STATE_GET),
917
+ exposes: [e.presence().withAccess(ea.STATE_GET), e.power_outage_count(), e.temperature(),
918
918
  exposes.enum('presence_event', ea.STATE, ['enter', 'leave', 'left_enter', 'right_leave', 'right_enter', 'left_leave',
919
919
  'approach', 'away']).withDescription('Presence events: "enter", "leave", "left_enter", "right_leave", ' +
920
920
  '"right_enter", "left_leave", "approach", "away"'),
@@ -925,8 +925,7 @@ module.exports = [
925
925
  exposes.enum('motion_sensitivity', ea.ALL, ['low', 'medium', 'high']).withDescription('Different sensitivities ' +
926
926
  'means different static human body recognition rate and response speed of occupied'),
927
927
  exposes.enum('reset_nopresence_status', ea.SET, ['Reset']).withDescription('Reset the status of no presence'),
928
- exposes.numeric('power_outage_count', ea.STATE).withDescription('Number of power outages (since last pairing)'),
929
- e.temperature()],
928
+ ],
930
929
  configure: async (device, coordinatorEndpoint, logger) => {
931
930
  const endpoint = device.getEndpoint(1);
932
931
  await endpoint.read('aqaraOpple', [0x010c], {manufacturerCode: 0x115f});
@@ -1173,7 +1172,7 @@ module.exports = [
1173
1172
  fromZigbee: [fz.aqara_opple],
1174
1173
  toZigbee: [tz.JTBZ01AQA_gas, tz.JTBZ01AQA_gas_density, tz.JTBZ01AQA_gas_sensitivity, tz.JTBZ01AQA_selftest,
1175
1174
  tz.JTBZ01AQA_mute_buzzer, tz.JTBZ01AQA_mute, tz.JTBZ01AQA_linkage_alarm, tz.JTBZ01AQA_state, tz.aqara_power_outage_count],
1176
- exposes: [e.gas().withAccess(ea.STATE_GET),
1175
+ exposes: [e.gas().withAccess(ea.STATE_GET), e.power_outage_count().withAccess(ea.STATE_GET),
1177
1176
  exposes.numeric('gas_density', ea.STATE_GET).withUnit('%LEL').withDescription('Value of gas concentration'),
1178
1177
  exposes.enum('gas_sensitivity', ea.ALL, ['10%LEL', '15%LEL']).withDescription('Gas concentration value at which ' +
1179
1178
  'an alarm is triggered ("10%LEL" is more sensitive than "15%LEL")'),
@@ -1187,7 +1186,7 @@ module.exports = [
1187
1186
  'is detected, other detectors with this option enabled will also sound the alarm buzzer'),
1188
1187
  exposes.binary('state', ea.STATE_GET, 'preparation', 'work').withDescription('"Preparation" or "work" ' +
1189
1188
  '(measurement of the gas concentration value and triggering of an alarm are only performed in the "work" state)'),
1190
- exposes.numeric('power_outage_count', ea.STATE_GET).withDescription('Number of power outages (since last pairing)')],
1189
+ ],
1191
1190
  configure: async (device, coordinatorEndpoint, logger) => {
1192
1191
  const endpoint = device.getEndpoint(1);
1193
1192
  await endpoint.read('aqaraOpple', [0x013a], {manufacturerCode: 0x115f});
@@ -1239,7 +1238,9 @@ module.exports = [
1239
1238
  vendor: 'Xiaomi',
1240
1239
  fromZigbee: [fz.xiaomi_curtain_position, fz.cover_position_tilt, fz.xiaomi_curtain_options],
1241
1240
  toZigbee: [tz.xiaomi_curtain_position_state, tz.xiaomi_curtain_options],
1242
- exposes: [e.cover_position().setAccess('state', ea.ALL)],
1241
+ exposes: [e.cover_position().setAccess('state', ea.ALL),
1242
+ exposes.binary('running', ea.STATE, true, false)
1243
+ .withDescription('Whether the motor is moving or not')],
1243
1244
  ota: ota.zigbeeOTA,
1244
1245
  },
1245
1246
  {
@@ -1249,7 +1250,9 @@ module.exports = [
1249
1250
  vendor: 'Xiaomi',
1250
1251
  fromZigbee: [fz.xiaomi_curtain_position, fz.cover_position_tilt, fz.xiaomi_curtain_options],
1251
1252
  toZigbee: [tz.xiaomi_curtain_position_state, tz.xiaomi_curtain_options],
1252
- exposes: [e.cover_position().setAccess('state', ea.ALL)],
1253
+ exposes: [e.cover_position().setAccess('state', ea.ALL),
1254
+ exposes.binary('running', ea.STATE, true, false)
1255
+ .withDescription('Whether the motor is moving or not')],
1253
1256
  ota: ota.zigbeeOTA,
1254
1257
  },
1255
1258
  {
@@ -1266,7 +1269,9 @@ module.exports = [
1266
1269
  await device.endpoints[0].read('genAnalogOutput', ['presentValue']);
1267
1270
  }
1268
1271
  },
1269
- exposes: [e.cover_position().setAccess('state', ea.ALL), e.battery()],
1272
+ exposes: [e.cover_position().setAccess('state', ea.ALL), e.battery(),
1273
+ exposes.binary('running', ea.STATE, true, false)
1274
+ .withDescription('Whether the motor is moving or not')],
1270
1275
  configure: async (device, coordinatorEndpoint, logger) => {
1271
1276
  const endpoint = device.endpoints[0];
1272
1277
  await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
@@ -1286,7 +1291,7 @@ module.exports = [
1286
1291
  exposes.enum('motor_state', ea.STATE, ['declining', 'rising', 'pause', 'blocked'])
1287
1292
  .withDescription('The current state of the motor.'),
1288
1293
  exposes.binary('running', ea.STATE, true, false)
1289
- .withDescription('Whether the motor is moving or not.')],
1294
+ .withDescription('Whether the motor is moving or not')],
1290
1295
  configure: async (device, coordinatorEndpoint, logger) => {
1291
1296
  device.powerSource = 'Battery';
1292
1297
  device.save();
@@ -1300,14 +1305,16 @@ module.exports = [
1300
1305
  description: 'Aqara wireless relay controller',
1301
1306
  fromZigbee: [fz.xiaomi_switch_basic, fz.xiaomi_power, fz.ignore_multistate_report, fz.on_off, fz.xiaomi_basic_raw],
1302
1307
  meta: {multiEndpoint: true},
1303
- toZigbee: [tz.on_off, tz.LLKZMK11LM_interlock, tz.xiaomi_power],
1308
+ toZigbee: [tz.on_off, tz.LLKZMK11LM_interlock, tz.xiaomi_power, tz.xiaomi_switch_power_outage_memory],
1304
1309
  endpoint: (device) => {
1305
1310
  return {'l1': 1, 'l2': 2};
1306
1311
  },
1307
- exposes: [e.power().withAccess(ea.STATE_GET), e.energy(), e.temperature(), e.voltage().withAccess(ea.STATE), e.current(),
1308
- e.switch().withEndpoint('l1'), e.switch().withEndpoint('l2'),
1312
+ exposes: [e.power().withAccess(ea.STATE_GET), e.energy(), e.temperature(), e.voltage(), e.current(),
1313
+ e.switch().withEndpoint('l1'), e.switch().withEndpoint('l2'), e.power_outage_count(false),
1314
+ e.power_outage_memory(),
1309
1315
  exposes.binary('interlock', ea.STATE_SET, true, false)
1310
- .withDescription('Enabling prevents both relais being on at the same time')],
1316
+ .withDescription('Enabling prevents both relais being on at the same time'),
1317
+ ],
1311
1318
  ota: ota.zigbeeOTA,
1312
1319
  },
1313
1320
  {
@@ -1481,8 +1488,9 @@ module.exports = [
1481
1488
  // Ignore energy metering reports, rely on aqara_opple: https://github.com/Koenkk/zigbee2mqtt/issues/10709
1482
1489
  fromZigbee: [fz.on_off, fz.device_temperature, fz.aqara_opple, fz.ignore_metering, fz.ignore_electrical_measurement,
1483
1490
  fz.xiaomi_power],
1484
- exposes: [e.switch(), e.energy(), e.power(), e.device_temperature(), e.power_outage_memory(), e.switch_type(),
1485
- e.voltage(), e.temperature(), e.current()],
1491
+ exposes: [e.switch(), e.energy(), e.power(), e.device_temperature(), e.power_outage_memory(), e.power_outage_count(),
1492
+ e.switch_type(), e.voltage(), e.temperature(), e.current(),
1493
+ ],
1486
1494
  toZigbee: [tz.xiaomi_switch_type, tz.on_off, tz.xiaomi_switch_power_outage_memory, tz.xiaomi_led_disabled_night],
1487
1495
  configure: async (device, coordinatorEndpoint, logger) => {
1488
1496
  const endpoint = device.getEndpoint(1);
package/lib/exposes.js CHANGED
@@ -582,6 +582,7 @@ module.exports = {
582
582
  position: () => new Numeric('position', access.STATE).withUnit('%').withDescription('Position'),
583
583
  power: () => new Numeric('power', access.STATE).withUnit('W').withDescription('Instantaneous measured power'),
584
584
  power_on_behavior: () => new Enum('power_on_behavior', access.ALL, ['off', 'previous', 'on']).withDescription('Controls the behavior when the device is powered on'),
585
+ power_outage_count: (resetsWhenPairing = true) => new Numeric('power_outage_count', access.STATE).withDescription('Number of power outages' + (resetsWhenPairing ? ' (since last pairing)' : '')),
585
586
  power_outage_memory: () => new Binary('power_outage_memory', access.ALL, true, false).withDescription('Enable/disable the power outage memory, this recovers the on/off mode after power failure'),
586
587
  presence: () => new Binary('presence', access.STATE, true, false).withDescription('Indicates whether the device detected presence'),
587
588
  pressure: () => new Numeric('pressure', access.STATE).withUnit('hPa').withDescription('The measured atmospheric pressure'),
package/lib/tuya.js CHANGED
@@ -258,6 +258,7 @@ const dataPoints = {
258
258
  scheduleWorkday: 112,
259
259
  scheduleHoliday: 113,
260
260
  awayTemp: 114,
261
+ windowOpen: 115,
261
262
  autoLock: 116,
262
263
  awayDays: 117,
263
264
  // Manufacturer specific
@@ -420,7 +421,9 @@ const dataPoints = {
420
421
  tuyaSabFormaldehyd: 22,
421
422
  // tuya Smart Air House Keeper, Multifunctionale air quality detector.
422
423
  // CO2, Temp, Humidity, VOC and Formaldehyd same as Smart Air Box
423
- tuyaSahkMP25: 20,
424
+ tuyaSahkMP25: 2,
425
+ tuyaSahkCO2: 22,
426
+ tuyaSahkFormaldehyd: 20,
424
427
  // Tuya CO (carbon monoxide) smart air box
425
428
  tuyaSabCOalarm: 1,
426
429
  tuyaSabCO: 2,
package/lib/xiaomi.js CHANGED
@@ -129,7 +129,11 @@ const buffer2DataObject = (meta, model, buffer) => {
129
129
  }
130
130
  }
131
131
 
132
- if (meta.logger) meta.logger.debug(`${model.zigbeeModel}: Processed buffer into data ${JSON.stringify(dataObject)}`);
132
+ if (meta.logger) {
133
+ meta.logger.debug(`${model.zigbeeModel}: Processed buffer into data ${JSON.stringify(dataObject,
134
+ (key, value) => typeof value === 'bigint' ? value.toString() : value)}`);
135
+ }
136
+
133
137
 
134
138
  return dataObject;
135
139
  };
@@ -160,7 +164,7 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
160
164
  payload.mode_switch = {4: 'anti_flicker_mode', 1: 'quick_mode'}[value];
161
165
  break;
162
166
  case '5':
163
- if (['JT-BZ-01AQ/A', 'RTCZCGQ11LM'].includes(model.model)) {
167
+ if (['Mains (single phase)', 'DC Source'].includes(meta.device.powerSource)) {
164
168
  payload.power_outage_count = value;
165
169
  }
166
170
  break;