zigbee-herdsman-converters 14.0.626 → 14.0.628

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.
@@ -8155,9 +8155,12 @@ const converters = {
8155
8155
  convert: (model, msg, publish, options, meta) => {
8156
8156
  const lookup = {'0': 'idle', '1': 'in', '2': 'out'};
8157
8157
  const value = precisionRound(parseFloat(msg.data['presentValue']), 1);
8158
+ const people = precisionRound(msg.data.presentValue, 0);
8158
8159
  let result = null;
8159
- result = {people: precisionRound(msg.data.presentValue, 0), status: lookup[value*10%10]};
8160
- return result;
8160
+ if (value <= 80) {
8161
+ result = {people: people, status: lookup[value*10%10]};
8162
+ return result;
8163
+ }
8161
8164
  },
8162
8165
  },
8163
8166
  sihas_action: {
@@ -3484,8 +3484,6 @@ const converters = {
3484
3484
  if (value == 'ON') {
3485
3485
  await tuya.sendDataPointBool(entity, tuya.dataPoints.tvHeatingStop, 1);
3486
3486
  } else {
3487
- await tuya.sendDataPointBool(entity, tuya.dataPoints.tvHeatingStop, 0);
3488
- await utils.sleep(500);
3489
3487
  await tuya.sendDataPointEnum(entity, tuya.dataPoints.tvMode, 1 /* manual */);
3490
3488
  }
3491
3489
  break;
@@ -3493,8 +3491,6 @@ const converters = {
3493
3491
  if (value == 'ON') {
3494
3492
  await tuya.sendDataPointBool(entity, tuya.dataPoints.tvFrostDetection, 1);
3495
3493
  } else {
3496
- await tuya.sendDataPointBool(entity, tuya.dataPoints.tvFrostDetection, 0);
3497
- await utils.sleep(500);
3498
3494
  await tuya.sendDataPointEnum(entity, tuya.dataPoints.tvMode, 1 /* manual */);
3499
3495
  }
3500
3496
  break;
package/devices/acova.js CHANGED
@@ -5,7 +5,7 @@ const reporting = require('../lib/reporting');
5
5
 
6
6
  module.exports = [
7
7
  {
8
- zigbeeModel: ['PERCALE2 D1.00P1.01Z1.00'],
8
+ zigbeeModel: ['PERCALE2 D1.00P1.01Z1.00', 'PERCALE2 D1.00P1.02Z1.00'],
9
9
  model: 'PERCALE2',
10
10
  vendor: 'Acova',
11
11
  description: 'Percale 2 heater',
@@ -3,13 +3,29 @@ const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/lega
3
3
  const tz = require('../converters/toZigbee');
4
4
  const extend = require('../lib/extend');
5
5
  const ea = exposes.access;
6
+ const e = exposes.presets;
7
+
8
+ const fzLocal = {
9
+ DTB2011014: {
10
+ cluster: 'genOnOff',
11
+ type: ['attributeReport', 'readResponse'],
12
+ convert: (model, msg, publish, options, meta) => {
13
+ return {
14
+ key_1: msg.data['41361'] === 1 ? 'ON' : 'OFF',
15
+ key_2: msg.data['41362'] === 1 ? 'ON' : 'OFF',
16
+ key_3: msg.data['41363'] === 1 ? 'ON' : 'OFF',
17
+ key_4: msg.data['41364'] === 1 ? 'ON' : 'OFF',
18
+ };
19
+ },
20
+ },
21
+ };
6
22
 
7
23
  module.exports = [
8
24
  {
9
25
  zigbeeModel: ['DTB190502A1'],
10
26
  model: 'DTB190502A1',
11
27
  vendor: 'databyte.ch',
12
- description: '[CC2530 based IO Board](https://databyte.ch/zigbee-dev-board-dtb190502a)',
28
+ description: 'CC2530 based IO Board',
13
29
  fromZigbee: [fz.DTB190502A1],
14
30
  toZigbee: [tz.DTB190502A1_LED],
15
31
  exposes: [exposes.binary('led_state', ea.STATE, 'ON', 'OFF'),
@@ -19,7 +35,21 @@ module.exports = [
19
35
  zigbeeModel: ['DTB-ED2004-012'],
20
36
  model: 'ED2004-012',
21
37
  vendor: 'databyte.ch',
22
- description: 'Panda 1 - wall switch (https://databyte.ch/panda1-wallswitch-zigbee)',
38
+ description: 'Panda 1 - wall switch',
23
39
  extend: extend.switch(),
24
40
  },
41
+ {
42
+ zigbeeModel: ['DTB-ED2011-014'],
43
+ model: 'Touch4',
44
+ vendor: 'databyte.ch',
45
+ description: 'Wall touchsensor with 4 keys',
46
+ fromZigbee: [fzLocal.DTB2011014, fz.battery],
47
+ toZigbee: [],
48
+ exposes: [e.battery(), e.linkquality(),
49
+ exposes.binary('key_1', ea.STATE, 'ON', 'OFF'),
50
+ exposes.binary('key_2', ea.STATE, 'ON', 'OFF'),
51
+ exposes.binary('key_3', ea.STATE, 'ON', 'OFF'),
52
+ exposes.binary('key_4', ea.STATE, 'ON', 'OFF'),
53
+ ],
54
+ },
25
55
  ];
@@ -1,5 +1,7 @@
1
1
  const reporting = require('../lib/reporting');
2
2
  const extend = require('../lib/extend');
3
+ const exposes = require('../lib/exposes');
4
+ const e = exposes.presets;
3
5
 
4
6
  module.exports = [
5
7
  {
@@ -8,11 +10,20 @@ module.exports = [
8
10
  vendor: 'HZC Electric',
9
11
  description: 'Zigbee dual dimmer',
10
12
  extend: extend.light_onoff_brightness({noConfigure: true}),
13
+ exposes: [e.light_brightness().withEndpoint('l1'), e.light_brightness().withEndpoint('l2')],
11
14
  configure: async (device, coordinatorEndpoint, logger) => {
12
15
  await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
13
- const endpoint = device.getEndpoint(1);
14
- await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
15
- await reporting.onOff(endpoint);
16
+ const endpoint1 = device.getEndpoint(1);
17
+ await reporting.bind(endpoint1, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
18
+ await reporting.onOff(endpoint1);
19
+
20
+ await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
21
+ const endpoint2 = device.getEndpoint(2);
22
+ await reporting.bind(endpoint2, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
23
+ await reporting.onOff(endpoint2);
24
+ },
25
+ endpoint: () => {
26
+ return {l1: 1, l2: 2};
16
27
  },
17
28
  },
18
29
  ];
package/devices/ikea.js CHANGED
@@ -6,6 +6,7 @@ const constants = require('../lib/constants');
6
6
  const reporting = require('../lib/reporting');
7
7
  const {repInterval} = require('../lib/constants');
8
8
  const utils = require('../lib/utils');
9
+ const libColor = require('../lib/color');
9
10
  const extend = require('../lib/extend');
10
11
  const globalStore = require('../lib/store');
11
12
  const e = exposes.presets;
@@ -60,6 +61,30 @@ const configureRemote = async (device, coordinatorEndpoint, logger) => {
60
61
  await reporting.batteryPercentageRemaining(endpoint);
61
62
  };
62
63
 
64
+ const tzLocal = {
65
+ LED1624G9_color_colortemp: {
66
+ ...tz.light_color_colortemp,
67
+ convertSet: async (entity, key, value, meta) => {
68
+ if (key == 'color') {
69
+ const result = await tz.light_color.convertSet(entity, key, value, meta);
70
+ return result;
71
+ } else if (key == 'color_temp' || key == 'color_temp_percent') {
72
+ const xy = libColor.ColorXY.fromMireds(value);
73
+ const payload = {
74
+ transtime: utils.getTransition(entity, key, meta).time,
75
+ colorx: utils.mapNumberRange(xy.x, 0, 1, 0, 65535),
76
+ colory: utils.mapNumberRange(xy.y, 0, 1, 0, 65535),
77
+ };
78
+ await entity.command('lightingColorCtrl', 'moveToColor', payload, utils.getOptions(meta.mapped, entity));
79
+ return {
80
+ state: libColor.syncColorState({'color_mode': constants.colorMode[2], 'color_temp': value}, meta.state,
81
+ entity, meta.options, meta.logger), readAfterWriteTime: payload.transtime * 100,
82
+ };
83
+ }
84
+ },
85
+ },
86
+ };
87
+
63
88
  const fzLocal = {
64
89
  // The STYRBAR sends an on +- 500ms after the arrow release. We don't want to send the ON action in this case.
65
90
  // https://github.com/Koenkk/zigbee2mqtt/issues/13335
@@ -453,7 +478,12 @@ module.exports = [
453
478
  model: 'LED1624G9',
454
479
  vendor: 'IKEA',
455
480
  description: 'TRADFRI LED bulb E14/E26/E27 600 lumen, dimmable, color, opal white',
456
- extend: tradfriExtend.light_onoff_brightness_color(),
481
+ extend: tradfriExtend.light_onoff_brightness_colortemp_color(),
482
+ toZigbee: utils.replaceInArray(
483
+ tradfriExtend.light_onoff_brightness_colortemp_color().toZigbee,
484
+ [tz.light_color_colortemp],
485
+ [tzLocal.LED1624G9_color_colortemp],
486
+ ),
457
487
  meta: {supportsHueAndSaturation: false},
458
488
  },
459
489
  {
@@ -38,13 +38,15 @@ module.exports = [
38
38
  model: 'MCLH-03',
39
39
  vendor: 'LifeControl',
40
40
  description: 'Power plug',
41
- fromZigbee: [fz.on_off, fz.electrical_measurement],
41
+ fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering],
42
42
  toZigbee: [tz.on_off],
43
43
  configure: async (device, coordinatorEndpoint, logger) => {
44
44
  const endpoint = device.getEndpoint(1);
45
- await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement']);
45
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'seMetering']);
46
46
  await reporting.onOff(endpoint);
47
47
  await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
48
+ await reporting.readMeteringMultiplierDivisor(endpoint);
49
+ await reporting.currentSummDelivered(endpoint);
48
50
  },
49
51
  onEvent: async (type, data, device) => {
50
52
  // This device doesn't support reporting correctly.
@@ -57,6 +59,7 @@ module.exports = [
57
59
  const interval = setInterval(async () => {
58
60
  try {
59
61
  await endpoint.read('haElectricalMeasurement', ['rmsVoltage', 'rmsCurrent', 'activePower']);
62
+ await endpoint.read('seMetering', ['currentSummDelivered', 'multiplier', 'divisor']);
60
63
  } catch (error) {
61
64
  // Do nothing
62
65
  }
@@ -64,7 +67,7 @@ module.exports = [
64
67
  globalStore.putValue(device, 'interval', interval);
65
68
  }
66
69
  },
67
- exposes: [e.switch(), e.power(), e.current(), e.voltage()],
70
+ exposes: [e.switch(), e.power(), e.current(), e.voltage(), e.energy()],
68
71
  },
69
72
  {
70
73
  zigbeeModel: ['Motion_Sensor'],
@@ -145,15 +145,22 @@ module.exports = [
145
145
  model: 'QS-Zigbee-D02-TRIAC-LN',
146
146
  vendor: 'Lonsonho',
147
147
  description: '1 gang smart dimmer switch module with neutral',
148
- extend: extend.light_onoff_brightness(),
148
+ fromZigbee: extend.light_onoff_brightness().fromZigbee.concat([fz.tuya_min_brightness]),
149
+ toZigbee: extend.light_onoff_brightness().toZigbee.concat([tz.tuya_min_brightness]),
150
+ exposes: [e.light_brightness().withMinBrightness()],
149
151
  },
150
152
  {
151
153
  fingerprint: [{modelID: 'TS110F', manufacturerName: '_TYZB01_v8gtiaed'}, {modelID: 'TS110E', manufacturerName: '_TZ3210_pagajpog'}],
152
154
  model: 'QS-Zigbee-D02-TRIAC-2C-LN',
153
155
  vendor: 'Lonsonho',
154
156
  description: '2 gang smart dimmer switch module with neutral',
155
- extend: extend.light_onoff_brightness({noConfigure: true}),
156
- exposes: [e.light_brightness().withEndpoint('l1'), e.light_brightness().withEndpoint('l2')],
157
+ fromZigbee: extend.light_onoff_brightness().fromZigbee.concat([fz.tuya_min_brightness]),
158
+ toZigbee: extend.light_onoff_brightness().toZigbee.concat([tz.tuya_min_brightness]),
159
+ exposes: [e.light_brightness().withMinBrightness().withEndpoint('l1'),
160
+ e.light_brightness().withMinBrightness().withEndpoint('l2')],
161
+ endpoint: (device) => {
162
+ return {'l1': 1, 'l2': 2};
163
+ },
157
164
  meta: {multiEndpoint: true},
158
165
  configure: async (device, coordinatorEndpoint, logger) => {
159
166
  await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
@@ -161,9 +168,6 @@ module.exports = [
161
168
  await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
162
169
  // Don't do: await reporting.onOff(endpoint); https://github.com/Koenkk/zigbee2mqtt/issues/6041
163
170
  },
164
- endpoint: (device) => {
165
- return {l1: 1, l2: 2};
166
- },
167
171
  },
168
172
  {
169
173
  fingerprint: [{modelID: 'TS110F', manufacturerName: '_TZ3000_92chsky7'}, {modelID: 'TS110E', manufacturerName: '_TZ3210_4ubylghk'}],
@@ -609,6 +609,13 @@ module.exports = [
609
609
  description: 'Hue Calla outdoor',
610
610
  extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
611
611
  },
612
+ {
613
+ zigbeeModel: ['1741930V7'],
614
+ model: '1741930V7',
615
+ vendor: 'Philips',
616
+ description: 'Hue Calla outdoor',
617
+ extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
618
+ },
612
619
  {
613
620
  zigbeeModel: ['1744130P7'],
614
621
  model: '1744130P7',
@@ -1815,7 +1822,9 @@ module.exports = [
1815
1822
  vendor: 'Philips',
1816
1823
  description: 'Hue wall switch module',
1817
1824
  fromZigbee: [fz.battery, fz.hue_wall_switch_device_mode, fz.hue_wall_switch],
1818
- exposes: [e.battery(), e.action(['left_press', 'left_press_release', 'right_press', 'right_press_release']),
1825
+ exposes: [
1826
+ e.battery(), e.action(['left_press', 'left_press_release', 'right_press', 'right_press_release',
1827
+ 'left_hold', 'left_hold_release', 'right_hold', 'right_hold_release']),
1819
1828
  exposes.enum('device_mode', ea.ALL, ['single_rocker', 'single_push_button', 'dual_rocker', 'dual_push_button'])],
1820
1829
  toZigbee: [tz.hue_wall_switch_device_mode],
1821
1830
  configure: async (device, coordinatorEndpoint, logger) => {
@@ -2580,6 +2589,13 @@ module.exports = [
2580
2589
  description: 'Hue White & Color Ambiance Xamento M',
2581
2590
  extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
2582
2591
  },
2592
+ {
2593
+ zigbeeModel: ['915005997901'],
2594
+ model: '915005997901',
2595
+ vendor: 'Philips',
2596
+ description: 'Hue White & Color Ambiance Xamento L',
2597
+ extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
2598
+ },
2583
2599
  {
2584
2600
  zigbeeModel: ['929002966401'],
2585
2601
  model: '929002966401',
@@ -2762,4 +2778,11 @@ module.exports = [
2762
2778
  description: 'Philips Hue Adore Bathroom Mirror Light',
2763
2779
  extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
2764
2780
  },
2781
+ {
2782
+ zigbeeModel: ['929003045901'],
2783
+ model: '929003045901',
2784
+ vendor: 'Philips',
2785
+ description: 'Hue White ambiance Runner spot white (1 spot)',
2786
+ extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
2787
+ },
2765
2788
  ];
package/devices/robb.js CHANGED
@@ -105,12 +105,22 @@ module.exports = [
105
105
  model: 'ROB_200-014-0',
106
106
  vendor: 'ROBB',
107
107
  description: 'ZigBee AC phase-cut rotary dimmer',
108
- extend: extend.light_onoff_brightness({noConfigure: true}),
108
+ fromZigbee: extend.light_onoff_brightness().fromZigbee.concat([fz.electrical_measurement, fz.metering, fz.ignore_genOta]),
109
+ toZigbee: extend.light_onoff_brightness().toZigbee,
110
+ exposes: [e.light_brightness(), e.power(), e.voltage(), e.current(), e.energy()],
111
+ whiteLabel: [{vendor: 'YPHIX', model: '50208695'}, {vendor: 'Samotech', model: 'SM311'}],
109
112
  configure: async (device, coordinatorEndpoint, logger) => {
110
- await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
111
113
  const endpoint = device.getEndpoint(1);
112
- await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
114
+ const binds = ['genOnOff', 'genLevelCtrl', 'haElectricalMeasurement', 'seMetering'];
115
+ await reporting.bind(endpoint, coordinatorEndpoint, binds);
113
116
  await reporting.onOff(endpoint);
117
+ await reporting.brightness(endpoint);
118
+ await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
119
+ await reporting.activePower(endpoint);
120
+ await reporting.rmsCurrent(endpoint, {min: 10, change: 10});
121
+ await reporting.rmsVoltage(endpoint, {min: 10});
122
+ await reporting.readMeteringMultiplierDivisor(endpoint);
123
+ await reporting.currentSummDelivered(endpoint);
114
124
  },
115
125
  },
116
126
  {
@@ -19,6 +19,7 @@ module.exports = [
19
19
  {modelID: 'TS0601', manufacturerName: '_TZE200_zuhszj9s'},
20
20
  {modelID: 'TS0601', manufacturerName: '_TZE200_9gvruqf5'},
21
21
  {modelID: 'TS0601', manufacturerName: '_TZE200_zr9c0day'},
22
+ {modelID: 'TS0601', manufacturerName: '_TZE200_0dvm9mva'},
22
23
  ],
23
24
  model: 'SEA801-Zigbee/SEA802-Zigbee',
24
25
  vendor: 'Saswell',
@@ -1,4 +1,5 @@
1
1
  const exposes = require('../lib/exposes');
2
+ const utils = require('../lib/utils');
2
3
  const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
3
4
  const tz = require('../converters/toZigbee');
4
5
  const reporting = require('../lib/reporting');
@@ -40,6 +41,20 @@ const fzLocal = {
40
41
  };
41
42
  },
42
43
  },
44
+ ISM300Z3_on_off: {
45
+ cluster: 'genOnOff',
46
+ type: ['attributeReport', 'readResponse'],
47
+ convert: (model, msg, publish, options, meta) => {
48
+ if (msg.data.hasOwnProperty('onOff')) {
49
+ const property = utils.postfixWithEndpointName('state', msg, model, meta);
50
+ return {[property]: msg.data['onOff'] === 1 ? 'ON' : 'OFF'};
51
+ } else if (msg.data.hasOwnProperty(0x9000)) {
52
+ const value = msg.data[0x9000];
53
+ const lookup = {0: 'auto', 1: 'push', 2: 'latch'};
54
+ return {operation_mode: lookup[value]};
55
+ }
56
+ },
57
+ },
43
58
  };
44
59
 
45
60
  const tzLocal = {
@@ -109,6 +124,44 @@ const tzLocal = {
109
124
  await endpoint.write('genAnalogInput', payload);
110
125
  },
111
126
  },
127
+ ISM300Z3_on_off: {
128
+ key: ['state', 'operation_mode'],
129
+ convertSet: async (entity, key, value, meta) => {
130
+ const endpoint = meta.device.getEndpoint(1);
131
+ if (key === 'state') {
132
+ const state = meta.message.hasOwnProperty('state') ? meta.message.state.toLowerCase() : null;
133
+ utils.validateValue(state, ['toggle', 'off', 'on']);
134
+ await entity.command('genOnOff', state, {}, utils.getOptions(meta.mapped, entity));
135
+ if (state === 'toggle') {
136
+ const currentState = meta.state[`state${meta.endpoint_name ? `_${meta.endpoint_name}` : ''}`];
137
+ return currentState ? {state: {state: currentState === 'OFF' ? 'ON' : 'OFF'}} : {};
138
+ } else {
139
+ return {state: {state: state.toUpperCase()}};
140
+ }
141
+ } else if (key === 'operation_mode') {
142
+ const lookup = {'auto': 0, 'push': 1, 'latch': 2};
143
+ const payload = {0x9000: {value: lookup[value], type: 0x20}}; // INT8U
144
+ await entity.write('genOnOff', payload);
145
+ await endpoint.read('genOnOff', [0x9000]);
146
+ }
147
+ },
148
+ convertGet: async (entity, key, meta) => {
149
+ if (key === 'operation_mode') {
150
+ const endpoint = meta.device.getEndpoint(1);
151
+ await endpoint.read('genOnOff', [0x9000]);
152
+ } else {
153
+ await entity.read('genOnOff', ['onOff']);
154
+ }
155
+ },
156
+ },
157
+ ISM300Z3_rf_pairing: {
158
+ key: ['rf_pairing'],
159
+ convertSet: async (entity, key, value, meta) => {
160
+ const lookup = {'l1': 1, 'l2': 2, 'l3': 3};
161
+ const payload = {0x9001: {value: lookup[value], type: 0x20}}; // INT8U
162
+ await entity.write('genOnOff', payload);
163
+ },
164
+ },
112
165
  };
113
166
 
114
167
  module.exports = [
@@ -543,13 +596,19 @@ module.exports = [
543
596
  vendor: 'ShinaSystem',
544
597
  ota: ota.zigbeeOTA,
545
598
  description: 'SiHAS IOT smart inner switch 3 gang',
546
- extend: extend.switch(),
547
- exposes: [e.switch().withEndpoint('l1'), e.switch().withEndpoint('l2'), e.switch().withEndpoint('l3')],
599
+ fromZigbee: [fzLocal.ISM300Z3_on_off],
600
+ toZigbee: [tzLocal.ISM300Z3_on_off, tzLocal.ISM300Z3_rf_pairing],
601
+ exposes: [e.switch().withEndpoint('l1'), e.switch().withEndpoint('l2'), e.switch().withEndpoint('l3'),
602
+ exposes.enum('operation_mode', ea.ALL, ['auto', 'push', 'latch'])
603
+ .withDescription('Operation mode: "auto" - toggle by S/W, "push" - for momentary S/W, "latch" - sync S/W'),
604
+ exposes.enum('rf_pairing', ea.SET, ['l1', 'l2', 'l3'])
605
+ .withDescription('Enable RF pairing mode each button l1, l2, l3')],
548
606
  endpoint: (device) => {
549
607
  return {l1: 1, l2: 2, l3: 3};
550
608
  },
551
609
  meta: {multiEndpoint: true},
552
610
  configure: async (device, coordinatorEndpoint, logger) => {
611
+ await device.getEndpoint(1).read('genOnOff', [0x9000]);
553
612
  await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
554
613
  await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
555
614
  await reporting.bind(device.getEndpoint(3), coordinatorEndpoint, ['genOnOff']);
package/devices/tuya.js CHANGED
@@ -21,7 +21,7 @@ const TS011Fplugs = ['_TZ3000_5f43h46b', '_TZ3000_cphmq0q7', '_TZ3000_dpo1ysak',
21
21
  '_TZ3000_1h2x4akh', '_TZ3000_9vo5icau', '_TZ3000_cehuw1lw', '_TZ3000_ko6v90pg', '_TZ3000_f1bapcit', '_TZ3000_cjrngdr3',
22
22
  '_TZ3000_zloso4jk', '_TZ3000_r6buo8ba', '_TZ3000_iksasdbv', '_TZ3000_idrffznf', '_TZ3000_okaz9tjs', '_TZ3210_q7oryllx',
23
23
  '_TZ3000_ss98ec5d', '_TZ3000_gznh2xla', '_TZ3000_hdopuwv6', '_TZ3000_gvn91tmx', '_TZ3000_dksbtrzs', '_TZ3000_b28wrpvx',
24
- '_TZ3000_aim0ztek'];
24
+ '_TZ3000_aim0ztek', '_TZ3000_mlswgkc3', '_TZ3000_7dndcnnb'];
25
25
 
26
26
  const tzLocal = {
27
27
  SA12IZL_silence_siren: {
@@ -796,6 +796,7 @@ module.exports = [
796
796
  {modelID: 'TS0001', manufacturerName: '_TZ3000_5ng23zjs'},
797
797
  {modelID: 'TS0001', manufacturerName: '_TZ3000_rmjr4ufz'},
798
798
  {modelID: 'TS0001', manufacturerName: '_TZ3000_v7gnj3ad'},
799
+ {modelID: 'TS0001', manufacturerName: '_TZ3000_ark8nv4y'},
799
800
  {modelID: 'TS0001', manufacturerName: '_TZ3000_mx3vgyea'},
800
801
  {modelID: 'TS0001', manufacturerName: '_TZ3000_qsp2pwtf'},
801
802
  {modelID: 'TS0001', manufacturerName: '_TZ3000_46t1rvdu'}],
@@ -1939,9 +1940,9 @@ module.exports = [
1939
1940
  exposes.binary('heating_stop', ea.STATE_SET, 'ON', 'OFF').withDescription('Battery life can be prolonged'+
1940
1941
  ' by switching the heating off. To achieve this, the valve is closed fully. To activate the '+
1941
1942
  'heating stop, the device display "HS", press the pair button to cancel.'),
1942
- e.holiday_temperature(), exposes.composite('holiday_mode_date').withDescription('The holiday mode( ⛱ ) will '+
1943
- 'automatically start at the set time starting point and run the holiday temperature.')
1944
- .withFeature(exposes.text('holiday_start_stop', ea.STATE_SET)),
1943
+ e.holiday_temperature(),
1944
+ exposes.text('holiday_start_stop', ea.STATE_SET).withDescription('The holiday mode( ) will '+
1945
+ 'automatically start at the set time starting point and run the holiday temperature.'),
1945
1946
  // exposes.enum('working_day', ea.STATE_SET, ['0', '1', '2', '3']),
1946
1947
  exposes.composite('schedule')/* .withFeature(exposes.text('week_schedule_programming', ea.STATE_SET)) */
1947
1948
  .withDescription('week_schedule').withDescription('Auto Mode ⏱ - In this mode, '+
@@ -3270,6 +3271,8 @@ module.exports = [
3270
3271
  configure: async (device, coordinatorEndpoint, logger) => {
3271
3272
  const endpoint = device.getEndpoint(1);
3272
3273
  await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'msTemperatureMeasurement', 'msRelativeHumidity']);
3274
+ await endpoint.read('genPowerCfg', ['batteryVoltage', 'batteryPercentageRemaining']);
3275
+ await reporting.batteryPercentageRemaining(endpoint);
3273
3276
  },
3274
3277
  },
3275
3278
  {
package/devices/xiaomi.js CHANGED
@@ -8,6 +8,7 @@ const extend = require('../lib/extend');
8
8
  const e = exposes.presets;
9
9
  const ea = exposes.access;
10
10
  const globalStore = require('../lib/store');
11
+ const xiaomi = require('../lib/xiaomi');
11
12
 
12
13
  const xiaomiExtend = {
13
14
  light_onoff_brightness_colortemp: (options={disableColorTempStartup: true}) => ({
@@ -125,6 +126,17 @@ const tzLocal = {
125
126
  }
126
127
  },
127
128
  },
129
+ VOCKQJK11LM_display_unit: {
130
+ key: ['display_unit'],
131
+ convertSet: async (entity, key, value, meta) => {
132
+ await entity.write('aqaraOpple',
133
+ {0x0114: {value: xiaomi.VOCKQJK11LMDisplayUnit[value], type: 0x20}}, {manufacturerCode: 0x115F});
134
+ return {state: {display_unit: value}};
135
+ },
136
+ convertGet: async (entity, key, meta) => {
137
+ await entity.read('aqaraOpple', [0x0114], {manufacturerCode: 0x115F, disableDefaultResponse: true});
138
+ },
139
+ },
128
140
  };
129
141
 
130
142
  module.exports = [
@@ -2021,9 +2033,11 @@ module.exports = [
2021
2033
  whiteLabel: [{vendor: 'Xiaomi', model: 'AAQS-S01'}],
2022
2034
  description: 'Aqara TVOC air quality monitor',
2023
2035
  fromZigbee: [fz.xiaomi_tvoc, fz.battery, fz.temperature, fz.humidity, fz.aqara_opple],
2024
- toZigbee: [],
2036
+ toZigbee: [tzLocal.VOCKQJK11LM_display_unit],
2025
2037
  meta: {battery: {voltageToPercentage: '3V_2850_3000'}},
2026
- exposes: [e.temperature(), e.humidity(), e.voc(), e.device_temperature(), e.battery(), e.battery_voltage()],
2038
+ exposes: [e.temperature(), e.humidity(), e.voc(), e.device_temperature(), e.battery(), e.battery_voltage(),
2039
+ exposes.enum('display_unit', ea.ALL, ['mgm3_celsius', 'ppb_celsius', 'mgm3_fahrenheit', 'ppb_fahrenheit'])
2040
+ .withDescription('Units to show on the display')],
2027
2041
  configure: async (device, coordinatorEndpoint, logger) => {
2028
2042
  const endpoint = device.getEndpoint(1);
2029
2043
  const binds = ['msTemperatureMeasurement', 'msRelativeHumidity', 'genAnalogInput'];
package/lib/xiaomi.js CHANGED
@@ -5,6 +5,7 @@ const {
5
5
  calibrateAndPrecisionRoundOptions,
6
6
  postfixWithEndpointName,
7
7
  precisionRound,
8
+ getKey,
8
9
  } = require('./utils');
9
10
 
10
11
  const buffer2DataObject = (meta, model, buffer) => {
@@ -432,6 +433,11 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
432
433
  payload.gas_sensitivity = {1: '15%LEL', 2: '10%LEL'}[value];
433
434
  }
434
435
  break;
436
+ case '276':
437
+ if (['VOCKQJK11LM'].includes(model.model)) {
438
+ payload.display_unit = getKey(VOCKQJK11LMDisplayUnit, value);
439
+ }
440
+ break;
435
441
  case '293':
436
442
  payload.click_mode = {1: 'fast', 2: 'multi'}[value];
437
443
  break;
@@ -637,7 +643,15 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
637
643
  return payload;
638
644
  };
639
645
 
646
+ const VOCKQJK11LMDisplayUnit = {
647
+ 'mgm3_celsius': 0x00, // mg/m³, °C (default)
648
+ 'ppb_celsius': 0x01, // ppb, °C
649
+ 'mgm3_fahrenheit': 0x10, // mg/m³, °F
650
+ 'ppb_fahrenheit': 0x11, // ppb, °F
651
+ };
652
+
640
653
  module.exports = {
641
654
  buffer2DataObject,
642
655
  numericAttributes2Payload,
656
+ VOCKQJK11LMDisplayUnit,
643
657
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.626",
3
+ "version": "14.0.628",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [