zigbee-herdsman-converters 14.0.430 → 14.0.431

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.
package/devices/awox.js CHANGED
@@ -117,6 +117,11 @@ module.exports = [
117
117
  {ID: 1, profileID: 260, deviceID: 268, inputClusters: [0, 3, 4, 5, 6, 8, 768, 4096, 64599], outputClusters: [6]},
118
118
  {ID: 3, profileID: 4751, deviceID: 268, inputClusters: [65360, 65361], outputClusters: [65360, 65361]},
119
119
  ]},
120
+ {type: 'Router', manufacturerName: 'AwoX', modelID: 'TLSR82xx', endpoints: [
121
+ {ID: 1, profileID: 260, deviceID: 268, inputClusters: [0, 3, 4, 5, 6, 8, 768, 4096, 64599], outputClusters: [6]},
122
+ {ID: 242, profileID: 41440, deviceID: 97, inputClusters: [], outputClusters: [33]},
123
+ {ID: 3, profileID: 4751, deviceID: 268, inputClusters: [65360, 65361], outputClusters: [65360, 65361]},
124
+ ]},
120
125
  ],
121
126
  model: '33957',
122
127
  vendor: 'AwoX',
@@ -706,7 +706,7 @@ module.exports = [
706
706
  ota: ota.zigbeeOTA,
707
707
  },
