zigbee-herdsman-converters 14.0.421 → 14.0.425

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.
@@ -1837,7 +1837,7 @@ const converters = {
1837
1837
  case tuya.dataPoints.nousBattery:
1838
1838
  return {battery: value};
1839
1839
  case tuya.dataPoints.nousTempUnitConvert:
1840
- return {temperature_unit_convert: {0x00: '°C', 0x01: '°F'}[value]};
1840
+ return {temperature_unit_convert: {0x00: 'celsius', 0x01: 'fahrenheit'}[value]};
1841
1841
  case tuya.dataPoints.nousMaxTemp:
1842
1842
  return {max_temperature: calibrateAndPrecisionRoundOptions(value / 10, options, 'temperature')};
1843
1843
  case tuya.dataPoints.nousMinTemp:
@@ -3224,8 +3224,9 @@ const converters = {
3224
3224
  }
3225
3225
 
3226
3226
  if (msg.data.hasOwnProperty('12288')) {
3227
- result.energy_consumed = precisionRound(msg.data['12288'], 2);
3227
+ result.energy_consumed = precisionRound(msg.data['12288'], 2); // deprecated
3228
3228
  result.energyconsumed = result.energy_consumed; // deprecated
3229
+ result.energy = result.energy_consumed;
3229
3230
  }
3230
3231
 
3231
3232
  if (msg.data.hasOwnProperty('12291')) {
@@ -4141,6 +4142,25 @@ const converters = {
4141
4142
  }
4142
4143
  },
4143
4144
  },
