zigbee-herdsman-converters 14.0.692 → 14.0.693
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/converters/fromZigbee.js +29 -50
- package/converters/toZigbee.js +44 -4
- package/devices/namron.js +10 -2
- package/devices/philips.js +17 -25
- package/devices/sinope.js +22 -0
- package/devices/third_reality.js +19 -7
- package/devices/tuya.js +12 -11
- package/devices/xiaomi.js +27 -11
- package/lib/utils.js +3 -2
- package/lib/xiaomi.js +44 -9
- package/package.json +1 -1
package/converters/fromZigbee.js
CHANGED
|
@@ -383,9 +383,11 @@ const converters = {
|
|
|
383
383
|
device_temperature: {
|
|
384
384
|
cluster: 'genDeviceTempCfg',
|
|
385
385
|
type: ['attributeReport', 'readResponse'],
|
|
386
|
+
options: [exposes.options.calibration('device_temperature')],
|
|
386
387
|
convert: (model, msg, publish, options, meta) => {
|
|
387
388
|
if (msg.data.hasOwnProperty('currentTemperature')) {
|
|
388
|
-
|
|
389
|
+
const value = parseInt(msg.data['currentTemperature']);
|
|
390
|
+
return {device_temperature: calibrateAndPrecisionRoundOptions(value, options, 'device_temperature')};
|
|
389
391
|
}
|
|
390
392
|
},
|
|
391
393
|
},
|
|
@@ -648,7 +650,7 @@ const converters = {
|
|
|
648
650
|
const result = converters.metering.convert(model, msg, publish, options, meta);
|
|
649
651
|
// Filter incorrect 0 energy values reported by the device:
|
|
650
652
|
// https://github.com/Koenkk/zigbee2mqtt/issues/7852
|
|
651
|
-
if (result.energy === 0) {
|
|
653
|
+
if (result && result.energy === 0) {
|
|
652
654
|
delete result.energy;
|
|
653
655
|
}
|
|
654
656
|
return result;
|
|
@@ -680,6 +682,17 @@ const converters = {
|
|
|
680
682
|
*/
|
|
681
683
|
cluster: 'seMetering',
|
|
682
684
|
type: ['attributeReport', 'readResponse'],
|
|
685
|
+
options: (definition) => {
|
|
686
|
+
const result = [];
|
|
687
|
+
if (definition.exposes.find((e) => e.name === 'power')) {
|
|
688
|
+
result.push(exposes.options.precision('power'), exposes.options.calibration('power', 'percentual'));
|
|
689
|
+
}
|
|
690
|
+
if (definition.exposes.find((e) => e.name === 'energy')) {
|
|
691
|
+
result.push(exposes.options.precision('energy'), exposes.options.calibration('energy', 'percentual'));
|
|
692
|
+
}
|
|
693
|
+
return result;
|
|
694
|
+
},
|
|
695
|
+
|
|
683
696
|
convert: (model, msg, publish, options, meta) => {
|
|
684
697
|
if (utils.hasAlreadyProcessedMessage(msg, model)) return;
|
|
685
698
|
const payload = {};
|
|
@@ -692,7 +705,7 @@ const converters = {
|
|
|
692
705
|
if (factor != null) {
|
|
693
706
|
power = (power * factor) * 1000; // kWh to Watt
|
|
694
707
|
}
|
|
695
|
-
payload.power =
|
|
708
|
+
payload.power = calibrateAndPrecisionRoundOptions(power, options, 'power');
|
|
696
709
|
}
|
|
697
710
|
|
|
698
711
|
if (factor != null && (msg.data.hasOwnProperty('currentSummDelivered') ||
|
|
@@ -708,7 +721,7 @@ const converters = {
|
|
|
708
721
|
const value = (parseInt(data[0]) << 32) + parseInt(data[1]);
|
|
709
722
|
energy -= value * factor;
|
|
710
723
|
}
|
|
711
|
-
payload.energy =
|
|
724
|
+
payload.energy = calibrateAndPrecisionRoundOptions(energy, options, 'energy');
|
|
712
725
|
}
|
|
713
726
|
|
|
714
727
|
return payload;
|
|
@@ -735,8 +748,11 @@ const converters = {
|
|
|
735
748
|
*/
|
|
736
749
|
cluster: 'haElectricalMeasurement',
|
|
737
750
|
type: ['attributeReport', 'readResponse'],
|
|
738
|
-
options: [
|
|
739
|
-
exposes.options.calibration('
|
|
751
|
+
options: [
|
|
752
|
+
exposes.options.calibration('power', 'percentual'), exposes.options.precision('power'),
|
|
753
|
+
exposes.options.calibration('current', 'percentual'), exposes.options.precision('current'),
|
|
754
|
+
exposes.options.calibration('voltage', 'percentual'), exposes.options.precision('voltage'),
|
|
755
|
+
],
|
|
740
756
|
convert: (model, msg, publish, options, meta) => {
|
|
741
757
|
if (utils.hasAlreadyProcessedMessage(msg, model)) return;
|
|
742
758
|
const getFactor = (key) => {
|
|
@@ -5322,47 +5338,23 @@ const converters = {
|
|
|
5322
5338
|
xiaomi_power: {
|
|
5323
5339
|
cluster: 'genAnalogInput',
|
|
5324
5340
|
type: ['attributeReport', 'readResponse'],
|
|
5341
|
+
options: [exposes.options.calibration('power', 'percentual'), exposes.options.precision('power')],
|
|
5325
5342
|
convert: (model, msg, publish, options, meta) => {
|
|
5326
|
-
return {power:
|
|
5343
|
+
return {power: calibrateAndPrecisionRoundOptions(msg.data['presentValue'], options, 'power')};
|
|
5327
5344
|
},
|
|
5328
5345
|
},
|
|
5329
5346
|
xiaomi_basic: {
|
|
5330
5347
|
cluster: 'genBasic',
|
|
5331
5348
|
type: ['attributeReport', 'readResponse'],
|
|
5332
|
-
options:
|
|
5333
|
-
const result = [];
|
|
5334
|
-
if (definition.exposes.find((e) => e.name === 'temperature')) {
|
|
5335
|
-
result.push(exposes.options.precision('temperature'), exposes.options.calibration('temperature'));
|
|
5336
|
-
}
|
|
5337
|
-
if (definition.exposes.find((e) => e.name === 'device_temperature')) {
|
|
5338
|
-
result.push(exposes.options.calibration('device_temperature'));
|
|
5339
|
-
}
|
|
5340
|
-
if (definition.exposes.find((e) => e.name === 'illuminance')) {
|
|
5341
|
-
result.push(exposes.options.calibration('illuminance', 'percentual'));
|
|
5342
|
-
}
|
|
5343
|
-
if (definition.exposes.find((e) => e.name === 'illuminance_lux')) {
|
|
5344
|
-
result.push(exposes.options.calibration('illuminance_lux', 'percentual'));
|
|
5345
|
-
}
|
|
5346
|
-
return result;
|
|
5347
|
-
},
|
|
5349
|
+
options: xiaomi.numericAttributes2Options,
|
|
5348
5350
|
convert: (model, msg, publish, options, meta) => {
|
|
5349
|
-
|
|
5350
|
-
return payload;
|
|
5351
|
+
return xiaomi.numericAttributes2Payload(msg, meta, model, options, msg.data);
|
|
5351
5352
|
},
|
|
5352
5353
|
},
|
|
5353
5354
|
xiaomi_basic_raw: {
|
|
5354
5355
|
cluster: 'genBasic',
|
|
5355
5356
|
type: ['raw'],
|
|
5356
|
-
options:
|
|
5357
|
-
const result = [];
|
|
5358
|
-
if (definition.exposes.find((e) => e.name === 'temperature')) {
|
|
5359
|
-
result.push(exposes.options.precision('temperature'), exposes.options.calibration('temperature'));
|
|
5360
|
-
}
|
|
5361
|
-
if (definition.exposes.find((e) => e.name === 'device_temperature')) {
|
|
5362
|
-
result.push(exposes.options.calibration('device_temperature'));
|
|
5363
|
-
}
|
|
5364
|
-
return result;
|
|
5365
|
-
},
|
|
5357
|
+
options: xiaomi.numericAttributes2Options,
|
|
5366
5358
|
convert: (model, msg, publish, options, meta) => {
|
|
5367
5359
|
let payload = {};
|
|
5368
5360
|
if (Buffer.isBuffer(msg.data)) {
|
|
@@ -5375,22 +5367,9 @@ const converters = {
|
|
|
5375
5367
|
aqara_opple: {
|
|
5376
5368
|
cluster: 'aqaraOpple',
|
|
5377
5369
|
type: ['attributeReport', 'readResponse'],
|
|
5378
|
-
options:
|
|
5379
|
-
const result = [];
|
|
5380
|
-
if (definition.exposes.find((e) => e.name === 'temperature')) {
|
|
5381
|
-
result.push(exposes.options.precision('temperature'), exposes.options.calibration('temperature'));
|
|
5382
|
-
}
|
|
5383
|
-
if (definition.exposes.find((e) => e.name === 'device_temperature')) {
|
|
5384
|
-
result.push(exposes.options.calibration('device_temperature'));
|
|
5385
|
-
}
|
|
5386
|
-
if (definition.exposes.find((e) => e.name === 'illuminance')) {
|
|
5387
|
-
result.push(exposes.options.calibration('illuminance', 'percentual'));
|
|
5388
|
-
}
|
|
5389
|
-
return result;
|
|
5390
|
-
},
|
|
5370
|
+
options: xiaomi.numericAttributes2Options,
|
|
5391
5371
|
convert: (model, msg, publish, options, meta) => {
|
|
5392
|
-
|
|
5393
|
-
return payload;
|
|
5372
|
+
return xiaomi.numericAttributes2Payload(msg, meta, model, options, msg.data);
|
|
5394
5373
|
},
|
|
5395
5374
|
},
|
|
5396
5375
|
xiaomi_on_off_action: {
|
package/converters/toZigbee.js
CHANGED
|
@@ -2588,6 +2588,18 @@ const converters = {
|
|
|
2588
2588
|
}
|
|
2589
2589
|
},
|
|
2590
2590
|
},
|
|
2591
|
+
xiaomi_curtain_battery_voltage: {
|
|
2592
|
+
key: ['voltage'],
|
|
2593
|
+
convertGet: async (entity, key, meta) => {
|
|
2594
|
+
switch (meta.mapped.model) {
|
|
2595
|
+
case 'ZNCLBL01LM':
|
|
2596
|
+
await entity.read('aqaraOpple', [0x040B], manufacturerOptions.xiaomi);
|
|
2597
|
+
break;
|
|
2598
|
+
default:
|
|
2599
|
+
throw new Error(`xiaomi_curtain_battery_voltage - unsupported model: ${meta.mapped.model}`);
|
|
2600
|
+
}
|
|
2601
|
+
},
|
|
2602
|
+
},
|
|
2591
2603
|
xiaomi_curtain_acn002_charging_status: {
|
|
2592
2604
|
key: ['charging_status'],
|
|
2593
2605
|
convertGet: async (entity, key, meta) => {
|
|
@@ -6513,10 +6525,12 @@ const converters = {
|
|
|
6513
6525
|
}
|
|
6514
6526
|
},
|
|
6515
6527
|
},
|
|
6516
|
-
|
|
6517
|
-
key: ['
|
|
6518
|
-
|
|
6519
|
-
|
|
6528
|
+
ZNCLBL01LM_hooks_lock: {
|
|
6529
|
+
key: ['hooks_lock'],
|
|
6530
|
+
convertSet: async (entity, key, value, meta) => {
|
|
6531
|
+
const lookup = {'UNLOCK': 0, 'LOCK': 1};
|
|
6532
|
+
await entity.write('aqaraOpple', {0x0427: {value: lookup[value], type: 0x20}}, manufacturerOptions.xiaomi);
|
|
6533
|
+
return {state: {[key]: value}};
|
|
6520
6534
|
},
|
|
6521
6535
|
},
|
|
6522
6536
|
ZNCLBL01LM_hooks_state: {
|
|
@@ -6525,6 +6539,32 @@ const converters = {
|
|
|
6525
6539
|
await entity.read('aqaraOpple', [0x0428], manufacturerOptions.xiaomi);
|
|
6526
6540
|
},
|
|
6527
6541
|
},
|
|
6542
|
+
ZNCLBL01LM_hand_open: {
|
|
6543
|
+
key: ['hand_open'],
|
|
6544
|
+
convertSet: async (entity, key, value, meta) => {
|
|
6545
|
+
await entity.write('aqaraOpple', {0x0401: {value: !value, type: 0x10}}, manufacturerOptions.xiaomi);
|
|
6546
|
+
},
|
|
6547
|
+
convertGet: async (entity, key, meta) => {
|
|
6548
|
+
await entity.read('aqaraOpple', [0x0401], manufacturerOptions.xiaomi);
|
|
6549
|
+
},
|
|
6550
|
+
},
|
|
6551
|
+
ZNCLBL01LM_limits_calibration: {
|
|
6552
|
+
key: ['limits_calibration'],
|
|
6553
|
+
convertSet: async (entity, key, value, meta) => {
|
|
6554
|
+
switch (value) {
|
|
6555
|
+
case 'start':
|
|
6556
|
+
await entity.write('aqaraOpple', {0x0407: {value: 0x01, type: 0x20}}, manufacturerOptions.xiaomi);
|
|
6557
|
+
break;
|
|
6558
|
+
case 'end':
|
|
6559
|
+
await entity.write('aqaraOpple', {0x0407: {value: 0x02, type: 0x20}}, manufacturerOptions.xiaomi);
|
|
6560
|
+
break;
|
|
6561
|
+
case 'reset':
|
|
6562
|
+
await entity.write('aqaraOpple', {0x0407: {value: 0x00, type: 0x20}}, manufacturerOptions.xiaomi);
|
|
6563
|
+
// also? await entity.write('aqaraOpple', {0x0402: {value: 0x00, type: 0x10}}, manufacturerOptions.xiaomi);
|
|
6564
|
+
break;
|
|
6565
|
+
}
|
|
6566
|
+
},
|
|
6567
|
+
},
|
|
6528
6568
|
wiser_vact_calibrate_valve: {
|
|
6529
6569
|
key: ['calibrate_valve'],
|
|
6530
6570
|
convertSet: async (entity, key, value, meta) => {
|
package/devices/namron.js
CHANGED
|
@@ -5,6 +5,7 @@ const tz = require('../converters/toZigbee');
|
|
|
5
5
|
const constants = require('../lib/constants');
|
|
6
6
|
const reporting = require('../lib/reporting');
|
|
7
7
|
const globalStore = require('../lib/store');
|
|
8
|
+
const ota = require('../lib/ota');
|
|
8
9
|
const utils = require('../lib/utils');
|
|
9
10
|
const extend = require('../lib/extend');
|
|
10
11
|
const ea = exposes.access;
|
|
@@ -159,6 +160,7 @@ module.exports = [
|
|
|
159
160
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
|
|
160
161
|
await reporting.onOff(endpoint);
|
|
161
162
|
},
|
|
163
|
+
ota: ota.zigbeeOTA,
|
|
162
164
|
},
|
|
163
165
|
{
|
|
164
166
|
zigbeeModel: ['1402755'],
|
|
@@ -190,6 +192,7 @@ module.exports = [
|
|
|
190
192
|
endpoint: (device) => {
|
|
191
193
|
return {l1: 1, l2: 2, l3: 3, l4: 4};
|
|
192
194
|
},
|
|
195
|
+
ota: ota.zigbeeOTA,
|
|
193
196
|
},
|
|
194
197
|
{
|
|
195
198
|
zigbeeModel: ['4512721'],
|
|
@@ -207,6 +210,7 @@ module.exports = [
|
|
|
207
210
|
endpoint: (device) => {
|
|
208
211
|
return {l1: 1, l2: 2, l3: 3, l4: 4};
|
|
209
212
|
},
|
|
213
|
+
ota: ota.zigbeeOTA,
|
|
210
214
|
},
|
|
211
215
|
{
|
|
212
216
|
zigbeeModel: ['4512701'],
|
|
@@ -231,7 +235,7 @@ module.exports = [
|
|
|
231
235
|
zigbeeModel: ['4512719'],
|
|
232
236
|
model: '4512719',
|
|
233
237
|
vendor: 'Namron',
|
|
234
|
-
description: 'Zigbee 2 channel switch K4 white',
|
|
238
|
+
description: 'Zigbee 2 channel switch K4 (white)',
|
|
235
239
|
fromZigbee: [fz.command_on, fz.command_off, fz.battery, fz.command_move, fz.command_stop],
|
|
236
240
|
meta: {multiEndpoint: true},
|
|
237
241
|
exposes: [e.battery(), e.action(['on_l1', 'off_l1', 'brightness_move_up_l1', 'brightness_move_down_l1', 'brightness_stop_l1',
|
|
@@ -240,6 +244,7 @@ module.exports = [
|
|
|
240
244
|
endpoint: (device) => {
|
|
241
245
|
return {l1: 1, l2: 2};
|
|
242
246
|
},
|
|
247
|
+
ota: ota.zigbeeOTA,
|
|
243
248
|
},
|
|
244
249
|
{
|
|
245
250
|
zigbeeModel: ['4512726'],
|
|
@@ -259,12 +264,13 @@ module.exports = [
|
|
|
259
264
|
await reporting.batteryPercentageRemaining(endpoint);
|
|
260
265
|
await reporting.batteryVoltage(endpoint);
|
|
261
266
|
},
|
|
267
|
+
ota: ota.zigbeeOTA,
|
|
262
268
|
},
|
|
263
269
|
{
|
|
264
270
|
zigbeeModel: ['4512729'],
|
|
265
271
|
model: '4512729',
|
|
266
272
|
vendor: 'Namron',
|
|
267
|
-
description: 'Zigbee 2 channel switch K4
|
|
273
|
+
description: 'Zigbee 2 channel switch K4 (black)',
|
|
268
274
|
fromZigbee: [fz.command_on, fz.command_off, fz.battery, fz.command_move, fz.command_stop],
|
|
269
275
|
meta: {multiEndpoint: true},
|
|
270
276
|
exposes: [e.battery(), e.action(['on_l1', 'off_l1', 'brightness_move_up_l1', 'brightness_move_down_l1', 'brightness_stop_l1',
|
|
@@ -273,6 +279,7 @@ module.exports = [
|
|
|
273
279
|
endpoint: (device) => {
|
|
274
280
|
return {l1: 1, l2: 2};
|
|
275
281
|
},
|
|
282
|
+
ota: ota.zigbeeOTA,
|
|
276
283
|
},
|
|
277
284
|
{
|
|
278
285
|
zigbeeModel: ['4512706'],
|
|
@@ -589,6 +596,7 @@ module.exports = [
|
|
|
589
596
|
await endpoint.read('hvacThermostat', [0x1008, 0x1009, 0x100A, 0x100B], options);
|
|
590
597
|
await endpoint.read('hvacThermostat', [0x2001, 0x2002], options);
|
|
591
598
|
},
|
|
599
|
+
ota: ota.zigbeeOTA,
|
|
592
600
|
},
|
|
593
601
|
{
|
|
594
602
|
zigbeeModel: ['4512735'],
|
package/devices/philips.js
CHANGED
|
@@ -769,7 +769,7 @@ module.exports = [
|
|
|
769
769
|
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
770
770
|
},
|
|
771
771
|
{
|
|
772
|
-
zigbeeModel: ['LCG002'],
|
|
772
|
+
zigbeeModel: ['LCG002', '929003047701'],
|
|
773
773
|
model: '929001953101',
|
|
774
774
|
vendor: 'Philips',
|
|
775
775
|
description: 'Hue White and Color Ambiance GU10',
|
|
@@ -2013,11 +2013,7 @@ module.exports = [
|
|
|
2013
2013
|
exposes.numeric('occupancy_timeout', ea.ALL).withUnit('second').withValueMin(0).withValueMax(65535)],
|
|
2014
2014
|
toZigbee: [tz.occupancy_timeout, tz.hue_motion_sensitivity, tz.hue_motion_led_indication],
|
|
2015
2015
|
endpoint: (device) => {
|
|
2016
|
-
return {
|
|
2017
|
-
'default': 2, // default
|
|
2018
|
-
'ep1': 1,
|
|
2019
|
-
'ep2': 2, // e.g. for write to msOccupancySensing
|
|
2020
|
-
};
|
|
2016
|
+
return {'default': 2, 'ep1': 1, 'ep2': 2};
|
|
2021
2017
|
},
|
|
2022
2018
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
2023
2019
|
const endpoint = device.getEndpoint(2);
|
|
@@ -2046,11 +2042,7 @@ module.exports = [
|
|
|
2046
2042
|
exposes.numeric('occupancy_timeout', ea.ALL).withUnit('second').withValueMin(0).withValueMax(65535)],
|
|
2047
2043
|
toZigbee: [tz.occupancy_timeout, tz.hue_motion_sensitivity, tz.hue_motion_led_indication],
|
|
2048
2044
|
endpoint: (device) => {
|
|
2049
|
-
return {
|
|
2050
|
-
'default': 2, // default
|
|
2051
|
-
'ep1': 1,
|
|
2052
|
-
'ep2': 2, // e.g. for write to msOccupancySensing
|
|
2053
|
-
};
|
|
2045
|
+
return {'default': 2, 'ep1': 1, 'ep2': 2};
|
|
2054
2046
|
},
|
|
2055
2047
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
2056
2048
|
const endpoint = device.getEndpoint(2);
|
|
@@ -2078,13 +2070,6 @@ module.exports = [
|
|
|
2078
2070
|
exposes.binary('led_indication', ea.ALL, true, false).withDescription('Blink green LED on motion detection'),
|
|
2079
2071
|
exposes.numeric('occupancy_timeout', ea.ALL).withUnit('second').withValueMin(0).withValueMax(65535)],
|
|
2080
2072
|
toZigbee: [tz.occupancy_timeout, tz.hue_motion_sensitivity, tz.hue_motion_led_indication],
|
|
2081
|
-
endpoint: (device) => {
|
|
2082
|
-
return {
|
|
2083
|
-
'default': 2, // default
|
|
2084
|
-
'ep1': 1,
|
|
2085
|
-
'ep2': 2, // e.g. for write to msOccupancySensing
|
|
2086
|
-
};
|
|
2087
|
-
},
|
|
2088
2073
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
2089
2074
|
const endpoint = device.getEndpoint(2);
|
|
2090
2075
|
const binds = ['genPowerCfg', 'msIlluminanceMeasurement', 'msTemperatureMeasurement', 'msOccupancySensing'];
|
|
@@ -2111,13 +2096,6 @@ module.exports = [
|
|
|
2111
2096
|
exposes.binary('led_indication', ea.ALL, true, false).withDescription('Blink green LED on motion detection'),
|
|
2112
2097
|
exposes.numeric('occupancy_timeout', ea.ALL).withUnit('second').withValueMin(0).withValueMax(65535)],
|
|
2113
2098
|
toZigbee: [tz.occupancy_timeout, tz.hue_motion_sensitivity, tz.hue_motion_led_indication],
|
|
2114
|
-
endpoint: (device) => {
|
|
2115
|
-
return {
|
|
2116
|
-
'default': 2, // default
|
|
2117
|
-
'ep1': 1,
|
|
2118
|
-
'ep2': 2, // e.g. for write to msOccupancySensing
|
|
2119
|
-
};
|
|
2120
|
-
},
|
|
2121
2099
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
2122
2100
|
const endpoint = device.getEndpoint(2);
|
|
2123
2101
|
const binds = ['genPowerCfg', 'msIlluminanceMeasurement', 'msTemperatureMeasurement', 'msOccupancySensing'];
|
|
@@ -3011,6 +2989,13 @@ module.exports = [
|
|
|
3011
2989
|
description: 'Hue Gradient Signe floor lamp (white)',
|
|
3012
2990
|
extend: hueExtend.light_onoff_brightness_colortemp_color_gradient({colorTempRange: [153, 500]}),
|
|
3013
2991
|
},
|
|
2992
|
+
{
|
|
2993
|
+
zigbeeModel: ['915005987301'],
|
|
2994
|
+
model: '915005987301',
|
|
2995
|
+
vendor: 'Philips',
|
|
2996
|
+
description: 'Hue Gradient Signe table lamp (white)',
|
|
2997
|
+
extend: hueExtend.light_onoff_brightness_colortemp_color_gradient({colorTempRange: [153, 500]}),
|
|
2998
|
+
},
|
|
3014
2999
|
{
|
|
3015
3000
|
zigbeeModel: ['929003526301'],
|
|
3016
3001
|
model: '929003526301',
|
|
@@ -3032,4 +3017,11 @@ module.exports = [
|
|
|
3032
3017
|
description: 'Hue white ambiance Pillar spotlight with Bluetooth (black)',
|
|
3033
3018
|
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
|
|
3034
3019
|
},
|
|
3020
|
+
{
|
|
3021
|
+
zigbeeModel: ['8719514288232'],
|
|
3022
|
+
model: '929002469216',
|
|
3023
|
+
vendor: 'Philips',
|
|
3024
|
+
description: 'Hue white E27 1100lm with Bluetooth',
|
|
3025
|
+
extend: hueExtend.light_onoff_brightness(),
|
|
3026
|
+
},
|
|
3035
3027
|
];
|
package/devices/sinope.js
CHANGED
|
@@ -1017,4 +1017,26 @@ module.exports = [
|
|
|
1017
1017
|
} catch (error) {/* Do Nothing */}
|
|
1018
1018
|
},
|
|
1019
1019
|
},
|
|
1020
|
+
{
|
|
1021
|
+
zigbeeModel: ['RM3500ZB'],
|
|
1022
|
+
model: 'RM3500ZB',
|
|
1023
|
+
vendor: 'Sinopé',
|
|
1024
|
+
description: 'Calypso smart water heater controller',
|
|
1025
|
+
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.ias_water_leak_alarm_1, fz.temperature],
|
|
1026
|
+
toZigbee: [tz.on_off],
|
|
1027
|
+
exposes: [e.switch(), e.power(), e.current(), e.voltage(), e.energy(), e.water_leak(), e.temperature()],
|
|
1028
|
+
configure: async (device, coordinatorEndpoint) => {
|
|
1029
|
+
const endpoint = device.getEndpoint(1);
|
|
1030
|
+
const binds = ['genOnOff', 'haElectricalMeasurement', 'seMetering', 'Temperature'];
|
|
1031
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
1032
|
+
await reporting.onOff(endpoint);
|
|
1033
|
+
await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
|
|
1034
|
+
await reporting.activePower(endpoint);
|
|
1035
|
+
await reporting.rmsCurrent(endpoint);
|
|
1036
|
+
await reporting.rmsVoltage(endpoint);
|
|
1037
|
+
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
1038
|
+
await reporting.currentSummDelivered(endpoint);
|
|
1039
|
+
await reporting.temperature(endpoint, {min: 60, max: 3600, change: 1});
|
|
1040
|
+
},
|
|
1041
|
+
},
|
|
1020
1042
|
];
|
package/devices/third_reality.js
CHANGED
|
@@ -102,17 +102,12 @@ module.exports = [
|
|
|
102
102
|
model: '3RSP019BZ',
|
|
103
103
|
vendor: 'Third Reality',
|
|
104
104
|
description: 'Zigbee / BLE smart plug',
|
|
105
|
-
|
|
106
|
-
toZigbee: [tz.on_off],
|
|
105
|
+
extend: extend.switch(),
|
|
107
106
|
ota: ota.zigbeeOTA,
|
|
108
|
-
exposes: [e.switch(), e.power(), e.current(), e.voltage()],
|
|
109
107
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
110
108
|
const endpoint = device.getEndpoint(1);
|
|
111
|
-
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff'
|
|
109
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
|
|
112
110
|
await reporting.onOff(endpoint);
|
|
113
|
-
await reporting.activePower(endpoint);
|
|
114
|
-
await reporting.rmsCurrent(endpoint);
|
|
115
|
-
await reporting.rmsVoltage(endpoint);
|
|
116
111
|
},
|
|
117
112
|
},
|
|
118
113
|
{
|
|
@@ -158,4 +153,21 @@ module.exports = [
|
|
|
158
153
|
exposes: [e.battery(), e.temperature(), e.humidity(), e.battery_voltage()],
|
|
159
154
|
ota: ota.zigbeeOTA,
|
|
160
155
|
},
|
|
156
|
+
{
|
|
157
|
+
zigbeeModel: ['3RSP02028BZ'],
|
|
158
|
+
model: '3RSP02028BZ',
|
|
159
|
+
vendor: 'Third Reality',
|
|
160
|
+
description: 'Zigbee / BLE smart plug with power',
|
|
161
|
+
fromZigbee: [fz.on_off, fz.electrical_measurement],
|
|
162
|
+
toZigbee: [tz.on_off],
|
|
163
|
+
exposes: [e.switch(), e.power(), e.current(), e.voltage()],
|
|
164
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
165
|
+
const endpoint = device.getEndpoint(1);
|
|
166
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement']);
|
|
167
|
+
await reporting.onOff(endpoint);
|
|
168
|
+
await reporting.activePower(endpoint);
|
|
169
|
+
await reporting.rmsCurrent(endpoint);
|
|
170
|
+
await reporting.rmsVoltage(endpoint);
|
|
171
|
+
},
|
|
172
|
+
},
|
|
161
173
|
];
|
package/devices/tuya.js
CHANGED
|
@@ -989,7 +989,8 @@ module.exports = [
|
|
|
989
989
|
{vendor: 'Zemismart', model: 'LXZB-ZB-09A', description: 'Zemismart LED Surface Mounted Downlight 9W RGBW'},
|
|
990
990
|
{vendor: 'Feconn', model: 'FE-GU10-5W', description: 'Zigbee GU10 5W smart bulb'},
|
|
991
991
|
],
|
|
992
|
-
extend: extend.light_onoff_brightness_colortemp_color(
|
|
992
|
+
extend: extend.light_onoff_brightness_colortemp_color(
|
|
993
|
+
{colorTempRange: [153, 500], disableColorTempStartup: true, disablePowerOnBehavior: true}),
|
|
993
994
|
meta: {applyRedFix: true, enhancedHue: false},
|
|
994
995
|
},
|
|
995
996
|
{
|
|
@@ -998,7 +999,7 @@ module.exports = [
|
|
|
998
999
|
vendor: 'TuYa',
|
|
999
1000
|
description: 'Zigbee RGB light',
|
|
1000
1001
|
whiteLabel: [{vendor: 'BTF-Lighting', model: 'C03Z'}],
|
|
1001
|
-
extend: extend.light_onoff_brightness_color(),
|
|
1002
|
+
extend: extend.light_onoff_brightness_color({disablePowerOnBehavior: true}),
|
|
1002
1003
|
// Requires red fix: https://github.com/Koenkk/zigbee2mqtt/issues/5962#issue-796462106
|
|
1003
1004
|
meta: {applyRedFix: true, enhancedHue: false},
|
|
1004
1005
|
},
|
|
@@ -1007,7 +1008,7 @@ module.exports = [
|
|
|
1007
1008
|
model: 'TS0504B',
|
|
1008
1009
|
vendor: 'TuYa',
|
|
1009
1010
|
description: 'Zigbee RGBW light',
|
|
1010
|
-
extend: extend.light_onoff_brightness_color(),
|
|
1011
|
+
extend: extend.light_onoff_brightness_color({disablePowerOnBehavior: true}),
|
|
1011
1012
|
toZigbee: utils.replaceInArray(extend.light_onoff_brightness_color().toZigbee, [tz.light_color], [tzLocal.TS0504B_color]),
|
|
1012
1013
|
meta: {applyRedFix: true},
|
|
1013
1014
|
},
|
|
@@ -1016,14 +1017,14 @@ module.exports = [
|
|
|
1016
1017
|
model: 'TS0501A',
|
|
1017
1018
|
description: 'Zigbee light',
|
|
1018
1019
|
vendor: 'TuYa',
|
|
1019
|
-
extend: extend.light_onoff_brightness(),
|
|
1020
|
+
extend: extend.light_onoff_brightness({disablePowerOnBehavior: true}),
|
|
1020
1021
|
},
|
|
1021
1022
|
{
|
|
1022
1023
|
zigbeeModel: ['TS0501B'],
|
|
1023
1024
|
model: 'TS0501B',
|
|
1024
1025
|
description: 'Zigbee light',
|
|
1025
1026
|
vendor: 'TuYa',
|
|
1026
|
-
extend: extend.light_onoff_brightness(),
|
|
1027
|
+
extend: extend.light_onoff_brightness({disablePowerOnBehavior: true}),
|
|
1027
1028
|
},
|
|
1028
1029
|
{
|
|
1029
1030
|
fingerprint: tuya.fingerprint('TS0202', ['_TZ3210_cwamkvua']),
|
|
@@ -1558,7 +1559,7 @@ module.exports = [
|
|
|
1558
1559
|
model: 'TS0503A',
|
|
1559
1560
|
vendor: 'TuYa',
|
|
1560
1561
|
description: 'Led strip controller',
|
|
1561
|
-
extend: extend.light_onoff_brightness_color(),
|
|
1562
|
+
extend: extend.light_onoff_brightness_color({disablePowerOnBehavior: true}),
|
|
1562
1563
|
meta: {applyRedFix: true},
|
|
1563
1564
|
},
|
|
1564
1565
|
{
|
|
@@ -1575,7 +1576,7 @@ module.exports = [
|
|
|
1575
1576
|
model: 'TS0502A',
|
|
1576
1577
|
vendor: 'TuYa',
|
|
1577
1578
|
description: 'Light controller',
|
|
1578
|
-
extend: extend.light_onoff_brightness_colortemp(),
|
|
1579
|
+
extend: extend.light_onoff_brightness_colortemp({disablePowerOnBehavior: true}),
|
|
1579
1580
|
},
|
|
1580
1581
|
{
|
|
1581
1582
|
zigbeeModel: ['TS0502B'],
|
|
@@ -1586,14 +1587,14 @@ module.exports = [
|
|
|
1586
1587
|
{vendor: 'Mercator Ikuü', model: 'SMI7040', description: 'Ford Batten Light'},
|
|
1587
1588
|
{vendor: 'Mercator Ikuü', model: 'SMD9300', description: 'Donovan Panel Light'},
|
|
1588
1589
|
],
|
|
1589
|
-
extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 500]}),
|
|
1590
|
+
extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 500], disablePowerOnBehavior: true}),
|
|
1590
1591
|
},
|
|
1591
1592
|
{
|
|
1592
1593
|
zigbeeModel: ['TS0504A'],
|
|
1593
1594
|
model: 'TS0504A',
|
|
1594
1595
|
vendor: 'TuYa',
|
|
1595
1596
|
description: 'RGBW LED controller',
|
|
1596
|
-
extend: extend.light_onoff_brightness_colortemp_color(),
|
|
1597
|
+
extend: extend.light_onoff_brightness_colortemp_color({disablePowerOnBehavior: true}),
|
|
1597
1598
|
},
|
|
1598
1599
|
{
|
|
1599
1600
|
fingerprint: [{modelID: 'TS0505A', manufacturerName: '_TZ3000_sosdczdl'}],
|
|
@@ -1609,7 +1610,7 @@ module.exports = [
|
|
|
1609
1610
|
model: 'TS0505A',
|
|
1610
1611
|
vendor: 'TuYa',
|
|
1611
1612
|
description: 'RGB+CCT light controller',
|
|
1612
|
-
extend: extend.light_onoff_brightness_colortemp_color(),
|
|
1613
|
+
extend: extend.light_onoff_brightness_colortemp_color({disablePowerOnBehavior: true}),
|
|
1613
1614
|
},
|
|
1614
1615
|
{
|
|
1615
1616
|
fingerprint: [{manufacturerName: '_TZ2000_a476raq2'}],
|
|
@@ -3657,7 +3658,7 @@ module.exports = [
|
|
|
3657
3658
|
},
|
|
3658
3659
|
},
|
|
3659
3660
|
{
|
|
3660
|
-
fingerprint:
|
|
3661
|
+
fingerprint: tuya.fingerprint('TS110E', ['_TZ3210_zxbtub8r', '_TZ3210_k1msuvg6']),
|
|
3661
3662
|
model: 'TS110E_1gang_1',
|
|
3662
3663
|
vendor: 'TuYa',
|
|
3663
3664
|
description: '1 channel dimmer',
|
package/devices/xiaomi.js
CHANGED
|
@@ -1939,22 +1939,38 @@ module.exports = [
|
|
|
1939
1939
|
vendor: 'Xiaomi',
|
|
1940
1940
|
whiteLabel: [{vendor: 'Xiaomi', model: 'CM-M01'}],
|
|
1941
1941
|
description: 'Aqara curtain driver E1',
|
|
1942
|
-
fromZigbee: [
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1942
|
+
fromZigbee: [
|
|
1943
|
+
fz.battery,
|
|
1944
|
+
fz.xiaomi_curtain_position_tilt,
|
|
1945
|
+
fz.aqara_opple,
|
|
1946
|
+
fz.power_source,
|
|
1947
|
+
],
|
|
1948
|
+
toZigbee: [
|
|
1949
|
+
tz.xiaomi_curtain_position_state,
|
|
1950
|
+
tz.xiaomi_curtain_battery_voltage,
|
|
1951
|
+
tz.ZNCLBL01LM_hooks_lock,
|
|
1952
|
+
tz.ZNCLBL01LM_hooks_state,
|
|
1953
|
+
tz.ZNCLBL01LM_hand_open,
|
|
1954
|
+
tz.ZNCLBL01LM_limits_calibration,
|
|
1955
|
+
tz.power_source,
|
|
1956
|
+
tz.battery_percentage_remaining,
|
|
1957
|
+
],
|
|
1958
|
+
exposes: [
|
|
1959
|
+
e.cover_position().setAccess('state', ea.ALL),
|
|
1960
|
+
exposes.binary('hand_open', ea.ALL, true, false).withDescription('Pulling curtains by hand starts the motor'),
|
|
1961
|
+
exposes.enum('limits_calibration', ea.SET, ['start', 'end', 'reset']).withDescription('Calibrate the position limits'),
|
|
1962
|
+
e.battery().withAccess(ea.STATE_GET),
|
|
1946
1963
|
e.battery_voltage().withAccess(ea.STATE_GET),
|
|
1947
1964
|
e.device_temperature(),
|
|
1948
1965
|
e.action(['manual_open', 'manual_close']),
|
|
1949
|
-
exposes.enum('motor_state', ea.STATE, ['stopped', 'opening', 'closing', 'pause'])
|
|
1950
|
-
|
|
1951
|
-
exposes.
|
|
1952
|
-
|
|
1953
|
-
exposes.enum('hooks_state', ea.STATE_GET, ['unlocked', 'locked', 'locking', 'unlocking'])
|
|
1954
|
-
.withDescription('Hooks state'),
|
|
1966
|
+
exposes.enum('motor_state', ea.STATE, ['stopped', 'opening', 'closing', 'pause']).withDescription('Motor state'),
|
|
1967
|
+
exposes.binary('running', ea.STATE, true, false).withDescription('Whether the motor is moving or not'),
|
|
1968
|
+
exposes.enum('hooks_lock', ea.STATE_SET, ['LOCK', 'UNLOCK']).withDescription('Lock the curtain driver hooks'),
|
|
1969
|
+
exposes.enum('hooks_state', ea.STATE_GET, ['unlocked', 'locked', 'locking', 'unlocking']).withDescription('Hooks state'),
|
|
1955
1970
|
exposes.numeric('target_position', ea.STATE).withUnit('%').withDescription('Target position'),
|
|
1956
1971
|
exposes.enum('power_source', ea.STATE_GET, ['battery', 'dc_source']).withDescription('The current power source'),
|
|
1957
|
-
exposes.binary('charging', ea.STATE_GET, true, false).withDescription('The current charging state')
|
|
1972
|
+
exposes.binary('charging', ea.STATE_GET, true, false).withDescription('The current charging state'),
|
|
1973
|
+
],
|
|
1958
1974
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1959
1975
|
const endpoint = device.getEndpoint(1);
|
|
1960
1976
|
await endpoint.read('genPowerCfg', ['batteryPercentageRemaining']);
|
package/lib/utils.js
CHANGED
|
@@ -77,10 +77,11 @@ function hasAlreadyProcessedMessage(msg, model, ID=null, key=null) {
|
|
|
77
77
|
|
|
78
78
|
const calibrateAndPrecisionRoundOptionsDefaultPrecision = {
|
|
79
79
|
temperature: 2, humidity: 2, pressure: 1, pm25: 0, power: 2, current: 2, current_phase_b: 2, current_phase_c: 2,
|
|
80
|
-
voltage: 2, voltage_phase_b: 2, voltage_phase_c: 2, power_phase_b: 2, power_phase_c: 2,
|
|
80
|
+
voltage: 2, voltage_phase_b: 2, voltage_phase_c: 2, power_phase_b: 2, power_phase_c: 2, energy: 2,
|
|
81
81
|
};
|
|
82
82
|
function calibrateAndPrecisionRoundOptionsIsPercentual(type) {
|
|
83
|
-
return type.startsWith('current') || type.startsWith('
|
|
83
|
+
return type.startsWith('current') || type.startsWith('energy') || type.startsWith('voltage') || type.startsWith('power') ||
|
|
84
|
+
type.startsWith('illuminance');
|
|
84
85
|
}
|
|
85
86
|
function calibrateAndPrecisionRoundOptions(number, options, type) {
|
|
86
87
|
// Calibrate
|
package/lib/xiaomi.js
CHANGED
|
@@ -3,11 +3,14 @@
|
|
|
3
3
|
const {
|
|
4
4
|
batteryVoltageToPercentage,
|
|
5
5
|
calibrateAndPrecisionRoundOptions,
|
|
6
|
+
calibrateAndPrecisionRoundOptionsIsPercentual,
|
|
6
7
|
postfixWithEndpointName,
|
|
7
8
|
precisionRound,
|
|
8
9
|
getKey,
|
|
9
10
|
} = require('./utils');
|
|
10
11
|
|
|
12
|
+
const exposes = require('../lib/exposes');
|
|
13
|
+
|
|
11
14
|
const buffer2DataObject = (meta, model, buffer) => {
|
|
12
15
|
const dataObject = {};
|
|
13
16
|
|
|
@@ -337,27 +340,27 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
|
|
|
337
340
|
}
|
|
338
341
|
break;
|
|
339
342
|
case '149':
|
|
340
|
-
payload.energy =
|
|
343
|
+
payload.energy = calibrateAndPrecisionRoundOptions(value, options, 'energy'); // 0x95
|
|
341
344
|
// Consumption is deprecated
|
|
342
345
|
payload.consumption = payload.energy;
|
|
343
346
|
break;
|
|
344
347
|
case '150':
|
|
345
348
|
if (!['JTYJ-GD-01LM/BW'].includes(model.model)) {
|
|
346
|
-
payload.voltage =
|
|
349
|
+
payload.voltage = calibrateAndPrecisionRoundOptions(value * 0.1, options, 'voltage'); // 0x96
|
|
347
350
|
}
|
|
348
351
|
break;
|
|
349
352
|
case '151':
|
|
350
353
|
if (['LLKZMK11LM'].includes(model.model)) {
|
|
351
|
-
payload.current =
|
|
354
|
+
payload.current = calibrateAndPrecisionRoundOptions(value, options, 'current');
|
|
352
355
|
} else {
|
|
353
|
-
payload.current =
|
|
356
|
+
payload.current = calibrateAndPrecisionRoundOptions(value * 0.001, options, 'current');
|
|
354
357
|
}
|
|
355
358
|
break;
|
|
356
359
|
case '152':
|
|
357
360
|
if (['DJT11LM'].includes(model.model)) {
|
|
358
361
|
// We don't know what implies for this device, it contains values like 30, 50,... that don't seem to change
|
|
359
362
|
} else {
|
|
360
|
-
payload.power =
|
|
363
|
+
payload.power = calibrateAndPrecisionRoundOptions(value, options, 'power'); // 0x98
|
|
361
364
|
}
|
|
362
365
|
break;
|
|
363
366
|
case '154':
|
|
@@ -545,10 +548,15 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
|
|
|
545
548
|
payload.button_switch_mode = value === 1 ? 'relay_and_usb' : 'relay';
|
|
546
549
|
break;
|
|
547
550
|
case '1025':
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
551
|
+
if (['ZNCLBL01LM'].includes(model.model)) {
|
|
552
|
+
payload.hand_open = !value;
|
|
553
|
+
} else {
|
|
554
|
+
// next values update only when curtain finished initial setup and knows current position
|
|
555
|
+
payload.options = {...payload.options,
|
|
556
|
+
reverse_direction: value[2] == '\u0001',
|
|
557
|
+
hand_open: value[5] == '\u0000',
|
|
558
|
+
};
|
|
559
|
+
}
|
|
552
560
|
break;
|
|
553
561
|
case '1028':
|
|
554
562
|
payload = {...payload,
|
|
@@ -597,9 +605,15 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
|
|
|
597
605
|
{1: 'manual_open', 2: 'manual_close'})[value];
|
|
598
606
|
}
|
|
599
607
|
break;
|
|
608
|
+
case '1063':
|
|
609
|
+
if (['ZNCLBL01LM'].includes(model.model)) {
|
|
610
|
+
payload.hooks_lock = {0: 'UNLOCK', 1: 'LOCK'}[value];
|
|
611
|
+
}
|
|
612
|
+
break;
|
|
600
613
|
case '1064':
|
|
601
614
|
if (['ZNCLBL01LM'].includes(model.model)) {
|
|
602
615
|
payload.hooks_state = {0: 'unlocked', 1: 'locked', 2: 'locking', 3: 'unlocking'}[value];
|
|
616
|
+
payload.hooks_lock = {0: 'UNLOCK', 1: 'LOCK', 2: 'UNLOCK', 3: 'LOCK'}[value];
|
|
603
617
|
}
|
|
604
618
|
break;
|
|
605
619
|
case '1289':
|
|
@@ -650,8 +664,29 @@ const VOCKQJK11LMDisplayUnit = {
|
|
|
650
664
|
'ppb_fahrenheit': 0x11, // ppb, °F
|
|
651
665
|
};
|
|
652
666
|
|
|
667
|
+
const numericAttributes2Options = (definition) => {
|
|
668
|
+
const supported = ['temperature', 'device_temperature', 'illuminance', 'illuminance_lux',
|
|
669
|
+
'pressure', 'power', 'current', 'voltage', 'energy', 'power'];
|
|
670
|
+
const precisionSupported = ['temperature', 'humidity', 'pressure', 'power', 'current', 'voltage', 'energy', 'power'];
|
|
671
|
+
const result = [];
|
|
672
|
+
for (const expose of definition.exposes) {
|
|
673
|
+
// only eletrical measurement voltage is supported, not battery
|
|
674
|
+
const isBatteryVoltage = expose.name === 'voltage' && definition.meta && definition.meta.battery;
|
|
675
|
+
if (supported.includes(expose.name) && !isBatteryVoltage) {
|
|
676
|
+
const type = calibrateAndPrecisionRoundOptionsIsPercentual(expose.name) ? 'percentual' : 'absolute';
|
|
677
|
+
result.push(exposes.options.calibration(expose.name, type));
|
|
678
|
+
if (precisionSupported.includes(expose.name)) {
|
|
679
|
+
result.push(exposes.options.precision(expose.name));
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
return result;
|
|
685
|
+
};
|
|
686
|
+
|
|
653
687
|
module.exports = {
|
|
654
688
|
buffer2DataObject,
|
|
655
689
|
numericAttributes2Payload,
|
|
690
|
+
numericAttributes2Options,
|
|
656
691
|
VOCKQJK11LMDisplayUnit,
|
|
657
692
|
};
|