zigbee-herdsman-converters 23.50.0 → 23.51.0
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/CHANGELOG.md +26 -0
- package/dist/devices/bacchus.d.ts.map +1 -1
- package/dist/devices/bacchus.js +15 -14
- package/dist/devices/bacchus.js.map +1 -1
- package/dist/devices/legrand.d.ts.map +1 -1
- package/dist/devices/legrand.js +69 -0
- package/dist/devices/legrand.js.map +1 -1
- package/dist/devices/third_reality.js +2 -2
- package/dist/devices/third_reality.js.map +1 -1
- package/dist/devices/tuya.d.ts.map +1 -1
- package/dist/devices/tuya.js +92 -5
- package/dist/devices/tuya.js.map +1 -1
- package/dist/devices/zemismart.d.ts.map +1 -1
- package/dist/devices/zemismart.js +0 -13
- package/dist/devices/zemismart.js.map +1 -1
- package/dist/lib/modernExtend.d.ts +1 -1
- package/dist/lib/modernExtend.d.ts.map +1 -1
- package/dist/lib/modernExtend.js +170 -211
- package/dist/lib/modernExtend.js.map +1 -1
- package/dist/models-index.json +1 -1
- package/package.json +1 -1
package/dist/lib/modernExtend.js
CHANGED
|
@@ -297,9 +297,8 @@ function forcePowerSource(args) {
|
|
|
297
297
|
];
|
|
298
298
|
return { configure, isModernExtend: true };
|
|
299
299
|
}
|
|
300
|
-
function linkQuality(args) {
|
|
301
|
-
|
|
302
|
-
args = { reporting: false, attribute: "zclVersion", reportingConfig: { min: "1_HOUR", max: "4_HOURS", change: 0 }, ...args };
|
|
300
|
+
function linkQuality(args = {}) {
|
|
301
|
+
const { reporting = false, attribute = "zclVersion", reportingConfig = { min: "1_HOUR", max: "4_HOURS", change: 0 } } = args;
|
|
303
302
|
// Exposes is empty because the application (e.g. Z2M) adds a linkquality sensor
|
|
304
303
|
// for every device already.
|
|
305
304
|
const exposes = [];
|
|
@@ -313,24 +312,13 @@ function linkQuality(args) {
|
|
|
313
312
|
},
|
|
314
313
|
];
|
|
315
314
|
const result = { exposes, fromZigbee, isModernExtend: true };
|
|
316
|
-
if (
|
|
317
|
-
result.configure = [setupConfigureForReporting("genBasic",
|
|
315
|
+
if (reporting) {
|
|
316
|
+
result.configure = [setupConfigureForReporting("genBasic", attribute, { config: reportingConfig, access: exposes_1.access.GET })];
|
|
318
317
|
}
|
|
319
318
|
return result;
|
|
320
319
|
}
|
|
321
|
-
function battery(args) {
|
|
322
|
-
|
|
323
|
-
args = {
|
|
324
|
-
percentage: true,
|
|
325
|
-
voltage: false,
|
|
326
|
-
lowStatus: false,
|
|
327
|
-
percentageReporting: true,
|
|
328
|
-
voltageReporting: false,
|
|
329
|
-
dontDividePercentage: false,
|
|
330
|
-
percentageReportingConfig: { min: "1_HOUR", max: "MAX", change: 10 },
|
|
331
|
-
voltageReportingConfig: { min: "1_HOUR", max: "MAX", change: 10 },
|
|
332
|
-
...args,
|
|
333
|
-
};
|
|
320
|
+
function battery(args = {}) {
|
|
321
|
+
const { percentage = true, voltage = false, lowStatus = false, percentageReporting = true, voltageReporting = false, dontDividePercentage = false, percentageReportingConfig = { min: "1_HOUR", max: "MAX", change: 10 }, voltageReportingConfig = { min: "1_HOUR", max: "MAX", change: 10 }, } = args;
|
|
334
322
|
const exposes = [];
|
|
335
323
|
if (args.percentage) {
|
|
336
324
|
exposes.push(exposes_1.presets
|
|
@@ -447,7 +435,7 @@ function battery(args) {
|
|
|
447
435
|
}
|
|
448
436
|
return result;
|
|
449
437
|
}
|
|
450
|
-
function deviceTemperature(args) {
|
|
438
|
+
function deviceTemperature(args = {}) {
|
|
451
439
|
return numeric({
|
|
452
440
|
name: "device_temperature",
|
|
453
441
|
cluster: "genDeviceTempCfg",
|
|
@@ -460,16 +448,15 @@ function deviceTemperature(args) {
|
|
|
460
448
|
...args,
|
|
461
449
|
});
|
|
462
450
|
}
|
|
463
|
-
function identify(args) {
|
|
464
|
-
|
|
465
|
-
args = { isSleepy: false, ...args };
|
|
451
|
+
function identify(args = { isSleepy: false }) {
|
|
452
|
+
const { isSleepy } = args;
|
|
466
453
|
const normal = exposes_1.presets.enum("identify", exposes_1.access.SET, ["identify"]).withDescription("Initiate device identification").withCategory("config");
|
|
467
454
|
const sleepy = exposes_1.presets
|
|
468
455
|
.enum("identify", exposes_1.access.SET, ["identify"])
|
|
469
456
|
.withDescription("Initiate device identification. This device is asleep by default." +
|
|
470
457
|
"You may need to wake it up first before sending the identify command.")
|
|
471
458
|
.withCategory("config");
|
|
472
|
-
const exposes =
|
|
459
|
+
const exposes = isSleepy ? [sleepy] : [normal];
|
|
473
460
|
const identifyTimeout = exposes_1.presets
|
|
474
461
|
.numeric("identify_timeout", exposes_1.access.SET)
|
|
475
462
|
.withDescription("Sets the duration of the identification procedure in seconds (i.e., how long the device would flash)." +
|
|
@@ -488,27 +475,24 @@ function identify(args) {
|
|
|
488
475
|
];
|
|
489
476
|
return { exposes, toZigbee, isModernExtend: true };
|
|
490
477
|
}
|
|
491
|
-
function onOff(args) {
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
const
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
const toZigbee = [args?.endpointNames ? { ...tz.on_off, endpoints: args?.endpointNames } : tz.on_off];
|
|
499
|
-
if (args.powerOnBehavior) {
|
|
500
|
-
exposes.push(...(0, utils_1.exposeEndpoints)(exposes_1.presets.power_on_behavior(["off", "on", "toggle", "previous"]), args.endpointNames));
|
|
478
|
+
function onOff(args = {}) {
|
|
479
|
+
const { powerOnBehavior = true, skipDuplicateTransaction = false, configureReporting = true, endpointNames = undefined, description = undefined, ota = false, } = args;
|
|
480
|
+
const exposes = description ? (0, utils_1.exposeEndpoints)(exposes_1.presets.switch(description), endpointNames) : (0, utils_1.exposeEndpoints)(exposes_1.presets.switch(), endpointNames);
|
|
481
|
+
const fromZigbee = [skipDuplicateTransaction ? fz.on_off_skip_duplicate_transaction : fz.on_off];
|
|
482
|
+
const toZigbee = [endpointNames ? { ...tz.on_off, endpoints: endpointNames } : tz.on_off];
|
|
483
|
+
if (powerOnBehavior) {
|
|
484
|
+
exposes.push(...(0, utils_1.exposeEndpoints)(exposes_1.presets.power_on_behavior(["off", "on", "toggle", "previous"]), endpointNames));
|
|
501
485
|
fromZigbee.push(fz.power_on_behavior);
|
|
502
486
|
toZigbee.push(tz.power_on_behavior);
|
|
503
487
|
}
|
|
504
488
|
const result = { exposes, fromZigbee, toZigbee, isModernExtend: true };
|
|
505
|
-
if (
|
|
506
|
-
result.ota =
|
|
507
|
-
if (
|
|
489
|
+
if (ota)
|
|
490
|
+
result.ota = ota;
|
|
491
|
+
if (configureReporting) {
|
|
508
492
|
result.configure = [
|
|
509
493
|
async (device, coordinatorEndpoint) => {
|
|
510
494
|
await setupAttributes(device, coordinatorEndpoint, "genOnOff", [{ attribute: "onOff", min: "MIN", max: "MAX", change: 1 }]);
|
|
511
|
-
if (
|
|
495
|
+
if (powerOnBehavior) {
|
|
512
496
|
try {
|
|
513
497
|
// Don't fail configure if reading this attribute fails, some devices don't support it.
|
|
514
498
|
await setupAttributes(device, coordinatorEndpoint, "genOnOff", [{ attribute: "startUpOnOff", min: "MIN", max: "MAX", change: 1 }], false);
|
|
@@ -528,12 +512,11 @@ function onOff(args) {
|
|
|
528
512
|
}
|
|
529
513
|
return result;
|
|
530
514
|
}
|
|
531
|
-
function commandsOnOff(args) {
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
actions = args.commands.flatMap((c) => args.endpointNames.map((e) => `${c}_${e}`));
|
|
515
|
+
function commandsOnOff(args = {}) {
|
|
516
|
+
const { commands = ["on", "off", "toggle"], bind = true, endpointNames = undefined } = args;
|
|
517
|
+
let actions = commands;
|
|
518
|
+
if (endpointNames) {
|
|
519
|
+
actions = commands.flatMap((c) => endpointNames.map((e) => `${c}_${e}`));
|
|
537
520
|
}
|
|
538
521
|
const exposes = [exposes_1.presets.enum("action", exposes_1.access.STATE, actions).withDescription("Triggered action (e.g. a button click)")];
|
|
539
522
|
const actionPayloadLookup = {
|
|
@@ -556,8 +539,8 @@ function commandsOnOff(args) {
|
|
|
556
539
|
},
|
|
557
540
|
];
|
|
558
541
|
const result = { exposes, fromZigbee, isModernExtend: true };
|
|
559
|
-
if (
|
|
560
|
-
result.configure = [setupConfigureForBinding("genOnOff", "output",
|
|
542
|
+
if (bind)
|
|
543
|
+
result.configure = [setupConfigureForBinding("genOnOff", "output", endpointNames)];
|
|
561
544
|
return result;
|
|
562
545
|
}
|
|
563
546
|
function customTimeResponse(start) {
|
|
@@ -596,7 +579,7 @@ function customTimeResponse(start) {
|
|
|
596
579
|
}
|
|
597
580
|
// #endregion
|
|
598
581
|
// #region Measurement and Sensing
|
|
599
|
-
function illuminance(args) {
|
|
582
|
+
function illuminance(args = {}) {
|
|
600
583
|
const luxScale = (value, type) => {
|
|
601
584
|
let result = value;
|
|
602
585
|
if (type === "from") {
|
|
@@ -632,7 +615,7 @@ function illuminance(args) {
|
|
|
632
615
|
result.exposes.push(exposeIlluminanceRaw);
|
|
633
616
|
return result;
|
|
634
617
|
}
|
|
635
|
-
function temperature(args) {
|
|
618
|
+
function temperature(args = {}) {
|
|
636
619
|
return numeric({
|
|
637
620
|
name: "temperature",
|
|
638
621
|
cluster: "msTemperatureMeasurement",
|
|
@@ -645,7 +628,7 @@ function temperature(args) {
|
|
|
645
628
|
...args,
|
|
646
629
|
});
|
|
647
630
|
}
|
|
648
|
-
function pressure(args) {
|
|
631
|
+
function pressure(args = {}) {
|
|
649
632
|
return numeric({
|
|
650
633
|
name: "pressure",
|
|
651
634
|
cluster: "msPressureMeasurement",
|
|
@@ -658,7 +641,7 @@ function pressure(args) {
|
|
|
658
641
|
...args,
|
|
659
642
|
});
|
|
660
643
|
}
|
|
661
|
-
function flow(args) {
|
|
644
|
+
function flow(args = {}) {
|
|
662
645
|
return numeric({
|
|
663
646
|
name: "flow",
|
|
664
647
|
cluster: "msFlowMeasurement",
|
|
@@ -671,7 +654,7 @@ function flow(args) {
|
|
|
671
654
|
...args,
|
|
672
655
|
});
|
|
673
656
|
}
|
|
674
|
-
function humidity(args) {
|
|
657
|
+
function humidity(args = {}) {
|
|
675
658
|
return numeric({
|
|
676
659
|
name: "humidity",
|
|
677
660
|
cluster: "msRelativeHumidity",
|
|
@@ -684,7 +667,7 @@ function humidity(args) {
|
|
|
684
667
|
...args,
|
|
685
668
|
});
|
|
686
669
|
}
|
|
687
|
-
function soilMoisture(args) {
|
|
670
|
+
function soilMoisture(args = {}) {
|
|
688
671
|
return numeric({
|
|
689
672
|
name: "soil_moisture",
|
|
690
673
|
cluster: "msSoilMoisture",
|
|
@@ -697,12 +680,11 @@ function soilMoisture(args) {
|
|
|
697
680
|
...args,
|
|
698
681
|
});
|
|
699
682
|
}
|
|
700
|
-
function occupancy(args) {
|
|
701
|
-
|
|
702
|
-
args = { reporting: true, reportingConfig: { min: "MIN", max: "1_HOUR", change: 0 }, ...args };
|
|
683
|
+
function occupancy(args = {}) {
|
|
684
|
+
const { reporting = true, reportingConfig = { min: "MIN", max: "1_HOUR", change: 0 }, pirConfig = undefined, ultrasonicConfig = undefined, contactConfig = undefined, endpointNames = undefined, } = args;
|
|
703
685
|
const templateExposes = [exposes_1.presets.occupancy().withAccess(exposes_1.access.STATE_GET)];
|
|
704
|
-
const exposes =
|
|
705
|
-
? templateExposes.flatMap((exp) =>
|
|
686
|
+
const exposes = endpointNames
|
|
687
|
+
? templateExposes.flatMap((exp) => endpointNames.map((ep) => exp.withEndpoint(ep)))
|
|
706
688
|
: templateExposes;
|
|
707
689
|
const fromZigbee = [
|
|
708
690
|
{
|
|
@@ -710,7 +692,7 @@ function occupancy(args) {
|
|
|
710
692
|
type: ["attributeReport", "readResponse"],
|
|
711
693
|
options: [exposes_1.options.no_occupancy_since_false()],
|
|
712
694
|
convert: (model, msg, publish, options, meta) => {
|
|
713
|
-
if ("occupancy" in msg.data && (!
|
|
695
|
+
if ("occupancy" in msg.data && (!endpointNames || endpointNames.includes((0, utils_1.getEndpointName)(msg, model, meta).toString()))) {
|
|
714
696
|
const propertyName = (0, utils_1.postfixWithEndpointName)("occupancy", msg, model, meta);
|
|
715
697
|
const payload = { [propertyName]: (msg.data.occupancy & 1) > 0 };
|
|
716
698
|
(0, utils_1.noOccupancySince)(msg.endpoint, options, publish, payload[propertyName] ? "stop" : "start");
|
|
@@ -731,13 +713,13 @@ function occupancy(args) {
|
|
|
731
713
|
const settingsTemplate = {
|
|
732
714
|
cluster: "msOccupancySensing",
|
|
733
715
|
description: "",
|
|
734
|
-
endpointNames:
|
|
716
|
+
endpointNames: endpointNames,
|
|
735
717
|
access: "ALL",
|
|
736
718
|
entityCategory: "config",
|
|
737
719
|
};
|
|
738
720
|
const attributesForReading = [];
|
|
739
|
-
if (
|
|
740
|
-
if (
|
|
721
|
+
if (pirConfig) {
|
|
722
|
+
if (pirConfig.includes("otu_delay")) {
|
|
741
723
|
settingsExtends.push(numeric({
|
|
742
724
|
name: "occupancy_timeout",
|
|
743
725
|
attribute: "pirOToUDelay",
|
|
@@ -749,7 +731,7 @@ function occupancy(args) {
|
|
|
749
731
|
}));
|
|
750
732
|
attributesForReading.push("pirOToUDelay");
|
|
751
733
|
}
|
|
752
|
-
if (
|
|
734
|
+
if (pirConfig.includes("uto_delay")) {
|
|
753
735
|
settingsExtends.push(numeric({
|
|
754
736
|
name: "pir_uto_delay",
|
|
755
737
|
attribute: "pirUToODelay",
|
|
@@ -759,7 +741,7 @@ function occupancy(args) {
|
|
|
759
741
|
}));
|
|
760
742
|
attributesForReading.push("pirUToODelay");
|
|
761
743
|
}
|
|
762
|
-
if (
|
|
744
|
+
if (pirConfig.includes("uto_threshold")) {
|
|
763
745
|
settingsExtends.push(numeric({
|
|
764
746
|
name: "pir_uto_threshold",
|
|
765
747
|
attribute: "pirUToOThreshold",
|
|
@@ -770,8 +752,8 @@ function occupancy(args) {
|
|
|
770
752
|
attributesForReading.push("pirUToOThreshold");
|
|
771
753
|
}
|
|
772
754
|
}
|
|
773
|
-
if (
|
|
774
|
-
if (
|
|
755
|
+
if (ultrasonicConfig) {
|
|
756
|
+
if (pirConfig.includes("otu_delay")) {
|
|
775
757
|
settingsExtends.push(numeric({
|
|
776
758
|
name: "ultrasonic_otu_delay",
|
|
777
759
|
attribute: "ultrasonicOToUDelay",
|
|
@@ -781,7 +763,7 @@ function occupancy(args) {
|
|
|
781
763
|
}));
|
|
782
764
|
attributesForReading.push("ultrasonicOToUDelay");
|
|
783
765
|
}
|
|
784
|
-
if (
|
|
766
|
+
if (pirConfig.includes("uto_delay")) {
|
|
785
767
|
settingsExtends.push(numeric({
|
|
786
768
|
name: "ultrasonic_uto_delay",
|
|
787
769
|
attribute: "ultrasonicUToODelay",
|
|
@@ -791,7 +773,7 @@ function occupancy(args) {
|
|
|
791
773
|
}));
|
|
792
774
|
attributesForReading.push("ultrasonicUToODelay");
|
|
793
775
|
}
|
|
794
|
-
if (
|
|
776
|
+
if (pirConfig.includes("uto_threshold")) {
|
|
795
777
|
settingsExtends.push(numeric({
|
|
796
778
|
name: "ultrasonic_uto_threshold",
|
|
797
779
|
attribute: "ultrasonicUToOThreshold",
|
|
@@ -802,8 +784,8 @@ function occupancy(args) {
|
|
|
802
784
|
attributesForReading.push("ultrasonicUToOThreshold");
|
|
803
785
|
}
|
|
804
786
|
}
|
|
805
|
-
if (
|
|
806
|
-
if (
|
|
787
|
+
if (contactConfig) {
|
|
788
|
+
if (pirConfig.includes("otu_delay")) {
|
|
807
789
|
settingsExtends.push(numeric({
|
|
808
790
|
name: "contact_otu_delay",
|
|
809
791
|
attribute: "contactOToUDelay",
|
|
@@ -813,7 +795,7 @@ function occupancy(args) {
|
|
|
813
795
|
}));
|
|
814
796
|
attributesForReading.push("contactOToUDelay");
|
|
815
797
|
}
|
|
816
|
-
if (
|
|
798
|
+
if (pirConfig.includes("uto_delay")) {
|
|
817
799
|
settingsExtends.push(numeric({
|
|
818
800
|
name: "contact_uto_delay",
|
|
819
801
|
attribute: "contactUToODelay",
|
|
@@ -823,7 +805,7 @@ function occupancy(args) {
|
|
|
823
805
|
}));
|
|
824
806
|
attributesForReading.push("contactUToODelay");
|
|
825
807
|
}
|
|
826
|
-
if (
|
|
808
|
+
if (pirConfig.includes("uto_threshold")) {
|
|
827
809
|
settingsExtends.push(numeric({
|
|
828
810
|
name: "contact_uto_threshold",
|
|
829
811
|
attribute: "contactUToOThreshold",
|
|
@@ -839,17 +821,17 @@ function occupancy(args) {
|
|
|
839
821
|
settingsExtends.map((extend) => toZigbee.push(...extend.toZigbee));
|
|
840
822
|
const configure = [];
|
|
841
823
|
if (attributesForReading.length > 0)
|
|
842
|
-
configure.push(setupConfigureForReading("msOccupancySensing", attributesForReading,
|
|
843
|
-
if (
|
|
824
|
+
configure.push(setupConfigureForReading("msOccupancySensing", attributesForReading, endpointNames));
|
|
825
|
+
if (reporting) {
|
|
844
826
|
configure.push(setupConfigureForReporting("msOccupancySensing", "occupancy", {
|
|
845
|
-
config:
|
|
827
|
+
config: reportingConfig,
|
|
846
828
|
access: exposes_1.access.STATE_GET,
|
|
847
|
-
endpointNames:
|
|
829
|
+
endpointNames: endpointNames,
|
|
848
830
|
}));
|
|
849
831
|
}
|
|
850
832
|
return { exposes, fromZigbee, toZigbee, configure, isModernExtend: true };
|
|
851
833
|
}
|
|
852
|
-
function co2(args) {
|
|
834
|
+
function co2(args = {}) {
|
|
853
835
|
return numeric({
|
|
854
836
|
name: "co2",
|
|
855
837
|
cluster: "msCO2",
|
|
@@ -863,7 +845,7 @@ function co2(args) {
|
|
|
863
845
|
...args,
|
|
864
846
|
});
|
|
865
847
|
}
|
|
866
|
-
function pm25(args) {
|
|
848
|
+
function pm25(args = {}) {
|
|
867
849
|
return numeric({
|
|
868
850
|
name: "pm25",
|
|
869
851
|
cluster: "pm25Measurement",
|
|
@@ -875,24 +857,24 @@ function pm25(args) {
|
|
|
875
857
|
...args,
|
|
876
858
|
});
|
|
877
859
|
}
|
|
878
|
-
function light(args) {
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
if (
|
|
882
|
-
|
|
860
|
+
function light(args = {}) {
|
|
861
|
+
const { effect = true, powerOnBehavior = true, configureReporting = false, ota = false, color = undefined, levelConfig = undefined, turnsOffAtBrightness1 = false, endpointNames = undefined, levelReportingConfig = undefined, } = args;
|
|
862
|
+
let { colorTemp = undefined } = args;
|
|
863
|
+
if (colorTemp) {
|
|
864
|
+
colorTemp = { startup: true, ...colorTemp };
|
|
883
865
|
}
|
|
884
|
-
const argsColor =
|
|
866
|
+
const argsColor = color
|
|
885
867
|
? {
|
|
886
868
|
modes: ["xy"],
|
|
887
869
|
applyRedFix: false,
|
|
888
870
|
enhancedHue: true,
|
|
889
|
-
...((0, utils_1.isObject)(
|
|
871
|
+
...((0, utils_1.isObject)(color) ? color : {}),
|
|
890
872
|
}
|
|
891
873
|
: false;
|
|
892
|
-
const lightExpose = (0, utils_1.exposeEndpoints)(exposes_1.presets.light().withBrightness(),
|
|
874
|
+
const lightExpose = (0, utils_1.exposeEndpoints)(exposes_1.presets.light().withBrightness(), endpointNames);
|
|
893
875
|
const fromZigbee = [fz.on_off, fz.brightness, fz.ignore_basic_report, fz.level_config];
|
|
894
876
|
const toZigbee = [
|
|
895
|
-
|
|
877
|
+
endpointNames ? { ...tz.light_onoff_brightness, endpoints: endpointNames } : tz.light_onoff_brightness,
|
|
896
878
|
tz.ignore_transition,
|
|
897
879
|
tz.level_config,
|
|
898
880
|
tz.ignore_rate,
|
|
@@ -900,24 +882,24 @@ function light(args) {
|
|
|
900
882
|
tz.light_brightness_step,
|
|
901
883
|
];
|
|
902
884
|
const meta = {};
|
|
903
|
-
if (
|
|
885
|
+
if (colorTemp || argsColor) {
|
|
904
886
|
fromZigbee.push(fz.color_colortemp);
|
|
905
|
-
if (
|
|
887
|
+
if (colorTemp && argsColor)
|
|
906
888
|
toZigbee.push(tz.light_color_colortemp);
|
|
907
|
-
else if (
|
|
889
|
+
else if (colorTemp)
|
|
908
890
|
toZigbee.push(tz.light_colortemp);
|
|
909
891
|
else if (argsColor)
|
|
910
892
|
toZigbee.push(tz.light_color);
|
|
911
893
|
toZigbee.push(tz.light_color_mode, tz.light_color_options);
|
|
912
894
|
}
|
|
913
|
-
if (
|
|
895
|
+
if (colorTemp) {
|
|
914
896
|
// biome-ignore lint/complexity/noForEach: ignored using `--suppress`
|
|
915
|
-
lightExpose.forEach((e) => e.withColorTemp(
|
|
897
|
+
lightExpose.forEach((e) => e.withColorTemp(colorTemp.range));
|
|
916
898
|
toZigbee.push(tz.light_colortemp_move, tz.light_colortemp_step);
|
|
917
|
-
if (
|
|
899
|
+
if (colorTemp.startup) {
|
|
918
900
|
toZigbee.push(tz.light_colortemp_startup);
|
|
919
901
|
// biome-ignore lint/complexity/noForEach: ignored using `--suppress`
|
|
920
|
-
lightExpose.forEach((e) => e.withColorTempStartup(
|
|
902
|
+
lightExpose.forEach((e) => e.withColorTempStartup(colorTemp.range));
|
|
921
903
|
}
|
|
922
904
|
}
|
|
923
905
|
if (argsColor) {
|
|
@@ -934,37 +916,37 @@ function light(args) {
|
|
|
934
916
|
meta.supportsEnhancedHue = false;
|
|
935
917
|
}
|
|
936
918
|
}
|
|
937
|
-
if (
|
|
919
|
+
if (levelConfig) {
|
|
938
920
|
// biome-ignore lint/complexity/noForEach: ignored using `--suppress`
|
|
939
|
-
lightExpose.forEach((e) => e.withLevelConfig(
|
|
921
|
+
lightExpose.forEach((e) => e.withLevelConfig(levelConfig.disabledFeatures ?? []));
|
|
940
922
|
toZigbee.push(tz.level_config);
|
|
941
923
|
}
|
|
942
924
|
const exposes = lightExpose;
|
|
943
|
-
if (
|
|
925
|
+
if (effect) {
|
|
944
926
|
const effects = exposes_1.presets.effect();
|
|
945
|
-
if (
|
|
927
|
+
if (color) {
|
|
946
928
|
effects.values.push("colorloop", "stop_colorloop");
|
|
947
929
|
}
|
|
948
|
-
exposes.push(...(0, utils_1.exposeEndpoints)(effects,
|
|
930
|
+
exposes.push(...(0, utils_1.exposeEndpoints)(effects, endpointNames));
|
|
949
931
|
toZigbee.push(tz.effect);
|
|
950
932
|
}
|
|
951
|
-
if (
|
|
952
|
-
exposes.push(...(0, utils_1.exposeEndpoints)(exposes_1.presets.power_on_behavior(["off", "on", "toggle", "previous"]),
|
|
933
|
+
if (powerOnBehavior) {
|
|
934
|
+
exposes.push(...(0, utils_1.exposeEndpoints)(exposes_1.presets.power_on_behavior(["off", "on", "toggle", "previous"]), endpointNames));
|
|
953
935
|
fromZigbee.push(fz.power_on_behavior);
|
|
954
936
|
toZigbee.push(tz.power_on_behavior);
|
|
955
937
|
}
|
|
956
|
-
if (
|
|
957
|
-
meta.turnsOffAtBrightness1 =
|
|
938
|
+
if (turnsOffAtBrightness1) {
|
|
939
|
+
meta.turnsOffAtBrightness1 = turnsOffAtBrightness1;
|
|
958
940
|
}
|
|
959
941
|
const configure = [
|
|
960
942
|
async (device, coordinatorEndpoint, definition) => {
|
|
961
943
|
await (0, light_1.configure)(device, coordinatorEndpoint, true);
|
|
962
|
-
if (
|
|
944
|
+
if (configureReporting) {
|
|
963
945
|
await setupAttributes(device, coordinatorEndpoint, "genOnOff", [{ attribute: "onOff", min: "MIN", max: "MAX", change: 1 }]);
|
|
964
946
|
await setupAttributes(device, coordinatorEndpoint, "genLevelCtrl", [
|
|
965
|
-
{ attribute: "currentLevel", min: "5_SECONDS", max: "MAX", change: 1, ...(
|
|
947
|
+
{ attribute: "currentLevel", min: "5_SECONDS", max: "MAX", change: 1, ...(levelReportingConfig || {}) },
|
|
966
948
|
]);
|
|
967
|
-
if (
|
|
949
|
+
if (colorTemp) {
|
|
968
950
|
await setupAttributes(device, coordinatorEndpoint, "lightingColorCtrl", [
|
|
969
951
|
{ attribute: "colorTemperature", min: "10_SECONDS", max: "MAX", change: 1 },
|
|
970
952
|
]);
|
|
@@ -984,66 +966,56 @@ function light(args) {
|
|
|
984
966
|
(0, utils_1.configureSetPowerSourceWhenUnknown)("Mains (single phase)"),
|
|
985
967
|
];
|
|
986
968
|
const result = { exposes, fromZigbee, toZigbee, configure, meta, isModernExtend: true };
|
|
987
|
-
if (
|
|
988
|
-
result.ota =
|
|
969
|
+
if (ota)
|
|
970
|
+
result.ota = ota;
|
|
989
971
|
return result;
|
|
990
972
|
}
|
|
991
|
-
function commandsLevelCtrl(args) {
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
...args,
|
|
1004
|
-
};
|
|
1005
|
-
let actions = args.commands;
|
|
1006
|
-
if (args.endpointNames) {
|
|
1007
|
-
actions = args.commands.flatMap((c) => args.endpointNames.map((e) => `${c}_${e}`));
|
|
973
|
+
function commandsLevelCtrl(args = {}) {
|
|
974
|
+
const { commands = [
|
|
975
|
+
"brightness_move_to_level",
|
|
976
|
+
"brightness_move_up",
|
|
977
|
+
"brightness_move_down",
|
|
978
|
+
"brightness_step_up",
|
|
979
|
+
"brightness_step_down",
|
|
980
|
+
"brightness_stop",
|
|
981
|
+
], bind = true, endpointNames = undefined, } = args;
|
|
982
|
+
let actions = commands;
|
|
983
|
+
if (endpointNames) {
|
|
984
|
+
actions = commands.flatMap((c) => endpointNames.map((e) => `${c}_${e}`));
|
|
1008
985
|
}
|
|
1009
986
|
const exposes = [
|
|
1010
987
|
exposes_1.presets.enum("action", exposes_1.access.STATE, actions).withDescription("Triggered action (e.g. a button click)").withCategory("diagnostic"),
|
|
1011
988
|
];
|
|
1012
989
|
const fromZigbee = [fz.command_move_to_level, fz.command_move, fz.command_step, fz.command_stop];
|
|
1013
990
|
const result = { exposes, fromZigbee, isModernExtend: true };
|
|
1014
|
-
if (
|
|
1015
|
-
result.configure = [setupConfigureForBinding("genLevelCtrl", "output",
|
|
991
|
+
if (bind)
|
|
992
|
+
result.configure = [setupConfigureForBinding("genLevelCtrl", "output", endpointNames)];
|
|
1016
993
|
return result;
|
|
1017
994
|
}
|
|
1018
|
-
function commandsColorCtrl(args) {
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
...args,
|
|
1043
|
-
};
|
|
1044
|
-
let actions = args.commands;
|
|
1045
|
-
if (args.endpointNames) {
|
|
1046
|
-
actions = args.commands.flatMap((c) => args.endpointNames.map((e) => `${c}_${e}`));
|
|
995
|
+
function commandsColorCtrl(args = {}) {
|
|
996
|
+
const { commands = [
|
|
997
|
+
"color_temperature_move_stop",
|
|
998
|
+
"color_temperature_move_up",
|
|
999
|
+
"color_temperature_move_down",
|
|
1000
|
+
"color_temperature_step_up",
|
|
1001
|
+
"color_temperature_step_down",
|
|
1002
|
+
"enhanced_move_to_hue_and_saturation",
|
|
1003
|
+
"move_to_hue_and_saturation",
|
|
1004
|
+
"color_hue_step_up",
|
|
1005
|
+
"color_hue_step_down",
|
|
1006
|
+
"color_saturation_step_up",
|
|
1007
|
+
"color_saturation_step_down",
|
|
1008
|
+
"color_loop_set",
|
|
1009
|
+
"color_temperature_move",
|
|
1010
|
+
"color_move",
|
|
1011
|
+
"hue_move",
|
|
1012
|
+
"hue_stop",
|
|
1013
|
+
"move_to_saturation",
|
|
1014
|
+
"move_to_hue",
|
|
1015
|
+
], bind = true, endpointNames = undefined, } = args;
|
|
1016
|
+
let actions = commands;
|
|
1017
|
+
if (endpointNames) {
|
|
1018
|
+
actions = commands.flatMap((c) => endpointNames.map((e) => `${c}_${e}`));
|
|
1047
1019
|
}
|
|
1048
1020
|
const exposes = [
|
|
1049
1021
|
exposes_1.presets.enum("action", exposes_1.access.STATE, actions).withDescription("Triggered action (e.g. a button click)").withCategory("diagnostic"),
|
|
@@ -1063,8 +1035,8 @@ function commandsColorCtrl(args) {
|
|
|
1063
1035
|
fz.command_move_to_hue,
|
|
1064
1036
|
];
|
|
1065
1037
|
const result = { exposes, fromZigbee, isModernExtend: true };
|
|
1066
|
-
if (
|
|
1067
|
-
result.configure = [setupConfigureForBinding("lightingColorCtrl", "output",
|
|
1038
|
+
if (bind)
|
|
1039
|
+
result.configure = [setupConfigureForBinding("lightingColorCtrl", "output", endpointNames)];
|
|
1068
1040
|
return result;
|
|
1069
1041
|
}
|
|
1070
1042
|
function lightingBallast() {
|
|
@@ -1087,16 +1059,9 @@ function lightingBallast() {
|
|
|
1087
1059
|
return result;
|
|
1088
1060
|
}
|
|
1089
1061
|
function lock(args) {
|
|
1090
|
-
|
|
1091
|
-
args = { ...args };
|
|
1062
|
+
const { endpointNames = undefined, pinCodeCount } = args;
|
|
1092
1063
|
const fromZigbee = [fz.lock, fz.lock_operation_event, fz.lock_programming_event, fz.lock_pin_code_response, fz.lock_user_status_response];
|
|
1093
|
-
const toZigbee = [
|
|
1094
|
-
{ ...tz.lock, endpoints: args?.endpointNames },
|
|
1095
|
-
tz.pincode_lock,
|
|
1096
|
-
tz.lock_userstatus,
|
|
1097
|
-
tz.lock_auto_relock_time,
|
|
1098
|
-
tz.lock_sound_volume,
|
|
1099
|
-
];
|
|
1064
|
+
const toZigbee = [{ ...tz.lock, endpoints: endpointNames }, tz.pincode_lock, tz.lock_userstatus, tz.lock_auto_relock_time, tz.lock_sound_volume];
|
|
1100
1065
|
const exposes = [
|
|
1101
1066
|
exposes_1.presets.lock(),
|
|
1102
1067
|
exposes_1.presets.pincode(),
|
|
@@ -1109,34 +1074,33 @@ function lock(args) {
|
|
|
1109
1074
|
const configure = [
|
|
1110
1075
|
setupConfigureForReporting("closuresDoorLock", "lockState", { config: { min: "MIN", max: "1_HOUR", change: 0 }, access: exposes_1.access.STATE_GET }),
|
|
1111
1076
|
];
|
|
1112
|
-
const meta = { pinCodeCount:
|
|
1077
|
+
const meta = { pinCodeCount: pinCodeCount };
|
|
1113
1078
|
const result = { fromZigbee, toZigbee, exposes, configure, meta, isModernExtend: true };
|
|
1114
|
-
if (
|
|
1115
|
-
result.exposes = (0, utils_1.flatten)(exposes.map((expose) =>
|
|
1079
|
+
if (endpointNames) {
|
|
1080
|
+
result.exposes = (0, utils_1.flatten)(exposes.map((expose) => endpointNames.map((endpoint) => expose.clone().withEndpoint(endpoint))));
|
|
1116
1081
|
}
|
|
1117
1082
|
return result;
|
|
1118
1083
|
}
|
|
1119
1084
|
function windowCovering(args) {
|
|
1120
|
-
|
|
1121
|
-
args = { stateSource: "lift", configureReporting: true, ...args };
|
|
1085
|
+
const { stateSource = "lift", configureReporting = true, controls, coverInverted = false, coverMode, endpointNames = undefined } = args;
|
|
1122
1086
|
let coverExpose = exposes_1.presets.cover();
|
|
1123
|
-
if (
|
|
1087
|
+
if (controls.includes("lift"))
|
|
1124
1088
|
coverExpose = coverExpose.withPosition();
|
|
1125
|
-
if (
|
|
1089
|
+
if (controls.includes("tilt"))
|
|
1126
1090
|
coverExpose = coverExpose.withTilt();
|
|
1127
1091
|
const exposes = [coverExpose];
|
|
1128
1092
|
const fromZigbee = [fz.cover_position_tilt];
|
|
1129
|
-
const toZigbee = [{ ...tz.cover_state, endpoints:
|
|
1093
|
+
const toZigbee = [{ ...tz.cover_state, endpoints: endpointNames }, tz.cover_position_tilt];
|
|
1130
1094
|
const result = { exposes, fromZigbee, toZigbee, isModernExtend: true };
|
|
1131
|
-
if (
|
|
1095
|
+
if (configureReporting) {
|
|
1132
1096
|
const configure = [];
|
|
1133
|
-
if (
|
|
1097
|
+
if (controls.includes("lift")) {
|
|
1134
1098
|
configure.push(setupConfigureForReporting("closuresWindowCovering", "currentPositionLiftPercentage", {
|
|
1135
1099
|
config: { min: "1_SECOND", max: "MAX", change: 1 },
|
|
1136
1100
|
access: exposes_1.access.STATE_GET,
|
|
1137
1101
|
}));
|
|
1138
1102
|
}
|
|
1139
|
-
if (
|
|
1103
|
+
if (controls.includes("tilt")) {
|
|
1140
1104
|
configure.push(setupConfigureForReporting("closuresWindowCovering", "currentPositionTiltPercentage", {
|
|
1141
1105
|
config: { min: "1_SECOND", max: "MAX", change: 1 },
|
|
1142
1106
|
access: exposes_1.access.STATE_GET,
|
|
@@ -1144,29 +1108,28 @@ function windowCovering(args) {
|
|
|
1144
1108
|
}
|
|
1145
1109
|
result.configure = configure;
|
|
1146
1110
|
}
|
|
1147
|
-
if (
|
|
1111
|
+
if (coverInverted || stateSource === "tilt") {
|
|
1148
1112
|
const meta = {};
|
|
1149
|
-
if (
|
|
1113
|
+
if (coverInverted)
|
|
1150
1114
|
meta.coverInverted = true;
|
|
1151
|
-
if (
|
|
1115
|
+
if (stateSource === "tilt")
|
|
1152
1116
|
meta.coverStateFromTilt = true;
|
|
1153
1117
|
result.meta = meta;
|
|
1154
1118
|
}
|
|
1155
|
-
if (
|
|
1119
|
+
if (coverMode) {
|
|
1156
1120
|
result.toZigbee.push(tz.cover_mode);
|
|
1157
1121
|
result.exposes.push(exposes_1.presets.cover_mode());
|
|
1158
1122
|
}
|
|
1159
|
-
if (
|
|
1160
|
-
result.exposes = (0, utils_1.flatten)(exposes.map((expose) =>
|
|
1123
|
+
if (endpointNames) {
|
|
1124
|
+
result.exposes = (0, utils_1.flatten)(exposes.map((expose) => endpointNames.map((endpoint) => expose.clone().withEndpoint(endpoint))));
|
|
1161
1125
|
}
|
|
1162
1126
|
return result;
|
|
1163
1127
|
}
|
|
1164
|
-
function commandsWindowCovering(args) {
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
actions = args.commands.flatMap((c) => args.endpointNames.map((e) => `${c}_${e}`));
|
|
1128
|
+
function commandsWindowCovering(args = {}) {
|
|
1129
|
+
const { commands = ["open", "close", "stop"], bind = true, endpointNames = undefined } = args;
|
|
1130
|
+
let actions = commands;
|
|
1131
|
+
if (endpointNames) {
|
|
1132
|
+
actions = commands.flatMap((c) => endpointNames.map((e) => `${c}_${e}`));
|
|
1170
1133
|
}
|
|
1171
1134
|
const exposes = [
|
|
1172
1135
|
exposes_1.presets.enum("action", exposes_1.access.STATE, actions).withDescription("Triggered action (e.g. a button click)").withCategory("diagnostic"),
|
|
@@ -1190,8 +1153,8 @@ function commandsWindowCovering(args) {
|
|
|
1190
1153
|
},
|
|
1191
1154
|
];
|
|
1192
1155
|
const result = { exposes, fromZigbee, isModernExtend: true };
|
|
1193
|
-
if (
|
|
1194
|
-
result.configure = [setupConfigureForBinding("closuresWindowCovering", "output",
|
|
1156
|
+
if (bind)
|
|
1157
|
+
result.configure = [setupConfigureForBinding("closuresWindowCovering", "output", endpointNames)];
|
|
1195
1158
|
return result;
|
|
1196
1159
|
}
|
|
1197
1160
|
function iasZoneAlarm(args) {
|
|
@@ -1336,7 +1299,8 @@ function iasZoneAlarm(args) {
|
|
|
1336
1299
|
}
|
|
1337
1300
|
return { fromZigbee, exposes, isModernExtend: true, ...(configure && { configure }) };
|
|
1338
1301
|
}
|
|
1339
|
-
function iasWarning(args) {
|
|
1302
|
+
function iasWarning(args = {}) {
|
|
1303
|
+
const { reversePayload = false } = args;
|
|
1340
1304
|
const warningMode = { stop: 0, burglar: 1, fire: 2, emergency: 3, police_panic: 4, fire_panic: 5, emergency_panic: 6 };
|
|
1341
1305
|
// levels for siren, strobe and squawk are identical
|
|
1342
1306
|
const level = { low: 0, medium: 1, high: 2, very_high: 3 };
|
|
@@ -1370,7 +1334,7 @@ function iasWarning(args) {
|
|
|
1370
1334
|
};
|
|
1371
1335
|
// biome-ignore lint/suspicious/noImplicitAnyLet: ignored using `--suppress`
|
|
1372
1336
|
let info;
|
|
1373
|
-
if (
|
|
1337
|
+
if (reversePayload) {
|
|
1374
1338
|
info = (0, utils_1.getFromLookup)(values.mode, warningMode) + ((values.strobe ? 1 : 0) << 4) + ((0, utils_1.getFromLookup)(values.level, level) << 6);
|
|
1375
1339
|
}
|
|
1376
1340
|
else {
|
|
@@ -1388,7 +1352,7 @@ function iasWarning(args) {
|
|
|
1388
1352
|
];
|
|
1389
1353
|
return { toZigbee, exposes, isModernExtend: true };
|
|
1390
1354
|
}
|
|
1391
|
-
function genericMeter(args) {
|
|
1355
|
+
function genericMeter(args = {}) {
|
|
1392
1356
|
if (args.cluster !== "electrical") {
|
|
1393
1357
|
const divisors = new Set([
|
|
1394
1358
|
args.cluster === "metering" && (0, utils_1.isObject)(args.power) ? args.power?.divisor : false,
|
|
@@ -1773,9 +1737,8 @@ function genericMeter(args) {
|
|
|
1773
1737
|
}
|
|
1774
1738
|
return result;
|
|
1775
1739
|
}
|
|
1776
|
-
function electricityMeter(args) {
|
|
1777
|
-
|
|
1778
|
-
args = {
|
|
1740
|
+
function electricityMeter(args = {}) {
|
|
1741
|
+
return genericMeter({
|
|
1779
1742
|
type: "electricity",
|
|
1780
1743
|
cluster: "both",
|
|
1781
1744
|
electricalMeasurementType: "ac",
|
|
@@ -1787,12 +1750,10 @@ function electricityMeter(args) {
|
|
|
1787
1750
|
status: false,
|
|
1788
1751
|
extendedStatus: false,
|
|
1789
1752
|
...args,
|
|
1790
|
-
};
|
|
1791
|
-
return genericMeter(args);
|
|
1753
|
+
});
|
|
1792
1754
|
}
|
|
1793
|
-
function gasMeter(args) {
|
|
1794
|
-
|
|
1795
|
-
args = {
|
|
1755
|
+
function gasMeter(args = {}) {
|
|
1756
|
+
return genericMeter({
|
|
1796
1757
|
type: "gas",
|
|
1797
1758
|
cluster: "metering",
|
|
1798
1759
|
configureReporting: true,
|
|
@@ -1800,8 +1761,7 @@ function gasMeter(args) {
|
|
|
1800
1761
|
extendedStatus: true,
|
|
1801
1762
|
producedEnergy: false,
|
|
1802
1763
|
...args,
|
|
1803
|
-
};
|
|
1804
|
-
return genericMeter(args);
|
|
1764
|
+
});
|
|
1805
1765
|
}
|
|
1806
1766
|
// #endregion
|
|
1807
1767
|
// #region Other extends
|
|
@@ -1911,13 +1871,12 @@ function genericGreenPower() {
|
|
|
1911
1871
|
];
|
|
1912
1872
|
return { exposes, fromZigbee, isModernExtend: true };
|
|
1913
1873
|
}
|
|
1914
|
-
function commandsScenes(args) {
|
|
1915
|
-
|
|
1916
|
-
args = { commands: ["recall", "store", "add", "remove", "remove_all"], bind: true, ...args };
|
|
1874
|
+
function commandsScenes(args = {}) {
|
|
1875
|
+
const { commands = ["recall", "store", "add", "remove", "remove_all"], bind = true, endpointNames = undefined } = args;
|
|
1917
1876
|
// biome-ignore lint/style/noNonNullAssertion: ignored using `--suppress`
|
|
1918
|
-
let actions =
|
|
1919
|
-
if (
|
|
1920
|
-
actions =
|
|
1877
|
+
let actions = commands;
|
|
1878
|
+
if (endpointNames) {
|
|
1879
|
+
actions = commands.flatMap((c) => endpointNames.map((e) => `${c}_${e}`));
|
|
1921
1880
|
}
|
|
1922
1881
|
const exposesArray = [exposes_1.presets.enum("action", exposes_1.access.STATE, actions).withDescription("Triggered scene action (e.g. recall a scene)")];
|
|
1923
1882
|
const actionPayloadLookup = {
|
|
@@ -1947,8 +1906,8 @@ function commandsScenes(args) {
|
|
|
1947
1906
|
},
|
|
1948
1907
|
];
|
|
1949
1908
|
const result = { exposes: exposesArray, fromZigbee, isModernExtend: true };
|
|
1950
|
-
if (
|
|
1951
|
-
result.configure = [setupConfigureForBinding("genScenes", "output",
|
|
1909
|
+
if (bind)
|
|
1910
|
+
result.configure = [setupConfigureForBinding("genScenes", "output", endpointNames)];
|
|
1952
1911
|
return result;
|
|
1953
1912
|
}
|
|
1954
1913
|
function enumLookup(args) {
|