zigbee-herdsman-converters 19.44.0 → 19.45.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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## [19.45.0](https://github.com/Koenkk/zigbee-herdsman-converters/compare/v19.44.0...v19.45.0) (2024-05-28)
4
+
5
+
6
+ ### Features
7
+
8
+ * Enable OTA for some Develco devices ([#7561](https://github.com/Koenkk/zigbee-herdsman-converters/issues/7561)) ([90d336e](https://github.com/Koenkk/zigbee-herdsman-converters/commit/90d336e22dcfaf56a08b5f3bec17d05494b554ca))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **detect:** Detect `_TZ3000_zrm3oxsh` as EARU EAYCB-Z-2P ([#7568](https://github.com/Koenkk/zigbee-herdsman-converters/issues/7568)) ([8c41f14](https://github.com/Koenkk/zigbee-herdsman-converters/commit/8c41f1406eee4053087ab79e61937c4da25aa2b7))
14
+ * **detect:** Detect `_TZ3000_zrm3oxsh` as TuYa TS011F_with_threshold ([#7571](https://github.com/Koenkk/zigbee-herdsman-converters/issues/7571)) ([51191e1](https://github.com/Koenkk/zigbee-herdsman-converters/commit/51191e1f7e0cb328f24423635d38d50746c5434b))
15
+ * **detect:** Detect `_TZE200_2odrmqwq` as TuYa TS0601_cover_1 [@mrespin](https://github.com/mrespin) https://github.com/Koenkk/zigbee2mqtt/issues/22795 ([b41636e](https://github.com/Koenkk/zigbee-herdsman-converters/commit/b41636e651279459883ed9204ffedcdf8dca021b))
16
+ * Partly convert Bosch BMCT-SLZ to `modernExtend` ([#7569](https://github.com/Koenkk/zigbee-herdsman-converters/issues/7569)) ([8242bb7](https://github.com/Koenkk/zigbee-herdsman-converters/commit/8242bb7b23ded4e1cdfddb1f87f991601e3aceef))
17
+
3
18
  ## [19.44.0](https://github.com/Koenkk/zigbee-herdsman-converters/compare/v19.43.0...v19.44.0) (2024-05-27)
4
19
 
5
20
 
@@ -1 +1 @@
1
- {"version":3,"file":"bosch.d.ts","sourceRoot":"","sources":["../src/devices/bosch.ts"],"names":[],"mappings":"AAcA,OAAO,EACK,UAAU,EACrB,MAAM,cAAc,CAAC;AA+9BtB,QAAA,MAAM,WAAW,EAAE,UAAU,EA6yB5B,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"bosch.d.ts","sourceRoot":"","sources":["../src/devices/bosch.ts"],"names":[],"mappings":"AAcA,OAAO,EACK,UAAU,EACrB,MAAM,cAAc,CAAC;AAy+BtB,QAAA,MAAM,WAAW,EAAE,UAAU,EA+0B5B,CAAC;AAEF,eAAe,WAAW,CAAC"}
package/devices/bosch.js CHANGED
@@ -60,25 +60,6 @@ const sirenPowerSupply = {
60
60
  'ac_power_supply': 0x02,
61
61
  'dc_power_supply': 0x03,
62
62
  };
63
- // BMCT
64
- const stateDeviceMode = {
65
- 'light': 0x04,
66
- 'shutter': 0x01,
67
- 'disabled': 0x00,
68
- };
69
- // BMCT
70
- const stateMotor = {
71
- 'stopped': 0x00,
72
- 'opening': 0x01,
73
- 'closing': 0x02,
74
- };
75
- // BMCT
76
- const stateSwitchType = {
77
- 'button': 0x01,
78
- 'button_key_change': 0x02,
79
- 'rocker_switch': 0x03,
80
- 'rocker_switch_key_change': 0x04,
81
- };
82
63
  // Radiator Thermostat II
83
64
  const stateOffOn = {
84
65
  'OFF': 0,
@@ -518,9 +499,9 @@ const boschExtend = {
518
499
  .withUnit('°C').withDescription('Measured temperature value'),
519
500
  e.numeric('humidity', ea.STATE).withValueMin(0).withValueMax(100).withValueStep(0.1)
520
501
  .withUnit('%').withDescription('Measured relative humidity'),
521
- e.numeric('voc', ea.STATE).withValueMin(0).withValueMax(35610).withValueStep(1)
502
+ e.numeric('voc', ea.STATE).withValueMin(0).withValueMax(50000).withValueStep(1)
522
503
  .withLabel('VOC').withUnit('µg/m³').withDescription('Measured VOC value'),
523
- e.numeric('co2', ea.STATE).withValueMin(500).withValueMax(5500).withValueStep(1)
504
+ e.numeric('co2', ea.STATE).withValueMin(400).withValueMax(2400).withValueStep(1)
524
505
  .withLabel('CO2').withUnit('ppm').withDescription('The measured CO2 (carbon dioxide) value'),
525
506
  e.numeric('aqi', ea.STATE).withValueMin(0).withValueMax(500).withValueStep(1)
526
507
  .withLabel('AQI').withDescription('Air Quality Index'),
@@ -731,6 +712,153 @@ const boschExtend = {
731
712
  isModernExtend: true,
732
713
  };
733
714
  },
715
+ bmct: () => {
716
+ const stateDeviceMode = {
717
+ 'light': 0x04,
718
+ 'shutter': 0x01,
719
+ 'disabled': 0x00,
720
+ };
721
+ const stateMotor = {
722
+ 'stopped': 0x00,
723
+ 'opening': 0x01,
724
+ 'closing': 0x02,
725
+ };
726
+ const stateSwitchType = {
727
+ 'button': 0x01,
728
+ 'button_key_change': 0x02,
729
+ 'rocker_switch': 0x03,
730
+ 'rocker_switch_key_change': 0x04,
731
+ };
732
+ const fromZigbee = [{
733
+ cluster: 'boschSpecific',
734
+ type: ['attributeReport', 'readResponse'],
735
+ convert: (model, msg, publish, options, meta) => {
736
+ const result = {};
737
+ const data = msg.data;
738
+ if (data.hasOwnProperty('deviceMode')) {
739
+ result.device_mode = Object.keys(stateDeviceMode).find((key) => stateDeviceMode[key] === msg.data['deviceMode']);
740
+ const deviceMode = msg.data['deviceMode'];
741
+ if (deviceMode !== meta.device.meta.deviceMode) {
742
+ meta.device.meta.deviceMode = deviceMode;
743
+ meta.deviceExposesChanged();
744
+ }
745
+ }
746
+ if (data.hasOwnProperty('switchType')) {
747
+ result.switch_type = Object.keys(stateSwitchType).find((key) => stateSwitchType[key] === msg.data['switchType']);
748
+ }
749
+ if (data.hasOwnProperty('calibrationOpeningTime')) {
750
+ result.calibration_opening_time = msg.data['calibrationOpeningTime'] / 10;
751
+ }
752
+ if (data.hasOwnProperty('calibrationClosingTime')) {
753
+ result.calibration_closing_time = msg.data['calibrationClosingTime'] / 10;
754
+ }
755
+ if (data.hasOwnProperty('childLock')) {
756
+ const property = utils.postfixWithEndpointName('child_lock', msg, model, meta);
757
+ result[property] = msg.data['childLock'] === 1 ? 'ON' : 'OFF';
758
+ }
759
+ if (data.hasOwnProperty('motorState')) {
760
+ result.motor_state = Object.keys(stateMotor).find((key) => stateMotor[key] === msg.data['motorState']);
761
+ }
762
+ return result;
763
+ },
764
+ }];
765
+ const toZigbee = [{
766
+ key: [
767
+ 'device_mode',
768
+ 'switch_type',
769
+ 'child_lock',
770
+ 'state',
771
+ 'on_time',
772
+ 'off_wait_time',
773
+ ],
774
+ convertSet: async (entity, key, value, meta) => {
775
+ if (key === 'state') {
776
+ if ('ID' in entity && entity.ID === 1) {
777
+ await toZigbee_1.default.cover_state.convertSet(entity, key, value, meta);
778
+ }
779
+ else {
780
+ await toZigbee_1.default.on_off.convertSet(entity, key, value, meta);
781
+ }
782
+ }
783
+ if (key === 'on_time' || key === 'on_wait_time') {
784
+ if ('ID' in entity && entity.ID !== 1) {
785
+ await toZigbee_1.default.on_off.convertSet(entity, key, value, meta);
786
+ }
787
+ }
788
+ if (key === 'device_mode') {
789
+ const index = utils.getFromLookup(value, stateDeviceMode);
790
+ await entity.write('boschSpecific', { deviceMode: index });
791
+ await entity.read('boschSpecific', ['deviceMode']);
792
+ return { state: { device_mode: value } };
793
+ }
794
+ if (key === 'switch_type') {
795
+ const index = utils.getFromLookup(value, stateSwitchType);
796
+ await entity.write('boschSpecific', { switchType: index });
797
+ return { state: { switch_type: value } };
798
+ }
799
+ if (key === 'child_lock') {
800
+ const index = utils.getFromLookup(value, stateOffOn);
801
+ await entity.write('boschSpecific', { childLock: index });
802
+ return { state: { child_lock: value } };
803
+ }
804
+ },
805
+ convertGet: async (entity, key, meta) => {
806
+ switch (key) {
807
+ case 'state':
808
+ case 'on_time':
809
+ case 'off_wait_time':
810
+ if ('ID' in entity && entity.ID !== 1) {
811
+ await entity.read('genOnOff', ['onOff']);
812
+ }
813
+ break;
814
+ case 'device_mode':
815
+ await entity.read('boschSpecific', ['deviceMode']);
816
+ break;
817
+ case 'switch_type':
818
+ await entity.read('boschSpecific', ['switchType']);
819
+ break;
820
+ case 'child_lock':
821
+ await entity.read('boschSpecific', ['childLock']);
822
+ break;
823
+ default:
824
+ throw new Error(`Unhandled key boschExtend.bmct.toZigbee.convertGet ${key}`);
825
+ }
826
+ },
827
+ }, {
828
+ key: ['calibration', 'calibration_closing_time', 'calibration_opening_time'],
829
+ convertSet: async (entity, key, value, meta) => {
830
+ if (key === 'calibration_opening_time') {
831
+ const number = utils.toNumber(value, 'calibration_opening_time');
832
+ const index = number * 10;
833
+ await entity.write('boschSpecific', { calibrationOpeningTime: index });
834
+ return { state: { calibration_opening_time: number } };
835
+ }
836
+ if (key === 'calibration_closing_time') {
837
+ const number = utils.toNumber(value, 'calibration_closing_time');
838
+ const index = number * 10;
839
+ await entity.write('boschSpecific', { calibrationClosingTime: index });
840
+ return { state: { calibration_closing_time: number } };
841
+ }
842
+ },
843
+ convertGet: async (entity, key, meta) => {
844
+ switch (key) {
845
+ case 'calibration_opening_time':
846
+ await entity.read('boschSpecific', ['calibrationOpeningTime']);
847
+ break;
848
+ case 'calibration_closing_time':
849
+ await entity.read('boschSpecific', ['calibrationClosingTime']);
850
+ break;
851
+ default:
852
+ throw new Error(`Unhandled key boschExtend.bmct.toZigbee.convertGet ${key}`);
853
+ }
854
+ },
855
+ }];
856
+ return {
857
+ fromZigbee,
858
+ toZigbee,
859
+ isModernExtend: true,
860
+ };
861
+ },
734
862
  };
735
863
  const tzLocal = {
736
864
  rbshoszbeu: {
@@ -812,88 +940,6 @@ const tzLocal = {
812
940
  }
813
941
  },
814
942
  },
815
- bmct: {
816
- key: [
817
- 'device_mode',
818
- 'switch_type',
819
- 'child_lock',
820
- 'calibration', 'calibration_closing_time', 'calibration_opening_time',
821
- 'state',
822
- 'on_time',
823
- 'off_wait_time',
824
- ],
825
- convertSet: async (entity, key, value, meta) => {
826
- if (key === 'state') {
827
- if ('ID' in entity && entity.ID === 1) {
828
- await toZigbee_1.default.cover_state.convertSet(entity, key, value, meta);
829
- }
830
- else {
831
- await toZigbee_1.default.on_off.convertSet(entity, key, value, meta);
832
- }
833
- }
834
- if (key === 'on_time' || key === 'on_wait_time') {
835
- if ('ID' in entity && entity.ID !== 1) {
836
- await toZigbee_1.default.on_off.convertSet(entity, key, value, meta);
837
- }
838
- }
839
- if (key === 'device_mode') {
840
- const index = utils.getFromLookup(value, stateDeviceMode);
841
- await entity.write('manuSpecificBosch10', { deviceMode: index });
842
- await entity.read('manuSpecificBosch10', ['deviceMode']);
843
- return { state: { device_mode: value } };
844
- }
845
- if (key === 'switch_type') {
846
- const index = utils.getFromLookup(value, stateSwitchType);
847
- await entity.write('manuSpecificBosch10', { switchType: index });
848
- return { state: { switch_type: value } };
849
- }
850
- if (key === 'child_lock') {
851
- const index = utils.getFromLookup(value, stateOffOn);
852
- await entity.write('manuSpecificBosch10', { childLock: index });
853
- return { state: { child_lock: value } };
854
- }
855
- if (key === 'calibration_opening_time') {
856
- const number = utils.toNumber(value, 'calibration_opening_time');
857
- const index = number * 10;
858
- await entity.write('manuSpecificBosch10', { calibrationOpeningTime: index });
859
- return { state: { calibration_opening_time: number } };
860
- }
861
- if (key === 'calibration_closing_time') {
862
- const number = utils.toNumber(value, 'calibration_closing_time');
863
- const index = number * 10;
864
- await entity.write('manuSpecificBosch10', { calibrationClosingTime: index });
865
- return { state: { calibration_closing_time: number } };
866
- }
867
- },
868
- convertGet: async (entity, key, meta) => {
869
- switch (key) {
870
- case 'state':
871
- case 'on_time':
872
- case 'off_wait_time':
873
- if ('ID' in entity && entity.ID !== 1) {
874
- await entity.read('genOnOff', ['onOff']);
875
- }
876
- break;
877
- case 'device_mode':
878
- await entity.read('manuSpecificBosch10', ['deviceMode']);
879
- break;
880
- case 'switch_type':
881
- await entity.read('manuSpecificBosch10', ['switchType']);
882
- break;
883
- case 'child_lock':
884
- await entity.read('manuSpecificBosch10', ['childLock']);
885
- break;
886
- case 'calibration_opening_time':
887
- await entity.read('manuSpecificBosch10', ['calibrationOpeningTime']);
888
- break;
889
- case 'calibration_closing_time':
890
- await entity.read('manuSpecificBosch10', ['calibrationClosingTime']);
891
- break;
892
- default: // Unknown key
893
- throw new Error(`Unhandled key toZigbee.bcmt.convertGet ${key}`);
894
- }
895
- },
896
- },
897
943
  bhius_config: {
898
944
  key: Object.keys(buttonMap),
899
945
  convertGet: async (entity, key, meta) => {
@@ -919,39 +965,6 @@ const tzLocal = {
919
965
  },
920
966
  };
921
967
  const fzLocal = {
922
- bmct: {
923
- cluster: 'manuSpecificBosch10',
924
- type: ['attributeReport', 'readResponse'],
925
- convert: (model, msg, publish, options, meta) => {
926
- const result = {};
927
- const data = msg.data;
928
- if (data.hasOwnProperty('deviceMode')) {
929
- result.device_mode = Object.keys(stateDeviceMode).find((key) => stateDeviceMode[key] === msg.data['deviceMode']);
930
- const deviceMode = msg.data['deviceMode'];
931
- if (deviceMode !== meta.device.meta.deviceMode) {
932
- meta.device.meta.deviceMode = deviceMode;
933
- meta.deviceExposesChanged();
934
- }
935
- }
936
- if (data.hasOwnProperty('switchType')) {
937
- result.switch_type = Object.keys(stateSwitchType).find((key) => stateSwitchType[key] === msg.data['switchType']);
938
- }
939
- if (data.hasOwnProperty('calibrationOpeningTime')) {
940
- result.calibration_opening_time = msg.data['calibrationOpeningTime'] / 10;
941
- }
942
- if (data.hasOwnProperty('calibrationClosingTime')) {
943
- result.calibration_closing_time = msg.data['calibrationClosingTime'] / 10;
944
- }
945
- if (data.hasOwnProperty('childLock')) {
946
- const property = utils.postfixWithEndpointName('child_lock', msg, model, meta);
947
- result[property] = msg.data['childLock'] === 1 ? 'ON' : 'OFF';
948
- }
949
- if (data.hasOwnProperty('motorState')) {
950
- result.motor_state = Object.keys(stateMotor).find((key) => stateMotor[key] === msg.data['motorState']);
951
- }
952
- return result;
953
- },
954
- },
955
968
  bhius_button_press: {
956
969
  cluster: 'manuSpecificBosch9',
957
970
  type: 'raw',
@@ -1678,12 +1691,10 @@ const definitions = [
1678
1691
  fromZigbee_1.default.on_off,
1679
1692
  fromZigbee_1.default.power_on_behavior,
1680
1693
  fromZigbee_1.default.cover_position_tilt,
1681
- fzLocal.bmct,
1682
1694
  ],
1683
1695
  toZigbee: [
1684
1696
  toZigbee_1.default.power_on_behavior,
1685
1697
  toZigbee_1.default.cover_position_tilt,
1686
- tzLocal.bmct,
1687
1698
  ],
1688
1699
  meta: {
1689
1700
  multiEndpoint: true,
@@ -1691,22 +1702,55 @@ const definitions = [
1691
1702
  endpoint: (device) => {
1692
1703
  return { 'left': 2, 'right': 3 };
1693
1704
  },
1705
+ extend: [
1706
+ (0, modernExtend_1.deviceAddCustomCluster)('boschSpecific', {
1707
+ ID: 0xfca0,
1708
+ manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.ROBERT_BOSCH_GMBH,
1709
+ attributes: {
1710
+ deviceMode: { ID: 0x0000, type: zigbee_herdsman_1.Zcl.DataType.ENUM8 },
1711
+ switchType: { ID: 0x0001, type: zigbee_herdsman_1.Zcl.DataType.ENUM8 },
1712
+ calibrationOpeningTime: { ID: 0x0002, type: zigbee_herdsman_1.Zcl.DataType.UINT32 },
1713
+ calibrationClosingTime: { ID: 0x0003, type: zigbee_herdsman_1.Zcl.DataType.UINT32 },
1714
+ childLock: { ID: 0x0008, type: zigbee_herdsman_1.Zcl.DataType.BOOLEAN },
1715
+ motorState: { ID: 0x0013, type: zigbee_herdsman_1.Zcl.DataType.ENUM8 },
1716
+ },
1717
+ commands: {},
1718
+ commandsResponse: {},
1719
+ }),
1720
+ boschExtend.bmct(),
1721
+ ],
1694
1722
  configure: async (device, coordinatorEndpoint) => {
1695
1723
  const endpoint1 = device.getEndpoint(1);
1696
- await reporting.bind(endpoint1, coordinatorEndpoint, ['genIdentify', 'closuresWindowCovering', 'manuSpecificBosch10']);
1724
+ await reporting.bind(endpoint1, coordinatorEndpoint, ['genIdentify', 'closuresWindowCovering', 'boschSpecific']);
1697
1725
  await reporting.currentPositionLiftPercentage(endpoint1);
1698
- await endpoint1.read('manuSpecificBosch10', ['deviceMode', 'switchType',
1726
+ await endpoint1.read('boschSpecific', ['deviceMode', 'switchType',
1699
1727
  'calibrationOpeningTime', 'calibrationClosingTime', 'childLock', 'motorState']).catch((e) => { });
1700
1728
  const endpoint2 = device.getEndpoint(2);
1701
- await endpoint2.read('manuSpecificBosch10', ['childLock']);
1729
+ await endpoint2.read('boschSpecific', ['childLock']);
1702
1730
  await reporting.bind(endpoint2, coordinatorEndpoint, ['genIdentify', 'genOnOff']).catch((e) => { });
1703
1731
  await reporting.onOff(endpoint2);
1704
1732
  const endpoint3 = device.getEndpoint(3);
1705
- await endpoint3.read('manuSpecificBosch10', ['childLock']).catch((e) => { });
1733
+ await endpoint3.read('boschSpecific', ['childLock']).catch((e) => { });
1706
1734
  await reporting.bind(endpoint3, coordinatorEndpoint, ['genIdentify', 'genOnOff']);
1707
1735
  await reporting.onOff(endpoint3);
1708
1736
  },
1709
1737
  exposes: (device, options) => {
1738
+ const stateDeviceMode = {
1739
+ 'light': 0x04,
1740
+ 'shutter': 0x01,
1741
+ 'disabled': 0x00,
1742
+ };
1743
+ const stateMotor = {
1744
+ 'stopped': 0x00,
1745
+ 'opening': 0x01,
1746
+ 'closing': 0x02,
1747
+ };
1748
+ const stateSwitchType = {
1749
+ 'button': 0x01,
1750
+ 'button_key_change': 0x02,
1751
+ 'rocker_switch': 0x03,
1752
+ 'rocker_switch_key_change': 0x04,
1753
+ };
1710
1754
  const commonExposes = [
1711
1755
  e.enum('switch_type', ea.ALL, Object.keys(stateSwitchType))
1712
1756
  .withDescription('Module controlled by a rocker switch or a button'),
@@ -1733,7 +1777,7 @@ const definitions = [
1733
1777
  .withDescription('Calibration opening time').withValueMin(1).withValueMax(90),
1734
1778
  ];
1735
1779
  if (device) {
1736
- const deviceModeKey = device.getEndpoint(1).getClusterAttributeValue('manuSpecificBosch10', 'deviceMode');
1780
+ const deviceModeKey = device.getEndpoint(1).getClusterAttributeValue('boschSpecific', 'deviceMode');
1737
1781
  const deviceMode = Object.keys(stateDeviceMode).find((key) => stateDeviceMode[key] === deviceModeKey);
1738
1782
  if (deviceMode === 'light') {
1739
1783
  return [...commonExposes, ...lightExposes];