zigbee-herdsman-converters 14.0.691 → 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 +59 -52
- package/converters/toZigbee.js +45 -5
- package/devices/bosch.js +35 -7
- package/devices/develco.js +1 -0
- package/devices/ledvance.js +1 -1
- package/devices/legrand.js +5 -5
- package/devices/lidl.js +1 -1
- package/devices/namron.js +32 -2
- package/devices/philips.js +17 -25
- package/devices/sinope.js +49 -0
- package/devices/third_reality.js +19 -7
- package/devices/tuya.js +13 -11
- package/devices/xiaomi.js +82 -20
- 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) => {
|
|
@@ -750,6 +766,7 @@ const converters = {
|
|
|
750
766
|
{key: 'activePower', name: 'power', factor: 'acPower'},
|
|
751
767
|
{key: 'activePowerPhB', name: 'power_phase_b', factor: 'acPower'},
|
|
752
768
|
{key: 'activePowerPhC', name: 'power_phase_c', factor: 'acPower'},
|
|
769
|
+
{key: 'apparentPower', name: 'power_apparent', factor: 'acPower'},
|
|
753
770
|
{key: 'rmsCurrent', name: 'current', factor: 'acCurrent'},
|
|
754
771
|
{key: 'rmsCurrentPhB', name: 'current_phase_b', factor: 'acCurrent'},
|
|
755
772
|
{key: 'rmsCurrentPhC', name: 'current_phase_c', factor: 'acCurrent'},
|
|
@@ -5321,47 +5338,23 @@ const converters = {
|
|
|
5321
5338
|
xiaomi_power: {
|
|
5322
5339
|
cluster: 'genAnalogInput',
|
|
5323
5340
|
type: ['attributeReport', 'readResponse'],
|
|
5341
|
+
options: [exposes.options.calibration('power', 'percentual'), exposes.options.precision('power')],
|
|
5324
5342
|
convert: (model, msg, publish, options, meta) => {
|
|
5325
|
-
return {power:
|
|
5343
|
+
return {power: calibrateAndPrecisionRoundOptions(msg.data['presentValue'], options, 'power')};
|
|
5326
5344
|
},
|
|
5327
5345
|
},
|
|
5328
5346
|
xiaomi_basic: {
|
|
5329
5347
|
cluster: 'genBasic',
|
|
5330
5348
|
type: ['attributeReport', 'readResponse'],
|
|
5331
|
-
options:
|
|
5332
|
-
const result = [];
|
|
5333
|
-
if (definition.exposes.find((e) => e.name === 'temperature')) {
|
|
5334
|
-
result.push(exposes.options.precision('temperature'), exposes.options.calibration('temperature'));
|
|
5335
|
-
}
|
|
5336
|
-
if (definition.exposes.find((e) => e.name === 'device_temperature')) {
|
|
5337
|
-
result.push(exposes.options.calibration('device_temperature'));
|
|
5338
|
-
}
|
|
5339
|
-
if (definition.exposes.find((e) => e.name === 'illuminance')) {
|
|
5340
|
-
result.push(exposes.options.calibration('illuminance', 'percentual'));
|
|
5341
|
-
}
|
|
5342
|
-
if (definition.exposes.find((e) => e.name === 'illuminance_lux')) {
|
|
5343
|
-
result.push(exposes.options.calibration('illuminance_lux', 'percentual'));
|
|
5344
|
-
}
|
|
5345
|
-
return result;
|
|
5346
|
-
},
|
|
5349
|
+
options: xiaomi.numericAttributes2Options,
|
|
5347
5350
|
convert: (model, msg, publish, options, meta) => {
|
|
5348
|
-
|
|
5349
|
-
return payload;
|
|
5351
|
+
return xiaomi.numericAttributes2Payload(msg, meta, model, options, msg.data);
|
|
5350
5352
|
},
|
|
5351
5353
|
},
|
|
5352
5354
|
xiaomi_basic_raw: {
|
|
5353
5355
|
cluster: 'genBasic',
|
|
5354
5356
|
type: ['raw'],
|
|
5355
|
-
options:
|
|
5356
|
-
const result = [];
|
|
5357
|
-
if (definition.exposes.find((e) => e.name === 'temperature')) {
|
|
5358
|
-
result.push(exposes.options.precision('temperature'), exposes.options.calibration('temperature'));
|
|
5359
|
-
}
|
|
5360
|
-
if (definition.exposes.find((e) => e.name === 'device_temperature')) {
|
|
5361
|
-
result.push(exposes.options.calibration('device_temperature'));
|
|
5362
|
-
}
|
|
5363
|
-
return result;
|
|
5364
|
-
},
|
|
5357
|
+
options: xiaomi.numericAttributes2Options,
|
|
5365
5358
|
convert: (model, msg, publish, options, meta) => {
|
|
5366
5359
|
let payload = {};
|
|
5367
5360
|
if (Buffer.isBuffer(msg.data)) {
|
|
@@ -5374,22 +5367,9 @@ const converters = {
|
|
|
5374
5367
|
aqara_opple: {
|
|
5375
5368
|
cluster: 'aqaraOpple',
|
|
5376
5369
|
type: ['attributeReport', 'readResponse'],
|
|
5377
|
-
options:
|
|
5378
|
-
const result = [];
|
|
5379
|
-
if (definition.exposes.find((e) => e.name === 'temperature')) {
|
|
5380
|
-
result.push(exposes.options.precision('temperature'), exposes.options.calibration('temperature'));
|
|
5381
|
-
}
|
|
5382
|
-
if (definition.exposes.find((e) => e.name === 'device_temperature')) {
|
|
5383
|
-
result.push(exposes.options.calibration('device_temperature'));
|
|
5384
|
-
}
|
|
5385
|
-
if (definition.exposes.find((e) => e.name === 'illuminance')) {
|
|
5386
|
-
result.push(exposes.options.calibration('illuminance', 'percentual'));
|
|
5387
|
-
}
|
|
5388
|
-
return result;
|
|
5389
|
-
},
|
|
5370
|
+
options: xiaomi.numericAttributes2Options,
|
|
5390
5371
|
convert: (model, msg, publish, options, meta) => {
|
|
5391
|
-
|
|
5392
|
-
return payload;
|
|
5372
|
+
return xiaomi.numericAttributes2Payload(msg, meta, model, options, msg.data);
|
|
5393
5373
|
},
|
|
5394
5374
|
},
|
|
5395
5375
|
xiaomi_on_off_action: {
|
|
@@ -5448,6 +5428,9 @@ const converters = {
|
|
|
5448
5428
|
61: 'all',
|
|
5449
5429
|
};
|
|
5450
5430
|
}
|
|
5431
|
+
if (['WS-USC02'].includes(model.model)) {
|
|
5432
|
+
buttonLookup = {41: 'top', 42: 'bottom', 51: 'both'};
|
|
5433
|
+
}
|
|
5451
5434
|
|
|
5452
5435
|
const action = actionLookup[msg.data['presentValue']];
|
|
5453
5436
|
if (buttonLookup) {
|
|
@@ -5724,8 +5707,9 @@ const converters = {
|
|
|
5724
5707
|
type: ['attributeReport', 'readResponse'],
|
|
5725
5708
|
options: [exposes.options.invert_cover()],
|
|
5726
5709
|
convert: (model, msg, publish, options, meta) => {
|
|
5727
|
-
if (model.model === 'ZNCLDJ12LM'
|
|
5728
|
-
|
|
5710
|
+
if ((model.model === 'ZNCLDJ12LM' || model.model === 'ZNCLDJ14LM') &&
|
|
5711
|
+
msg.type === 'attributeReport' && [0, 2].includes(msg.data['presentValue'])) {
|
|
5712
|
+
// Incorrect reports from the device, ignore (re-read by onEvent of ZNCLDJ12LM and ZNCLDJ14LM)
|
|
5729
5713
|
// https://github.com/Koenkk/zigbee-herdsman-converters/pull/1427#issuecomment-663862724
|
|
5730
5714
|
return;
|
|
5731
5715
|
}
|
|
@@ -5779,6 +5763,29 @@ const converters = {
|
|
|
5779
5763
|
}
|
|
5780
5764
|
},
|
|
5781
5765
|
},
|
|
5766
|
+
xiaomi_curtain_hagl07_status: {
|
|
5767
|
+
cluster: 'genMultistateOutput',
|
|
5768
|
+
type: ['attributeReport'],
|
|
5769
|
+
convert: (model, msg, publish, options, meta) => {
|
|
5770
|
+
let running = false;
|
|
5771
|
+
const data = msg.data;
|
|
5772
|
+
const lookup = {
|
|
5773
|
+
0: 'closing',
|
|
5774
|
+
1: 'opening',
|
|
5775
|
+
2: 'stop',
|
|
5776
|
+
};
|
|
5777
|
+
if (data && data.hasOwnProperty('presentValue')) {
|
|
5778
|
+
const value = data['presentValue'];
|
|
5779
|
+
if (value < 2) {
|
|
5780
|
+
running = true;
|
|
5781
|
+
}
|
|
5782
|
+
return {
|
|
5783
|
+
motor_state: lookup[value],
|
|
5784
|
+
running: running,
|
|
5785
|
+
};
|
|
5786
|
+
}
|
|
5787
|
+
},
|
|
5788
|
+
},
|
|
5782
5789
|
xiaomi_curtain_acn002_status: {
|
|
5783
5790
|
cluster: 'genMultistateOutput',
|
|
5784
5791
|
type: ['attributeReport'],
|
package/converters/toZigbee.js
CHANGED
|
@@ -2503,7 +2503,7 @@ const converters = {
|
|
|
2503
2503
|
if (value.hasOwnProperty('auto_close')) opts.hand_open = value.auto_close;
|
|
2504
2504
|
if (value.hasOwnProperty('reset_move')) opts.reset_limits = value.reset_move;
|
|
2505
2505
|
|
|
2506
|
-
if (meta.mapped.model === 'ZNCLDJ12LM') {
|
|
2506
|
+
if (meta.mapped.model === 'ZNCLDJ12LM' || meta.mapped.model === 'ZNCLDJ14LM') {
|
|
2507
2507
|
await entity.write('genBasic', {0xff28: {value: opts.reverse_direction, type: 0x10}}, manufacturerOptions.xiaomi);
|
|
2508
2508
|
await entity.write('genBasic', {0xff29: {value: !opts.hand_open, type: 0x10}}, manufacturerOptions.xiaomi);
|
|
2509
2509
|
|
|
@@ -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/bosch.js
CHANGED
|
@@ -4,6 +4,7 @@ const fz = require('../converters/fromZigbee');
|
|
|
4
4
|
const tz = require('../converters/toZigbee');
|
|
5
5
|
const reporting = require('../lib/reporting');
|
|
6
6
|
const utils = require('../lib/utils');
|
|
7
|
+
const constants = require('../lib/constants');
|
|
7
8
|
const e = exposes.presets;
|
|
8
9
|
const ea = exposes.access;
|
|
9
10
|
|
|
@@ -57,7 +58,7 @@ const tzLocal = {
|
|
|
57
58
|
if (value=='off') {
|
|
58
59
|
opMode = operatingModes.pause; // OperatingMode 5 = Pause
|
|
59
60
|
} else if (value == 'auto') {
|
|
60
|
-
opMode = operatingModes.automatic; //
|
|
61
|
+
opMode = operatingModes.automatic; // OperatingMode 0 = Automatic
|
|
61
62
|
}
|
|
62
63
|
await entity.write('hvacThermostat', {0x4007: {value: opMode, type: herdsman.Zcl.DataType.enum8}}, boschManufacturer);
|
|
63
64
|
return {state: {system_mode: value}};
|
|
@@ -139,9 +140,12 @@ const fzLocal = {
|
|
|
139
140
|
result.boost = (Object.keys(stateOffOn)[data[0x4043]]);
|
|
140
141
|
}
|
|
141
142
|
if (data.hasOwnProperty(0x4007)) {
|
|
142
|
-
const opModes = {0: 'auto', 1: 'heat', 2: '
|
|
143
|
+
const opModes = {0: 'auto', 1: 'heat', 2: 'unknown_2', 3: 'unknown_3', 4: 'unknown_4', 5: 'off'};
|
|
143
144
|
result.system_mode = opModes[data[0x4007]];
|
|
144
145
|
}
|
|
146
|
+
if (data.hasOwnProperty(0x4020)) {
|
|
147
|
+
result.pi_heating_demand = data[0x4020];
|
|
148
|
+
}
|
|
145
149
|
|
|
146
150
|
return result;
|
|
147
151
|
},
|
|
@@ -214,16 +218,17 @@ const definition = [
|
|
|
214
218
|
toZigbee: [
|
|
215
219
|
tz.thermostat_occupied_heating_setpoint,
|
|
216
220
|
tz.thermostat_local_temperature_calibration,
|
|
217
|
-
tz.thermostat_local_temperature,
|
|
218
221
|
tz.thermostat_keypad_lockout,
|
|
219
222
|
tzLocal.bosch_thermostat,
|
|
220
|
-
tzLocal.bosch_userInterface
|
|
223
|
+
tzLocal.bosch_userInterface,
|
|
224
|
+
],
|
|
221
225
|
exposes: [
|
|
222
226
|
exposes.climate()
|
|
223
|
-
.withLocalTemperature()
|
|
227
|
+
.withLocalTemperature(ea.STATE)
|
|
224
228
|
.withSetpoint('occupied_heating_setpoint', 5, 30, 0.5)
|
|
225
229
|
.withLocalTemperatureCalibration(-12, 12, 0.5)
|
|
226
|
-
.withSystemMode(['off', 'heat', 'auto'])
|
|
230
|
+
.withSystemMode(['off', 'heat', 'auto'])
|
|
231
|
+
.withPiHeatingDemand(ea.STATE),
|
|
227
232
|
exposes.binary('boost', ea.ALL, 'ON', 'OFF')
|
|
228
233
|
.withDescription('Activate Boost heating'),
|
|
229
234
|
exposes.binary('window_open', ea.ALL, 'ON', 'OFF')
|
|
@@ -246,10 +251,33 @@ const definition = [
|
|
|
246
251
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'hvacThermostat', 'hvacUserInterfaceCfg']);
|
|
247
252
|
await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
|
|
248
253
|
await reporting.thermostatTemperature(endpoint);
|
|
254
|
+
await reporting.thermostatKeypadLockMode(endpoint);
|
|
249
255
|
await reporting.batteryPercentageRemaining(endpoint);
|
|
250
256
|
|
|
257
|
+
// report operating_mode (system_mode)
|
|
258
|
+
await endpoint.configureReporting('hvacThermostat', [{
|
|
259
|
+
attribute: {ID: 0x4007, type: herdsman.Zcl.DataType.enum8},
|
|
260
|
+
minimumReportInterval: 0,
|
|
261
|
+
maximumReportInterval: constants.repInterval.HOUR,
|
|
262
|
+
reportableChange: 1,
|
|
263
|
+
}], boschManufacturer);
|
|
264
|
+
// report pi_heating_demand (valve opening)
|
|
265
|
+
await endpoint.configureReporting('hvacThermostat', [{
|
|
266
|
+
attribute: {ID: 0x4020, type: herdsman.Zcl.DataType.enum8},
|
|
267
|
+
minimumReportInterval: 0,
|
|
268
|
+
maximumReportInterval: constants.repInterval.HOUR,
|
|
269
|
+
reportableChange: 1,
|
|
270
|
+
}], boschManufacturer);
|
|
271
|
+
// report window_open
|
|
272
|
+
await endpoint.configureReporting('hvacThermostat', [{
|
|
273
|
+
attribute: {ID: 0x4042, type: herdsman.Zcl.DataType.enum8},
|
|
274
|
+
minimumReportInterval: 0,
|
|
275
|
+
maximumReportInterval: constants.repInterval.HOUR,
|
|
276
|
+
reportableChange: 1,
|
|
277
|
+
}], boschManufacturer);
|
|
278
|
+
|
|
251
279
|
await endpoint.read('hvacThermostat', ['localTemperatureCalibration']);
|
|
252
|
-
await endpoint.read('hvacThermostat', [0x4007, 0x4042, 0x4043], boschManufacturer);
|
|
280
|
+
await endpoint.read('hvacThermostat', [0x4007, 0x4020, 0x4042, 0x4043], boschManufacturer);
|
|
253
281
|
|
|
254
282
|
await endpoint.read('hvacUserInterfaceCfg', ['keypadLockout']);
|
|
255
283
|
await endpoint.read('hvacUserInterfaceCfg', [0x400b, 0x403a, 0x403b], boschManufacturer);
|
package/devices/develco.js
CHANGED
package/devices/ledvance.js
CHANGED
|
@@ -48,7 +48,7 @@ module.exports = [
|
|
|
48
48
|
model: 'AC25697',
|
|
49
49
|
vendor: 'LEDVANCE',
|
|
50
50
|
description: 'SMART+ CLASSIC MULTICOLOUR 60 10W E27',
|
|
51
|
-
extend: extend.ledvance.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
51
|
+
extend: extend.ledvance.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500], disablePowerOnBehavior: true}),
|
|
52
52
|
ota: ota.ledvance,
|
|
53
53
|
},
|
|
54
54
|
{
|
package/devices/legrand.js
CHANGED
|
@@ -209,8 +209,8 @@ module.exports = [
|
|
|
209
209
|
exposes.numeric('ballast_maximum_level', ea.ALL).withValueMin(1).withValueMax(254)
|
|
210
210
|
.withDescription('Specifies the maximum brightness value'),
|
|
211
211
|
exposes.binary('device_mode', ea.ALL, 'dimmer_on', 'dimmer_off').withDescription('Allow the device to change brightness'),
|
|
212
|
-
exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing to
|
|
213
|
-
see the switch in the dark`),
|
|
212
|
+
exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing to` +
|
|
213
|
+
` see the switch in the dark`),
|
|
214
214
|
exposes.binary('led_if_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is turned on'),
|
|
215
215
|
e.power_on_behavior()],
|
|
216
216
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
@@ -231,7 +231,7 @@ module.exports = [
|
|
|
231
231
|
fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement, fz.power_on_behavior],
|
|
232
232
|
toZigbee: [tz.on_off, tz.legrand_settingEnableLedInDark, tz.legrand_identify, tz.legrand_settingEnableLedIfOn,
|
|
233
233
|
tz.power_on_behavior],
|
|
234
|
-
exposes: [e.switch(), e.action(['identify']), e.power(),
|
|
234
|
+
exposes: [e.switch(), e.action(['identify']), e.power(), e.power_apparent(),
|
|
235
235
|
exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the power socket is turned off,
|
|
236
236
|
allowing to see it in the dark`),
|
|
237
237
|
exposes.binary('led_if_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the device is turned on'),
|
|
@@ -383,8 +383,8 @@ module.exports = [
|
|
|
383
383
|
toZigbee: [tz.on_off, tz.legrand_settingEnableLedInDark, tz.legrand_settingEnableLedIfOn],
|
|
384
384
|
exposes: [e.switch().withEndpoint('left'),
|
|
385
385
|
e.switch().withEndpoint('right'),
|
|
386
|
-
exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing to
|
|
387
|
-
see the switch in the dark`),
|
|
386
|
+
exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing to` +
|
|
387
|
+
` see the switch in the dark`),
|
|
388
388
|
exposes.binary('led_if_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is turned on')],
|
|
389
389
|
meta: {multiEndpoint: true},
|
|
390
390
|
configure: async (device, coordinatorEndpoint, logger) => {
|
package/devices/lidl.js
CHANGED
|
@@ -671,7 +671,7 @@ module.exports = [
|
|
|
671
671
|
model: 'HG06106C',
|
|
672
672
|
vendor: 'Lidl',
|
|
673
673
|
description: 'Livarno Lux E27 bulb RGB',
|
|
674
|
-
...extend.light_onoff_brightness_colortemp_color({disableColorTempStartup: true}),
|
|
674
|
+
...extend.light_onoff_brightness_colortemp_color({disableColorTempStartup: true, disablePowerOnBehavior: true}),
|
|
675
675
|
meta: {applyRedFix: true, enhancedHue: false},
|
|
676
676
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
677
677
|
device.getEndpoint(1).saveClusterAttributeKeyValue('lightingColorCtrl', {colorCapabilities: 29});
|
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,29 @@ 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,
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
zigbeeModel: ['4512735'],
|
|
603
|
+
model: '4512735',
|
|
604
|
+
vendor: 'Namron',
|
|
605
|
+
description: 'Multiprise with 4 AC outlets and 2 USB super charging ports (16A)',
|
|
606
|
+
fromZigbee: [fz.on_off],
|
|
607
|
+
toZigbee: [tz.on_off],
|
|
608
|
+
exposes: [e.switch().withEndpoint('l1'), e.switch().withEndpoint('l2'), e.switch().withEndpoint('l3'),
|
|
609
|
+
e.switch().withEndpoint('l4'), e.switch().withEndpoint('l5')],
|
|
610
|
+
endpoint: (device) => {
|
|
611
|
+
return {'l1': 1, 'l2': 2, 'l3': 3, 'l4': 4, 'l5': 5};
|
|
612
|
+
},
|
|
613
|
+
meta: {multiEndpoint: true},
|
|
614
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
615
|
+
for (const ID of [1, 2, 3, 4, 5]) {
|
|
616
|
+
const endpoint = device.getEndpoint(ID);
|
|
617
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
|
|
618
|
+
}
|
|
619
|
+
device.powerSource = 'Mains (single phase)';
|
|
620
|
+
device.save();
|
|
621
|
+
},
|
|
592
622
|
},
|
|
593
623
|
{
|
|
594
624
|
zigbeeModel: ['5401392', '5401396', '5401393', '5401397', '5401394', '5401398', '5401395', '5401399', '5401395'],
|
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
|
@@ -990,4 +990,53 @@ module.exports = [
|
|
|
990
990
|
await reporting.brightness(endpoint); // valve position
|
|
991
991
|
},
|
|
992
992
|
},
|
|
993
|
+
{
|
|
994
|
+
zigbeeModel: ['VA4220ZB'],
|
|
995
|
+
model: 'VA4220ZB',
|
|
996
|
+
vendor: 'Sinopé',
|
|
997
|
+
description: 'Sedna smart water valve',
|
|
998
|
+
fromZigbee: [fz.ignore_iaszone_statuschange, fz.cover_position_via_brightness, fz.cover_state_via_onoff,
|
|
999
|
+
fz.battery, fz.metering],
|
|
1000
|
+
toZigbee: [tz.cover_via_brightness],
|
|
1001
|
+
meta: {battery: {voltageToPercentage: {min: 5400, max: 6800}}},
|
|
1002
|
+
exposes: [e.valve_switch(), e.valve_position(), e.battery_low(), e.battery(), e.battery_voltage()],
|
|
1003
|
+
configure: async (device, coordinatorEndpoint) => {
|
|
1004
|
+
const endpoint = device.getEndpoint(1);
|
|
1005
|
+
const binds = [
|
|
1006
|
+
'genBasic', 'genGroups', 'genOnOff', 'ssIasZone', 'genLevelCtrl',
|
|
1007
|
+
'genPowerCfg', 'seMetering', 'manuSpecificSinope'];
|
|
1008
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
1009
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
1010
|
+
await reporting.onOff(endpoint);
|
|
1011
|
+
await reporting.brightness(endpoint); // valve position
|
|
1012
|
+
try {
|
|
1013
|
+
await reporting.batteryVoltage(endpoint);
|
|
1014
|
+
} catch (error) {/* Do Nothing */}
|
|
1015
|
+
try {
|
|
1016
|
+
await reporting.batteryAlarmState(endpoint);
|
|
1017
|
+
} catch (error) {/* Do Nothing */}
|
|
1018
|
+
},
|
|
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
|
+
},
|
|
993
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']),
|
|
@@ -1207,6 +1208,7 @@ module.exports = [
|
|
|
1207
1208
|
{modelID: 'TS0601', manufacturerName: '_TZE200_ojzhk75b'},
|
|
1208
1209
|
{modelID: 'TS0601', manufacturerName: '_TZE200_swaamsoy'},
|
|
1209
1210
|
{modelID: 'TS0601', manufacturerName: '_TZE200_3p5ydos3'},
|
|
1211
|
+
{modelID: 'TS0601', manufacturerName: '_TZE200_p0gzbqct'},
|
|
1210
1212
|
],
|
|
1211
1213
|
model: 'TS0601_dimmer',
|
|
1212
1214
|
vendor: 'TuYa',
|
|
@@ -1557,7 +1559,7 @@ module.exports = [
|
|
|
1557
1559
|
model: 'TS0503A',
|
|
1558
1560
|
vendor: 'TuYa',
|
|
1559
1561
|
description: 'Led strip controller',
|
|
1560
|
-
extend: extend.light_onoff_brightness_color(),
|
|
1562
|
+
extend: extend.light_onoff_brightness_color({disablePowerOnBehavior: true}),
|
|
1561
1563
|
meta: {applyRedFix: true},
|
|
1562
1564
|
},
|
|
1563
1565
|
{
|
|
@@ -1574,7 +1576,7 @@ module.exports = [
|
|
|
1574
1576
|
model: 'TS0502A',
|
|
1575
1577
|
vendor: 'TuYa',
|
|
1576
1578
|
description: 'Light controller',
|
|
1577
|
-
extend: extend.light_onoff_brightness_colortemp(),
|
|
1579
|
+
extend: extend.light_onoff_brightness_colortemp({disablePowerOnBehavior: true}),
|
|
1578
1580
|
},
|
|
1579
1581
|
{
|
|
1580
1582
|
zigbeeModel: ['TS0502B'],
|
|
@@ -1585,14 +1587,14 @@ module.exports = [
|
|
|
1585
1587
|
{vendor: 'Mercator Ikuü', model: 'SMI7040', description: 'Ford Batten Light'},
|
|
1586
1588
|
{vendor: 'Mercator Ikuü', model: 'SMD9300', description: 'Donovan Panel Light'},
|
|
1587
1589
|
],
|
|
1588
|
-
extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 500]}),
|
|
1590
|
+
extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 500], disablePowerOnBehavior: true}),
|
|
1589
1591
|
},
|
|
1590
1592
|
{
|
|
1591
1593
|
zigbeeModel: ['TS0504A'],
|
|
1592
1594
|
model: 'TS0504A',
|
|
1593
1595
|
vendor: 'TuYa',
|
|
1594
1596
|
description: 'RGBW LED controller',
|
|
1595
|
-
extend: extend.light_onoff_brightness_colortemp_color(),
|
|
1597
|
+
extend: extend.light_onoff_brightness_colortemp_color({disablePowerOnBehavior: true}),
|
|
1596
1598
|
},
|
|
1597
1599
|
{
|
|
1598
1600
|
fingerprint: [{modelID: 'TS0505A', manufacturerName: '_TZ3000_sosdczdl'}],
|
|
@@ -1608,7 +1610,7 @@ module.exports = [
|
|
|
1608
1610
|
model: 'TS0505A',
|
|
1609
1611
|
vendor: 'TuYa',
|
|
1610
1612
|
description: 'RGB+CCT light controller',
|
|
1611
|
-
extend: extend.light_onoff_brightness_colortemp_color(),
|
|
1613
|
+
extend: extend.light_onoff_brightness_colortemp_color({disablePowerOnBehavior: true}),
|
|
1612
1614
|
},
|
|
1613
1615
|
{
|
|
1614
1616
|
fingerprint: [{manufacturerName: '_TZ2000_a476raq2'}],
|
|
@@ -3656,7 +3658,7 @@ module.exports = [
|
|
|
3656
3658
|
},
|
|
3657
3659
|
},
|
|
3658
3660
|
{
|
|
3659
|
-
fingerprint:
|
|
3661
|
+
fingerprint: tuya.fingerprint('TS110E', ['_TZ3210_zxbtub8r', '_TZ3210_k1msuvg6']),
|
|
3660
3662
|
model: 'TS110E_1gang_1',
|
|
3661
3663
|
vendor: 'TuYa',
|
|
3662
3664
|
description: '1 channel dimmer',
|
package/devices/xiaomi.js
CHANGED
|
@@ -441,6 +441,7 @@ module.exports = [
|
|
|
441
441
|
fromZigbee: [fz.temperature, fz.humidity, fzLocal.aqara_s1_pm25, fzLocal.aqara_s1_co2],
|
|
442
442
|
toZigbee: [],
|
|
443
443
|
exposes: [e.temperature(), e.humidity(), e.pm25(), e.co2()],
|
|
444
|
+
ota: ota.zigbeeOTA,
|
|
444
445
|
},
|
|
445
446
|
{
|
|
446
447
|
zigbeeModel: ['lumi.magnet.acn001'],
|
|
@@ -693,7 +694,8 @@ module.exports = [
|
|
|
693
694
|
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled']).withDescription('Decoupled mode'),
|
|
694
695
|
exposes.enum('mode_switch', ea.ALL, ['anti_flicker_mode', 'quick_mode'])
|
|
695
696
|
.withDescription('Anti flicker mode can be used to solve blinking issues of some lights.' +
|
|
696
|
-
'Quick mode makes the device respond faster.')
|
|
697
|
+
'Quick mode makes the device respond faster.'),
|
|
698
|
+
e.power_outage_count(), e.device_temperature().withAccess(ea.STATE)],
|
|
697
699
|
onEvent: preventReset,
|
|
698
700
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
699
701
|
const endpoint1 = device.getEndpoint(1);
|
|
@@ -707,19 +709,35 @@ module.exports = [
|
|
|
707
709
|
model: 'WS-USC02',
|
|
708
710
|
vendor: 'Xiaomi',
|
|
709
711
|
description: 'Aqara smart wall switch (no neutral, double rocker)',
|
|
710
|
-
|
|
711
|
-
|
|
712
|
+
fromZigbee: [fz.on_off, fz.xiaomi_multistate_action, fz.aqara_opple],
|
|
713
|
+
toZigbee: [tz.on_off, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_flip_indicator_light, tz.aqara_switch_mode_switch],
|
|
714
|
+
exposes: [
|
|
715
|
+
e.switch().withEndpoint('top'),
|
|
716
|
+
e.switch().withEndpoint('bottom'),
|
|
717
|
+
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
|
|
718
|
+
.withDescription('Decoupled mode for top button')
|
|
719
|
+
.withEndpoint('top'),
|
|
720
|
+
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
|
|
721
|
+
.withDescription('Decoupled mode for bottom button')
|
|
722
|
+
.withEndpoint('bottom'),
|
|
723
|
+
exposes.enum('mode_switch', ea.ALL, ['anti_flicker_mode', 'quick_mode'])
|
|
724
|
+
.withDescription(
|
|
725
|
+
'Anti flicker mode can be used to solve blinking issues of some lights.' +
|
|
726
|
+
'Quick mode makes the device respond faster.',
|
|
727
|
+
),
|
|
728
|
+
e.power_outage_count(),
|
|
729
|
+
e.device_temperature().withAccess(ea.STATE),
|
|
730
|
+
e.flip_indicator_light(),
|
|
731
|
+
e.action(['single_top', 'single_bottom', 'single_both', 'double_top', 'double_bottom', 'double_both'])],
|
|
712
732
|
meta: {multiEndpoint: true},
|
|
713
733
|
endpoint: (device) => {
|
|
714
734
|
return {'top': 1, 'bottom': 2};
|
|
715
735
|
},
|
|
736
|
+
onEvent: preventReset,
|
|
716
737
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
const endpoint2 = device.getEndpoint(2);
|
|
721
|
-
await reporting.bind(endpoint2, coordinatorEndpoint, ['genOnOff']);
|
|
722
|
-
await reporting.onOff(endpoint2);
|
|
738
|
+
await device.getEndpoint(1).write(
|
|
739
|
+
'aqaraOpple', {mode: 1}, {manufacturerCode: 0x115f, disableResponse: true},
|
|
740
|
+
);
|
|
723
741
|
},
|
|
724
742
|
ota: ota.zigbeeOTA,
|
|
725
743
|
},
|
|
@@ -1862,6 +1880,27 @@ module.exports = [
|
|
|
1862
1880
|
.withDescription('The current state of the motor.'), e.power_outage_count()],
|
|
1863
1881
|
ota: ota.zigbeeOTA,
|
|
1864
1882
|
},
|
|
1883
|
+
{
|
|
1884
|
+
zigbeeModel: ['lumi.curtain.hagl07'],
|
|
1885
|
+
model: 'ZNCLDJ14LM',
|
|
1886
|
+
vendor: 'Xiaomi',
|
|
1887
|
+
description: 'Aqara C2 curtain motor',
|
|
1888
|
+
fromZigbee: [fz.xiaomi_basic, fz.xiaomi_curtain_position, fz.xiaomi_curtain_position_tilt, fz.xiaomi_curtain_hagl07_status],
|
|
1889
|
+
toZigbee: [tz.xiaomi_curtain_position_state, tz.xiaomi_curtain_options],
|
|
1890
|
+
onEvent: async (type, data, device) => {
|
|
1891
|
+
// The position (genAnalogOutput.presentValue) reported via an attribute contains an invaid value
|
|
1892
|
+
// however when reading it will provide the correct value.
|
|
1893
|
+
if (data.type === 'attributeReport' && data.cluster === 'genAnalogOutput') {
|
|
1894
|
+
await device.endpoints[0].read('genAnalogOutput', ['presentValue']);
|
|
1895
|
+
}
|
|
1896
|
+
},
|
|
1897
|
+
exposes: [e.cover_position().setAccess('state', ea.ALL),
|
|
1898
|
+
exposes.binary('running', ea.STATE, true, false)
|
|
1899
|
+
.withDescription('Whether the motor is moving or not'),
|
|
1900
|
+
exposes.enum('motor_state', ea.STATE, ['closing', 'opening', 'stop'])
|
|
1901
|
+
.withDescription('The current state of the motor.'), e.power_outage_count()],
|
|
1902
|
+
ota: ota.zigbeeOTA,
|
|
1903
|
+
},
|
|
1865
1904
|
{
|
|
1866
1905
|
zigbeeModel: ['lumi.curtain.acn002'],
|
|
1867
1906
|
model: 'ZNJLBL01LM',
|
|
@@ -1900,22 +1939,38 @@ module.exports = [
|
|
|
1900
1939
|
vendor: 'Xiaomi',
|
|
1901
1940
|
whiteLabel: [{vendor: 'Xiaomi', model: 'CM-M01'}],
|
|
1902
1941
|
description: 'Aqara curtain driver E1',
|
|
1903
|
-
fromZigbee: [
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
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),
|
|
1907
1963
|
e.battery_voltage().withAccess(ea.STATE_GET),
|
|
1908
1964
|
e.device_temperature(),
|
|
1909
1965
|
e.action(['manual_open', 'manual_close']),
|
|
1910
|
-
exposes.enum('motor_state', ea.STATE, ['stopped', 'opening', 'closing', 'pause'])
|
|
1911
|
-
|
|
1912
|
-
exposes.
|
|
1913
|
-
|
|
1914
|
-
exposes.enum('hooks_state', ea.STATE_GET, ['unlocked', 'locked', 'locking', 'unlocking'])
|
|
1915
|
-
.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'),
|
|
1916
1970
|
exposes.numeric('target_position', ea.STATE).withUnit('%').withDescription('Target position'),
|
|
1917
1971
|
exposes.enum('power_source', ea.STATE_GET, ['battery', 'dc_source']).withDescription('The current power source'),
|
|
1918
|
-
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
|
+
],
|
|
1919
1974
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1920
1975
|
const endpoint = device.getEndpoint(1);
|
|
1921
1976
|
await endpoint.read('genPowerCfg', ['batteryPercentageRemaining']);
|
|
@@ -1944,6 +1999,10 @@ module.exports = [
|
|
|
1944
1999
|
.withDescription('Enabling prevents both relais being on at the same time'),
|
|
1945
2000
|
],
|
|
1946
2001
|
ota: ota.zigbeeOTA,
|
|
2002
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
2003
|
+
device.powerSource = 'Mains (single phase)';
|
|
2004
|
+
device.save();
|
|
2005
|
+
},
|
|
1947
2006
|
},
|
|
1948
2007
|
{
|
|
1949
2008
|
zigbeeModel: ['lumi.lock.acn02'],
|
|
@@ -2165,6 +2224,8 @@ module.exports = [
|
|
|
2165
2224
|
e.voltage().withAccess(ea.STATE), e.power_outage_memory(), e.led_disabled_night(), e.switch_type()],
|
|
2166
2225
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
2167
2226
|
await device.getEndpoint(1).write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f, disableResponse: true});
|
|
2227
|
+
device.powerSource = 'Mains (single phase)';
|
|
2228
|
+
device.save();
|
|
2168
2229
|
},
|
|
2169
2230
|
ota: ota.zigbeeOTA,
|
|
2170
2231
|
},
|
|
@@ -2441,6 +2502,7 @@ module.exports = [
|
|
|
2441
2502
|
const endpoint1 = device.getEndpoint(1);
|
|
2442
2503
|
await endpoint1.write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f, disableResponse: true});
|
|
2443
2504
|
},
|
|
2505
|
+
ota: ota.zigbeeOTA,
|
|
2444
2506
|
},
|
|
2445
2507
|
{
|
|
2446
2508
|
zigbeeModel: ['lumi.sen_ill.agl01'],
|
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
|
};
|