4145
+ tuya_CO: {
4146
+ cluster: 'manuSpecificTuya',
4147
+ type: ['commandDataReport', 'commandDataResponse'],
4148
+ options: [exposes.options.precision('co'), exposes.options.calibration('co')],
4149
+ convert: (model, msg, publish, options, meta) => {
4150
+ const dpValue = tuya.firstDpValue(msg, meta, 'tuya_CO');
4151
+ const dp = dpValue.dp;
4152
+ const value = tuya.getDataValue(dpValue);
4153
+ switch (dp) {
4154
+ case tuya.dataPoints.tuyaSabCO:
4155
+ return {co: calibrateAndPrecisionRoundOptions(value / 100, options, 'co')};
4156
+ case tuya.dataPoints.tuyaSabCOalarm:
4157
+ return {carbon_monoxide: value ? 'OFF' : 'ON'};
4158
+ default:
4159
+ meta.logger.warn(`zigbee-herdsman-converters:TuyaSmartAirBox: Unrecognized DP #${
4160
+ dp} with data ${JSON.stringify(dpValue)}`);
4161
+ }
4162
+ },
4163
+ },
4144
4164
  saswell_thermostat: {
4145
4165
  cluster: 'manuSpecificTuya',
4146
4166
  type: ['commandDataResponse', 'commandDataReport'],
@@ -4434,7 +4454,7 @@ const converters = {
4434
4454
  case tuya.dataPoints.ecoTemp:
4435
4455
  return {eco_temperature: value};
4436
4456
  case tuya.dataPoints.valvePos:
4437
- return {position: value};
4457
+ return {position: value, running_state: value ? 'heat' : 'idle'};
4438
4458
  case tuya.dataPoints.awayTemp:
4439
4459
  return {away_preset_temperature: value};
4440
4460
  case tuya.dataPoints.awayDays:
@@ -5106,7 +5126,7 @@ const converters = {
5106
5126
  },
5107
5127
  },
5108
5128
  legrand_cable_outlet_mode: {
5109
- cluster: '64576',
5129
+ cluster: 'manuSpecificLegrandDevices2',
5110
5130
  type: ['readResponse'],
5111
5131
  convert: (model, msg, publish, options, meta) => {
5112
5132
  const payload = {};
@@ -5505,7 +5525,7 @@ const converters = {
5505
5525
 
5506
5526
  // Maybe other QKBG also support release/hold?
5507
5527
  const actionLookup = !isLegacyEnabled(options) && ['QBKG03LM', 'QBKG22LM', 'QBKG04LM', 'QBKG21LM'].includes(model.model) ?
5508
- {0: 'hold', 1: 'release'} : {0: 'single', 1: 'single'};
5528
+ {0: 'hold', 1: 'release', 2: 'double'} : {0: 'single', 1: 'single'};
5509
5529
 
5510
5530
  // Dont' use postfixWithEndpointName here, endpoints don't match
5511
5531
  if (mapping) {
@@ -7521,6 +7541,17 @@ const converters = {
7521
7541
  return result;
7522
7542
  },
7523
7543
  },
7544
+ wiser_lighting_ballast_configuration: {
7545
+ cluster: 'lightingBallastCfg',
7546
+ type: ['attributeReport', 'readResponse'],
7547
+ convert: (model, msg, publish, options, meta) => {
7548
+ const result = converters.lighting_ballast_configuration.convert(model, msg, publish, options, meta);
7549
+ if (msg.data.hasOwnProperty('wiserControlMode')) {
7550
+ result.dimmer_mode = constants.wiserDimmerControlMode[msg.data['wiserControlMode']];
7551
+ }
7552
+ return result;
7553
+ },
7554
+ },
7524
7555
  schneider_ui_action: {
7525
7556
  cluster: 'wiserDeviceInfo',
7526
7557
  type: 'attributeReport',
@@ -8134,6 +8165,7 @@ const converters = {
8134
8165
  }
8135
8166
  if (dp === tuya.dataPoints.hochTotalActivePower) {
8136
8167
  result.energy_consumed = value / 100;
8168
+ result.energy = result.energy_consumed;
8137
8169
  }
8138
8170
  if (dp === tuya.dataPoints.hochLocking) {
8139
8171
  result.trip = value ? 'trip' : 'clear';
@@ -8150,7 +8182,7 @@ const converters = {
8150
8182
  1: 'on',
8151
8183
  2: 'previous',
8152
8184
  };
8153
- result.power_on_behaviour = lookup[value];
8185
+ result.power_on_behavior = lookup[value];
8154
8186
  }
8155
8187
  if (dp === tuya.dataPoints.hochFaultCode) {
8156
8188
  const lookup = {
@@ -8410,6 +8442,20 @@ const converters = {
8410
8442
  }
8411
8443
  },
8412
8444
  },
8445
+ tm081: {
8446
+ cluster: 'manuSpecificTuya',
8447
+ type: ['commandDataReport'],
8448
+ convert: (model, msg, publish, options, meta) => {
8449
+ const dpValue = tuya.firstDpValue(msg, meta, 'tm0801');
8450
+ const dp = dpValue.dp;
8451
+ const value = tuya.getDataValue(dpValue);
8452
+ if (dp === 1) return {contact: value === true ? false : true};
8453
+ if (dp === 2) return {battery: value};
8454
+ else {
8455
+ meta.logger.warn(`zigbee-herdsman-converters:TM081: NOT RECOGNIZED DP #${dp} with data ${JSON.stringify(dpValue)}`);
8456
+ }
8457
+ },
8458
+ },
8413
8459
  // #endregion
8414
8460
 
8415
8461
  // #region Ignore converters (these message dont need parsing).
@@ -2449,7 +2449,9 @@ const converters = {
2449
2449
  matsee_garage_door_opener: {
2450
2450
  key: ['trigger'],
2451
2451
  convertSet: (entity, key, value, meta) => {
2452
- tuya.sendDataPointBool(entity, tuya.dataPoints.garageDoorTrigger, true);
2452
+ const state = meta.message.hasOwnProperty('trigger') ? meta.message.trigger : true;
2453
+ tuya.sendDataPointBool(entity, tuya.dataPoints.garageDoorTrigger, state);
2454
+ return {state: {trigger: state}};
2453
2455
  },
2454
2456
  },
2455
2457
  SPZ01_power_outage_memory: {
@@ -4577,10 +4579,20 @@ const converters = {
4577
4579
  legrand_cableOutletMode: {
4578
4580
  key: ['cable_outlet_mode'],
4579
4581
  convertSet: async (entity, key, value, meta) => {
4580
- meta.logger.warn('Feature under development !');
4582
+ const mode = {
4583
+ 'comfort': 0x00,
4584
+ 'comfort-1': 0x01,
4585
+ 'comfort-2': 0x02,
4586
+ 'eco': 0x03,
4587
+ 'frost_protection': 0x04,
4588
+ 'off': 0x05,
4589
+ };
4590
+ const payload = {data: Buffer.from([mode[value]])};
4591
+ await entity.command('manuSpecificLegrandDevices2', 'command0', payload);
4592
+ return {state: {'cable_outlet_mode': value}};
4581
4593
  },
4582
4594
  convertGet: async (entity, key, meta) => {
4583
- await entity.read(64576, [0x0000], manufacturerOptions.legrand);
4595
+ await entity.read('manuSpecificLegrandDevices2', [0x0000], manufacturerOptions.legrand);
4584
4596
  },
4585
4597
  },
4586
4598
  legrand_powerAlarm: {
@@ -5279,7 +5291,7 @@ const converters = {
5279
5291
  convertSet: async (entity, key, value, meta) => {
5280
5292
  switch (key) {
5281
5293
  case 'temperature_unit_convert':
5282
- await tuya.sendDataPointEnum(entity, tuya.dataPoints.nousTempUnitConvert, ['°C', '°F'].indexOf(value));
5294
+ await tuya.sendDataPointEnum(entity, tuya.dataPoints.nousTempUnitConvert, ['celsius', 'fahrenheit'].indexOf(value));
5283
5295
  break;
5284
5296
  case 'min_temperature':
5285
5297
  await tuya.sendDataPointValue(entity, tuya.dataPoints.nousMinTemp, Math.round(value * 10));
@@ -6307,6 +6319,18 @@ const converters = {
6307
6319
  await entity.read('lightingBallastCfg', [0xe000], {manufacturerCode: 0x105e});
6308
6320
  },
6309
6321
  },
6322
+ wiser_dimmer_mode: {
6323
+ key: ['dimmer_mode'],
6324
+ convertSet: async (entity, key, value, meta) => {
6325
+ const controlMode = utils.getKey(constants.wiserDimmerControlMode, value, value, Number);
6326
+ await entity.write('lightingBallastCfg', {'wiserControlMode': controlMode},
6327
+ {manufacturerCode: herdsman.Zcl.ManufacturerCode.SCHNEIDER});
6328
+ return {state: {dimmer_mode: value}};
6329
+ },
6330
+ convertGet: async (entity, key, meta) => {
6331
+ await entity.read('lightingBallastCfg', ['wiserControlMode'], {manufacturerCode: herdsman.Zcl.ManufacturerCode.SCHNEIDER});
6332
+ },
6333
+ },
6310
6334
  schneider_temperature_measured_value: {
6311
6335
  key: ['temperature_measured_value'],
6312
6336
  convertSet: async (entity, key, value, meta) => {
@@ -7006,7 +7030,7 @@ const converters = {
7006
7030
  key: ['state',
7007
7031
  'child_lock',
7008
7032
  'countdown_timer',
7009
- 'power_on_behaviour',
7033
+ 'power_on_behavior',
7010
7034
  'trip',
7011
7035
  'clear_device_data',
7012
7036
  /* TODO: Add the below keys when toZigbee converter work has been completed
@@ -7025,10 +7049,10 @@ const converters = {
7025
7049
  } else if (key === 'countdown_timer') {
7026
7050
  await tuya.sendDataPointValue(entity, tuya.dataPoints.hochCountdownTimer, value);
7027
7051
  return {state: {countdown_timer: value}};
7028
- } else if (key === 'power_on_behaviour') {
7052
+ } else if (key === 'power_on_behavior') {
7029
7053
  const lookup = {'off': 0, 'on': 1, 'previous': 2};
7030
7054
  await tuya.sendDataPointEnum(entity, tuya.dataPoints.hochRelayStatus, lookup[value], 'sendData');
7031
- return {state: {power_on_behaviour: value}};
7055
+ return {state: {power_on_behavior: value}};
7032
7056
  } else if (key === 'trip') {
7033
7057
  if (value === 'clear') {
7034
7058
  await tuya.sendDataPointBool(entity, tuya.dataPoints.hochLocking, true, 'sendData');
package/devices/adeo.js CHANGED
@@ -71,6 +71,13 @@ module.exports = [
71
71
  description: 'ENKI Lexman E27 14W to 100W LED RGBW',
72
72
  extend: extend.light_onoff_brightness_colortemp_color(),
73
73
  },
74
+ {
75
+ zigbeeModel: ['ZBEK-2'],
76
+ model: 'IG-CDZOTAAG014RA-MAN',
77
+ vendor: 'ADEO',
78
+ description: 'ENKI Lexman E27 14W to 100W LED RGBW v2',
79
+ extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 370]}),
80
+ },
74
81
  {
75
82
  zigbeeModel: ['LXEK-7'],
76
83
  model: '9CZA-A806ST-Q1Z',
@@ -4,6 +4,21 @@ const tz = require('../converters/toZigbee');
4
4
  const reporting = require('../lib/reporting');
5
5
  const extend = require('../lib/extend');
6
6
  const e = exposes.presets;
7
+ const utils = require('../lib/utils');
8
+ const ea = exposes.access;
9
+
10
+ const tzLocal = {
11
+ aOneBacklight: {
12
+ key: ['backlight_led'],
13
+ convertSet: async (entity, key, value, meta) => {
14
+ const state = value.toLowerCase();
15
+ utils.validateValue(state, ['toggle', 'off', 'on']);
16
+ const endpoint = meta.device.getEndpoint(3);
17
+ await endpoint.command('genOnOff', state, {});
18
+ return {state: {backlight_led: state.toUpperCase()}};
19
+ },
20
+ },
21
+ };
7
22
 
8
23
  const batteryRotaryDimmer = (...endpointsIds) => ({
9
24
  fromZigbee: [fz.battery, fz.command_on, fz.command_off, fz.command_step, fz.command_step_color_temperature],
@@ -129,6 +144,9 @@ module.exports = [
129
144
  model: 'AU-A1ZB2WDM',
130
145
  vendor: 'Aurora Lighting',
131
146
  description: 'AOne 250W smart rotary dimmer module',
147
+ exposes: [...extend.light_onoff_brightness({noConfigure: true}).exposes,
148
+ exposes.binary('backlight_led', ea.STATE_SET, 'ON', 'OFF').withDescription('Enable or disable the blue backlight LED')],
149
+ toZigbee: [...extend.light_onoff_brightness({noConfigure: true}).toZigbee, tzLocal.aOneBacklight],
132
150
  extend: extend.light_onoff_brightness({noConfigure: true}),
133
151
  configure: async (device, coordinatorEndpoint, logger) => {
134
152
  await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
@@ -15,6 +15,18 @@ module.exports = [
15
15
  await reporting.onOff(endpoint);
16
16
  },
17
17
  },
18
+ {
19
+ zigbeeModel: ['43078'],
20
+ model: '43078',
21
+ vendor: 'Enbrighten',
22
+ description: 'Zigbee in-wall smart switch',
23
+ extend: extend.switch(),
24
+ configure: async (device, coordinatorEndpoint, logger) => {
25
+ const endpoint = device.getEndpoint(1);
26
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
27
+ await reporting.onOff(endpoint);
28
+ },
29
+ },
18
30
  {
19
31
  zigbeeModel: ['43080'],
20
32
  model: '43080',
package/devices/hive.js CHANGED
@@ -496,4 +496,18 @@ module.exports = [
496
496
  },
497
497
  exposes: [],
498
498
  },
499
+ {
500
+ zigbeeModel: ['SLT6'],
501
+ model: 'SLT6',
502
+ vendor: 'Hive',
503
+ description: 'Heating thermostat remote control',
504
+ fromZigbee: [fz.battery],
505
+ toZigbee: [],
506
+ exposes: [e.battery()],
507
+ configure: async (device, coordinatorEndpoint, logger) => {
508
+ const endpoint = device.getEndpoint(9);
509
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
510
+ await reporting.batteryPercentageRemaining(endpoint);
511
+ },
512
+ },
499
513
  ];
package/devices/ikea.js CHANGED
@@ -285,6 +285,13 @@ module.exports = [
285
285
  description: 'TRADFRI LED bulb E27 1055 lumen, dimmable, white spectrum, opal white',
286
286
  extend: tradfriExtend.light_onoff_brightness_colortemp(),
287
287
  },
288
+ {
289
+ zigbeeModel: ['TRADFRIbulbE27WSglobeclear806lm'],
290
+ model: 'LED2004G8',
291
+ vendor: 'IKEA',
292
+ description: 'TRADFRI LED bulb E27 806 lumen, dimmable, white spectrum, clear',
293
+ extend: tradfriExtend.light_onoff_brightness_colortemp(),
294
+ },
288
295
  {
289
296
  zigbeeModel: ['TRADFRI bulb E27 opal 470lm', 'TRADFRI bulb E27 W opal 470lm', 'TRADFRIbulbT120E27WSopal470lm'],
290
297
  model: 'LED1937T5_E27',
package/devices/lds.js ADDED
@@ -0,0 +1,11 @@
1
+ const extend = require('../lib/extend');
2
+
3
+ module.exports = [
4
+ {
5
+ zigbeeModel: ['ZBT-RGBWLight-A0000'],
6
+ model: 'ZBT-RGBWLight-A0000',
7
+ vendor: 'LDS',
8
+ description: 'Ynoa smart LED E27',
9
+ extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555]}),
10
+ },
11
+ ];
@@ -313,7 +313,7 @@ module.exports = [
313
313
  e.power().withAccess(ea.STATE_GET)],
314
314
  configure: async (device, coordinatorEndpoint, logger) => {
315
315
  const endpoint = device.getEndpoint(1);
316
- await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 64576]);
316
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'manuSpecificLegrandDevices2']);
317
317
  await reporting.onOff(endpoint);
318
318
  await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
319
319
  await reporting.activePower(endpoint);
package/devices/lixee.js CHANGED
@@ -192,6 +192,9 @@ const fzLocal = {
192
192
  },
193
193
  };
194
194
 
195
+
196
+ // we are doing it with exclusion and not inclusion because the list is dynamic (based on zlinky mode),
197
+ // and change based on that. Just some few attributes are useless, so we exclude them
195
198
  const tarifsDef = {
196
199
  histo_BASE: {fname: 'Historique - BASE',
197
200
  currentTarf: 'BASE', excluded: [
@@ -298,16 +301,16 @@ const exposedData = [
298
301
  {cluster: clustersDef._0x0702, att: 'currentSummDelivered', reportable: true, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BASE', ea.STATE).withUnit('kWh').withProperty('current_summ_delivered').withDescription('Base index')},
299
302
  {cluster: clustersDef._0xFF66, att: 'currentTarif', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.text('OPTARIF', ea.STATE).withProperty('current_tarif').withDescription('Tarif option')},
300
303
  {cluster: clustersDef._0x0B01, att: 'availablePower', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('ISOUSC', ea.STATE).withUnit('A').withProperty('available_power').withDescription('Subscribed intensity level')},
301
- {cluster: clustersDef._0x0702, att: 'currentTier1SummDelivered', reportable: false, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('HCHC', ea.STATE).withUnit('kWh').withProperty('current_tier1_summ_delivered').withDescription('HCHC index')},
302
- {cluster: clustersDef._0x0702, att: 'currentTier2SummDelivered', reportable: false, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('HCHP', ea.STATE).withUnit('kWh').withProperty('current_tier2_summ_delivered').withDescription('HCHP index')},
303
- {cluster: clustersDef._0x0702, att: 'currentTier1SummDelivered', reportable: false, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('EJPHN', ea.STATE).withUnit('kWh').withProperty('current_tier1_summ_delivered').withDescription('EJPHN index')},
304
- {cluster: clustersDef._0x0702, att: 'currentTier2SummDelivered', reportable: false, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('EJPHPM', ea.STATE).withUnit('kWh').withProperty('current_tier2_summ_delivered').withDescription('EJPHPM index')},
305
- {cluster: clustersDef._0x0702, att: 'currentTier1SummDelivered', reportable: false, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHCJB', ea.STATE).withUnit('kWh').withProperty('current_tier1_summ_delivered').withDescription('BBRHCJB index')},
306
- {cluster: clustersDef._0x0702, att: 'currentTier2SummDelivered', reportable: false, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHPJB', ea.STATE).withUnit('kWh').withProperty('current_tier2_summ_delivered').withDescription('BBRHPJB index')},
307
- {cluster: clustersDef._0x0702, att: 'currentTier3SummDelivered', reportable: false, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHCJW', ea.STATE).withUnit('kWh').withProperty('current_tier3_summ_delivered').withDescription('BBRHCJW index')},
308
- {cluster: clustersDef._0x0702, att: 'currentTier4SummDelivered', reportable: false, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHPJW', ea.STATE).withUnit('kWh').withProperty('current_tier4_summ_delivered').withDescription('BBRHPJW index')},
309
- {cluster: clustersDef._0x0702, att: 'currentTier5SummDelivered', reportable: false, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHCJR', ea.STATE).withUnit('kWh').withProperty('current_tier5_summ_delivered').withDescription('BBRHCJR index')},
310
- {cluster: clustersDef._0x0702, att: 'currentTier6SummDelivered', reportable: false, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHPJR', ea.STATE).withUnit('kWh').withProperty('current_tier6_summ_delivered').withDescription('BBRHPJR index')},
304
+ {cluster: clustersDef._0x0702, att: 'currentTier1SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('HCHC', ea.STATE).withUnit('kWh').withProperty('current_tier1_summ_delivered').withDescription('HCHC index')},
305
+ {cluster: clustersDef._0x0702, att: 'currentTier2SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('HCHP', ea.STATE).withUnit('kWh').withProperty('current_tier2_summ_delivered').withDescription('HCHP index')},
306
+ {cluster: clustersDef._0x0702, att: 'currentTier1SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('EJPHN', ea.STATE).withUnit('kWh').withProperty('current_tier1_summ_delivered').withDescription('EJPHN index')},
307
+ {cluster: clustersDef._0x0702, att: 'currentTier2SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('EJPHPM', ea.STATE).withUnit('kWh').withProperty('current_tier2_summ_delivered').withDescription('EJPHPM index')},
308
+ {cluster: clustersDef._0x0702, att: 'currentTier1SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHCJB', ea.STATE).withUnit('kWh').withProperty('current_tier1_summ_delivered').withDescription('BBRHCJB index')},
309
+ {cluster: clustersDef._0x0702, att: 'currentTier2SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHPJB', ea.STATE).withUnit('kWh').withProperty('current_tier2_summ_delivered').withDescription('BBRHPJB index')},
310
+ {cluster: clustersDef._0x0702, att: 'currentTier3SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHCJW', ea.STATE).withUnit('kWh').withProperty('current_tier3_summ_delivered').withDescription('BBRHCJW index')},
311
+ {cluster: clustersDef._0x0702, att: 'currentTier4SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHPJW', ea.STATE).withUnit('kWh').withProperty('current_tier4_summ_delivered').withDescription('BBRHPJW index')},
312
+ {cluster: clustersDef._0x0702, att: 'currentTier5SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHCJR', ea.STATE).withUnit('kWh').withProperty('current_tier5_summ_delivered').withDescription('BBRHCJR index')},
313
+ {cluster: clustersDef._0x0702, att: 'currentTier6SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHPJR', ea.STATE).withUnit('kWh').withProperty('current_tier6_summ_delivered').withDescription('BBRHPJR index')},
311
314
  {cluster: clustersDef._0x0B04, att: 'rmsCurrent', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IINST', ea.STATE).withUnit('A').withProperty('rms_current').withDescription('RMS current')},
312
315
  {cluster: clustersDef._0x0B04, att: 'rmsCurrent', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IINST1', ea.STATE).withUnit('A').withProperty('rms_current').withDescription('RMS current (phase 1)')},
313
316
  {cluster: clustersDef._0x0B04, att: 'rmsCurrentPhB', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IINST2', ea.STATE).withUnit('A').withProperty('rms_current_ph_b').withDescription('RMS current (phase 2)')},
@@ -317,7 +320,7 @@ const exposedData = [
317
320
  {cluster: clustersDef._0x0B04, att: 'rmsCurrentMaxPhB', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IMAX2', ea.STATE).withUnit('A').withProperty('rms_current_max_ph_b').withDescription('RMS current peak (phase 2)')},
318
321
  {cluster: clustersDef._0x0B04, att: 'rmsCurrentMaxPhC', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IMAX3', ea.STATE).withUnit('A').withProperty('rms_current_max_ph_c').withDescription('RMS current peak (phase 3)')},
319
322
  {cluster: clustersDef._0x0B04, att: 'activePowerMax', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('PMAX', ea.STATE).withUnit('W').withProperty('active_power_max').withDescription('Three-phase power peak')},
320
- {cluster: clustersDef._0x0B04, att: 'apparentPower', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('PAPP', ea.STATE).withUnit('VA').withProperty('apparent_power').withDescription('Apparent power')},
323
+ {cluster: clustersDef._0x0B04, att: 'apparentPower', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('PAPP', ea.STATE).withUnit('VA').withProperty('apparent_power').withDescription('Apparent power')},
321
324
  {cluster: clustersDef._0x0702, att: 'activeRegisterTierDelivered', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.text('PTEC', ea.STATE).withProperty('active_register_tier_delivered').withDescription('Current pricing period')},
322
325
  {cluster: clustersDef._0xFF66, att: 'tomorrowColor', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.text('DEMAIN', ea.STATE).withProperty('tomorrow_color').withDescription('Tomorrow color')},
323
326
  {cluster: clustersDef._0xFF66, att: 'scheduleHPHC', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('HHPHC', ea.STATE).withProperty('schedule_h_p_h_c').withDescription('Schedule HPHC')},
@@ -334,16 +337,16 @@ const exposedData = [
334
337
  {cluster: clustersDef._0x0B01, att: 'softwareRevision', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('VTIC', ea.STATE).withProperty('software_revision').withDescription('Customer tele-information protocol version')},
335
338
  {cluster: clustersDef._0xFF66, att: 'currentDate', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.text('DATE', ea.STATE).withProperty('current_date').withDescription('Current date and time')},
336
339
  {cluster: clustersDef._0x0702, att: 'currentSummDelivered', reportable: true, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EAST', ea.STATE).withUnit('kWh').withProperty('current_summ_delivered').withDescription('Total active power delivered')},
337
- {cluster: clustersDef._0x0702, att: 'currentTier1SummDelivered', reportable: true, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF01', ea.STATE).withUnit('kWh').withProperty('current_tier1_summ_delivered').withDescription('Total provider active power delivered (index 01)')},
338
- {cluster: clustersDef._0x0702, att: 'currentTier2SummDelivered', reportable: true, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF02', ea.STATE).withUnit('kWh').withProperty('current_tier2_summ_delivered').withDescription('Total provider active power delivered (index 02)')},
339
- {cluster: clustersDef._0x0702, att: 'currentTier3SummDelivered', reportable: true, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF03', ea.STATE).withUnit('kWh').withProperty('current_tier3_summ_delivered').withDescription('Total provider active power delivered (index 03)')},
340
- {cluster: clustersDef._0x0702, att: 'currentTier4SummDelivered', reportable: false, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF04', ea.STATE).withUnit('kWh').withProperty('current_tier4_summ_delivered').withDescription('Total provider active power delivered (index 04)')},
341
- {cluster: clustersDef._0x0702, att: 'currentTier5SummDelivered', reportable: false, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF05', ea.STATE).withUnit('kWh').withProperty('current_tier5_summ_delivered').withDescription('Total provider active power delivered (index 05)')},
342
- {cluster: clustersDef._0x0702, att: 'currentTier6SummDelivered', reportable: false, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF06', ea.STATE).withUnit('kWh').withProperty('current_tier6_summ_delivered').withDescription('Total provider active power delivered (index 06)')},
343
- {cluster: clustersDef._0x0702, att: 'currentTier7SummDelivered', reportable: false, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF07', ea.STATE).withUnit('kWh').withProperty('current_tier7_summ_delivered').withDescription('Total provider active power delivered (index 07)')},
344
- {cluster: clustersDef._0x0702, att: 'currentTier8SummDelivered', reportable: false, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF08', ea.STATE).withUnit('kWh').withProperty('current_tier8_summ_delivered').withDescription('Total provider active power delivered (index 08)')},
345
- {cluster: clustersDef._0x0702, att: 'currentTier9SummDelivered', reportable: false, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF09', ea.STATE).withUnit('kWh').withProperty('current_tier9_summ_delivered').withDescription('Total provider active power delivered (index 09)')},
346
- {cluster: clustersDef._0x0702, att: 'currentTier10SummDelivered', reportable: false, report: {change: 100, min: 60}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF10', ea.STATE).withUnit('kWh').withProperty('current_tier10_summ_delivered').withDescription('Total provider active power delivered (index 10)')},
340
+ {cluster: clustersDef._0x0702, att: 'currentTier1SummDelivered', reportable: true, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF01', ea.STATE).withUnit('kWh').withProperty('current_tier1_summ_delivered').withDescription('Total provider active power delivered (index 01)')},
341
+ {cluster: clustersDef._0x0702, att: 'currentTier2SummDelivered', reportable: true, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF02', ea.STATE).withUnit('kWh').withProperty('current_tier2_summ_delivered').withDescription('Total provider active power delivered (index 02)')},
342
+ {cluster: clustersDef._0x0702, att: 'currentTier3SummDelivered', reportable: true, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF03', ea.STATE).withUnit('kWh').withProperty('current_tier3_summ_delivered').withDescription('Total provider active power delivered (index 03)')},
343
+ {cluster: clustersDef._0x0702, att: 'currentTier4SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF04', ea.STATE).withUnit('kWh').withProperty('current_tier4_summ_delivered').withDescription('Total provider active power delivered (index 04)')},
344
+ {cluster: clustersDef._0x0702, att: 'currentTier5SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF05', ea.STATE).withUnit('kWh').withProperty('current_tier5_summ_delivered').withDescription('Total provider active power delivered (index 05)')},
345
+ {cluster: clustersDef._0x0702, att: 'currentTier6SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF06', ea.STATE).withUnit('kWh').withProperty('current_tier6_summ_delivered').withDescription('Total provider active power delivered (index 06)')},
346
+ {cluster: clustersDef._0x0702, att: 'currentTier7SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF07', ea.STATE).withUnit('kWh').withProperty('current_tier7_summ_delivered').withDescription('Total provider active power delivered (index 07)')},
347
+ {cluster: clustersDef._0x0702, att: 'currentTier8SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF08', ea.STATE).withUnit('kWh').withProperty('current_tier8_summ_delivered').withDescription('Total provider active power delivered (index 08)')},
348
+ {cluster: clustersDef._0x0702, att: 'currentTier9SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF09', ea.STATE).withUnit('kWh').withProperty('current_tier9_summ_delivered').withDescription('Total provider active power delivered (index 09)')},
349
+ {cluster: clustersDef._0x0702, att: 'currentTier10SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF10', ea.STATE).withUnit('kWh').withProperty('current_tier10_summ_delivered').withDescription('Total provider active power delivered (index 10)')},
347
350
  {cluster: clustersDef._0xFF66, att: 'activeEnerfyOutD01', reportable: true, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASD01', ea.STATE).withUnit('kWh').withProperty('active_enerfy_out_d01').withDescription('Active energy withdrawn Distributor (index 01)')},
348
351
  {cluster: clustersDef._0xFF66, att: 'activeEnerfyOutD02', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASD02', ea.STATE).withUnit('kWh').withProperty('active_enerfy_out_d02').withDescription('Active energy withdrawn Distributor (index 02)')},
349
352
  {cluster: clustersDef._0xFF66, att: 'activeEnerfyOutD03', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASD03', ea.STATE).withUnit('kWh').withProperty('active_enerfy_out_d03').withDescription('Active energy withdrawn Distributor (index 03)')},
@@ -443,19 +446,21 @@ function getCurrentConfig(device, options, logger=console) {
443
446
  .filter((e) => e.linkyMode == linkyMode && (e.linkyPhase == linkyPhase || e.linkyPhase == linkyPhaseDef.all) && (linkyProduction || !e.onlyProducer));
444
447
 
445
448
  // Filter even more, based on our current tarif
446
- let currentTarf;
449
+ let currentTarf = '';
447
450
 
448
- try {
449
- // Try to remove atributes which doesn't match current tarif
450
- currentTarf = endpoint.clusters.liXeePrivate.attributes.currentTarif.replace(/\0/g, '');
451
- } catch (error) {
452
- currentTarf = '';
453
- if (options && options.hasOwnProperty('tarif') && options['tarif'] != 'auto') {
454
- currentTarf = Object.entries(tarifsDef).find(( [k, v] ) => (v.fname == options['tarif']))[1].currentTarf;
451
+ if (options && options.hasOwnProperty('tarif') && options['tarif'] != 'auto') {
452
+ currentTarf = Object.entries(tarifsDef).find(( [k, v] ) => (v.fname == options['tarif']))[1].currentTarf;
453
+ } else {
454
+ try {
455
+ const lixAtts = endpoint.clusters[clustersDef._0xFF66].attributes;
456
+ lixAtts.raiseIfEmpty;
457
+ currentTarf = fzLocal.lixee_private_fz.convert({}, {data: lixAtts}).current_tarif;
458
+ } catch (error) {
459
+ logger.warn(`Not able to detect the current tarif. Not filtering any expose...`);
455
460
  }
456
461
  }
457
462
 
458
- // logger.debug(`zlinky config: ` + linkyMode + `, `+ linkyPhase + `, `+ linkyProduction.toString() +`, `+ currentTarf);
463
+ logger.debug(`zlinky config: ` + linkyMode + `, `+ linkyPhase + `, `+ linkyProduction.toString() +`, `+ currentTarf);
459
464
 
460
465
  switch (currentTarf) {
461
466
  case linkyMode == linkyModeDef.legacy && tarifsDef.histo_BASE.currentTarf:
@@ -467,7 +472,7 @@ function getCurrentConfig(device, options, logger=console) {
467
472
  case linkyMode == linkyModeDef.legacy && tarifsDef.histo_EJP.currentTarf:
468
473
  myExpose = myExpose.filter((a) => !tarifsDef.histo_EJP.excluded.includes(a.exposes.name));
469
474
  break;
470
- case linkyMode == linkyModeDef.legacy && currentTarf.startsWith(tarifsDef.histo_BBR.currentTarf):
475
+ case linkyMode == linkyModeDef.legacy && currentTarf && currentTarf.startsWith(tarifsDef.histo_BBR.currentTarf):
471
476
  myExpose = myExpose.filter((a) => !tarifsDef.histo_BBR.excluded.includes(a.exposes.name));
472
477
  break;
473
478
  case linkyMode == linkyModeDef.standard && tarifsDef.stand_SEM_WE_MERCR.currentTarf:
@@ -481,7 +486,7 @@ function getCurrentConfig(device, options, logger=console) {
481
486
  return myExpose;
482
487
  }
483
488
  const definition = {
484
- zigbeeModel: ['ZLinky_TIC'],
489
+ zigbeeModel: ['ZLinky_TIC', 'ZLinky_TIC\u0000'],
485
490
  model: 'ZLinky_TIC',
486
491
  vendor: 'LiXee',
487
492
  description: 'Lixee ZLinky',
@@ -512,8 +517,9 @@ const definition = {
512
517
  .withDescription(`Power with single or three phase. May require restart (default: auto)`),
513
518
  exposes.enum(`production`, ea.SET, ['auto', 'true', 'false']).withDescription(`If you produce energy back to the grid (works ONLY when linky_mode: ${linkyModeDef.standard}, default: auto)`),
514
519
  exposes.enum(`tarif`, ea.SET, [...Object.entries(tarifsDef).map(( [k, v] ) => (v.fname)), 'auto'])
515
- .withDescription(`The current tarif. This option will exclude unnecesary attributes. Default: auto`),
520
+ .withDescription(`Overrides the automatic current tarif. This option will exclude unnecesary attributes. Open a issue to support more of them. Default: auto`),
516
521
  exposes.options.precision(`kWh`),
522
+ 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`),
517
523
  ],
518
524
  configure: async (device, coordinatorEndpoint, logger, options) => {
519
525
  const endpoint = device.getEndpoint(1);
@@ -525,13 +531,15 @@ const definition = {
525
531
  clustersDef._0xFF66, /* liXeePrivate */
526
532
  ]);
527
533
 
534
+ await endpoint.read('liXeePrivate', ['linkyMode', 'currentTarif'], {manufacturerCode: null});
535
+
528
536
  const configReportings = [];
529
537
  const suscribeNew = getCurrentConfig(device, options, logger).filter((e) => e.reportable);
530
538
 
531
539
  const unsuscribe = endpoint.configuredReportings
532
540
  .filter((e) => !suscribeNew.some((r) => e.cluster.name == r.cluster && e.attribute.name == r.att));
533
541
  // Unsuscribe reports that doesn't correspond with the current config
534
- (await Promise.allSettled(unsuscribe.map((e) => endpoint.configureReporting(e.cluster.name, reporting.payload(e.attribute.name, e.minimumReportInterval, 65535, e.reportableChange)))))
542
+ (await Promise.allSettled(unsuscribe.map((e) => endpoint.configureReporting(e.cluster.name, reporting.payload(e.attribute.name, e.minimumReportInterval, 65535, e.reportableChange), {manufacturerCode: null}))))
535
543
  .filter((e) => e.status == 'rejected')
536
544
  .forEach((e) => {
537
545
  throw e.reason;
@@ -540,7 +548,7 @@ const definition = {
540
548
  for (const e of suscribeNew) {
541
549
  let params = {
542
550
  att: e.att,
543
- min: 0,
551
+ min: repInterval.MINUTE,
544
552
  max: repInterval.MINUTES_15,
545
553
  change: 1,
546
554
  };
@@ -550,7 +558,8 @@ const definition = {
550
558
  }
551
559
  configReportings.push(endpoint
552
560
  .configureReporting(
553
- e.cluster, reporting.payload(params.att, params.min, params.max, params.change)),
561
+ e.cluster, reporting.payload(params.att, params.min, params.max, params.change),
562
+ {manufacturerCode: null}),
554
563
  );
555
564
  }
556
565
  (await Promise.allSettled(configReportings))
@@ -562,19 +571,33 @@ const definition = {
562
571
  ota: ota.lixee,
563
572
  onEvent: async (type, data, device, options) => {
564
573
  const endpoint = device.getEndpoint(1);
565
- if (type === 'stop') {
574
+ if (type === 'start') {
575
+ endpoint.read('liXeePrivate', ['linkyMode', 'currentTarif'], {manufacturerCode: null});
576
+ } else if (type === 'stop') {
566
577
  clearInterval(globalStore.getValue(device, 'interval'));
567
578
  globalStore.clearValue(device, 'interval');
568
579
  } else if (!globalStore.hasValue(device, 'interval')) {
569
580
  const seconds = options && options.measurement_poll_interval ? options.measurement_poll_interval : 60;
581
+ const measurement_poll_chunk = options && options.measurement_poll_chunk ? options.measurement_poll_chunk : 1;
570
582
 
571
583
  const interval = setInterval(async () => {
572
584
  const currentExposes = getCurrentConfig(device, options)
573
585
  .filter((e) => !endpoint.configuredReportings.some((r) => r.cluster.name == e.cluster && r.attribute.name == e.att));
574
- for (const e of currentExposes) {
575
- await endpoint
576
- .read(e.cluster, [e.att])
577
- .catch((err) => { }); // TODO: Ignore reads error?
586
+
587
+ for (const key in clustersDef) {
588
+ if (Object.hasOwnProperty.call(clustersDef, key)) {
589
+ const cluster = clustersDef[key];
590
+
591
+ const targ = currentExposes.filter((e)=> e.cluster == cluster).map((e)=> e.att);
592
+ if (targ.length) {
593
+ let i; let j;
594
+ // Split array by chunks
595
+ for (i = 0, j = targ.length; i < j; i += measurement_poll_chunk) {
596
+ await endpoint
597
+ .read(cluster, targ.slice(i, i + measurement_poll_chunk), {manufacturerCode: null});
598
+ }
599
+ }
600
+ }
578
601
  }
579
602
  }, seconds * 1000);
580
603
  globalStore.putValue(device, 'interval', interval);
package/devices/meazon.js CHANGED
@@ -13,7 +13,7 @@ module.exports = [
13
13
  vendor: 'Meazon',
14
14
  description: 'Bizy plug meter',
15
15
  fromZigbee: [fz.command_on, fz.legacy.genOnOff_cmdOn, fz.command_off, fz.legacy.genOnOff_cmdOff, fz.on_off, fz.meazon_meter],
16
- exposes: [e.switch(), e.power(), e.voltage(), e.current()],
16
+ exposes: [e.switch(), e.power(), e.voltage(), e.current(), e.energy()],
17
17
  toZigbee: [tz.on_off],
18
18
  configure: async (device, coordinatorEndpoint, logger) => {
19
19
  const endpoint = device.getEndpoint(10);
@@ -1,5 +1,4 @@
1
1
  const exposes = require('../lib/exposes');
2
- const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
3
2
  const tz = require('../converters/toZigbee');
4
3
  const e = exposes.presets;
5
4
  const ea = exposes.access;
@@ -12,8 +11,11 @@ module.exports = [
12
11
  model: 'FUT039Z',
13
12
  vendor: 'Miboxer',
14
13
  description: 'RGB+CCT LED controller',
15
- toZigbee: [tz.on_off, tz.tuya_led_control, tz.tuya_do_not_disturb, tz.tuya_color_power_on_behavior],
16
- fromZigbee: [fz.on_off, fz.tuya_led_controller, fz.brightness, fz.ignore_basic_report],
14
+ toZigbee: extend.light_onoff_brightness_colortemp_color().toZigbee.concat([
15
+ tz.tuya_do_not_disturb, tz.tuya_color_power_on_behavior,
16
+ ]),
17
+ meta: {applyRedFix: true, enhancedHue: false},
18
+ fromZigbee: extend.light_onoff_brightness_colortemp_color().fromZigbee,
17
19
  exposes: [e.light_brightness_colortemp_colorhs([153, 500]).removeFeature('color_temp_startup'),
18
20
  exposes.binary('do_not_disturb', ea.STATE_SET, true, false)
19
21
  .withDescription('Do not disturb mode'),
@@ -31,7 +33,8 @@ module.exports = [
31
33
  onEvent: tuya.onEventSetTime,
32
34
  },
33
35
  {
34
- fingerprint: [{modelID: 'TS0502B', manufacturerName: '_TZ3210_frm6149r'}],
36
+ fingerprint: [{modelID: 'TS0502B', manufacturerName: '_TZ3210_frm6149r'},
37
+ {modelID: 'TS0502B', manufacturerName: '_TZ3210_jtifm80b'}],
35
38
  model: 'FUT035Z',
36
39
  description: 'Dual white LED controller',
37
40
  vendor: 'Miboxer',
package/devices/moes.js CHANGED
@@ -10,7 +10,8 @@ const ea = exposes.access;
10
10
 
11
11
  module.exports = [
12
12
  {
13
- fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_cymsnfvf'}],
13
+ fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_cymsnfvf'},
14
+ {modelID: 'TS011F', manufacturerName: '_TZ3000_2xlvlnez'}],
14
15
  model: 'ZP-LZ-FR2U',
15
16
  vendor: 'Moes',
16
17
  description: 'Zigbee 3.0 dual USB wireless socket plug',
@@ -45,7 +45,7 @@ module.exports = [
45
45
  },
46
46
  {
47
47
  zigbeeModel: ['ZBT-ExtendedColor'],
48
- model: '404000/404005/404012',
48
+ model: '404000/404005/404012/404019',
49
49
  vendor: 'Müller Licht',
50
50
  description: 'Tint LED bulb GU10/E14/E27 350/470/806 lumen, dimmable, color, opal white',
51
51
  extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 556], supportsHS: true}),
@@ -88,6 +88,13 @@ module.exports = [
88
88
  description: 'Amaris LED panels',
89
89
  extend: extend.light_onoff_brightness_colortemp_color(),
90
90
  },
91
+ {
92
+ zigbeeModel: ['371232040'],
93
+ model: '371232040',
94
+ vendor: 'Paulmann',
95
+ description: 'LED panels',
96
+ extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 350]}),
97
+ },
91
98
  {
92
99
  zigbeeModel: ['500.45'],
93
100
  model: '500.45',
@@ -2465,7 +2465,7 @@ module.exports = [
2465
2465
  ota: ota.zigbeeOTA,
2466
2466
  },
2467
2467
  {
2468
- zigbeeModel: ['5309230P6', '5309231P6'],
2468
+ zigbeeModel: ['5309230P6', '5309231P6', '929003045701_01', '929003045701_02'],
2469
2469
  model: '5309230P6',
2470
2470
  vendor: 'Philips',
2471
2471
  description: 'Hue White ambiance Runner double spotlight',
@@ -1,7 +1,7 @@
1
- const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
2
- const tz = require('zigbee-herdsman-converters/converters/toZigbee');
3
- const exposes = require('zigbee-herdsman-converters/lib/exposes');
4
- const reporting = require('zigbee-herdsman-converters/lib/reporting');
1
+ const fz = require('../converters/fromZigbee');
2
+ const tz = require('../converters/toZigbee');
3
+ const exposes = require('../lib/exposes');
4
+ const reporting = require('../lib/reporting');
5
5
  const e = exposes.presets;
6
6
  const ea = exposes.access;
7
7
 
@@ -100,13 +100,15 @@ module.exports = [
100
100
  model: 'CCT5010-0001',
101
101
  vendor: 'Schneider Electric',
102
102
  description: 'Micro module dimmer',
103
- fromZigbee: [fz.on_off, fz.brightness, fz.level_config, fz.lighting_ballast_configuration],
104
- toZigbee: [tz.light_onoff_brightness, tz.level_config, tz.ballast_config],
103
+ fromZigbee: [fz.on_off, fz.brightness, fz.level_config, fz.wiser_lighting_ballast_configuration],
104
+ toZigbee: [tz.light_onoff_brightness, tz.level_config, tz.ballast_config, tz.wiser_dimmer_mode],
105
105
  exposes: [e.light_brightness().withLevelConfig(),
106
106
  exposes.numeric('ballast_minimum_level', ea.ALL).withValueMin(1).withValueMax(254)
107
107
  .withDescription('Specifies the minimum light output of the ballast'),
108
108
  exposes.numeric('ballast_maximum_level', ea.ALL).withValueMin(1).withValueMax(254)
109
- .withDescription('Specifies the maximum light output of the ballast')],
109
+ .withDescription('Specifies the maximum light output of the ballast'),
110
+ exposes.enum('dimmer_mode', ea.ALL, ['auto', 'rc', 'rl', 'rl_led'])
111
+ .withDescription('Sets dimming mode to autodetect or fixed RC/RL/RL_LED mode (max load is reduced in RL_LED)')],
110
112
  whiteLabel: [{vendor: 'Elko', model: 'EKO07090'}],
111
113
  configure: async (device, coordinatorEndpoint, logger) => {
112
114
  await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
@@ -134,13 +136,15 @@ module.exports = [
134
136
  model: 'WDE002334',
135
137
  vendor: 'Schneider Electric',
136
138
  description: 'Rotary dimmer',
137
- fromZigbee: [fz.on_off, fz.brightness, fz.level_config, fz.lighting_ballast_configuration],
138
- toZigbee: [tz.light_onoff_brightness, tz.level_config, tz.ballast_config],
139
+ fromZigbee: [fz.on_off, fz.brightness, fz.level_config, fz.wiser_lighting_ballast_configuration],
140
+ toZigbee: [tz.light_onoff_brightness, tz.level_config, tz.ballast_config, tz.wiser_dimmer_mode],
139
141
  exposes: [e.light_brightness().withLevelConfig(),
140
142
  exposes.numeric('ballast_minimum_level', ea.ALL).withValueMin(1).withValueMax(254)
141
143
  .withDescription('Specifies the minimum light output of the ballast'),
142
144
  exposes.numeric('ballast_maximum_level', ea.ALL).withValueMin(1).withValueMax(254)
143
- .withDescription('Specifies the maximum light output of the ballast')],
145
+ .withDescription('Specifies the maximum light output of the ballast'),
146
+ exposes.enum('dimmer_mode', ea.ALL, ['auto', 'rc', 'rl', 'rl_led'])
147
+ .withDescription('Sets dimming mode to autodetect or fixed RC/RL/RL_LED mode (max load is reduced in RL_LED)')],
144
148
  configure: async (device, coordinatorEndpoint, logger) => {
145
149
  const endpoint = device.getEndpoint(3);
146
150
  await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl', 'lightingBallastCfg']);
package/devices/slv.js ADDED
@@ -0,0 +1,20 @@
1
+ const extend = require('../lib/extend');
2
+
3
+ module.exports = [
4
+ {
5
+ zigbeeModel: ['1001248', 'ZBT-ColorTemperature-Panel'],
6
+ model: '1001248',
7
+ vendor: 'SLV',
8
+ description: 'VALETO CCT LED driver',
9
+ extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 370]}),
10
+ },
11
+ {
12
+ zigbeeModel: ['1002994'],
13
+ model: '1002994',
14
+ vendor: 'SLV',
15
+ description: 'VALETO remote (binds to device)',
16
+ fromZigbee: [],
17
+ toZigbee: [],
18
+ exposes: [],
19
+ },
20
+ ];
package/devices/sonoff.js CHANGED
@@ -78,7 +78,7 @@ module.exports = [
78
78
  vendor: 'SONOFF',
79
79
  whiteLabel: [{vendor: 'eWeLink', model: 'RHK07'}],
80
80
  description: 'Wireless button',
81
- exposes: [e.battery(), e.action(['single', 'double', 'long'])],
81
+ exposes: [e.battery(), e.action(['single', 'double', 'long']), e.battery_voltage()],
82
82
  fromZigbee: [fz.ewelink_action, fz.battery],
83
83
  toZigbee: [],
84
84
  configure: async (device, coordinatorEndpoint, logger) => {
@@ -144,7 +144,7 @@ module.exports = [
144
144
  await reporting.batteryVoltage(endpoint);
145
145
  await reporting.batteryPercentageRemaining(endpoint);
146
146
  },
147
- exposes: [e.occupancy(), e.battery_low(), e.tamper(), e.battery()],
147
+ exposes: [e.occupancy(), e.battery_low(), e.tamper(), e.battery(), e.battery_voltage()],
148
148
  },
149
149
  {
150
150
  zigbeeModel: ['S26R2ZB'],
@@ -36,4 +36,11 @@ module.exports = [
36
36
  await reporting.onOff(endpoint);
37
37
  },
38
38
  },
39
+ {
40
+ zigbeeModel: ['S32053'],
41
+ model: 'S32053',
42
+ vendor: 'The Light Group',
43
+ description: 'SLC SmartOne CV led dimmable driver',
44
+ extend: extend.light_onoff_brightness(),
45
+ },
39
46
  ];
package/devices/tuya.js CHANGED
@@ -12,7 +12,7 @@ const utils = require('../lib/utils');
12
12
 
13
13
  const TS011Fplugs = ['_TZ3000_5f43h46b', '_TZ3000_cphmq0q7', '_TZ3000_dpo1ysak', '_TZ3000_ew3ldmgx', '_TZ3000_gjnozsaz',
14
14
  '_TZ3000_jvzvulen', '_TZ3000_mraovvmm', '_TZ3000_nfnmi125', '_TZ3000_ps3dmato', '_TZ3000_w0qqde0g', '_TZ3000_u5u4cakc',
15
- '_TZ3000_rdtixbnu', '_TZ3000_typdpbpg', '_TZ3000_2xlvlnez'];
15
+ '_TZ3000_rdtixbnu', '_TZ3000_typdpbpg'];
16
16
 
17
17
  const tzLocal = {
18
18
  TS0504B_color: {
@@ -98,6 +98,15 @@ module.exports = [
98
98
  toZigbee: [],
99
99
  exposes: [e.temperature(), e.humidity(), e.co2(), e.voc(), e.formaldehyd(), e.pm25()],
100
100
  },
101
+ {
102
+ fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_7bztmfm1'}],
103
+ model: 'TS0601_smart_CO_air_box',
104
+ vendor: 'TuYa',
105
+ description: 'Smart air box (carbon monoxide)',
106
+ fromZigbee: [fz.tuya_CO],
107
+ toZigbee: [],
108
+ exposes: [e.carbon_monoxide(), e.co()],
109
+ },
101
110
  {
102
111
  fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_ggev5fsl'}],
103
112
  model: 'TS0601_gas_sensor',
@@ -110,14 +119,14 @@ module.exports = [
110
119
  {
111
120
  fingerprint: [{modelID: 'TS0001', manufacturerName: '_TZ3000_hktqahrq'}, {manufacturerName: '_TZ3000_hktqahrq'},
112
121
  {manufacturerName: '_TZ3000_q6a3tepg'}, {modelID: 'TS000F', manufacturerName: '_TZ3000_m9af2l6g'},
113
- {modelID: 'TS0001', manufacturerName: '_TZ3000_npzfdcof'}],
122
+ {modelID: 'TS0001', manufacturerName: '_TZ3000_npzfdcof'},
123
+ {modelID: 'TS0001', manufacturerName: '_TZ3000_v7gnj3ad'}],
114
124
  model: 'WHD02',
115
125
  vendor: 'TuYa',
116
126
  description: 'Wall switch module',
117
- toZigbee: extend.switch().toZigbee.concat([tz.moes_power_on_behavior]),
118
- fromZigbee: extend.switch().fromZigbee.concat([fz.moes_power_on_behavior]),
119
- exposes: extend.switch().exposes.concat([exposes.enum('power_on_behavior', ea.ALL, ['off', 'previous', 'on'])
120
- .withDescription('Controls the behaviour when the device is powered on')]),
127
+ toZigbee: extend.switch().toZigbee.concat([tz.moes_power_on_behavior, tz.tuya_switch_type]),
128
+ fromZigbee: extend.switch().fromZigbee.concat([fz.moes_power_on_behavior, fz.tuya_switch_type]),
129
+ exposes: extend.switch().exposes.concat([e.power_on_behavior(), e.switch_type_2()]),
121
130
  configure: async (device, coordinatorEndpoint, logger) => {
122
131
  await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
123
132
  },
@@ -248,6 +257,7 @@ module.exports = [
248
257
  {modelID: 'TS0202', manufacturerName: '_TYZB01_tv3wxhcz'},
249
258
  {modelID: 'TS0202', manufacturerName: '_TYZB01_hqbdru35'},
250
259
  {modelID: 'TS0202', manufacturerName: '_TZ3000_tiwq83wk'},
260
+ {modelID: 'TS0202', manufacturerName: '_TZ3000_ykwcwxmz'},
251
261
  {modelID: 'WHD02', manufacturerName: '_TZ3000_hktqahrq'}],
252
262
  model: 'TS0202',
253
263
  vendor: 'TuYa',
@@ -255,7 +265,7 @@ module.exports = [
255
265
  whiteLabel: [{vendor: 'Mercator Ikuü', model: 'SMA02P'}, {vendor: 'TuYa', model: 'TY-ZPR06'}],
256
266
  fromZigbee: [fz.ias_occupancy_alarm_1, fz.battery, fz.ignore_basic_report, fz.ias_occupancy_alarm_1_report],
257
267
  toZigbee: [],
258
- exposes: [e.occupancy(), e.battery_low(), e.tamper(), e.battery()],
268
+ exposes: [e.occupancy(), e.battery_low(), e.tamper(), e.battery(), e.battery_voltage()],
259
269
  },
260
270
  {
261
271
  fingerprint: [{modelID: 'TS0202', manufacturerName: '_TZ3000_mcxw5ehu'},
@@ -411,6 +421,7 @@ module.exports = [
411
421
  {modelID: 'TS0601', manufacturerName: '_TZE200_vhy3iakz'},
412
422
  {modelID: 'TS0601', manufacturerName: '_TZE200_oisqyl4o'},
413
423
  {modelID: 'TS0601', manufacturerName: '_TZ3000_uim07oem'},
424
+ {modelID: 'TS0601', manufacturerName: '_TZE200_js3mgbjb'},
414
425
  ],
415
426
  model: 'TS0601_switch',
416
427
  vendor: 'TuYa',
@@ -962,7 +973,8 @@ module.exports = [
962
973
  'to the desired temperature. If you want TRV to properly regulate the temperature you need to use mode `auto` ' +
963
974
  'instead setting the desired temperature.')
964
975
  .withLocalTemperatureCalibration(-9, 9, 1, ea.STATE_SET)
965
- .withAwayMode().withPreset(['schedule', 'manual', 'boost', 'complex', 'comfort', 'eco']),
976
+ .withAwayMode().withPreset(['schedule', 'manual', 'boost', 'complex', 'comfort', 'eco'])
977
+ .withRunningState(['idle', 'heat'], ea.STATE),
966
978
  e.auto_lock(), e.away_mode(), e.away_preset_days(), e.boost_time(), e.comfort_temperature(), e.eco_temperature(), e.force(),
967
979
  e.max_temperature(), e.min_temperature(), e.away_preset_temperature(),
968
980
  exposes.composite('programming_mode').withDescription('Schedule MODE ⏱ - In this mode, ' +
@@ -1741,7 +1753,7 @@ module.exports = [
1741
1753
  await reporting.bind(endpoint, coordinatorEndpoint, ['genBasic']);
1742
1754
  },
1743
1755
  exposes: [exposes.binary('trigger', ea.STATE_SET, true, false).withDescription('Trigger the door movement'),
1744
- e.action(['trigger']), exposes.binary('garage_door_contact', ea.STATE, true, false)],
1756
+ exposes.binary('garage_door_contact', ea.STATE, true, false)],
1745
1757
  },
1746
1758
  {
1747
1759
  fingerprint: [{modelID: 'TS0201', manufacturerName: '_TZ3000_qaaysllp'}],
@@ -1895,15 +1907,13 @@ module.exports = [
1895
1907
  exposes.text('alarm', ea.STATE),
1896
1908
  exposes.binary('trip', ea.STATE_SET, 'trip', 'clear'),
1897
1909
  exposes.binary('child_lock', ea.STATE_SET, 'ON', 'OFF'),
1898
- exposes.enum('power_on_behaviour', ea.STATE_SET, ['off', 'on', 'previous']),
1910
+ exposes.enum('power_on_behavior', ea.STATE_SET, ['off', 'on', 'previous']),
1899
1911
  exposes.numeric('countdown_timer', ea.STATE_SET).withValueMin(0).withValueMax(86400).withUnit('s'),
1900
- exposes.numeric('voltage', ea.STATE).withUnit('V'),
1901
1912
  exposes.numeric('voltage_rms', ea.STATE).withUnit('V'),
1902
1913
  exposes.numeric('current', ea.STATE).withUnit('A'),
1903
1914
  exposes.numeric('current_average', ea.STATE).withUnit('A'),
1904
- exposes.numeric('power', ea.STATE).withUnit('W'),
1915
+ e.power(), e.voltage(), e.energy(), e.temperature(),
1905
1916
  exposes.numeric('energy_consumed', ea.STATE).withUnit('kWh'),
1906
- exposes.numeric('temperature', ea.STATE).withUnit('°C'),
1907
1917
  /* TODO: Add toZigbee converters for the below composites
1908
1918
  exposes.composite('voltage_setting', 'voltage_setting')
1909
1919
  .withFeature(exposes.numeric('under_voltage_threshold', ea.STATE_SET)
@@ -2006,4 +2016,13 @@ module.exports = [
2006
2016
  toZigbee: [],
2007
2017
  exposes: [e.illuminance_lux(), e.brightness_state()],
2008
2018
  },
2019
+ {
2020
+ fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_kltffuzl'}, {modelID: 'TS0601', manufacturerName: '_TZE200_fwoorn8y'}],
2021
+ model: 'TM001-ZA/TM081',
2022
+ vendor: 'TuYa',
2023
+ description: 'Door and window sensor',
2024
+ fromZigbee: [fz.tm081],
2025
+ toZigbee: [],
2026
+ exposes: [e.contact(), e.battery()],
2027
+ },
2009
2028
  ];
package/devices/xiaomi.js CHANGED
@@ -436,11 +436,11 @@ module.exports = [
436
436
  fromZigbee: [fz.xiaomi_on_off_ignore_endpoint_4_5_6, fz.xiaomi_on_off_action, fz.legacy.QBKG04LM_QBKG11LM_click,
437
437
  fz.xiaomi_operation_mode_basic],
438
438
  exposes: [
439
- e.switch(), e.action(['single', 'release', 'hold']),
440
- exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
439
+ e.switch(), e.action(['release', 'hold']),
440
+ exposes.enum('operation_mode', ea.STATE_SET, ['control_relay', 'decoupled'])
441
441
  .withDescription('Decoupled mode'),
442
442
  ],
443
- toZigbee: [tz.on_off, tz.xiaomi_switch_operation_mode_basic],
443
+ toZigbee: [tz.on_off, {...tz.xiaomi_switch_operation_mode_basic, convertGet: null}],
444
444
  endpoint: (device) => {
445
445
  return {'system': 1, 'default': 2};
446
446
  },
@@ -484,15 +484,15 @@ module.exports = [
484
484
  e.switch().withEndpoint('left'),
485
485
  e.switch().withEndpoint('right'),
486
486
  e.temperature(),
487
- e.action(['single_left', 'single_right', 'single_both']),
488
- exposes.enum('operation_mode', ea.ALL, ['control_left_relay', 'control_right_relay', 'decoupled'])
487
+ e.action(['release_left', 'release_right', 'release_both']),
488
+ exposes.enum('operation_mode', ea.STATE_SET, ['control_left_relay', 'control_right_relay', 'decoupled'])
489
489
  .withDescription('Operation mode for left button')
490
490
  .withEndpoint('left'),
491
- exposes.enum('operation_mode', ea.ALL, ['control_left_relay', 'control_right_relay', 'decoupled'])
491
+ exposes.enum('operation_mode', ea.STATE_SET, ['control_left_relay', 'control_right_relay', 'decoupled'])
492
492
  .withDescription('Operation mode for right button')
493
493
  .withEndpoint('right'),
494
494
  ],
495
- toZigbee: [tz.on_off, tz.xiaomi_switch_operation_mode_basic, tz.xiaomi_power],
495
+ toZigbee: [tz.on_off, {...tz.xiaomi_switch_operation_mode_basic, convertGet: null}, tz.xiaomi_power],
496
496
  meta: {multiEndpoint: true},
497
497
  endpoint: (device) => {
498
498
  return {'system': 1, 'left': 2, 'right': 3};
package/lib/constants.js CHANGED
@@ -247,6 +247,13 @@ const easyCodeTouchActions = {
247
247
  0xFF0E: 'zigbee_unlock',
248
248
  };
249
249
 
250
+ const wiserDimmerControlMode = {
251
+ 0: 'auto',
252
+ 1: 'rc',
253
+ 2: 'rl',
254
+ 3: 'rl_led',
255
+ };
256
+
250
257
  module.exports = {
251
258
  OneJanuary2000,
252
259
  repInterval,
@@ -275,4 +282,5 @@ module.exports = {
275
282
  lockSoundVolume,
276
283
  lockUserStatus,
277
284
  easyCodeTouchActions,
285
+ wiserDimmerControlMode,
278
286
  };
package/lib/exposes.js CHANGED
@@ -519,6 +519,7 @@ module.exports = {
519
519
  carbon_monoxide: () => new Binary('carbon_monoxide', access.STATE, true, false).withDescription('Indicates if CO (carbon monoxide) is detected'),
520
520
  child_lock: () => new Lock().withState('child_lock', 'LOCK', 'UNLOCK', 'Enables/disables physical input on the device', access.STATE_SET),
521
521
  co2: () => new Numeric('co2', access.STATE).withUnit('ppm').withDescription('The measured CO2 (carbon dioxide) value'),
522
+ co: () => new Numeric('co', access.STATE).withUnit('ppm').withDescription('The measured CO (carbon monoxide) value'),
522
523
  comfort_temperature: () => new Numeric('comfort_temperature', access.STATE_SET).withUnit('°C').withDescription('Comfort temperature').withValueMin(0).withValueMax(30),
523
524
  consumer_connected: () => new Binary('consumer_connected', access.STATE, true, false).withDescription('Indicates whether a plug is physically attached. Device does not have to pull power or even be connected electrically (state of this binary switch can be ON even if main power switch is OFF)'),
524
525
  contact: () => new Binary('contact', access.STATE, false, true).withDescription('Indicates if the contact is closed (= true) or open (= false)'),
package/lib/legacy.js CHANGED
@@ -1012,12 +1012,14 @@ const fromZigbee = {
1012
1012
  type: ['attributeReport'],
1013
1013
  options: [exposes.options.legacy()],
1014
1014
  convert: (model, msg, publish, options, meta) => {
1015
- const mapping = {4: 'left', 5: 'right'};
1016
- const button = mapping[msg.endpoint.ID];
1017
- if (button) {
1018
- const payload = {};
1019
- payload[`button_${button}`] = msg.data['onOff'] === 1 ? 'release' : 'hold';
1020
- return payload;
1015
+ if (isLegacyEnabled(options)) {
1016
+ const mapping = {4: 'left', 5: 'right'};
1017
+ const button = mapping[msg.endpoint.ID];
1018
+ if (button) {
1019
+ const payload = {};
1020
+ payload[`button_${button}`] = msg.data['onOff'] === 1 ? 'release' : 'hold';
1021
+ return payload;
1022
+ }
1021
1023
  }
1022
1024
  },
1023
1025
  },
package/lib/tuya.js CHANGED
@@ -421,6 +421,9 @@ const dataPoints = {
421
421
  // tuya Smart Air House Keeper, Multifunctionale air quality detector.
422
422
  // CO2, Temp, Humidity, VOC and Formaldehyd same as Smart Air Box
423
423
  tuyaSahkMP25: 20,
424
+ // Tuya CO (carbon monoxide) smart air box
425
+ tuyaSabCOalarm: 1,
426
+ tuyaSabCO: 2,
424
427
  lidlTimer: 5,
425
428
  // Moes MS-105 Dimmer
426
429
  moes105DimmerState1: 1,
package/lib/utils.js CHANGED
@@ -74,7 +74,8 @@ function hasAlreadyProcessedMessage(msg, ID=null, key=null) {
74
74
  return false;
75
75
  }
76
76
 
77
- const defaultPrecision = {temperature: 2, humidity: 2, pressure: 1, pm25: 0, power: 2, voltage: 2, current: 2};
77
+ const defaultPrecision = {temperature: 2, humidity: 2, pressure: 1, pm25: 0, power: 2, current: 2, current_phase_b: 2, current_phase_c: 2,
78
+ voltage: 2, voltage_phase_b: 2, voltage_phase_c: 2};
78
79
  function calibrateAndPrecisionRoundOptions(number, options, type) {
79
80
  // Calibrate
80
81
  const calibrateKey = `${type}_calibration`;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.421",
3
+ "version": "14.0.425",
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.421",
3
+ "version": "14.0.425",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [