zigbee-herdsman-converters 25.9.0 → 25.10.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 +21 -0
- package/dist/devices/bosch.d.ts.map +1 -1
- package/dist/devices/bosch.js +306 -24
- package/dist/devices/bosch.js.map +1 -1
- package/dist/devices/custom_devices_diy.d.ts.map +1 -1
- package/dist/devices/custom_devices_diy.js +4 -3
- package/dist/devices/custom_devices_diy.js.map +1 -1
- package/dist/devices/giex.js +2 -2
- package/dist/devices/inovelli.d.ts.map +1 -1
- package/dist/devices/inovelli.js +191 -221
- package/dist/devices/inovelli.js.map +1 -1
- package/dist/devices/philips.d.ts.map +1 -1
- package/dist/devices/philips.js +17 -2
- package/dist/devices/philips.js.map +1 -1
- package/dist/devices/seastar_intelligence.js +1 -1
- package/dist/devices/seastar_intelligence.js.map +1 -1
- package/dist/devices/slacky_diy.d.ts.map +1 -1
- package/dist/devices/slacky_diy.js +249 -2
- package/dist/devices/slacky_diy.js.map +1 -1
- package/dist/devices/tuya.d.ts.map +1 -1
- package/dist/devices/tuya.js +6 -2
- package/dist/devices/tuya.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/models-index.json +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [25.10.0](https://github.com/Koenkk/zigbee-herdsman-converters/compare/v25.9.0...v25.10.0) (2025-08-27)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **add:** 929003808801 ([#9853](https://github.com/Koenkk/zigbee-herdsman-converters/issues/9853)) ([e1e7f12](https://github.com/Koenkk/zigbee-herdsman-converters/commit/e1e7f12bf5210a9a363ee46451908f6c0f5207b7))
|
|
9
|
+
* **add:** 929004297402 https://github.com/Koenkk/zigbee2mqtt/issues/28397 ([d238f93](https://github.com/Koenkk/zigbee-herdsman-converters/commit/d238f93bb8934fc51fe43a895d0b6adc09c1423c))
|
|
10
|
+
* **add:** AirQ_Monitor_S01 ([#9841](https://github.com/Koenkk/zigbee-herdsman-converters/issues/9841)) ([ff8b222](https://github.com/Koenkk/zigbee-herdsman-converters/commit/ff8b222636a76ee0ce98e1cc11bbcfeb601934d9))
|
|
11
|
+
* **add:** FUT068ZR ([#9859](https://github.com/Koenkk/zigbee-herdsman-converters/issues/9859)) ([56105e0](https://github.com/Koenkk/zigbee-herdsman-converters/commit/56105e0016f4e9e695998c91ba2161f8c2cbbf73))
|
|
12
|
+
* Zemismart TB26-3: support more features ([#9849](https://github.com/Koenkk/zigbee-herdsman-converters/issues/9849)) ([067a499](https://github.com/Koenkk/zigbee-herdsman-converters/commit/067a499849b2630fea779cbfa4584ccb55816a70))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* Bosch `BMCT-SLZ`: various enhancements and fixes ([#9852](https://github.com/Koenkk/zigbee-herdsman-converters/issues/9852)) ([2902e7c](https://github.com/Koenkk/zigbee-herdsman-converters/commit/2902e7ca4d9f422f35375501652e3ea79e854d74))
|
|
18
|
+
* Correct vendor from GiEX to GIEX ([#9848](https://github.com/Koenkk/zigbee-herdsman-converters/issues/9848)) ([d214855](https://github.com/Koenkk/zigbee-herdsman-converters/commit/d21485546be6642d3a929c11f0b49bd17473bcb3))
|
|
19
|
+
* Create custom modernExtend classes to use with Inovelli devices ([#9835](https://github.com/Koenkk/zigbee-herdsman-converters/issues/9835)) ([e3e76ad](https://github.com/Koenkk/zigbee-herdsman-converters/commit/e3e76ad2b628a4841b248ad163484c8dd8455354))
|
|
20
|
+
* **detect:** Detect `929003811201` as Philips 5633030P6 ([#9851](https://github.com/Koenkk/zigbee-herdsman-converters/issues/9851)) ([ba349f0](https://github.com/Koenkk/zigbee-herdsman-converters/commit/ba349f0728767df85cbee1884a51f6dc6f250eb5))
|
|
21
|
+
* Tuya `_TZ3000_okaz9tjs`: fix configure failing https://github.com/Koenkk/zigbee-herdsman-converters/issues/9786 ([1d9f8bb](https://github.com/Koenkk/zigbee-herdsman-converters/commit/1d9f8bbc1309d91e71368b9ff71db19b50246bda))
|
|
22
|
+
* Various code fixes ([#9854](https://github.com/Koenkk/zigbee-herdsman-converters/issues/9854)) ([7ba943e](https://github.com/Koenkk/zigbee-herdsman-converters/commit/7ba943e6abaa9978c00d048dfeac80d3721fd4ae))
|
|
23
|
+
|
|
3
24
|
## [25.9.0](https://github.com/Koenkk/zigbee-herdsman-converters/compare/v25.8.0...v25.9.0) (2025-08-25)
|
|
4
25
|
|
|
5
26
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bosch.d.ts","sourceRoot":"","sources":["../../src/devices/bosch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bosch.d.ts","sourceRoot":"","sources":["../../src/devices/bosch.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAC,oBAAoB,EAAyC,MAAM,cAAc,CAAC;AAk3C/F,eAAO,MAAM,WAAW,EAAE,oBAAoB,EAwoC7C,CAAC"}
|
package/dist/devices/bosch.js
CHANGED
|
@@ -38,10 +38,12 @@ const zigbee_herdsman_1 = require("zigbee-herdsman");
|
|
|
38
38
|
const fz = __importStar(require("../converters/fromZigbee"));
|
|
39
39
|
const tz = __importStar(require("../converters/toZigbee"));
|
|
40
40
|
const constants = __importStar(require("../lib/constants"));
|
|
41
|
+
const constants_1 = require("../lib/constants");
|
|
41
42
|
const exposes = __importStar(require("../lib/exposes"));
|
|
42
43
|
const logger_1 = require("../lib/logger");
|
|
43
44
|
const m = __importStar(require("../lib/modernExtend"));
|
|
44
45
|
const reporting = __importStar(require("../lib/reporting"));
|
|
46
|
+
const reporting_1 = require("../lib/reporting");
|
|
45
47
|
const globalStore = __importStar(require("../lib/store"));
|
|
46
48
|
const utils = __importStar(require("../lib/utils"));
|
|
47
49
|
const e = exposes.presets;
|
|
@@ -352,6 +354,38 @@ const boschExtend = {
|
|
|
352
354
|
isModernExtend: true,
|
|
353
355
|
};
|
|
354
356
|
},
|
|
357
|
+
seMeteringCluster: () => m.deviceAddCustomCluster("seMetering", {
|
|
358
|
+
ID: zigbee_herdsman_1.Zcl.Clusters.seMetering.ID,
|
|
359
|
+
attributes: {},
|
|
360
|
+
commands: {
|
|
361
|
+
resetEnergyReading: {
|
|
362
|
+
ID: 0x80,
|
|
363
|
+
parameters: [],
|
|
364
|
+
},
|
|
365
|
+
},
|
|
366
|
+
commandsResponse: {},
|
|
367
|
+
}),
|
|
368
|
+
resetEnergyReading: () => {
|
|
369
|
+
const exposes = [
|
|
370
|
+
e
|
|
371
|
+
.enum("reset_energy_reading", ea.SET, ["reset"])
|
|
372
|
+
.withDescription("Triggers the reset of the energy reading to 0 kWh.")
|
|
373
|
+
.withCategory("config"),
|
|
374
|
+
];
|
|
375
|
+
const toZigbee = [
|
|
376
|
+
{
|
|
377
|
+
key: ["reset_energy_reading"],
|
|
378
|
+
convertSet: async (entity, key, value, meta) => {
|
|
379
|
+
await entity.command("seMetering", "resetEnergyReading", {}, manufacturerOptions);
|
|
380
|
+
},
|
|
381
|
+
},
|
|
382
|
+
];
|
|
383
|
+
return {
|
|
384
|
+
exposes,
|
|
385
|
+
toZigbee,
|
|
386
|
+
isModernExtend: true,
|
|
387
|
+
};
|
|
388
|
+
},
|
|
355
389
|
doorWindowContact: (hasVibrationSensor) => {
|
|
356
390
|
const exposes = [
|
|
357
391
|
e.binary("contact", ea.STATE, false, true).withDescription("Indicates whether the device is opened or closed"),
|
|
@@ -789,21 +823,59 @@ const boschExtend = {
|
|
|
789
823
|
stopped: 0x00,
|
|
790
824
|
opening: 0x01,
|
|
791
825
|
closing: 0x02,
|
|
826
|
+
unknownOne: 0x03,
|
|
827
|
+
unknownTwo: 0x04,
|
|
792
828
|
};
|
|
793
829
|
const stateSwitchType = {
|
|
794
830
|
button: 0x01,
|
|
795
831
|
button_key_change: 0x02,
|
|
796
832
|
rocker_switch: 0x03,
|
|
797
833
|
rocker_switch_key_change: 0x04,
|
|
834
|
+
none: 0x00,
|
|
835
|
+
};
|
|
836
|
+
const stateSwitchMode = {
|
|
837
|
+
coupled: 0x00,
|
|
838
|
+
decoupled: 0x01,
|
|
839
|
+
only_short_press_decoupled: 0x02,
|
|
840
|
+
only_long_press_decoupled: 0x03,
|
|
798
841
|
};
|
|
799
842
|
const stateOffOn = {
|
|
800
843
|
OFF: 0x00,
|
|
801
844
|
ON: 0x01,
|
|
802
845
|
};
|
|
803
846
|
const fromZigbee = [
|
|
804
|
-
fz.
|
|
847
|
+
fz.on_off_force_multiendpoint,
|
|
805
848
|
fz.power_on_behavior,
|
|
806
849
|
fz.cover_position_tilt,
|
|
850
|
+
{
|
|
851
|
+
cluster: "boschSpecific",
|
|
852
|
+
type: ["raw"],
|
|
853
|
+
convert: (model, msg, publish, options, meta) => {
|
|
854
|
+
const command = msg.data[4];
|
|
855
|
+
if (command !== 0x03 && command !== 0x04) {
|
|
856
|
+
return;
|
|
857
|
+
}
|
|
858
|
+
let state;
|
|
859
|
+
const status = msg.data[5];
|
|
860
|
+
const duration = msg.data[6] / 10;
|
|
861
|
+
switch (status) {
|
|
862
|
+
case 0:
|
|
863
|
+
state = "press_released";
|
|
864
|
+
break;
|
|
865
|
+
case 1:
|
|
866
|
+
state = duration !== 0 ? "hold" : "hold_released";
|
|
867
|
+
break;
|
|
868
|
+
case 2:
|
|
869
|
+
state = "closed";
|
|
870
|
+
break;
|
|
871
|
+
case 3:
|
|
872
|
+
state = "opened";
|
|
873
|
+
break;
|
|
874
|
+
}
|
|
875
|
+
const triggeredSide = command === 0x03 ? "left" : "right";
|
|
876
|
+
return { action: `${state}_${triggeredSide}`, action_duration: duration };
|
|
877
|
+
},
|
|
878
|
+
},
|
|
807
879
|
{
|
|
808
880
|
cluster: "boschSpecific",
|
|
809
881
|
type: ["attributeReport", "readResponse"],
|
|
@@ -821,6 +893,10 @@ const boschExtend = {
|
|
|
821
893
|
if (data.switchType !== undefined) {
|
|
822
894
|
result.switch_type = Object.keys(stateSwitchType).find((key) => stateSwitchType[key] === msg.data.switchType);
|
|
823
895
|
}
|
|
896
|
+
if (data.switchMode !== undefined) {
|
|
897
|
+
const property = utils.postfixWithEndpointName("switch_mode", msg, model, meta);
|
|
898
|
+
result[property] = Object.keys(stateSwitchMode).find((key) => stateSwitchMode[key] === msg.data.switchMode);
|
|
899
|
+
}
|
|
824
900
|
if (data.calibrationOpeningTime !== undefined) {
|
|
825
901
|
result.calibration_opening_time = msg.data.calibrationOpeningTime / 10;
|
|
826
902
|
}
|
|
@@ -840,6 +916,14 @@ const boschExtend = {
|
|
|
840
916
|
if (data.motorState !== undefined) {
|
|
841
917
|
result.motor_state = Object.keys(stateMotor).find((key) => stateMotor[key] === msg.data.motorState);
|
|
842
918
|
}
|
|
919
|
+
if (data.autoOffEnabled !== undefined) {
|
|
920
|
+
const property = utils.postfixWithEndpointName("auto_off_enabled", msg, model, meta);
|
|
921
|
+
result[property] = msg.data.autoOffEnabled === 1 ? "ON" : "OFF";
|
|
922
|
+
}
|
|
923
|
+
if (data.autoOffTime !== undefined) {
|
|
924
|
+
const property = utils.postfixWithEndpointName("auto_off_time", msg, model, meta);
|
|
925
|
+
result[property] = msg.data.autoOffTime / 60;
|
|
926
|
+
}
|
|
843
927
|
return result;
|
|
844
928
|
},
|
|
845
929
|
},
|
|
@@ -848,7 +932,17 @@ const boschExtend = {
|
|
|
848
932
|
tz.power_on_behavior,
|
|
849
933
|
tz.cover_position_tilt,
|
|
850
934
|
{
|
|
851
|
-
key: [
|
|
935
|
+
key: [
|
|
936
|
+
"device_mode",
|
|
937
|
+
"switch_type",
|
|
938
|
+
"switch_mode",
|
|
939
|
+
"child_lock",
|
|
940
|
+
"state",
|
|
941
|
+
"on_time",
|
|
942
|
+
"off_wait_time",
|
|
943
|
+
"auto_off_enabled",
|
|
944
|
+
"auto_off_time",
|
|
945
|
+
],
|
|
852
946
|
convertSet: async (entity, key, value, meta) => {
|
|
853
947
|
if (key === "state") {
|
|
854
948
|
if ("ID" in entity && entity.ID === 1) {
|
|
@@ -874,11 +968,25 @@ const boschExtend = {
|
|
|
874
968
|
await entity.write("boschSpecific", { switchType: index });
|
|
875
969
|
return { state: { switch_type: value } };
|
|
876
970
|
}
|
|
971
|
+
if (key === "switch_mode") {
|
|
972
|
+
const index = utils.getFromLookup(value, stateSwitchMode);
|
|
973
|
+
await entity.write("boschSpecific", { switchMode: index });
|
|
974
|
+
return { state: { switch_mode: value } };
|
|
975
|
+
}
|
|
877
976
|
if (key === "child_lock") {
|
|
878
977
|
const index = utils.getFromLookup(value, stateOffOn);
|
|
879
978
|
await entity.write("boschSpecific", { childLock: index });
|
|
880
979
|
return { state: { child_lock: value } };
|
|
881
980
|
}
|
|
981
|
+
if (key === "auto_off_enabled") {
|
|
982
|
+
const index = utils.getFromLookup(value, stateOffOn);
|
|
983
|
+
await entity.write("boschSpecific", { autoOffEnabled: index });
|
|
984
|
+
return { state: { auto_off_enabled: value } };
|
|
985
|
+
}
|
|
986
|
+
if (key === "auto_off_time" && typeof value === "number") {
|
|
987
|
+
await entity.write("boschSpecific", { autoOffTime: value * 60 });
|
|
988
|
+
return { state: { auto_off_time: value } };
|
|
989
|
+
}
|
|
882
990
|
},
|
|
883
991
|
convertGet: async (entity, key, meta) => {
|
|
884
992
|
switch (key) {
|
|
@@ -895,9 +1003,18 @@ const boschExtend = {
|
|
|
895
1003
|
case "switch_type":
|
|
896
1004
|
await entity.read("boschSpecific", ["switchType"]);
|
|
897
1005
|
break;
|
|
1006
|
+
case "switch_mode":
|
|
1007
|
+
await entity.read("boschSpecific", ["switchMode"]);
|
|
1008
|
+
break;
|
|
898
1009
|
case "child_lock":
|
|
899
1010
|
await entity.read("boschSpecific", ["childLock"]);
|
|
900
1011
|
break;
|
|
1012
|
+
case "auto_off_enabled":
|
|
1013
|
+
await entity.read("boschSpecific", ["autoOffEnabled"]);
|
|
1014
|
+
break;
|
|
1015
|
+
case "auto_off_time":
|
|
1016
|
+
await entity.read("boschSpecific", ["autoOffTime"]);
|
|
1017
|
+
break;
|
|
901
1018
|
default:
|
|
902
1019
|
throw new Error(`Unhandled key boschExtend.bmct.toZigbee.convertGet ${key}`);
|
|
903
1020
|
}
|
|
@@ -1834,48 +1951,130 @@ exports.definitions = [
|
|
|
1834
1951
|
description: "Light/shutter control unit II",
|
|
1835
1952
|
extend: [
|
|
1836
1953
|
m.deviceEndpoints({ endpoints: { left: 2, right: 3 } }),
|
|
1837
|
-
m.electricityMeter({
|
|
1954
|
+
m.electricityMeter({
|
|
1955
|
+
voltage: false,
|
|
1956
|
+
current: false,
|
|
1957
|
+
power: { change: 1 },
|
|
1958
|
+
energy: { change: 1 },
|
|
1959
|
+
}),
|
|
1838
1960
|
m.deviceAddCustomCluster("boschSpecific", {
|
|
1839
1961
|
ID: 0xfca0,
|
|
1840
1962
|
manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.ROBERT_BOSCH_GMBH,
|
|
1841
1963
|
attributes: {
|
|
1842
1964
|
deviceMode: { ID: 0x0000, type: zigbee_herdsman_1.Zcl.DataType.ENUM8 },
|
|
1843
1965
|
switchType: { ID: 0x0001, type: zigbee_herdsman_1.Zcl.DataType.ENUM8 },
|
|
1966
|
+
switchMode: { ID: 0x0031, type: zigbee_herdsman_1.Zcl.DataType.UINT8 },
|
|
1844
1967
|
calibrationOpeningTime: { ID: 0x0002, type: zigbee_herdsman_1.Zcl.DataType.UINT32 },
|
|
1845
1968
|
calibrationClosingTime: { ID: 0x0003, type: zigbee_herdsman_1.Zcl.DataType.UINT32 },
|
|
1969
|
+
// 0x0005 isn't used at all when using the Bosch SHC as of 30-06-2025.
|
|
1970
|
+
// As I don't have any shutters, I can't run all calibration steps
|
|
1971
|
+
// successfully. So, keep any comments regarding these
|
|
1972
|
+
// attributes with caution.
|
|
1846
1973
|
calibrationButtonHoldTime: { ID: 0x0005, type: zigbee_herdsman_1.Zcl.DataType.UINT8 },
|
|
1974
|
+
autoOffEnabled: { ID: 0x0006, type: zigbee_herdsman_1.Zcl.DataType.BOOLEAN },
|
|
1975
|
+
autoOffTime: { ID: 0x0007, type: zigbee_herdsman_1.Zcl.DataType.UINT16 },
|
|
1847
1976
|
childLock: { ID: 0x0008, type: zigbee_herdsman_1.Zcl.DataType.BOOLEAN },
|
|
1977
|
+
// 0x000f is only being set when using the automatic calibration.
|
|
1978
|
+
// It's being set to 0 then before sending the calibration
|
|
1979
|
+
// command. Additionally, when changing
|
|
1980
|
+
// the calibrationOpeningTime or calibrationClosingTime in the
|
|
1981
|
+
// Bosch app, it's also being set to 0.
|
|
1982
|
+
// I couldn't find any way to set 0x000f manually in the Bosch app.
|
|
1848
1983
|
calibrationMotorStartDelay: { ID: 0x000f, type: zigbee_herdsman_1.Zcl.DataType.UINT8 },
|
|
1984
|
+
calibrationMotorReverseDirection: { ID: 0x0032, type: zigbee_herdsman_1.Zcl.DataType.BOOLEAN },
|
|
1849
1985
|
motorState: { ID: 0x0013, type: zigbee_herdsman_1.Zcl.DataType.ENUM8 },
|
|
1986
|
+
// unknownAttributeOne is always being configured as reporting
|
|
1987
|
+
// attribute on endpoint 1 when using the Bosch SHC.
|
|
1988
|
+
// Can't tell what this attribute does (always received
|
|
1989
|
+
// 0x00 as answer on manual lookup).
|
|
1990
|
+
unknownAttributeOne: { ID: 0x0004, type: zigbee_herdsman_1.Zcl.DataType.BITMAP8 },
|
|
1991
|
+
// Attribute is being set to 255 when deactivating the automatic
|
|
1992
|
+
// detection of the motor end position by the Bosch SHC. After
|
|
1993
|
+
// activating the automatic end position detection it's being set
|
|
1994
|
+
// to 0 by the Bosch SHC. Apart from that, there's no way to manually
|
|
1995
|
+
// change the value.
|
|
1996
|
+
calibrationMotorEndPosition: { ID: 0x0021, type: zigbee_herdsman_1.Zcl.DataType.UINT8 },
|
|
1997
|
+
// 0x0033 is used when setting the motor start delay manually
|
|
1998
|
+
// using the Bosch SHC as of 30-06-2025.
|
|
1999
|
+
// If the user wants to automatically detect the delay during
|
|
2000
|
+
// calibration, it's being set to 0 over the Bosch app.
|
|
2001
|
+
calibrationNewMotorStartDelay: { ID: 0x0033, type: zigbee_herdsman_1.Zcl.DataType.UINT16 },
|
|
2002
|
+
// 0x0010 and 0x0011 is being set simultaneously with the same value
|
|
2003
|
+
// when changing the delay for the rotation of the slats on venetian
|
|
2004
|
+
// blinds. Maybe one attribute for each direction?
|
|
2005
|
+
// It's also being configured as reporting attribute when using
|
|
2006
|
+
// venetian blinds.
|
|
2007
|
+
slatRotationDurationOne: { ID: 0x0010, type: zigbee_herdsman_1.Zcl.DataType.UINT32 },
|
|
2008
|
+
slatRotationDurationTwo: { ID: 0x0011, type: zigbee_herdsman_1.Zcl.DataType.UINT32 },
|
|
2009
|
+
// 0x002a is only being used when doing an automatic calibration
|
|
2010
|
+
// with the Bosch specific startAutomaticMotorCalibration command.
|
|
2011
|
+
// It's being set to true before starting the calibration process.
|
|
2012
|
+
// This happens regardless of the shutter type. I didn't capture
|
|
2013
|
+
// any packages where this attribute is being actively set to false.
|
|
2014
|
+
// Maybe this activates some "full calibration" flag which is being
|
|
2015
|
+
// set to false by the device itself afterward?
|
|
2016
|
+
unknownAttributeTwo: { ID: 0x002a, type: zigbee_herdsman_1.Zcl.DataType.BOOLEAN },
|
|
2017
|
+
},
|
|
2018
|
+
commands: {
|
|
2019
|
+
// Command being sent by the Bosch SHC when starting an
|
|
2020
|
+
// automatic shutter calibration.
|
|
2021
|
+
startAutomaticMotorCalibration: { ID: 0x00, parameters: [] },
|
|
1850
2022
|
},
|
|
1851
|
-
commands: {},
|
|
1852
2023
|
commandsResponse: {},
|
|
1853
2024
|
}),
|
|
1854
2025
|
boschExtend.bmct(),
|
|
2026
|
+
boschExtend.seMeteringCluster(),
|
|
2027
|
+
boschExtend.resetEnergyReading(),
|
|
1855
2028
|
],
|
|
1856
2029
|
ota: true,
|
|
1857
2030
|
configure: async (device, coordinatorEndpoint) => {
|
|
2031
|
+
const lightConfiguration = async () => {
|
|
2032
|
+
const endpoint1 = device.getEndpoint(1);
|
|
2033
|
+
await reporting.bind(endpoint1, coordinatorEndpoint, ["genIdentify"]);
|
|
2034
|
+
await endpoint1.read("boschSpecific", ["switchType"]);
|
|
2035
|
+
const endpoint2 = device.getEndpoint(2);
|
|
2036
|
+
await reporting.bind(endpoint2, coordinatorEndpoint, ["genIdentify", "genOnOff", "boschSpecific"]);
|
|
2037
|
+
await reporting.onOff(endpoint2);
|
|
2038
|
+
await endpoint2.read("genOnOff", ["onOff", "startUpOnOff"]);
|
|
2039
|
+
await endpoint2.read("boschSpecific", [
|
|
2040
|
+
"switchMode",
|
|
2041
|
+
"childLock",
|
|
2042
|
+
"autoOffEnabled",
|
|
2043
|
+
"autoOffTime",
|
|
2044
|
+
]);
|
|
2045
|
+
const endpoint3 = device.getEndpoint(3);
|
|
2046
|
+
await reporting.bind(endpoint3, coordinatorEndpoint, ["genIdentify", "genOnOff", "boschSpecific"]);
|
|
2047
|
+
await reporting.onOff(endpoint3);
|
|
2048
|
+
await endpoint3.read("genOnOff", ["onOff", "startUpOnOff"]);
|
|
2049
|
+
await endpoint3.read("boschSpecific", [
|
|
2050
|
+
"switchMode",
|
|
2051
|
+
"childLock",
|
|
2052
|
+
"autoOffEnabled",
|
|
2053
|
+
"autoOffTime",
|
|
2054
|
+
]);
|
|
2055
|
+
};
|
|
2056
|
+
const shutterConfiguration = async () => {
|
|
2057
|
+
const endpoint1 = device.getEndpoint(1);
|
|
2058
|
+
await reporting.bind(endpoint1, coordinatorEndpoint, ["genIdentify", "closuresWindowCovering", "boschSpecific"]);
|
|
2059
|
+
await reporting.currentPositionLiftPercentage(endpoint1);
|
|
2060
|
+
await endpoint1.read("closuresWindowCovering", ["currentPositionLiftPercentage"]);
|
|
2061
|
+
const payloadMotorState = (0, reporting_1.payload)("motorState", 0, constants_1.repInterval.MAX, 0);
|
|
2062
|
+
await endpoint1.configureReporting("boschSpecific", payloadMotorState);
|
|
2063
|
+
await endpoint1.read("boschSpecific", [
|
|
2064
|
+
"switchType",
|
|
2065
|
+
"switchMode",
|
|
2066
|
+
"motorState",
|
|
2067
|
+
"calibrationOpeningTime",
|
|
2068
|
+
"calibrationClosingTime",
|
|
2069
|
+
"calibrationButtonHoldTime",
|
|
2070
|
+
"calibrationMotorStartDelay",
|
|
2071
|
+
"childLock",
|
|
2072
|
+
]);
|
|
2073
|
+
};
|
|
1858
2074
|
const endpoint1 = device.getEndpoint(1);
|
|
1859
|
-
await
|
|
1860
|
-
await
|
|
1861
|
-
await
|
|
1862
|
-
"deviceMode",
|
|
1863
|
-
"switchType",
|
|
1864
|
-
"motorState",
|
|
1865
|
-
"childLock",
|
|
1866
|
-
"calibrationOpeningTime",
|
|
1867
|
-
"calibrationClosingTime",
|
|
1868
|
-
"calibrationButtonHoldTime",
|
|
1869
|
-
"calibrationMotorStartDelay",
|
|
1870
|
-
]);
|
|
1871
|
-
const endpoint2 = device.getEndpoint(2);
|
|
1872
|
-
await endpoint2.read("boschSpecific", ["childLock"]);
|
|
1873
|
-
await reporting.bind(endpoint2, coordinatorEndpoint, ["genIdentify", "genOnOff"]);
|
|
1874
|
-
await reporting.onOff(endpoint2);
|
|
1875
|
-
const endpoint3 = device.getEndpoint(3);
|
|
1876
|
-
await endpoint3.read("boschSpecific", ["childLock"]);
|
|
1877
|
-
await reporting.bind(endpoint3, coordinatorEndpoint, ["genIdentify", "genOnOff"]);
|
|
1878
|
-
await reporting.onOff(endpoint3);
|
|
2075
|
+
await endpoint1.read("boschSpecific", ["deviceMode"]);
|
|
2076
|
+
await lightConfiguration();
|
|
2077
|
+
await shutterConfiguration();
|
|
1879
2078
|
},
|
|
1880
2079
|
exposes: (device, options) => {
|
|
1881
2080
|
const stateDeviceMode = {
|
|
@@ -1893,15 +2092,67 @@ exports.definitions = [
|
|
|
1893
2092
|
button_key_change: 0x02,
|
|
1894
2093
|
rocker_switch: 0x03,
|
|
1895
2094
|
rocker_switch_key_change: 0x04,
|
|
2095
|
+
none: 0x00,
|
|
2096
|
+
};
|
|
2097
|
+
const stateSwitchMode = {
|
|
2098
|
+
coupled: 0x00,
|
|
2099
|
+
decoupled: 0x01,
|
|
2100
|
+
only_short_press_decoupled: 0x02,
|
|
2101
|
+
only_long_press_decoupled: 0x03,
|
|
1896
2102
|
};
|
|
1897
2103
|
const commonExposes = [
|
|
1898
2104
|
e.enum("switch_type", ea.ALL, Object.keys(stateSwitchType)).withDescription("Module controlled by a rocker switch or a button"),
|
|
2105
|
+
e.action([
|
|
2106
|
+
"press_released_left",
|
|
2107
|
+
"press_released_right",
|
|
2108
|
+
"hold_left",
|
|
2109
|
+
"hold_right",
|
|
2110
|
+
"hold_released_left",
|
|
2111
|
+
"hold_released_right",
|
|
2112
|
+
"opened_left",
|
|
2113
|
+
"opened_right",
|
|
2114
|
+
"closed_left",
|
|
2115
|
+
"closed_right",
|
|
2116
|
+
]),
|
|
2117
|
+
e.action_duration(),
|
|
1899
2118
|
];
|
|
1900
2119
|
const lightExposes = [
|
|
1901
2120
|
e.switch().withEndpoint("left"),
|
|
1902
2121
|
e.switch().withEndpoint("right"),
|
|
1903
2122
|
e.power_on_behavior().withEndpoint("left"),
|
|
1904
2123
|
e.power_on_behavior().withEndpoint("right"),
|
|
2124
|
+
e
|
|
2125
|
+
.enum("switch_mode", ea.ALL, Object.keys(stateSwitchMode))
|
|
2126
|
+
.withEndpoint("left")
|
|
2127
|
+
.withDescription("Decouple the switch from the corresponding output to use it for other purposes. Please keep in mind that not all options may work depending on your switch type."),
|
|
2128
|
+
e
|
|
2129
|
+
.enum("switch_mode", ea.ALL, Object.keys(stateSwitchMode))
|
|
2130
|
+
.withEndpoint("right")
|
|
2131
|
+
.withDescription("Decouple the switch from the corresponding output to use it for other purposes. Please keep in mind that not all options may work depending on your switch type."),
|
|
2132
|
+
e
|
|
2133
|
+
.binary("auto_off_enabled", ea.ALL, "ON", "OFF")
|
|
2134
|
+
.withEndpoint("left")
|
|
2135
|
+
.withDescription("Enable/Disable the automatic turn-off feature"),
|
|
2136
|
+
e
|
|
2137
|
+
.binary("auto_off_enabled", ea.ALL, "ON", "OFF")
|
|
2138
|
+
.withEndpoint("right")
|
|
2139
|
+
.withDescription("Enable/Disable the automatic turn-off feature"),
|
|
2140
|
+
e
|
|
2141
|
+
.numeric("auto_off_time", ea.ALL)
|
|
2142
|
+
.withValueMin(0)
|
|
2143
|
+
.withValueMax(720)
|
|
2144
|
+
.withValueStep(1)
|
|
2145
|
+
.withUnit("min")
|
|
2146
|
+
.withDescription("Turn off the output after the specified amount of time. Only in action when the automatic turn-off is enabled.")
|
|
2147
|
+
.withEndpoint("left"),
|
|
2148
|
+
e
|
|
2149
|
+
.numeric("auto_off_time", ea.ALL)
|
|
2150
|
+
.withValueMin(0)
|
|
2151
|
+
.withValueMax(720)
|
|
2152
|
+
.withValueStep(1)
|
|
2153
|
+
.withUnit("min")
|
|
2154
|
+
.withDescription("Turn off the output after the specified amount of time. Only in action when the automatic turn-off is enabled.")
|
|
2155
|
+
.withEndpoint("right"),
|
|
1905
2156
|
e.binary("child_lock", ea.ALL, "ON", "OFF").withEndpoint("left").withDescription("Enable/Disable child lock"),
|
|
1906
2157
|
e.binary("child_lock", ea.ALL, "ON", "OFF").withEndpoint("right").withDescription("Enable/Disable child lock"),
|
|
1907
2158
|
];
|
|
@@ -1909,6 +2160,9 @@ exports.definitions = [
|
|
|
1909
2160
|
e.cover_position(),
|
|
1910
2161
|
e.enum("motor_state", ea.STATE, Object.keys(stateMotor)).withDescription("Current shutter motor state"),
|
|
1911
2162
|
e.binary("child_lock", ea.ALL, "ON", "OFF").withDescription("Enable/Disable child lock"),
|
|
2163
|
+
e
|
|
2164
|
+
.enum("switch_mode", ea.ALL, Object.keys(stateSwitchMode).filter((switchMode) => switchMode === "coupled" || switchMode === "only_long_press_decoupled"))
|
|
2165
|
+
.withDescription("Decouple the switch from the corresponding output to use it for other purposes. Please keep in mind that not all options may work depending on your switch type."),
|
|
1912
2166
|
e
|
|
1913
2167
|
.numeric("calibration_closing_time", ea.ALL)
|
|
1914
2168
|
.withUnit("s")
|
|
@@ -1950,6 +2204,34 @@ exports.definitions = [
|
|
|
1950
2204
|
}
|
|
1951
2205
|
return [e.enum("device_mode", ea.ALL, Object.keys(stateDeviceMode)).withDescription("Device mode")];
|
|
1952
2206
|
},
|
|
2207
|
+
onEvent: (event) => {
|
|
2208
|
+
if (event.type !== "deviceInterview") {
|
|
2209
|
+
return;
|
|
2210
|
+
}
|
|
2211
|
+
// During interview, the Bosch BMCT-SLZ is requesting
|
|
2212
|
+
// the zclVersion attribute from the coordinator. As
|
|
2213
|
+
// Z2M doesn't know the zclVersion of the device yet,
|
|
2214
|
+
// the request is left unanswered. This makes the device
|
|
2215
|
+
// believe it dropped out of network every 10 minutes which
|
|
2216
|
+
// not only generates unnecessary network congestion, but
|
|
2217
|
+
// makes the LED on the device blink during that sequence
|
|
2218
|
+
// as well. To prevent that, we have to manually answer
|
|
2219
|
+
// the zclVersion request at the earliest possible stage
|
|
2220
|
+
// and mimic the answer from the Bosch SHC II.
|
|
2221
|
+
event.data.device.customReadResponse = (frame, endpoint) => {
|
|
2222
|
+
const isZclVersionRequest = frame.isCluster("genBasic") && frame.payload.find((i) => i.attrId === 0);
|
|
2223
|
+
if (!isZclVersionRequest) {
|
|
2224
|
+
return false;
|
|
2225
|
+
}
|
|
2226
|
+
const payload = {
|
|
2227
|
+
zclVersion: 1,
|
|
2228
|
+
};
|
|
2229
|
+
endpoint.readResponse(frame.cluster.name, frame.header.transactionSequenceNumber, payload).catch((e) => {
|
|
2230
|
+
logger_1.logger.warning(`Custom zclVersion response failed for '${event.data.device.ieeeAddr}': ${e}`, NS);
|
|
2231
|
+
});
|
|
2232
|
+
return true;
|
|
2233
|
+
};
|
|
2234
|
+
},
|
|
1953
2235
|
},
|
|
1954
2236
|
{
|
|
1955
2237
|
zigbeeModel: ["RBSH-US4BTN-ZB-EU"],
|