708
708
  {
709
- zigbeeModel: ['LTA001'],
709
+ zigbeeModel: ['LTA001', '4080130P6'],
710
710
  model: '9290022169',
711
711
  vendor: 'Philips',
712
712
  description: 'Hue white ambiance E27 with Bluetooth',
@@ -1906,8 +1906,8 @@ module.exports = [
1906
1906
  description: 'Hue dimmer switch',
1907
1907
  fromZigbee: [fz.ignore_command_on, fz.ignore_command_off, fz.ignore_command_step, fz.ignore_command_stop,
1908
1908
  fz.legacy.hue_dimmer_switch, fz.battery],
1909
- exposes: [e.battery(), e.action(['on-press', 'on-hold', 'on-hold-release', 'up-press', 'up-hold', 'up-hold-release',
1910
- 'down-press', 'down-hold', 'down-hold-release', 'off-press', 'off-hold', 'off-hold-release']),
1909
+ exposes: [e.battery(), e.action(['on_press', 'on_hold', 'on_hold_release', 'up_press', 'up_hold', 'up_hold_release',
1910
+ 'down_press', 'down_hold', 'down_hold_release', 'off_press', 'off_hold', 'off_hold_release']),
1911
1911
  exposes.numeric('action_duration', ea.STATE).withUnit('second')],
1912
1912
  toZigbee: [],
1913
1913
  configure: async (device, coordinatorEndpoint, logger) => {
package/devices/sprut.js CHANGED
@@ -3,12 +3,21 @@ const fz = require('../converters/fromZigbee');
3
3
  const tz = require('../converters/toZigbee');
4
4
  const reporting = require('../lib/reporting');
5
5
  const ota = require('../lib/ota');
6
+ const constants = require('../lib/constants');
6
7
  const e = exposes;
7
8
  const ep = exposes.presets;
8
9
  const eo = exposes.options;
9
10
  const ea = exposes.access;
10
11
  const {calibrateAndPrecisionRoundOptions, getOptions} = require('../lib/utils');
11
12
 
13
+ const sprutCode = 0x6666;
14
+ const manufacturerOptions = {manufacturerCode: sprutCode};
15
+ const switchActionValues = ['OFF', 'ON'];
16
+ const co2Lookup = {
17
+ co2_autocalibration: 'sprutCO2AutoCalibration',
18
+ co2_manual_calibration: 'sprutCO2Calibration',
19
+ };
20
+
12
21
  const fzLocal = {
13
22
  temperature: {
14
23
  cluster: 'msTemperatureMeasurement',
@@ -19,7 +28,7 @@ const fzLocal = {
19
28
  return {temperature: calibrateAndPrecisionRoundOptions(temperature, options, 'temperature')};
20
29
  },
21
30
  },
22
- occupancy: {
31
+ occupancy_level: {
23
32
  cluster: 'msOccupancySensing',
24
33
  type: ['readResponse', 'attributeReport'],
25
34
  convert: (model, msg, publish, options, meta) => {
@@ -59,27 +68,65 @@ const fzLocal = {
59
68
  cluster: 'msOccupancySensing',
60
69
  type: ['readResponse', 'attributeReport'],
61
70
  convert: (model, msg, publish, options, meta) => {
62
- return {occupancy_timeout: msg.data.pirOToUDelay};
71
+ return {occupancy_timeout: msg.data['pirOToUDelay']};
63
72
  },
64
73
  },
65
74
  noise_timeout: {
66
75
  cluster: 'sprutNoise',
67
76
  type: ['readResponse', 'attributeReport'],
68
77
  convert: (model, msg, publish, options, meta) => {
69
- return {noise_timeout: msg.data.noiseAfterDetectDelay};
78
+ return {noise_timeout: msg.data['noiseAfterDetectDelay']};
79
+ },
80
+ },
81
+ occupancy_sensitivity: {
82
+ cluster: 'msOccupancySensing',
83
+ type: ['readResponse', 'attributeReport'],
84
+ convert: (model, msg, publish, options, meta) => {
85
+ return {occupancy_sensitivity: msg.data['sprutOccupancySensitivity']};
86
+ },
87
+ },
88
+ noise_detect_level: {
89
+ cluster: 'sprutNoise',
90
+ type: ['readResponse', 'attributeReport'],
91
+ convert: (model, msg, publish, options, meta) => {
92
+ return {noise_detect_level: msg.data['noiseDetectLevel']};
93
+ },
94
+ },
95
+ co2_config: {
96
+ key: ['co2_autocalibration', 'co2_manual_calibration'],
97
+ cluster: 'msCO2',
98
+ type: ['attributeReport', 'readResponse'],
99
+ convert: (model, msg, publish, options, meta) => {
100
+ if (msg.data.hasOwnProperty('sprutCO2AutoCalibration')) {
101
+ return {co2_autocalibration: switchActionValues[msg.data['sprutCO2AutoCalibration']]};
102
+ }
103
+ if (msg.data.hasOwnProperty('sprutCO2Calibration')) {
104
+ return {co2_manual_calibration: switchActionValues[msg.data['sprutCO2Calibration']]};
105
+ }
106
+ },
107
+ },
108
+ th_heater: {
109
+ key: ['th_heater'],
110
+ cluster: 'msRelativeHumidity',
111
+ type: ['attributeReport', 'readResponse'],
112
+ convert: (model, msg, publish, options, meta) => {
113
+ if (msg.data.hasOwnProperty('sprutHeater')) {
114
+ return {th_heater: switchActionValues[msg.data['sprutHeater']]};
115
+ }
70
116
  },
71
117
  },
72
118
  };
73
119
 
74
120
  const tzLocal = {
75
121
  sprut_ir_remote: {
76
- key: ['play_store', 'learn_start', 'learn_stop'],
122
+ key: ['play_store', 'learn_start', 'learn_stop', 'clear_store', 'play_ram', 'learn_ram_start', 'learn_ram_stop'],
77
123
  convertSet: async (entity, key, value, meta) => {
78
124
  const options = {
79
- frameType: 0, manufacturerCode: 26214, disableDefaultResponse: true,
125
+ frameType: 0, manufacturerCode: sprutCode, disableDefaultResponse: true,
80
126
  disableResponse: true, reservedBits: 0, direction: 0, writeUndiv: false,
81
127
  transactionSequenceNumber: null,
82
128
  };
129
+
83
130
  switch (key) {
84
131
  case 'play_store':
85
132
  await entity.command('sprutIrBlaster', 'playStore',
@@ -93,6 +140,22 @@ const tzLocal = {
93
140
  await entity.command('sprutIrBlaster', 'learnStop',
94
141
  {value: value['rom']}, options);
95
142
  break;
143
+ case 'clear_store':
144
+ await entity.command('sprutIrBlaster', 'clearStore',
145
+ {}, options);
146
+ break;
147
+ case 'play_ram':
148
+ await entity.command('sprutIrBlaster', 'playRam',
149
+ {}, options);
150
+ break;
151
+ case 'learn_ram_start':
152
+ await entity.command('sprutIrBlaster', 'learnRamStart',
153
+ {}, options);
154
+ break;
155
+ case 'learn_ram_stop':
156
+ await entity.command('sprutIrBlaster', 'learnRamStop',
157
+ {}, options);
158
+ break;
96
159
  }
97
160
  },
98
161
  },
@@ -100,26 +163,85 @@ const tzLocal = {
100
163
  key: ['occupancy_timeout'],
101
164
  convertSet: async (entity, key, value, meta) => {
102
165
  value *= 1;
103
- const endpoint = meta.device.getEndpoint(1);
104
- await endpoint.write('msOccupancySensing', {pirOToUDelay: value}, getOptions(meta.mapped, entity));
105
- return {state: {occupancy_timeout: value}};
166
+ await entity.write('msOccupancySensing', {pirOToUDelay: value}, getOptions(meta.mapped, entity));
167
+ return {state: {[key]: value}};
106
168
  },
107
169
  convertGet: async (entity, key, meta) => {
108
- const endpoint = meta.device.getEndpoint(1);
109
- await endpoint.read('msOccupancySensing', ['pirOToUDelay']);
170
+ await entity.read('msOccupancySensing', ['pirOToUDelay']);
110
171
  },
111
172
  },
112
173
  noise_timeout: {
113
174
  key: ['noise_timeout'],
114
175
  convertSet: async (entity, key, value, meta) => {
115
176
  value *= 1;
116
- const endpoint = meta.device.getEndpoint(1);
117
- await endpoint.write('sprutNoise', {noiseAfterDetectDelay: value}, getOptions(meta.mapped, entity));
118
- return {state: {noise_timeout: value}};
177
+ await entity.write('sprutNoise', {noiseAfterDetectDelay: value}, getOptions(meta.mapped, entity));
178
+ return {state: {[key]: value}};
119
179
  },
120
180
  convertGet: async (entity, key, meta) => {
121
- const endpoint = meta.device.getEndpoint(1);
122
- await endpoint.read('sprutNoise', ['noiseAfterDetectDelay']);
181
+ await entity.read('sprutNoise', ['noiseAfterDetectDelay']);
182
+ },
183
+ },
184
+ occupancy_sensitivity: {
185
+ key: ['occupancy_sensitivity'],
186
+ convertSet: async (entity, key, value, meta) => {
187
+ value *= 1;
188
+ const options = getOptions(meta.mapped, entity, manufacturerOptions);
189
+ await entity.write('msOccupancySensing', {'sprutOccupancySensitivity': value}, options);
190
+ return {state: {[key]: value}};
191
+ },
192
+ convertGet: async (entity, key, meta) => {
193
+ await entity.read('msOccupancySensing', ['sprutOccupancySensitivity'], manufacturerOptions);
194
+ },
195
+ },
196
+ noise_detect_level: {
197
+ key: ['noise_detect_level'],
198
+ convertSet: async (entity, key, value, meta) => {
199
+ value *= 1;
200
+ const options = getOptions(meta.mapped, entity, manufacturerOptions);
201
+ await entity.write('sprutNoise', {'noiseDetectLevel': value}, options);
202
+ return {state: {[key]: value}};
203
+ },
204
+ convertGet: async (entity, key, meta) => {
205
+ await entity.read('sprutNoise', ['noiseDetectLevel'], manufacturerOptions);
206
+ },
207
+ },
208
+ temperature_offset: {
209
+ key: ['temperature_offset'],
210
+ convertSet: async (entity, key, value, meta) => {
211
+ value *= 1;
212
+ const newValue = parseFloat(value) * 100.0;
213
+ const options = getOptions(meta.mapped, entity, manufacturerOptions);
214
+ await entity.write('msTemperatureMeasurement', {'sprutTemperatureOffset': newValue}, options);
215
+ return {state: {[key]: value}};
216
+ },
217
+ },
218
+ co2_config: {
219
+ key: ['co2_autocalibration', 'co2_manual_calibration'],
220
+ convertSet: async (entity, key, value, meta) => {
221
+ let newValue = value;
222
+ newValue = switchActionValues.indexOf(value);
223
+ const options = getOptions(meta.mapped, entity, manufacturerOptions);
224
+ await entity.write('msCO2', {[co2Lookup[key]]: newValue}, options);
225
+
226
+
227
+ return {state: {[key]: value}};
228
+ },
229
+ convertGet: async (entity, key, meta) => {
230
+ await entity.read('msCO2', [co2Lookup[key]], manufacturerOptions);
231
+ },
232
+ },
233
+ th_heater: {
234
+ key: ['th_heater'],
235
+ convertSet: async (entity, key, value, meta) => {
236
+ let newValue = value;
237
+ newValue = switchActionValues.indexOf(value);
238
+ const options = getOptions(meta.mapped, entity, manufacturerOptions);
239
+ await entity.write('msRelativeHumidity', {'sprutHeater': newValue}, options);
240
+
241
+ return {state: {[key]: value}};
242
+ },
243
+ convertGet: async (entity, key, meta) => {
244
+ await entity.read('msRelativeHumidity', ['sprutHeater'], manufacturerOptions);
123
245
  },
124
246
  },
125
247
  };
@@ -130,22 +252,53 @@ module.exports = [
130
252
  model: 'WB-MSW-ZIGBEE v.3',
131
253
  vendor: 'Sprut.device',
132
254
  description: 'Wall-mounted Zigbee sensor',
133
- fromZigbee: [fzLocal.temperature, fz.illuminance, fz.humidity, fz.occupancy, fzLocal.occupancy, fz.co2, fzLocal.voc,
134
- fzLocal.noise, fzLocal.noise_detected, fz.on_off, fzLocal.occupancy_timeout, fzLocal.noise_timeout],
135
- toZigbee: [tz.on_off, tzLocal.sprut_ir_remote, tzLocal.occupancy_timeout, tzLocal.noise_timeout],
136
- exposes: [ep.temperature(), ep.illuminance(), ep.illuminance_lux(), ep.humidity(),
137
- ep.occupancy(), ep.occupancy_level(), ep.co2(), ep.voc(), ep.noise(), ep.noise_detected(ea.STATE_GET),
138
- ep.switch().withEndpoint('l1'), ep.switch().withEndpoint('l2'), ep.switch().withEndpoint('default'),
255
+ fromZigbee: [fzLocal.temperature, fz.illuminance, fz.humidity, fz.occupancy, fzLocal.occupancy_level, fz.co2, fzLocal.voc,
256
+ fzLocal.noise, fzLocal.noise_detected, fz.on_off, fzLocal.occupancy_timeout, fzLocal.noise_timeout, fzLocal.co2_config,
257
+ fzLocal.th_heater, fzLocal.occupancy_sensitivity, fzLocal.noise_detect_level],
258
+ toZigbee: [tz.on_off, tzLocal.sprut_ir_remote, tzLocal.occupancy_timeout, tzLocal.noise_timeout, tzLocal.co2_config,
259
+ tzLocal.th_heater, tzLocal.temperature_offset, tzLocal.occupancy_sensitivity, tzLocal.noise_detect_level],
260
+ exposes: [ep.temperature(), ep.illuminance(), ep.illuminance_lux(), ep.humidity(), ep.occupancy(), ep.occupancy_level(), ep.co2(),
261
+ ep.voc(), ep.noise(), ep.noise_detected(ea.STATE_GET), ep.switch().withEndpoint('l1'), ep.switch().withEndpoint('l2'),
262
+ ep.switch().withEndpoint('l3'),
139
263
  e.numeric('noise_timeout', ea.ALL).withValueMin(0).withValueMax(2000).withUnit('s')
140
- .withDescription('Time in seconds after which noise is cleared after detecting it (default: 30)'),
264
+ .withDescription('Time in seconds after which noise is cleared after detecting it (default: 60)'),
141
265
  e.numeric('occupancy_timeout', ea.ALL).withValueMin(0).withValueMax(2000).withUnit('s')
142
- .withDescription('Time in seconds after which occupancy is cleared after detecting it (default: 30)')],
266
+ .withDescription('Time in seconds after which occupancy is cleared after detecting it (default: 60)'),
267
+ e.numeric('temperature_offset', ea.SET).withValueMin(-10).withValueMax(10).withUnit('°C')
268
+ .withDescription('Self-heating compensation. The compensation value is subtracted from the measured temperature'),
269
+ e.numeric('occupancy_sensitivity', ea.ALL).withValueMin(0).withValueMax(2000)
270
+ .withDescription('If the sensor is triggered by the slightest movement, reduce the sensitivity, '+
271
+ 'otherwise increase it (default: 50)'),
272
+ e.numeric('noise_detect_level', ea.ALL).withValueMin(0).withValueMax(150).withUnit('dBA')
273
+ .withDescription('The minimum noise level at which the detector will work (default: 50)'),
274
+ e.enum('co2_autocalibration', ea.ALL, switchActionValues)
275
+ .withDescription('Automatic calibration of the CO2 sensor. If ON, the CO2 sensor will automatically calibrate '+
276
+ 'every 7 days.'),
277
+ e.enum('co2_manual_calibration', ea.ALL, switchActionValues)
278
+ .withDescription('Ventilate the room for 20 minutes, turn on manual calibration, and turn it off after one second. '+
279
+ 'After about 5 minutes the CO2 sensor will show 400ppm. Calibration completed'),
280
+ e.enum('th_heater', ea.ALL, switchActionValues)
281
+ .withDescription('Turn on when working in conditions of high humidity (more than 70 %, RH) or condensation, '+
282
+ 'if the sensor shows 0 or 100 %.'),
283
+ ],
143
284
  configure: async (device, coordinatorEndpoint, logger) => {
144
285
  const endpoint1 = device.getEndpoint(1);
145
286
  const binds = ['genBasic', 'msTemperatureMeasurement', 'msIlluminanceMeasurement', 'msRelativeHumidity',
146
287
  'msOccupancySensing', 'msCO2', 'sprutVoc', 'sprutNoise', 'sprutIrBlaster', 'genOta'];
147
288
  await reporting.bind(endpoint1, coordinatorEndpoint, binds);
148
289
 
290
+ // report configuration
291
+ await reporting.temperature(endpoint1);
292
+ await reporting.illuminance(endpoint1);
293
+ await reporting.humidity(endpoint1);
294
+ await reporting.occupancy(endpoint1);
295
+
296
+ let payload = reporting.payload('sprutOccupancyLevel', 10, constants.repInterval.MINUTE, 5);
297
+ await endpoint1.configureReporting('msOccupancySensing', payload, manufacturerOptions);
298
+
299
+ payload = reporting.payload('noise', 10, constants.repInterval.MINUTE, 5);
300
+ await endpoint1.configureReporting('sprutNoise', payload);
301
+
149
302
  // led_red
150
303
  await device.getEndpoint(2).read('genOnOff', ['onOff']);
151
304
 
@@ -155,10 +308,6 @@ module.exports = [
155
308
  // buzzer
156
309
  await device.getEndpoint(4).read('genOnOff', ['onOff']);
157
310
 
158
- // Read settings at start
159
- await endpoint1.read('msOccupancySensing', ['pirOToUDelay']);
160
- await endpoint1.read('sprutNoise', ['noiseAfterDetectDelay']);
161
-
162
311
  // Read data at start
163
312
  await endpoint1.read('msTemperatureMeasurement', ['measuredValue']);
164
313
  await endpoint1.read('msIlluminanceMeasurement', ['measuredValue']);
@@ -168,7 +317,7 @@ module.exports = [
168
317
  await endpoint1.read('sprutNoise', ['noiseDetected']);
169
318
  },
170
319
  endpoint: (device) => {
171
- return {'system': 1, 'l1': 2, 'l2': 3, 'default': 4};
320
+ return {'default': 1, 'l1': 2, 'l2': 3, 'l3': 4};
172
321
  },
173
322
  meta: {multiEndpoint: true},
174
323
  ota: ota.zigbeeOTA,
@@ -57,11 +57,11 @@ module.exports = [
57
57
  ota: ota.ledvance,
58
58
  },
59
59
  {
60
- zigbeeModel: ['LIGHTIFY BR Tunable White'],
60
+ zigbeeModel: ['LIGHTIFY BR Tunable White', 'BR30 TW'],
61
61
  model: '73740',
62
62
  vendor: 'Sylvania',
63
63
  description: 'LIGHTIFY LED adjustable white BR30',
64
- extend: extend.ledvance.light_onoff_brightness_colortemp(),
64
+ extend: extend.ledvance.light_onoff_brightness_colortemp({colorTempRange: [153, 370]}),
65
65
  ota: ota.ledvance,
66
66
  },
67
67
  {
@@ -0,0 +1,18 @@
1
+ const reporting = require('../lib/reporting');
2
+ const extend = require('../lib/extend');
3
+
4
+ module.exports = [
5
+ {
6
+ fingerprint: [
7
+ {modelID: 'TS0001', manufacturerName: '_TYZB01_reyozfcg'},
8
+ {modelID: 'TS0001', manufacturerName: '_TYZB01_4vgantdz'},
9
+ ],
10
+ model: 'VR-X701U',
11
+ vendor: 'Vrey',
12
+ description: '1 gang switch',
13
+ extend: extend.switch(),
14
+ configure: async (device, coordinatorEndpoint, logger) => {
15
+ await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
16
+ },
17
+ },
18
+ ];
package/devices/xiaomi.js CHANGED
@@ -56,7 +56,7 @@ module.exports = [
56
56
  description: 'Aqara P1 door & window contact sensor',
57
57
  fromZigbee: [fz. xiaomi_contact, fz.ias_contact_alarm_1, fz.aqara_opple, fz.battery],
58
58
  toZigbee: [],
59
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
59
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
60
60
  exposes: [e.contact(), e.battery(), e.battery_voltage()],
61
61
  configure: async (device, coordinatorEndpoint, logger) => {
62
62
  const endpoint = device.getEndpoint(1);
@@ -158,7 +158,7 @@ module.exports = [
158
158
  model: 'WXKG01LM',
159
159
  vendor: 'Xiaomi',
160
160
  description: 'MiJia wireless switch',
161
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
161
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
162
162
  fromZigbee: [fz.xiaomi_battery, fz.xiaomi_WXKG01LM_action, fz.legacy.WXKG01LM_click],
163
163
  exposes: [e.battery(), e.action(['single', 'double', 'triple', 'quadruple', 'hold', 'release', 'many']), e.battery_voltage()],
164
164
  toZigbee: [],
@@ -168,7 +168,7 @@ module.exports = [
168
168
  model: 'WXKG11LM',
169
169
  vendor: 'Xiaomi',
170
170
  description: 'Aqara wireless switch',
171
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
171
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
172
172
  exposes: [e.battery(), e.battery_voltage(), e.action(['single', 'double', 'triple', 'quadruple', 'hold', 'release'])],
173
173
  fromZigbee: [fz.xiaomi_multistate_action, fz.xiaomi_WXKG11LM_action, fz.xiaomi_battery,
174
174
  fz.legacy.WXKG11LM_click, fz.legacy.xiaomi_action_click_multistate],
@@ -179,7 +179,7 @@ module.exports = [
179
179
  model: 'WXKG12LM',
180
180
  vendor: 'Xiaomi',
181
181
  description: 'Aqara wireless switch (with gyroscope)',
182
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
182
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
183
183
  exposes: [e.battery(), e.action(['single', 'double', 'hold', 'release', 'shake']), e.battery_voltage()],
184
184
  fromZigbee: [fz.xiaomi_battery, fz.xiaomi_multistate_action, fz.legacy.WXKG12LM_action_click_multistate],
185
185
  toZigbee: [],
@@ -189,7 +189,7 @@ module.exports = [
189
189
  model: 'WXKG03LM_rev1',
190
190
  vendor: 'Xiaomi',
191
191
  description: 'Aqara single key wireless wall switch (2016 model)',
192
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
192
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
193
193
  exposes: [e.battery(), e.action(['single']), e.battery_voltage()],
194
194
  fromZigbee: [fz.xiaomi_on_off_action, fz.xiaomi_battery, fz.legacy.WXKG03LM_click],
195
195
  toZigbee: [],
@@ -200,7 +200,7 @@ module.exports = [
200
200
  model: 'WXKG03LM_rev2',
201
201
  vendor: 'Xiaomi',
202
202
  description: 'Aqara single key wireless wall switch (2018 model)',
203
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
203
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
204
204
  exposes: [e.battery(), e.action(['single', 'double', 'hold']), e.battery_voltage()],
205
205
  fromZigbee: [fz.xiaomi_on_off_action, fz.xiaomi_multistate_action, fz.xiaomi_battery,
206
206
  fz.legacy.WXKG03LM_click, fz.legacy.xiaomi_action_click_multistate],
@@ -218,7 +218,7 @@ module.exports = [
218
218
  e.action(['single', 'double', 'hold']),
219
219
  e.battery_voltage()],
220
220
  onEvent: preventReset,
221
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
221
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
222
222
  configure: async (device, coordinatorEndpoint, logger) => {
223
223
  try {
224
224
  const endpoint = device.endpoints[1];
@@ -233,7 +233,7 @@ module.exports = [
233
233
  model: 'WXKG02LM_rev1',
234
234
  vendor: 'Xiaomi',
235
235
  description: 'Aqara double key wireless wall switch (2016 model)',
236
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
236
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
237
237
  exposes: [e.battery(), e.action(['single_left', 'single_right', 'single_both']), e.battery_voltage()],
238
238
  fromZigbee: [fz.xiaomi_on_off_action, fz.xiaomi_battery, fz.legacy.WXKG02LM_click],
239
239
  toZigbee: [],
@@ -244,7 +244,7 @@ module.exports = [
244
244
  model: 'WXKG02LM_rev2',
245
245
  vendor: 'Xiaomi',
246
246
  description: 'Aqara double key wireless wall switch (2018 model)',
247
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
247
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
248
248
  exposes: [e.battery(), e.action(['single_left', 'single_right', 'single_both', 'double_left', 'double_right', 'double_both',
249
249
  'hold_left', 'hold_right', 'hold_both']), e.battery_voltage()],
250
250
  fromZigbee: [fz.xiaomi_on_off_action, fz.xiaomi_multistate_action, fz.xiaomi_battery,
@@ -537,7 +537,7 @@ module.exports = [
537
537
  model: 'WXKG07LM',
538
538
  vendor: 'Xiaomi',
539
539
  description: 'Aqara D1 double key wireless wall switch',
540
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
540
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
541
541
  fromZigbee: [fz.xiaomi_battery, fz.legacy.xiaomi_on_off_action, fz.legacy.xiaomi_multistate_action],
542
542
  toZigbee: [],
543
543
  endpoint: (device) => {
@@ -814,7 +814,7 @@ module.exports = [
814
814
  model: 'WSDCGQ01LM',
815
815
  vendor: 'Xiaomi',
816
816
  description: 'MiJia temperature & humidity sensor',
817
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
817
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
818
818
  fromZigbee: [fz.xiaomi_battery, fz.WSDCGQ01LM_WSDCGQ11LM_interval, fz.xiaomi_temperature, fz.humidity],
819
819
  toZigbee: [],
820
820
  exposes: [e.battery(), e.temperature(), e.humidity(), e.battery_voltage()],
@@ -824,7 +824,7 @@ module.exports = [
824
824
  model: 'WSDCGQ11LM',
825
825
  vendor: 'Xiaomi',
826
826
  description: 'Aqara temperature, humidity and pressure sensor',
827
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
827
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
828
828
  fromZigbee: [fz.xiaomi_battery, fz.xiaomi_temperature, fz.humidity, fz.pressure, fz.WSDCGQ01LM_WSDCGQ11LM_interval],
829
829
  toZigbee: [],
830
830
  exposes: [e.battery(), e.temperature(), e.humidity(), e.pressure(), e.battery_voltage()],
@@ -840,7 +840,7 @@ module.exports = [
840
840
  description: 'Aqara T1 temperature, humidity and pressure sensor',
841
841
  fromZigbee: [fz.xiaomi_battery, fz.temperature, fz.humidity, fz.pressure],
842
842
  toZigbee: [],
843
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
843
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
844
844
  configure: async (device, coordinatorEndpoint, logger) => {
845
845
  const endpoint = device.getEndpoint(1);
846
846
  const binds = ['msTemperatureMeasurement', 'msRelativeHumidity', 'msPressureMeasurement'];
@@ -853,7 +853,7 @@ module.exports = [
853
853
  model: 'RTCGQ01LM',
854
854
  vendor: 'Xiaomi',
855
855
  description: 'MiJia human body movement sensor',
856
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
856
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
857
857
  fromZigbee: [fz.xiaomi_battery, fz.occupancy_with_timeout],
858
858
  toZigbee: [],
859
859
  exposes: [e.battery(), e.occupancy(), e.battery_voltage()],
@@ -863,7 +863,7 @@ module.exports = [
863
863
  model: 'RTCGQ11LM',
864
864
  vendor: 'Xiaomi',
865
865
  description: 'Aqara human body movement and illuminance sensor',
866
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
866
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
867
867
  fromZigbee: [fz.xiaomi_battery, fz.occupancy_with_timeout, fz.RTCGQ11LM_illuminance, fz.RTCGQ11LM_interval],
868
868
  toZigbee: [],
869
869
  exposes: [e.battery(), e.occupancy(), e.temperature(), e.battery_voltage(), e.illuminance_lux().withProperty('illuminance'),
@@ -879,7 +879,7 @@ module.exports = [
879
879
  exposes: [e.occupancy(), e.illuminance().withUnit('lx').withDescription('Measured illuminance in lux'),
880
880
  exposes.numeric('detection_interval', ea.ALL).withValueMin(2).withValueMax(65535).withUnit('s')
881
881
  .withDescription('Time interval for detecting actions'), e.battery()],
882
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
882
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
883
883
  configure: async (device, coordinatorEndpoint, logger) => {
884
884
  const endpoint = device.getEndpoint(1);
885
885
  await endpoint.read('genPowerCfg', ['batteryVoltage']);
@@ -897,7 +897,7 @@ module.exports = [
897
897
  exposes: [e.occupancy(), exposes.enum('motion_sensitivity', ea.ALL, ['low', 'medium', 'high']),
898
898
  exposes.numeric('detection_interval', ea.ALL).withValueMin(2).withValueMax(65535).withUnit('s')
899
899
  .withDescription('Time interval for detecting actions'), e.battery()],
900
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
900
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
901
901
  configure: async (device, coordinatorEndpoint, logger) => {
902
902
  const endpoint = device.getEndpoint(1);
903
903
  await endpoint.read('genPowerCfg', ['batteryVoltage']);
@@ -935,7 +935,7 @@ module.exports = [
935
935
  model: 'MCCGQ01LM',
936
936
  vendor: 'Xiaomi',
937
937
  description: 'MiJia door & window contact sensor',
938
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
938
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
939
939
  fromZigbee: [fz.xiaomi_battery, fz.xiaomi_contact],
940
940
  toZigbee: [],
941
941
  exposes: [e.battery(), e.contact(), e.battery_voltage()],
@@ -945,7 +945,7 @@ module.exports = [
945
945
  model: 'MCCGQ11LM',
946
946
  vendor: 'Xiaomi',
947
947
  description: 'Aqara door & window contact sensor',
948
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
948
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
949
949
  fromZigbee: [fz.xiaomi_battery, fz.xiaomi_contact, fz.xiaomi_contact_interval],
950
950
  toZigbee: [],
951
951
  exposes: [e.battery(), e.contact(), e.temperature(), e.battery_voltage()],
@@ -959,7 +959,7 @@ module.exports = [
959
959
  model: 'SJCGQ11LM',
960
960
  vendor: 'Xiaomi',
961
961
  description: 'Aqara water leak sensor',
962
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
962
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
963
963
  fromZigbee: [fz.xiaomi_battery, fz.ias_water_leak_alarm_1, fz.SJCGQ11LM_temperature],
964
964
  toZigbee: [],
965
965
  exposes: [e.battery(), e.water_leak(), e.battery_low(), e.battery_voltage(), e.temperature()],
@@ -969,7 +969,7 @@ module.exports = [
969
969
  model: 'SJCGQ12LM',
970
970
  vendor: 'Xiaomi',
971
971
  description: 'Aqara T1 water leak sensor',
972
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
972
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
973
973
  fromZigbee: [fz.xiaomi_battery, fz.ias_water_leak_alarm_1],
974
974
  toZigbee: [],
975
975
  exposes: [e.battery(), e.water_leak(), e.battery_low(), e.tamper(), e.battery_voltage()],
@@ -980,7 +980,7 @@ module.exports = [
980
980
  model: 'MFKZQ01LM',
981
981
  vendor: 'Xiaomi',
982
982
  description: 'Mi/Aqara smart home cube',
983
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
983
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
984
984
  fromZigbee: [fz.xiaomi_battery, fz.MFKZQ01LM_action_multistate, fz.MFKZQ01LM_action_analog],
985
985
  exposes: [e.battery(), e.battery_voltage(), e.angle('action_angle'),
986
986
  e.cube_side('action_from_side'), e.cube_side('action_side'), e.cube_side('action_to_side'),
@@ -1138,7 +1138,7 @@ module.exports = [
1138
1138
  model: 'JTYJ-GD-01LM/BW',
1139
1139
  description: 'MiJia Honeywell smoke detector',
1140
1140
  vendor: 'Xiaomi',
1141
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1141
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1142
1142
  fromZigbee: [fz.xiaomi_battery, fz.JTYJGD01LMBW_smoke, fz.JTYJGD01LMBW_smoke_density],
1143
1143
  toZigbee: [tz.JTQJBF01LMBW_JTYJGD01LMBW_sensitivity, tz.JTQJBF01LMBW_JTYJGD01LMBW_selfest],
1144
1144
  exposes: [
@@ -1208,7 +1208,7 @@ module.exports = [
1208
1208
  model: 'DJT11LM',
1209
1209
  vendor: 'Xiaomi',
1210
1210
  description: 'Aqara vibration sensor',
1211
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1211
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1212
1212
  fromZigbee: [fz.xiaomi_battery, fz.DJT11LM_vibration],
1213
1213
  toZigbee: [tz.DJT11LM_vibration_sensitivity],
1214
1214
  exposes: [
@@ -1380,7 +1380,7 @@ module.exports = [
1380
1380
  ]), exposes.enum('operation_mode', ea.ALL, ['command', 'event'])
1381
1381
  .withDescription('Operation mode, select "command" to enable bindings (wake up the device before changing modes!)')],
1382
1382
  toZigbee: [tz.aqara_opple_operation_mode],
1383
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1383
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1384
1384
  configure: async (device, coordinatorEndpoint, logger) => {
1385
1385
  const endpoint = device.getEndpoint(1);
1386
1386
  await endpoint.write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f});
@@ -1402,7 +1402,7 @@ module.exports = [
1402
1402
  ]), exposes.enum('operation_mode', ea.ALL, ['command', 'event'])
1403
1403
  .withDescription('Operation mode, select "command" to enable bindings (wake up the device before changing modes!)')],
1404
1404
  toZigbee: [tz.aqara_opple_operation_mode],
1405
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1405
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1406
1406
  configure: async (device, coordinatorEndpoint, logger) => {
1407
1407
  const endpoint = device.getEndpoint(1);
1408
1408
  await endpoint.write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f});
@@ -1428,7 +1428,7 @@ module.exports = [
1428
1428
  ]), exposes.enum('operation_mode', ea.ALL, ['command', 'event'])
1429
1429
  .withDescription('Operation mode, select "command" to enable bindings (wake up the device before changing modes!)')],
1430
1430
  toZigbee: [tz.aqara_opple_operation_mode],
1431
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1431
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1432
1432
  configure: async (device, coordinatorEndpoint, logger) => {
1433
1433
  const endpoint = device.getEndpoint(1);
1434
1434
  await endpoint.write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f});
@@ -1444,7 +1444,7 @@ module.exports = [
1444
1444
  description: 'MiJia light intensity sensor',
1445
1445
  fromZigbee: [fz.battery, fz.illuminance],
1446
1446
  toZigbee: [],
1447
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1447
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1448
1448
  configure: async (device, coordinatorEndpoint, logger) => {
1449
1449
  const endpoint = device.getEndpoint(1);
1450
1450
  await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'msIlluminanceMeasurement']);
@@ -1596,7 +1596,7 @@ module.exports = [
1596
1596
  description: 'Aqara wireless remote switch H1 (double rocker)',
1597
1597
  fromZigbee: [fz.battery, fz.xiaomi_multistate_action, fz.aqara_opple, fz.command_toggle],
1598
1598
  toZigbee: [tz.xiaomi_switch_click_mode, tz.aqara_opple_operation_mode],
1599
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}, multiEndpoint: true},
1599
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}, multiEndpoint: true},
1600
1600
  exposes: [
1601
1601
  e.battery(), e.battery_voltage(), e.action([
1602
1602
  'single_left', 'single_right', 'single_both',
@@ -1683,7 +1683,7 @@ module.exports = [
1683
1683
  description: 'Aqara TVOC air quality monitor',
1684
1684
  fromZigbee: [fz.xiaomi_tvoc, fz.battery, fz.temperature, fz.humidity],
1685
1685
  toZigbee: [],
1686
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1686
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1687
1687
  exposes: [e.battery(), e.temperature(), e.humidity(), e.voc()],
1688
1688
  configure: async (device, coordinatorEndpoint, logger) => {
1689
1689
  const endpoint = device.getEndpoint(1);
@@ -1762,7 +1762,7 @@ module.exports = [
1762
1762
  model: 'WXKG13LM',
1763
1763
  vendor: 'Xiaomi',
1764
1764
  description: 'Aqara T1 wireless mini switch',
1765
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1765
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1766
1766
  fromZigbee: [fz.battery, fz.aqara_opple_multistate, fz.aqara_opple],
1767
1767
  toZigbee: [],
1768
1768
  exposes: [e.battery(), e.battery_voltage(), e.action(['single', 'double', 'triple', 'quintuple', 'hold', 'release', 'many'])],
@@ -1778,7 +1778,7 @@ module.exports = [
1778
1778
  description: 'Aqara T1 light intensity sensor',
1779
1779
  fromZigbee: [fz.battery, fz.illuminance, fz.aqara_opple],
1780
1780
  toZigbee: [tz.GZCGQ11LM_detection_period],
1781
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1781
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1782
1782
  exposes: [e.battery(), e.battery_voltage(), e.illuminance(), e.illuminance_lux(),
1783
1783
  exposes.numeric('detection_period', exposes.access.ALL).withValueMin(1).withValueMax(59).withUnit('s')
1784
1784
  .withDescription('Time interval in seconds to report after light changes')],
@@ -1817,7 +1817,7 @@ module.exports = [
1817
1817
  description: 'Aqara T1 door & window contact sensor',
1818
1818
  fromZigbee: [fz.xiaomi_contact, fz.battery],
1819
1819
  toZigbee: [],
1820
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1820
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1821
1821
  exposes: [e.contact(), e.battery(), e.battery_voltage()],
1822
1822
  configure: async (device, coordinatorEndpoint, logger) => {
1823
1823
  const endpoint = device.getEndpoint(1);
@@ -1846,7 +1846,7 @@ module.exports = [
1846
1846
  model: 'ZNXNKG02LM',
1847
1847
  vendor: 'Xiaomi',
1848
1848
  description: 'Aqara knob H1 (wireless)',
1849
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1849
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1850
1850
  exposes: [e.battery(), e.battery_voltage(),
1851
1851
  e.action(['single', 'double', 'hold', 'release', 'start_rotating', 'rotation', 'stop_rotating']),
1852
1852
  exposes.enum('operation_mode', ea.ALL, ['event', 'command']).withDescription('Button mode'),
@@ -1884,7 +1884,7 @@ module.exports = [
1884
1884
  model: 'WXKG17LM',
1885
1885
  vendor: 'Xiaomi',
1886
1886
  description: 'Aqara E1 double key wireless switch',
1887
- meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1887
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1888
1888
  exposes: [e.battery(), e.battery_voltage(),
1889
1889
  e.action(['single_left', 'single_right', 'single_both', 'double_left', 'double_right', 'hold_left', 'hold_right']),
1890
1890
  // eslint-disable-next-line max-len
package/lib/utils.js CHANGED
@@ -94,7 +94,7 @@ function calibrateAndPrecisionRoundOptions(number, options, type) {
94
94
  return precisionRound(number, precision);
95
95
  }
96
96
 
97
- function toPercentage(value, min, max) {
97
+ function toPercentage(value, min, max, log=false) {
98
98
  if (value > max) {
99
99
  value = max;
100
100
  } else if (value < min) {
@@ -102,7 +102,13 @@ function toPercentage(value, min, max) {
102
102
  }
103
103
 
104
104
  const normalised = (value - min) / (max - min);
105
- return Math.round(normalised * 100);
105
+ let percentage;
106
+ if (log == true) {
107
+ percentage = normalised === 0 ? 0 : normalised * (1 - Math.log( normalised ));
108
+ } else {
109
+ percentage = normalised;
110
+ }
111
+ return Math.round(percentage * 100);
106
112
  }
107
113
 
108
114
  function addActionGroup(payload, msg, definition) {
@@ -163,6 +169,8 @@ function batteryVoltageToPercentage(voltage, option) {
163
169
  percentage = Math.round(percentage);
164
170
  } else if (option === '3V_2850_3200') {
165
171
  percentage = toPercentage(voltage, 2850, 3200);
172
+ } else if (option === '3V_2850_3000_log') {
173
+ percentage = toPercentage(voltage, 2850, 3000, true);
166
174
  } else if (option === '4LR6AA1_5v') {
167
175
  percentage = toPercentage(voltage, 3000, 4200);
168
176
  } else {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.430",
3
+ "version": "14.0.431",
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.430",
3
+ "version": "14.0.431",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [