zigbee-herdsman-converters 15.0.71 → 15.0.73
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/devices/gledopto.js +7 -0
- package/devices/gs.js +1 -1
- package/devices/heiman.js +3 -3
- package/devices/lidl.js +9 -5
- package/devices/lixee.js +211 -123
- package/devices/philips.js +1 -1
- package/devices/qoto.js +1 -1
- package/devices/robb.js +7 -0
- package/devices/sonoff.js +13 -0
- package/devices/tuya.js +3 -3
- package/devices/xiaomi.js +3 -1
- package/lib/xiaomi.js +5 -0
- package/package.json +2 -2
- package/devices/woolley.js +0 -17
package/devices/gledopto.js
CHANGED
|
@@ -451,6 +451,13 @@ module.exports = [
|
|
|
451
451
|
description: 'Zigbee 6W E26/E27 Bulb RGB+CCT',
|
|
452
452
|
extend: gledoptoExtend.light_onoff_brightness_colortemp_color(),
|
|
453
453
|
},
|
|
454
|
+
{
|
|
455
|
+
zigbeeModel: ['GL-G-004P'],
|
|
456
|
+
model: 'GL-G-004P',
|
|
457
|
+
vendor: 'Gledopto',
|
|
458
|
+
description: 'Zigbee 7W garden light Pro RGB+CCT',
|
|
459
|
+
extend: gledoptoExtend.light_onoff_brightness_colortemp_color({colorTempRange: [158, 495]}),
|
|
460
|
+
},
|
|
454
461
|
{
|
|
455
462
|
zigbeeModel: ['GL-B-007ZS'],
|
|
456
463
|
model: 'GL-B-007ZS',
|
package/devices/gs.js
CHANGED
package/devices/heiman.js
CHANGED
|
@@ -394,10 +394,10 @@ module.exports = [
|
|
|
394
394
|
zigbeeModel: ['SGMHM-I1'],
|
|
395
395
|
model: 'SGMHM-I1',
|
|
396
396
|
vendor: 'HEIMAN',
|
|
397
|
-
description: '
|
|
398
|
-
fromZigbee: [fz.
|
|
397
|
+
description: 'Methane gas sensor',
|
|
398
|
+
fromZigbee: [fz.ias_gas_alarm_2],
|
|
399
399
|
toZigbee: [],
|
|
400
|
-
exposes: [e.gas()
|
|
400
|
+
exposes: [e.gas()],
|
|
401
401
|
},
|
|
402
402
|
{
|
|
403
403
|
zigbeeModel: ['STHM-I1H'],
|
package/devices/lidl.js
CHANGED
|
@@ -193,8 +193,8 @@ const tzLocal = {
|
|
|
193
193
|
// Load current state or defaults
|
|
194
194
|
const newSettings = {
|
|
195
195
|
brightness: meta.state.brightness ?? 254, // full brightness
|
|
196
|
-
hue: (meta.state.color ?? {}).
|
|
197
|
-
saturation: (meta.state.color ?? {}).
|
|
196
|
+
hue: (meta.state.color ?? {}).hue ?? 0, // red
|
|
197
|
+
saturation: (meta.state.color ?? {}).saturation ?? 100, // full saturation
|
|
198
198
|
};
|
|
199
199
|
|
|
200
200
|
// Apply changes
|
|
@@ -217,8 +217,8 @@ const tzLocal = {
|
|
|
217
217
|
newSettings.saturation = color.saturation;
|
|
218
218
|
|
|
219
219
|
newState.color = {
|
|
220
|
-
|
|
221
|
-
|
|
220
|
+
hue: color.hue,
|
|
221
|
+
saturation: color.saturation,
|
|
222
222
|
};
|
|
223
223
|
}
|
|
224
224
|
|
|
@@ -234,6 +234,10 @@ const tzLocal = {
|
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
+
// If we're in white mode, calculate a matching display color for the set color temperature. This also kind
|
|
238
|
+
// of works in the other direction.
|
|
239
|
+
Object.assign(newState, libColor.syncColorState(newState, meta.state, entity, meta.options, meta.logger));
|
|
240
|
+
|
|
237
241
|
return {state: newState};
|
|
238
242
|
},
|
|
239
243
|
convertGet: async (entity, key, meta) => {
|
|
@@ -816,7 +820,7 @@ module.exports = [
|
|
|
816
820
|
model: '14153905L',
|
|
817
821
|
vendor: 'Lidl',
|
|
818
822
|
description: 'Livarno Home LED floor lamp',
|
|
819
|
-
extend: tuya.extend.light_onoff_brightness_colortemp({colorTempRange: [153,
|
|
823
|
+
extend: tuya.extend.light_onoff_brightness_colortemp({colorTempRange: [153, 500], noConfigure: true}),
|
|
820
824
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
821
825
|
device.getEndpoint(1).saveClusterAttributeKeyValue('lightingColorCtrl', {colorCapabilities: 16});
|
|
822
826
|
},
|
package/devices/lixee.js
CHANGED
|
@@ -11,6 +11,73 @@ const e = exposes.presets;
|
|
|
11
11
|
const utils = require('../lib/utils');
|
|
12
12
|
const ota = require('../lib/ota');
|
|
13
13
|
const {Buffer} = require('buffer');
|
|
14
|
+
const herdsman = require('zigbee-herdsman');
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
/* Start ZiPulses */
|
|
18
|
+
|
|
19
|
+
const unitsZiPulses = [
|
|
20
|
+
'kWh',
|
|
21
|
+
'm3',
|
|
22
|
+
'ft3',
|
|
23
|
+
'ccf',
|
|
24
|
+
'US gl',
|
|
25
|
+
'IMP gl',
|
|
26
|
+
'BTUs',
|
|
27
|
+
'L (litre)',
|
|
28
|
+
'kPA (jauge)',
|
|
29
|
+
'kPA (absolu)',
|
|
30
|
+
'kPA (absolu)',
|
|
31
|
+
'sans unité',
|
|
32
|
+
'MJ',
|
|
33
|
+
'kVar',
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
const tzSeMetering = {
|
|
37
|
+
key: ['divisor', 'multiplier', 'unitOfMeasure'],
|
|
38
|
+
convertSet: async (entity, key, value, meta) => {
|
|
39
|
+
if (key === 'unitOfMeasure') {
|
|
40
|
+
const val = unitsZiPulses.indexOf(value);
|
|
41
|
+
const payload = {768: {value: val, type: herdsman.Zcl.DataType.enum8}};
|
|
42
|
+
await entity.write('seMetering', payload);
|
|
43
|
+
await entity.read('seMetering', [key]);
|
|
44
|
+
return {state: {'unitOfMeasure': value}};
|
|
45
|
+
} else {
|
|
46
|
+
await entity.write('seMetering', {
|
|
47
|
+
[key]: value,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return {state: {[key]: value}};
|
|
52
|
+
},
|
|
53
|
+
// convertGet: async (entity, key, meta) => {
|
|
54
|
+
// await entity.read('seMetering', [key]);
|
|
55
|
+
// },
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
const fzZiPulses = {
|
|
60
|
+
cluster: 'seMetering',
|
|
61
|
+
type: ['attributeReport', 'readResponse'],
|
|
62
|
+
convert: (model, msg, publish, options, meta) => {
|
|
63
|
+
const payload = {};
|
|
64
|
+
if (msg.data.hasOwnProperty('multiplier')) {
|
|
65
|
+
payload['multiplier'] = msg.data['multiplier'];
|
|
66
|
+
}
|
|
67
|
+
if (msg.data.hasOwnProperty('divisor')) {
|
|
68
|
+
payload['divisor'] = msg.data['divisor'];
|
|
69
|
+
}
|
|
70
|
+
if (msg.data.hasOwnProperty('unitOfMeasure')) {
|
|
71
|
+
const val = msg.data['unitOfMeasure'];
|
|
72
|
+
payload['unitOfMeasure'] = unitsZiPulses[val];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return payload;
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
/* End ZiPulses */
|
|
14
81
|
|
|
15
82
|
const fzLocal = {
|
|
16
83
|
lixee_ha_electrical_measurement: {
|
|
@@ -555,137 +622,158 @@ function getCurrentConfig(device, options, logger=console) {
|
|
|
555
622
|
|
|
556
623
|
return myExpose;
|
|
557
624
|
}
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
.
|
|
571
|
-
index
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
625
|
+
module.exports = [
|
|
626
|
+
{
|
|
627
|
+
zigbeeModel: ['ZLinky_TIC', 'ZLinky_TIC\u0000'],
|
|
628
|
+
model: 'ZLinky_TIC',
|
|
629
|
+
vendor: 'LiXee',
|
|
630
|
+
description: 'Lixee ZLinky',
|
|
631
|
+
fromZigbee: [fzLocal.lixee_metering, fz.meter_identification, fzLocal.lixee_ha_electrical_measurement, fzLocal.lixee_private_fz],
|
|
632
|
+
toZigbee: [],
|
|
633
|
+
exposes: (device, options) => {
|
|
634
|
+
// docs generation
|
|
635
|
+
let exposes;
|
|
636
|
+
if (device == null && options == null) {
|
|
637
|
+
exposes = exposedData.map((e) => e.exposes)
|
|
638
|
+
.filter((value, index, self) =>
|
|
639
|
+
index === self.findIndex((t) => (
|
|
640
|
+
t.property === value.property // Remove duplicates
|
|
641
|
+
)),
|
|
642
|
+
);
|
|
643
|
+
} else {
|
|
644
|
+
exposes = getCurrentConfig(device, options).map((e) => e.exposes);
|
|
645
|
+
}
|
|
578
646
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
647
|
+
exposes.push(e.linkquality());
|
|
648
|
+
return exposes;
|
|
649
|
+
},
|
|
650
|
+
options: [
|
|
651
|
+
exposes.options.measurement_poll_interval(),
|
|
652
|
+
exposes.enum(`linky_mode`, ea.SET, ['auto', linkyModeDef.legacy, linkyModeDef.standard])
|
|
653
|
+
.withDescription(`Counter with TIC in mode standard or historique. May require restart (default: auto)`),
|
|
654
|
+
exposes.enum(`energy_phase`, ea.SET, ['auto', linkyPhaseDef.single, linkyPhaseDef.three])
|
|
655
|
+
.withDescription(`Power with single or three phase. May require restart (default: auto)`),
|
|
656
|
+
exposes.enum(`production`, ea.SET, ['auto', 'true', 'false']).withDescription(`If you produce energy back to the grid (works ONLY when linky_mode: ${linkyModeDef.standard}, default: auto)`),
|
|
657
|
+
exposes.enum(`tarif`, ea.SET, [...Object.entries(tarifsDef).map(( [k, v] ) => (v.fname)), 'auto'])
|
|
658
|
+
.withDescription(`Overrides the automatic current tarif. This option will exclude unnecesary attributes. Open a issue to support more of them. Default: auto`),
|
|
659
|
+
exposes.options.precision(`kWh`),
|
|
660
|
+
exposes.numeric(`measurement_poll_chunk`, ea.SET).withValueMin(1).withDescription(`During the poll, request multiple exposes to the Zlinky at once for reducing Zigbee network overload. Too much request at once could exceed device limit. Requieres Z2M restart. Default: 1`),
|
|
661
|
+
exposes.text(`tic_command_whitelist`, ea.SET).withDescription(`List of TIC commands to be exposed (separated by comma). Reconfigure device after change. Default: all`),
|
|
662
|
+
],
|
|
663
|
+
configure: async (device, coordinatorEndpoint, logger, options) => {
|
|
664
|
+
const endpoint = device.getEndpoint(1);
|
|
665
|
+
|
|
666
|
+
await reporting.bind(endpoint, coordinatorEndpoint, [
|
|
667
|
+
clustersDef._0x0702, /* seMetering */
|
|
668
|
+
clustersDef._0x0B01, /* haMeterIdentification */
|
|
669
|
+
clustersDef._0x0B04, /* haElectricalMeasurement */
|
|
670
|
+
clustersDef._0xFF66, /* liXeePrivate */
|
|
671
|
+
]);
|
|
672
|
+
|
|
673
|
+
await endpoint.read('liXeePrivate', ['linkyMode', 'currentTarif'], {manufacturerCode: null})
|
|
674
|
+
.catch((e) => {
|
|
675
|
+
// https://github.com/Koenkk/zigbee2mqtt/issues/11674
|
|
676
|
+
logger.warn(`Failed to read zigbee attributes: ${e}`);
|
|
677
|
+
});
|
|
610
678
|
|
|
611
|
-
|
|
612
|
-
|
|
679
|
+
const configReportings = [];
|
|
680
|
+
const suscribeNew = getCurrentConfig(device, options, logger).filter((e) => e.reportable);
|
|
613
681
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
682
|
+
const unsuscribe = endpoint.configuredReportings
|
|
683
|
+
.filter((e) => !suscribeNew.some((r) => e.cluster.name == r.cluster && e.attribute.name == r.att));
|
|
684
|
+
// Unsuscribe reports that doesn't correspond with the current config
|
|
685
|
+
(await Promise.allSettled(unsuscribe.map((e) => endpoint.configureReporting(e.cluster.name, reporting.payload(e.attribute.name, e.minimumReportInterval, 65535, e.reportableChange), {manufacturerCode: null}))))
|
|
686
|
+
.filter((e) => e.status == 'rejected')
|
|
687
|
+
.forEach((e) => {
|
|
688
|
+
throw e.reason;
|
|
689
|
+
});
|
|
622
690
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
691
|
+
for (const e of suscribeNew) {
|
|
692
|
+
let params = {
|
|
693
|
+
att: e.att,
|
|
694
|
+
min: repInterval.MINUTE,
|
|
695
|
+
max: repInterval.MINUTES_15,
|
|
696
|
+
change: 1,
|
|
697
|
+
};
|
|
698
|
+
// Override reportings
|
|
699
|
+
if (e.hasOwnProperty('report')) {
|
|
700
|
+
params = {...params, ...e.report};
|
|
701
|
+
}
|
|
702
|
+
configReportings.push(endpoint
|
|
703
|
+
.configureReporting(
|
|
704
|
+
e.cluster, reporting.payload(params.att, params.min, params.max, params.change),
|
|
705
|
+
{manufacturerCode: null}),
|
|
706
|
+
);
|
|
633
707
|
}
|
|
634
|
-
|
|
635
|
-
.
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
);
|
|
639
|
-
}
|
|
640
|
-
(await Promise.allSettled(configReportings))
|
|
641
|
-
.filter((e) => e.status == 'rejected')
|
|
642
|
-
.forEach((e) => {
|
|
643
|
-
throw e.reason;
|
|
644
|
-
});
|
|
645
|
-
},
|
|
646
|
-
ota: ota.lixee,
|
|
647
|
-
onEvent: async (type, data, device, options) => {
|
|
648
|
-
const endpoint = device.getEndpoint(1);
|
|
649
|
-
if (type === 'start') {
|
|
650
|
-
endpoint.read('liXeePrivate', ['linkyMode', 'currentTarif'], {manufacturerCode: null})
|
|
651
|
-
.catch((e) => {
|
|
652
|
-
// https://github.com/Koenkk/zigbee2mqtt/issues/11674
|
|
653
|
-
console.warn(`Failed to read zigbee attributes: ${e}`);
|
|
708
|
+
(await Promise.allSettled(configReportings))
|
|
709
|
+
.filter((e) => e.status == 'rejected')
|
|
710
|
+
.forEach((e) => {
|
|
711
|
+
throw e.reason;
|
|
654
712
|
});
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
713
|
+
},
|
|
714
|
+
ota: ota.lixee,
|
|
715
|
+
onEvent: async (type, data, device, options) => {
|
|
716
|
+
const endpoint = device.getEndpoint(1);
|
|
717
|
+
if (type === 'start') {
|
|
718
|
+
endpoint.read('liXeePrivate', ['linkyMode', 'currentTarif'], {manufacturerCode: null})
|
|
719
|
+
.catch((e) => {
|
|
720
|
+
// https://github.com/Koenkk/zigbee2mqtt/issues/11674
|
|
721
|
+
console.warn(`Failed to read zigbee attributes: ${e}`);
|
|
722
|
+
});
|
|
723
|
+
} else if (type === 'stop') {
|
|
724
|
+
clearInterval(globalStore.getValue(device, 'interval'));
|
|
725
|
+
globalStore.clearValue(device, 'interval');
|
|
726
|
+
} else if (!globalStore.hasValue(device, 'interval')) {
|
|
727
|
+
const seconds = options && options.measurement_poll_interval ? options.measurement_poll_interval : 60;
|
|
728
|
+
const measurement_poll_chunk = options && options.measurement_poll_chunk ? options.measurement_poll_chunk : 1;
|
|
729
|
+
|
|
730
|
+
const interval = setInterval(async () => {
|
|
731
|
+
const currentExposes = getCurrentConfig(device, options)
|
|
732
|
+
.filter((e) => !endpoint.configuredReportings.some((r) => r.cluster.name == e.cluster && r.attribute.name == e.att));
|
|
733
|
+
|
|
734
|
+
for (const key in clustersDef) {
|
|
735
|
+
if (Object.hasOwnProperty.call(clustersDef, key)) {
|
|
736
|
+
const cluster = clustersDef[key];
|
|
737
|
+
|
|
738
|
+
const targ = currentExposes.filter((e)=> e.cluster == cluster).map((e)=> e.att);
|
|
739
|
+
if (targ.length) {
|
|
740
|
+
let i; let j;
|
|
741
|
+
// Split array by chunks
|
|
742
|
+
for (i = 0, j = targ.length; i < j; i += measurement_poll_chunk) {
|
|
743
|
+
await endpoint
|
|
744
|
+
.read(cluster, targ.slice(i, i + measurement_poll_chunk), {manufacturerCode: null})
|
|
745
|
+
.catch((e) => {
|
|
746
|
+
// https://github.com/Koenkk/zigbee2mqtt/issues/11674
|
|
747
|
+
console.warn(`Failed to read zigbee attributes: ${e}`);
|
|
748
|
+
});
|
|
749
|
+
}
|
|
681
750
|
}
|
|
682
751
|
}
|
|
683
752
|
}
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
}
|
|
753
|
+
}, seconds * 1000);
|
|
754
|
+
globalStore.putValue(device, 'interval', interval);
|
|
755
|
+
}
|
|
756
|
+
},
|
|
688
757
|
},
|
|
689
|
-
};
|
|
690
758
|
|
|
691
|
-
|
|
759
|
+
{
|
|
760
|
+
zigbeeModel: ['ZiPulses'],
|
|
761
|
+
model: 'ZiPulses',
|
|
762
|
+
vendor: 'LiXee',
|
|
763
|
+
description: 'Lixee ZiPulses',
|
|
764
|
+
fromZigbee: [fz.battery, fz.temperature, fz.metering, fzZiPulses],
|
|
765
|
+
toZigbee: [tzSeMetering],
|
|
766
|
+
exposes: [e.battery_voltage(), e.temperature(),
|
|
767
|
+
exposes.numeric('multiplier', ea.STATE_SET).withValueMin(1).withValueMax(1000).withDescription('It is necessary to press the link button to update'),
|
|
768
|
+
exposes.numeric('divisor', ea.STATE_SET).withValueMin(1).withValueMax(1000).withDescription('It is necessary to press the link button to update'),
|
|
769
|
+
exposes.enum('unitOfMeasure', ea.STATE_SET, unitsZiPulses).withDescription('It is necessary to press the link button to update'),
|
|
770
|
+
exposes.numeric('energy', ea.STATE),
|
|
771
|
+
],
|
|
772
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
773
|
+
const endpoint = device.getEndpoint(1);
|
|
774
|
+
const binds = ['genPowerCfg', 'seMetering', 'msTemperatureMeasurement'];
|
|
775
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
776
|
+
await endpoint.read('seMetering', ['divisor', 'unitOfMeasure', 'multiplier']);
|
|
777
|
+
},
|
|
778
|
+
},
|
|
779
|
+
];
|
package/devices/philips.js
CHANGED
|
@@ -2480,7 +2480,7 @@ module.exports = [
|
|
|
2480
2480
|
extend: philips.extend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
|
|
2481
2481
|
},
|
|
2482
2482
|
{
|
|
2483
|
-
zigbeeModel: ['5309331P6', '5309330P6', '929003046301_03', '929003046301_02'],
|
|
2483
|
+
zigbeeModel: ['5309331P6', '5309330P6', '929003046301_03', '929003046301_02', '929003046301_01'],
|
|
2484
2484
|
model: '5309331P6',
|
|
2485
2485
|
vendor: 'Philips',
|
|
2486
2486
|
description: 'Hue White ambiance Runner triple spotlight',
|
package/devices/qoto.js
CHANGED
|
@@ -89,7 +89,7 @@ const tzLocal = {
|
|
|
89
89
|
|
|
90
90
|
module.exports = [
|
|
91
91
|
{
|
|
92
|
-
fingerprint:
|
|
92
|
+
fingerprint: tuya.fingerprint('TS0601', ['_TZE200_arge1ptm', '_TZE200_anv5ujhv']),
|
|
93
93
|
model: 'QT-05M',
|
|
94
94
|
vendor: 'QOTO',
|
|
95
95
|
description: 'Solar powered garden watering timer',
|
package/devices/robb.js
CHANGED
|
@@ -6,6 +6,13 @@ const extend = require('../lib/extend');
|
|
|
6
6
|
const e = exposes.presets;
|
|
7
7
|
|
|
8
8
|
module.exports = [
|
|
9
|
+
{
|
|
10
|
+
zigbeeModel: ['ROB_200-060-0'],
|
|
11
|
+
model: 'ROB_200-060-0',
|
|
12
|
+
vendor: 'ROBB',
|
|
13
|
+
description: 'Zigbee LED driver',
|
|
14
|
+
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [160, 450]}),
|
|
15
|
+
},
|
|
9
16
|
{
|
|
10
17
|
zigbeeModel: ['ROB_200-061-0'],
|
|
11
18
|
model: 'ROB_200-061-0',
|
package/devices/sonoff.js
CHANGED
|
@@ -246,4 +246,17 @@ module.exports = [
|
|
|
246
246
|
toZigbee: [tz.cover_state, tz.cover_position_tilt],
|
|
247
247
|
exposes: [e.cover_position(), e.battery()],
|
|
248
248
|
},
|
|
249
|
+
{
|
|
250
|
+
zigbeeModel: ['Z111PL0H-1JX', 'SA-029-1'],
|
|
251
|
+
model: 'SA-028/SA-029',
|
|
252
|
+
vendor: 'SONOFF',
|
|
253
|
+
whiteLabel: [{vendor: 'Woolley', model: 'SA-029-1'}],
|
|
254
|
+
description: 'Smart Plug',
|
|
255
|
+
extend: extend.switch(),
|
|
256
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
257
|
+
const endpoint = device.getEndpoint(1);
|
|
258
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
|
|
259
|
+
await reporting.onOff(endpoint);
|
|
260
|
+
},
|
|
261
|
+
},
|
|
249
262
|
];
|
package/devices/tuya.js
CHANGED
|
@@ -2224,11 +2224,11 @@ module.exports = [
|
|
|
2224
2224
|
'Mode of this device, in the `heat` mode the TS0601 will remain continuously heating, i.e. it does not regulate ' +
|
|
2225
2225
|
'to the desired temperature. If you want TRV to properly regulate the temperature you need to use mode `auto` ' +
|
|
2226
2226
|
'instead setting the desired temperature.')
|
|
2227
|
-
.withLocalTemperatureCalibration(-9, 9,
|
|
2227
|
+
.withLocalTemperatureCalibration(-9, 9, 0.5, ea.STATE_SET)
|
|
2228
2228
|
.withPreset(['schedule', 'manual', 'boost', 'complex', 'comfort', 'eco', 'away'])
|
|
2229
2229
|
.withRunningState(['idle', 'heat'], ea.STATE),
|
|
2230
2230
|
e.auto_lock(), e.away_mode(), e.away_preset_days(), e.boost_time(), e.comfort_temperature(), e.eco_temperature(), e.force(),
|
|
2231
|
-
e.max_temperature(), e.min_temperature(), e.away_preset_temperature(),
|
|
2231
|
+
e.max_temperature().withValueMin(16).withValueMax(70), e.min_temperature(), e.away_preset_temperature(),
|
|
2232
2232
|
exposes.composite('programming_mode', 'programming_mode', ea.STATE).withDescription('Schedule MODE ⏱ - In this mode, ' +
|
|
2233
2233
|
'the device executes a preset week programming temperature time and temperature.')
|
|
2234
2234
|
.withFeature(e.week())
|
|
@@ -2611,7 +2611,7 @@ module.exports = [
|
|
|
2611
2611
|
whiteLabel: [{vendor: 'LELLKI', model: 'TS011F_plug'}, {vendor: 'NEO', model: 'NAS-WR01B'},
|
|
2612
2612
|
{vendor: 'BlitzWolf', model: 'BW-SHP15'}, {vendor: 'Nous', model: 'A1Z'}, {vendor: 'BlitzWolf', model: 'BW-SHP13'},
|
|
2613
2613
|
{vendor: 'MatSee Plus', model: 'PJ-ZSW01'}, {vendor: 'MODEMIX', model: 'MOD037'}, {vendor: 'MODEMIX', model: 'MOD048'},
|
|
2614
|
-
{vendor: 'Coswall', model: 'CS-AJ-DE2U-ZG-11'}, {vendor: 'Aubess', model: 'TS011F_plug_1'}],
|
|
2614
|
+
{vendor: 'Coswall', model: 'CS-AJ-DE2U-ZG-11'}, {vendor: 'Aubess', model: 'TS011F_plug_1'}, {vendor: 'Immax', model: '07752L'}],
|
|
2615
2615
|
ota: ota.zigbeeOTA,
|
|
2616
2616
|
extend: tuya.extend.switch({electricalMeasurements: true, powerOutageMemory: true, indicatorMode: true, childLock: true}),
|
|
2617
2617
|
configure: async (device, coordinatorEndpoint, logger) => {
|
package/devices/xiaomi.js
CHANGED
|
@@ -745,7 +745,9 @@ module.exports = [
|
|
|
745
745
|
fromZigbee: [fz.xiaomi_contact, fz.ias_contact_alarm_1, fz.aqara_opple],
|
|
746
746
|
toZigbee: [],
|
|
747
747
|
meta: {battery: {voltageToPercentage: '3V_2850_3000'}},
|
|
748
|
-
exposes: [e.contact(), e.battery(), e.battery_voltage()
|
|
748
|
+
exposes: [e.contact(), e.battery(), e.battery_voltage(),
|
|
749
|
+
exposes.binary('battery_cover', ea.STATE, 'OPEN', 'CLOSE'),
|
|
750
|
+
],
|
|
749
751
|
},
|
|
750
752
|
{
|
|
751
753
|
zigbeeModel: ['lumi.dimmer.rcbac1'],
|
package/lib/xiaomi.js
CHANGED
|
@@ -502,6 +502,11 @@ const numericAttributes2Payload = async (msg, meta, model, options, dataObject)
|
|
|
502
502
|
payload.buzzer_manual_alarm = value === 1;
|
|
503
503
|
}
|
|
504
504
|
break;
|
|
505
|
+
case '320':
|
|
506
|
+
if (['MCCGQ13LM'].includes(model.model)) {
|
|
507
|
+
payload.battery_cover = {0: 'CLOSE', 1: 'OPEN'}[value];
|
|
508
|
+
}
|
|
509
|
+
break;
|
|
505
510
|
case '322':
|
|
506
511
|
if (['RTCZCGQ11LM'].includes(model.model)) {
|
|
507
512
|
payload.presence = {0: false, 1: true, 255: null}[value];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zigbee-herdsman-converters",
|
|
3
|
-
"version": "15.0.
|
|
3
|
+
"version": "15.0.73",
|
|
4
4
|
"description": "Collection of device converters to be used with zigbee-herdsman",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"buffer-crc32": "^0.2.13",
|
|
39
39
|
"https-proxy-agent": "^5.0.1",
|
|
40
40
|
"tar-stream": "^3.0.0",
|
|
41
|
-
"zigbee-herdsman": "^0.14.
|
|
41
|
+
"zigbee-herdsman": "^0.14.99"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"eslint": "*",
|
package/devices/woolley.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
const extend = require('../lib/extend');
|
|
2
|
-
const reporting = require('../lib/reporting');
|
|
3
|
-
|
|
4
|
-
module.exports = [
|
|
5
|
-
{
|
|
6
|
-
zigbeeModel: ['Z111PL0H-1JX', 'SA-029-1'],
|
|
7
|
-
model: 'SA-029',
|
|
8
|
-
vendor: 'Woolley',
|
|
9
|
-
description: 'Smart Plug',
|
|
10
|
-
extend: extend.switch(),
|
|
11
|
-
configure: async (device, coordinatorEndpoint, logger) => {
|
|
12
|
-
const endpoint = device.getEndpoint(1);
|
|
13
|
-
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
|
|
14
|
-
await reporting.onOff(endpoint);
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
];
|