@willieee802/zigbee-herdsman 0.49.3 → 0.50.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.
Files changed (211) hide show
  1. package/.github/dependabot.yml +0 -3
  2. package/.github/workflows/ci.yml +1 -2
  3. package/.github/workflows/release-please.yml +1 -1
  4. package/.github/workflows/typedoc.yaml +3 -3
  5. package/.release-please-manifest.json +1 -1
  6. package/CHANGELOG.md +143 -0
  7. package/biome.json +1 -1
  8. package/dist/adapter/adapter.d.ts +14 -1
  9. package/dist/adapter/adapter.d.ts.map +1 -1
  10. package/dist/adapter/adapter.js +17 -0
  11. package/dist/adapter/adapter.js.map +1 -1
  12. package/dist/adapter/adapterDiscovery.d.ts.map +1 -1
  13. package/dist/adapter/adapterDiscovery.js.map +1 -1
  14. package/dist/adapter/deconz/adapter/deconzAdapter.d.ts +1 -3
  15. package/dist/adapter/deconz/adapter/deconzAdapter.d.ts.map +1 -1
  16. package/dist/adapter/deconz/adapter/deconzAdapter.js +14 -29
  17. package/dist/adapter/deconz/adapter/deconzAdapter.js.map +1 -1
  18. package/dist/adapter/deconz/driver/constants.d.ts +1 -1
  19. package/dist/adapter/deconz/driver/constants.d.ts.map +1 -1
  20. package/dist/adapter/ember/adapter/emberAdapter.d.ts +1 -1
  21. package/dist/adapter/ember/adapter/emberAdapter.d.ts.map +1 -1
  22. package/dist/adapter/ember/adapter/emberAdapter.js +19 -10
  23. package/dist/adapter/ember/adapter/emberAdapter.js.map +1 -1
  24. package/dist/adapter/ember/adapter/oneWaitress.d.ts +2 -0
  25. package/dist/adapter/ember/adapter/oneWaitress.d.ts.map +1 -1
  26. package/dist/adapter/ember/adapter/oneWaitress.js +13 -5
  27. package/dist/adapter/ember/adapter/oneWaitress.js.map +1 -1
  28. package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts +1 -3
  29. package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts.map +1 -1
  30. package/dist/adapter/ezsp/adapter/ezspAdapter.js +17 -30
  31. package/dist/adapter/ezsp/adapter/ezspAdapter.js.map +1 -1
  32. package/dist/adapter/ezsp/driver/index.d.ts +1 -1
  33. package/dist/adapter/ezsp/driver/index.d.ts.map +1 -1
  34. package/dist/adapter/ezsp/driver/index.js +1 -1
  35. package/dist/adapter/ezsp/driver/index.js.map +1 -1
  36. package/dist/adapter/ezsp/driver/types/index.d.ts +1 -1
  37. package/dist/adapter/ezsp/driver/types/index.d.ts.map +1 -1
  38. package/dist/adapter/ezsp/driver/types/index.js +3 -3
  39. package/dist/adapter/ezsp/driver/types/index.js.map +1 -1
  40. package/dist/adapter/serialPort.d.ts.map +1 -1
  41. package/dist/adapter/serialPort.js +7 -0
  42. package/dist/adapter/serialPort.js.map +1 -1
  43. package/dist/adapter/z-stack/adapter/adapter-backup.js +1 -1
  44. package/dist/adapter/z-stack/adapter/adapter-backup.js.map +1 -1
  45. package/dist/adapter/z-stack/adapter/adapter-nv-memory.js +1 -1
  46. package/dist/adapter/z-stack/adapter/adapter-nv-memory.js.map +1 -1
  47. package/dist/adapter/z-stack/adapter/manager.d.ts.map +1 -1
  48. package/dist/adapter/z-stack/adapter/manager.js +12 -2
  49. package/dist/adapter/z-stack/adapter/manager.js.map +1 -1
  50. package/dist/adapter/z-stack/adapter/tstype.d.ts.map +1 -1
  51. package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts +1 -3
  52. package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts.map +1 -1
  53. package/dist/adapter/z-stack/adapter/zStackAdapter.js +20 -34
  54. package/dist/adapter/z-stack/adapter/zStackAdapter.js.map +1 -1
  55. package/dist/adapter/z-stack/constants/index.d.ts +1 -1
  56. package/dist/adapter/z-stack/constants/index.d.ts.map +1 -1
  57. package/dist/adapter/z-stack/constants/index.js +1 -1
  58. package/dist/adapter/z-stack/constants/index.js.map +1 -1
  59. package/dist/adapter/z-stack/unpi/constants.d.ts +1 -1
  60. package/dist/adapter/z-stack/unpi/constants.d.ts.map +1 -1
  61. package/dist/adapter/z-stack/unpi/constants.js +1 -1
  62. package/dist/adapter/z-stack/unpi/constants.js.map +1 -1
  63. package/dist/adapter/zboss/adapter/zbossAdapter.d.ts +7 -8
  64. package/dist/adapter/zboss/adapter/zbossAdapter.d.ts.map +1 -1
  65. package/dist/adapter/zboss/adapter/zbossAdapter.js +12 -30
  66. package/dist/adapter/zboss/adapter/zbossAdapter.js.map +1 -1
  67. package/dist/adapter/zboss/driver.d.ts.map +1 -1
  68. package/dist/adapter/zboss/driver.js +8 -1
  69. package/dist/adapter/zboss/driver.js.map +1 -1
  70. package/dist/adapter/zboss/uart.d.ts.map +1 -1
  71. package/dist/adapter/zboss/uart.js +14 -2
  72. package/dist/adapter/zboss/uart.js.map +1 -1
  73. package/dist/adapter/zigate/adapter/zigateAdapter.d.ts +1 -3
  74. package/dist/adapter/zigate/adapter/zigateAdapter.d.ts.map +1 -1
  75. package/dist/adapter/zigate/adapter/zigateAdapter.js +8 -29
  76. package/dist/adapter/zigate/adapter/zigateAdapter.js.map +1 -1
  77. package/dist/adapter/zoh/adapter/zohAdapter.d.ts +1 -3
  78. package/dist/adapter/zoh/adapter/zohAdapter.d.ts.map +1 -1
  79. package/dist/adapter/zoh/adapter/zohAdapter.js +18 -33
  80. package/dist/adapter/zoh/adapter/zohAdapter.js.map +1 -1
  81. package/dist/controller/controller.d.ts.map +1 -1
  82. package/dist/controller/controller.js +10 -2
  83. package/dist/controller/controller.js.map +1 -1
  84. package/dist/controller/greenPower.d.ts.map +1 -1
  85. package/dist/controller/greenPower.js +15 -9
  86. package/dist/controller/greenPower.js.map +1 -1
  87. package/dist/controller/helpers/ota.d.ts +4 -4
  88. package/dist/controller/helpers/ota.d.ts.map +1 -1
  89. package/dist/controller/helpers/ota.js +28 -9
  90. package/dist/controller/helpers/ota.js.map +1 -1
  91. package/dist/controller/helpers/zclFrameConverter.d.ts.map +1 -1
  92. package/dist/controller/helpers/zclFrameConverter.js +17 -16
  93. package/dist/controller/helpers/zclFrameConverter.js.map +1 -1
  94. package/dist/controller/model/device.d.ts +14 -4
  95. package/dist/controller/model/device.d.ts.map +1 -1
  96. package/dist/controller/model/device.js +167 -85
  97. package/dist/controller/model/device.js.map +1 -1
  98. package/dist/controller/model/endpoint.d.ts +7 -3
  99. package/dist/controller/model/endpoint.d.ts.map +1 -1
  100. package/dist/controller/model/endpoint.js +34 -21
  101. package/dist/controller/model/endpoint.js.map +1 -1
  102. package/dist/controller/model/group.d.ts +0 -1
  103. package/dist/controller/model/group.d.ts.map +1 -1
  104. package/dist/controller/model/group.js +14 -19
  105. package/dist/controller/model/group.js.map +1 -1
  106. package/dist/controller/touchlink.js +3 -3
  107. package/dist/controller/touchlink.js.map +1 -1
  108. package/dist/utils/timeService.js +2 -2
  109. package/dist/utils/timeService.js.map +1 -1
  110. package/dist/zspec/zcl/buffaloZcl.d.ts +3 -3
  111. package/dist/zspec/zcl/buffaloZcl.d.ts.map +1 -1
  112. package/dist/zspec/zcl/buffaloZcl.js +198 -96
  113. package/dist/zspec/zcl/buffaloZcl.js.map +1 -1
  114. package/dist/zspec/zcl/definition/cluster.d.ts +2 -2
  115. package/dist/zspec/zcl/definition/cluster.d.ts.map +1 -1
  116. package/dist/zspec/zcl/definition/cluster.js +2699 -2808
  117. package/dist/zspec/zcl/definition/cluster.js.map +1 -1
  118. package/dist/zspec/zcl/definition/clusters-types.d.ts +63 -1109
  119. package/dist/zspec/zcl/definition/clusters-types.d.ts.map +1 -1
  120. package/dist/zspec/zcl/definition/enums.d.ts +0 -1
  121. package/dist/zspec/zcl/definition/enums.d.ts.map +1 -1
  122. package/dist/zspec/zcl/definition/enums.js +0 -1
  123. package/dist/zspec/zcl/definition/enums.js.map +1 -1
  124. package/dist/zspec/zcl/definition/foundation.d.ts +306 -7
  125. package/dist/zspec/zcl/definition/foundation.d.ts.map +1 -1
  126. package/dist/zspec/zcl/definition/foundation.js +552 -207
  127. package/dist/zspec/zcl/definition/foundation.js.map +1 -1
  128. package/dist/zspec/zcl/definition/status.d.ts +21 -10
  129. package/dist/zspec/zcl/definition/status.d.ts.map +1 -1
  130. package/dist/zspec/zcl/definition/status.js +11 -0
  131. package/dist/zspec/zcl/definition/status.js.map +1 -1
  132. package/dist/zspec/zcl/definition/tstype.d.ts +57 -48
  133. package/dist/zspec/zcl/definition/tstype.d.ts.map +1 -1
  134. package/dist/zspec/zcl/utils.d.ts +7 -4
  135. package/dist/zspec/zcl/utils.d.ts.map +1 -1
  136. package/dist/zspec/zcl/utils.js +133 -240
  137. package/dist/zspec/zcl/utils.js.map +1 -1
  138. package/dist/zspec/zcl/zclFrame.d.ts +4 -4
  139. package/dist/zspec/zcl/zclFrame.d.ts.map +1 -1
  140. package/dist/zspec/zcl/zclFrame.js +19 -103
  141. package/dist/zspec/zcl/zclFrame.js.map +1 -1
  142. package/dist/zspec/zcl/zclStatusError.d.ts +1 -1
  143. package/dist/zspec/zcl/zclStatusError.d.ts.map +1 -1
  144. package/dist/zspec/zcl/zclStatusError.js +2 -2
  145. package/dist/zspec/zcl/zclStatusError.js.map +1 -1
  146. package/package.json +1 -1
  147. package/scripts/clusters-typegen.ts +44 -139
  148. package/src/adapter/adapter.ts +38 -3
  149. package/src/adapter/adapterDiscovery.ts +2 -1
  150. package/src/adapter/deconz/adapter/deconzAdapter.ts +24 -51
  151. package/src/adapter/deconz/driver/constants.ts +1 -1
  152. package/src/adapter/ember/adapter/emberAdapter.ts +23 -10
  153. package/src/adapter/ember/adapter/oneWaitress.ts +16 -6
  154. package/src/adapter/ezsp/adapter/ezspAdapter.ts +27 -48
  155. package/src/adapter/ezsp/driver/index.ts +1 -1
  156. package/src/adapter/ezsp/driver/types/index.ts +99 -99
  157. package/src/adapter/serialPort.ts +9 -0
  158. package/src/adapter/z-stack/adapter/adapter-backup.ts +1 -1
  159. package/src/adapter/z-stack/adapter/adapter-nv-memory.ts +1 -1
  160. package/src/adapter/z-stack/adapter/manager.ts +16 -2
  161. package/src/adapter/z-stack/adapter/tstype.ts +1 -0
  162. package/src/adapter/z-stack/adapter/zStackAdapter.ts +34 -81
  163. package/src/adapter/z-stack/constants/index.ts +1 -1
  164. package/src/adapter/z-stack/unpi/constants.ts +1 -1
  165. package/src/adapter/zboss/adapter/zbossAdapter.ts +23 -54
  166. package/src/adapter/zboss/driver.ts +8 -1
  167. package/src/adapter/zboss/uart.ts +14 -1
  168. package/src/adapter/zigate/adapter/zigateAdapter.ts +17 -48
  169. package/src/adapter/zoh/adapter/zohAdapter.ts +27 -50
  170. package/src/controller/controller.ts +12 -2
  171. package/src/controller/greenPower.ts +16 -9
  172. package/src/controller/helpers/ota.ts +37 -11
  173. package/src/controller/helpers/zclFrameConverter.ts +20 -17
  174. package/src/controller/model/device.ts +204 -97
  175. package/src/controller/model/endpoint.ts +36 -24
  176. package/src/controller/model/group.ts +14 -20
  177. package/src/controller/touchlink.ts +3 -3
  178. package/src/utils/timeService.ts +2 -2
  179. package/src/zspec/zcl/buffaloZcl.ts +226 -100
  180. package/src/zspec/zcl/definition/cluster.ts +2713 -2822
  181. package/src/zspec/zcl/definition/clusters-types.ts +80 -1135
  182. package/src/zspec/zcl/definition/enums.ts +0 -1
  183. package/src/zspec/zcl/definition/foundation.ts +703 -216
  184. package/src/zspec/zcl/definition/status.ts +22 -11
  185. package/src/zspec/zcl/definition/tstype.ts +59 -58
  186. package/src/zspec/zcl/utils.ts +137 -264
  187. package/src/zspec/zcl/zclFrame.ts +25 -130
  188. package/src/zspec/zcl/zclStatusError.ts +2 -2
  189. package/test/adapter/ember/emberAdapter.test.ts +191 -4
  190. package/test/adapter/ezsp/uart.test.ts +10 -10
  191. package/test/adapter/z-stack/adapter.test.ts +88 -32
  192. package/test/adapter/zoh/zohAdapter.test.ts +4 -4
  193. package/test/controller.test.ts +822 -248
  194. package/test/device-ota.test.ts +141 -16
  195. package/test/device.test.ts +731 -0
  196. package/test/requests.bench.ts +2 -0
  197. package/test/zcl.test.ts +70 -95
  198. package/test/zspec/zcl/buffalo.test.ts +251 -11
  199. package/test/zspec/zcl/foundation.test.ts +990 -0
  200. package/test/zspec/zcl/frame.test.ts +84 -69
  201. package/test/zspec/zcl/utils.test.ts +105 -81
  202. package/tsconfig.json +0 -1
  203. package/scripts/check-clusters-changes.ts +0 -328
  204. package/scripts/clusters-changes.log +0 -584
  205. package/scripts/utils.ts +0 -88
  206. package/scripts/zap-update-clusters-report.json +0 -303
  207. package/scripts/zap-update-clusters.ts +0 -1520
  208. package/scripts/zap-update-types.ts +0 -707
  209. package/scripts/zap-xml-clusters-overrides-data.ts +0 -52
  210. package/scripts/zap-xml-clusters-overrides.ts +0 -400
  211. package/scripts/zap-xml-types.ts +0 -146
@@ -1,23 +1,45 @@
1
1
  import {describe, expect, it} from "vitest";
2
2
  import * as Zcl from "../../../src/zspec/zcl";
3
3
  import {ZCL_TYPE_INVALID_BY_TYPE} from "../../../src/zspec/zcl/definition/datatypes";
4
- import type {Attribute, Command, CustomClusters, Parameter} from "../../../src/zspec/zcl/definition/tstype";
4
+ import type {Attribute, CustomClusters, Parameter} from "../../../src/zspec/zcl/definition/tstype";
5
5
 
6
6
  const CUSTOM_CLUSTERS: CustomClusters = {
7
- genBasic: {ID: Zcl.Clusters.genBasic.ID, commands: {}, commandsResponse: {}, attributes: {myCustomAttr: {ID: 65533, type: Zcl.DataType.UINT8}}},
8
- myCustomCluster: {ID: 65534, commands: {}, commandsResponse: {}, attributes: {myCustomAttr: {ID: 65533, type: Zcl.DataType.UINT8}}},
7
+ genBasic: {
8
+ name: "genBasic",
9
+ ID: Zcl.Clusters.genBasic.ID,
10
+ commands: {},
11
+ commandsResponse: {},
12
+ attributes: {myCustomAttr: {name: "myCustomAttr", ID: 65533, type: Zcl.DataType.UINT8}},
13
+ },
14
+ myCustomCluster: {
15
+ name: "myCustomCluster",
16
+ ID: 65534,
17
+ commands: {},
18
+ commandsResponse: {},
19
+ attributes: {myCustomAttr: {name: "myCustomAttr", ID: 65533, type: Zcl.DataType.UINT8}},
20
+ },
9
21
  myCustomClusterManuf: {
22
+ name: "myCustomClusterManuf",
10
23
  ID: 65533,
11
24
  manufacturerCode: 65534,
12
25
  commands: {},
13
26
  commandsResponse: {},
14
- attributes: {myCustomAttr: {ID: 65533, type: Zcl.DataType.UINT8}},
27
+ attributes: {myCustomAttr: {name: "myCustomAttr", ID: 65533, type: Zcl.DataType.UINT8}},
15
28
  },
16
- manuSpecificProfalux1NoManuf: {
17
- ID: Zcl.Clusters.manuSpecificProfalux1.ID,
29
+ myCustomWithManufAttr: {
30
+ name: "haDiagnostic",
31
+ ID: 0x0b05,
32
+ manufacturerCode: Zcl.ManufacturerCode.DANFOSS_A_S,
18
33
  commands: {},
19
34
  commandsResponse: {},
20
- attributes: {myCustomAttr: {ID: 65533, type: Zcl.DataType.UINT8}},
35
+ attributes: {
36
+ danfossSystemStatusCode: {
37
+ name: "danfossSystemStatusCode",
38
+ ID: 65530,
39
+ type: Zcl.DataType.UINT8,
40
+ manufacturerCode: Zcl.ManufacturerCode.DANFOSS_A_S,
41
+ },
42
+ },
21
43
  },
22
44
  };
23
45
 
@@ -30,12 +52,10 @@ describe("ZCL Utils", () => {
30
52
  expect(zclError.message).toStrictEqual(`Status '${Zcl.Status[Zcl.Status.ABORT]}'`);
31
53
  });
32
54
 
33
- it("Gets data type class", () => {
34
- expect(Zcl.Utils.getDataTypeClass(Zcl.DataType.UINT16)).toStrictEqual(Zcl.DataTypeClass.ANALOG);
35
- expect(Zcl.Utils.getDataTypeClass(Zcl.DataType.DATA16)).toStrictEqual(Zcl.DataTypeClass.DISCRETE);
36
- expect(() => {
37
- Zcl.Utils.getDataTypeClass(Zcl.DataType.NO_DATA);
38
- }).toThrow();
55
+ it("Checks analog data type", () => {
56
+ expect(Zcl.Utils.isAnalogDataType(Zcl.DataType.UINT16)).toStrictEqual(true);
57
+ expect(Zcl.Utils.isAnalogDataType(Zcl.DataType.DATA16)).toStrictEqual(false);
58
+ expect(Zcl.Utils.isAnalogDataType(Zcl.DataType.NO_DATA)).toStrictEqual(false);
39
59
  });
40
60
 
41
61
  it.each([
@@ -52,13 +72,17 @@ describe("ZCL Utils", () => {
52
72
  ],
53
73
  [
54
74
  "by ID with non-matching manufacturer code",
55
- {key: Zcl.Clusters.manuSpecificSinope.ID, manufacturerCode: 123, customClusters: {}},
56
- {cluster: Zcl.Clusters.manuSpecificSinope, name: "manuSpecificSinope"},
75
+ {key: Zcl.Clusters.manuSpecificAmazonWWAH.ID, manufacturerCode: 123, customClusters: {}},
76
+ {cluster: Zcl.Clusters.manuSpecificAmazonWWAH, name: "manuSpecificAmazonWWAH"},
57
77
  ],
58
78
  [
59
79
  "by ID with matching manufacturer code",
60
- {key: Zcl.Clusters.manuSpecificSinope.ID, manufacturerCode: Zcl.Clusters.manuSpecificSinope.manufacturerCode!, customClusters: {}},
61
- {cluster: Zcl.Clusters.manuSpecificSinope, name: "manuSpecificSinope"},
80
+ {
81
+ key: Zcl.Clusters.manuSpecificAmazonWWAH.ID,
82
+ manufacturerCode: Zcl.Clusters.manuSpecificAmazonWWAH.manufacturerCode!,
83
+ customClusters: {},
84
+ },
85
+ {cluster: Zcl.Clusters.manuSpecificAmazonWWAH, name: "manuSpecificAmazonWWAH"},
62
86
  ],
63
87
  [
64
88
  "custom by ID",
@@ -94,15 +118,6 @@ describe("ZCL Utils", () => {
94
118
  {key: CUSTOM_CLUSTERS.genBasic.ID, manufacturerCode: undefined, customClusters: CUSTOM_CLUSTERS},
95
119
  {cluster: CUSTOM_CLUSTERS.genBasic, name: "genBasic"},
96
120
  ],
97
- [
98
- "by ID ignoring same custom ID if Zcl is better match with manufacturer code",
99
- {
100
- key: CUSTOM_CLUSTERS.manuSpecificProfalux1NoManuf.ID,
101
- manufacturerCode: Zcl.ManufacturerCode.PROFALUX,
102
- customClusters: CUSTOM_CLUSTERS,
103
- },
104
- {cluster: Zcl.Clusters.manuSpecificProfalux1, name: "manuSpecificProfalux1"},
105
- ],
106
121
  ])("Gets cluster %s", (_name, payload, expected) => {
107
122
  const cluster = Zcl.Utils.getCluster(payload.key, payload.manufacturerCode, payload.customClusters);
108
123
 
@@ -115,9 +130,6 @@ describe("ZCL Utils", () => {
115
130
  }
116
131
 
117
132
  expect(cluster.manufacturerCode).toStrictEqual(expected.cluster.manufacturerCode);
118
- expect(cluster.getAttribute).toBeInstanceOf(Function);
119
- expect(cluster.getCommand).toBeInstanceOf(Function);
120
- expect(cluster.getCommandResponse).toBeInstanceOf(Function);
121
133
  });
122
134
 
123
135
  it("Creates empty cluster when getting by invalid ID", () => {
@@ -128,9 +140,6 @@ describe("ZCL Utils", () => {
128
140
  expect(cluster.attributes).toStrictEqual({});
129
141
  expect(cluster.commands).toStrictEqual({});
130
142
  expect(cluster.commandsResponse).toStrictEqual({});
131
- expect(cluster.getAttribute).toBeInstanceOf(Function);
132
- expect(cluster.getCommand).toBeInstanceOf(Function);
133
- expect(cluster.getCommandResponse).toBeInstanceOf(Function);
134
143
  });
135
144
 
136
145
  it("Throws when getting invalid cluster name", () => {
@@ -154,9 +163,9 @@ describe("ZCL Utils", () => {
154
163
  [
155
164
  "by ID with matching manufacturer code",
156
165
  {
157
- key: Zcl.Clusters.haDiagnostic.attributes.danfossSystemStatusCode.ID,
166
+ key: CUSTOM_CLUSTERS.myCustomWithManufAttr.attributes.danfossSystemStatusCode.ID,
158
167
  manufacturerCode: Zcl.ManufacturerCode.DANFOSS_A_S,
159
- customClusters: {},
168
+ customClusters: CUSTOM_CLUSTERS,
160
169
  },
161
170
  {cluster: Zcl.Clusters.haDiagnostic, name: "danfossSystemStatusCode"},
162
171
  ],
@@ -172,20 +181,22 @@ describe("ZCL Utils", () => {
172
181
  ],
173
182
  ])("Gets and checks cluster attribute %s", (_name, payload, expected) => {
174
183
  const cluster = Zcl.Utils.getCluster(expected.cluster.ID, payload.manufacturerCode, payload.customClusters);
175
- const attribute = cluster.getAttribute(payload.key);
184
+ const attribute = Zcl.Utils.getClusterAttribute(cluster, payload.key, payload.manufacturerCode);
176
185
  expect(attribute).not.toBeUndefined();
177
186
  expect(attribute).toStrictEqual(cluster.attributes[expected.name]);
178
187
  });
179
188
 
180
189
  it("Returns undefined when getting invalid attribute", () => {
181
190
  const cluster = Zcl.Utils.getCluster(Zcl.Clusters.genAlarms.ID, undefined, {});
182
- expect(cluster.getAttribute("abcd")).toBeUndefined();
183
- expect(cluster.getAttribute(99999)).toBeUndefined();
191
+ expect(Zcl.Utils.getClusterAttribute(cluster, "abcd", undefined)).toBeUndefined();
192
+ expect(Zcl.Utils.getClusterAttribute(cluster, 99999, undefined)).toBeUndefined();
184
193
  });
185
194
 
186
195
  it("Returns undefined when getting attribute with invalid manufacturer code", () => {
187
- const cluster = Zcl.Utils.getCluster(Zcl.Clusters.haDiagnostic.ID, 123, {});
188
- expect(cluster.getAttribute(Zcl.Clusters.haDiagnostic.attributes.danfossSystemStatusCode.ID)).toBeUndefined();
196
+ const cluster = Zcl.Utils.getCluster(Zcl.Clusters.haDiagnostic.ID, 123, CUSTOM_CLUSTERS);
197
+ expect(
198
+ Zcl.Utils.getClusterAttribute(cluster, CUSTOM_CLUSTERS.myCustomWithManufAttr.attributes.danfossSystemStatusCode.ID, 123),
199
+ ).toBeUndefined();
189
200
  });
190
201
 
191
202
  it.each([
@@ -193,17 +204,17 @@ describe("ZCL Utils", () => {
193
204
  ["by name", {key: "resetAll"}, {cluster: Zcl.Clusters.genAlarms, name: "resetAll"}],
194
205
  ])("Gets cluster command %s", (_name, payload, expected) => {
195
206
  const cluster = Zcl.Utils.getCluster(expected.cluster.ID, undefined, {});
196
- const command = cluster.getCommand(payload.key);
207
+ const command = Zcl.Utils.getClusterCommand(cluster, payload.key);
197
208
  expect(command).toStrictEqual(cluster.commands[expected.name]);
198
209
  });
199
210
 
200
211
  it("Throws when getting invalid command", () => {
201
212
  const cluster = Zcl.Utils.getCluster(Zcl.Clusters.genAlarms.ID, undefined, {});
202
213
  expect(() => {
203
- cluster.getCommand("abcd");
214
+ Zcl.Utils.getClusterCommand(cluster, "abcd");
204
215
  }).toThrow();
205
216
  expect(() => {
206
- cluster.getCommand(99999);
217
+ Zcl.Utils.getClusterCommand(cluster, 99999);
207
218
  }).toThrow();
208
219
  });
209
220
 
@@ -213,20 +224,20 @@ describe("ZCL Utils", () => {
213
224
  {key: Zcl.Clusters.genIdentify.commandsResponse.identifyQueryRsp.ID},
214
225
  {cluster: Zcl.Clusters.genIdentify, name: "identifyQueryRsp"},
215
226
  ],
216
- ["by name", {key: "getEventLog"}, {cluster: Zcl.Clusters.genAlarms, name: "getEventLog"}],
227
+ ["by name", {key: "getRsp"}, {cluster: Zcl.Clusters.genAlarms, name: "getRsp"}],
217
228
  ])("Gets cluster command response %s", (_name, payload, expected) => {
218
229
  const cluster = Zcl.Utils.getCluster(expected.cluster.ID, undefined, {});
219
- const commandResponse = cluster.getCommandResponse(payload.key);
230
+ const commandResponse = Zcl.Utils.getClusterCommandResponse(cluster, payload.key);
220
231
  expect(commandResponse).toStrictEqual(cluster.commandsResponse[expected.name]);
221
232
  });
222
233
 
223
234
  it("Throws when getting invalid command response", () => {
224
235
  const cluster = Zcl.Utils.getCluster(Zcl.Clusters.genAlarms.ID, undefined, {});
225
236
  expect(() => {
226
- cluster.getCommandResponse("abcd");
237
+ Zcl.Utils.getClusterCommandResponse(cluster, "abcd");
227
238
  }).toThrow();
228
239
  expect(() => {
229
- cluster.getCommandResponse(99999);
240
+ Zcl.Utils.getClusterCommandResponse(cluster, 99999);
230
241
  }).toThrow();
231
242
  });
232
243
 
@@ -234,17 +245,22 @@ describe("ZCL Utils", () => {
234
245
  ["by ID", {key: Zcl.Foundation.writeUndiv.ID}, {cluster: Zcl.Foundation.writeUndiv, name: "writeUndiv"}],
235
246
  ["by name", {key: "read"}, {cluster: Zcl.Foundation.read, name: "read"}],
236
247
  ])("Gets global command %s", (_name, payload, expected) => {
237
- const command: Command = {
238
- ID: expected.cluster.ID,
239
- name: expected.name,
240
- parameters: expected.cluster.parameters,
241
- };
242
-
243
- if (expected.cluster.response) {
244
- command.response = expected.cluster.response;
245
- }
246
-
247
- expect(Zcl.Utils.getGlobalCommand(payload.key)).toStrictEqual(command);
248
+ expect(Zcl.Utils.getGlobalCommand(payload.key)).toMatchObject(
249
+ "response" in expected.cluster
250
+ ? {
251
+ ID: expected.cluster.ID,
252
+ name: expected.name,
253
+ response: expected.cluster.response,
254
+ parse: expect.any(Function),
255
+ write: expect.any(Function),
256
+ }
257
+ : {
258
+ ID: expected.cluster.ID,
259
+ name: expected.name,
260
+ parse: expect.any(Function),
261
+ write: expect.any(Function),
262
+ },
263
+ );
248
264
  });
249
265
 
250
266
  it("Throws when getting invalid global command", () => {
@@ -264,12 +280,16 @@ describe("ZCL Utils", () => {
264
280
 
265
281
  it("Gets Foundation command", () => {
266
282
  expect(Zcl.Utils.getFoundationCommand(0)).toStrictEqual(Zcl.Foundation.read);
283
+ expect(Zcl.Utils.getFoundationCommandByName("read")).toStrictEqual(Zcl.Foundation.read);
267
284
  });
268
285
 
269
286
  it("Throws when getting invalid Foundation command ID", () => {
270
287
  expect(() => {
271
288
  Zcl.Utils.getFoundationCommand(9999);
272
- }).toThrow(`Foundation command '9999' does not exist.`);
289
+ }).toThrow(`Status 'UNSUP_COMMAND' foundation:9999`);
290
+ expect(() => {
291
+ Zcl.Utils.getFoundationCommandByName("doesnotexist");
292
+ }).toThrow(`Status 'UNSUP_COMMAND' foundation:doesnotexist`);
273
293
  });
274
294
 
275
295
  function createAttribute(overrides: Partial<Attribute> = {}): Attribute {
@@ -327,24 +347,26 @@ describe("ZCL Utils", () => {
327
347
 
328
348
  it("level control for lighting attributes currentLevel and options", () => {
329
349
  const cluster = Zcl.Utils.getCluster("genLevelCtrl");
330
- let result = Zcl.Utils.processAttributeWrite(cluster.getAttribute("options")!, 0x00);
350
+ let result = Zcl.Utils.processAttributeWrite(Zcl.Utils.getClusterAttribute(cluster, "options", undefined)!, 0x00);
331
351
  expect(result).toStrictEqual(0x00);
332
- result = Zcl.Utils.processAttributeWrite(cluster.getAttribute("options")!, 0xff);
352
+ result = Zcl.Utils.processAttributeWrite(Zcl.Utils.getClusterAttribute(cluster, "options", undefined)!, 0xff);
333
353
  expect(result).toStrictEqual(0xff);
334
- expect(() => Zcl.Utils.processAttributeWrite(cluster.getAttribute("currentLevel")!, 0x01)).toThrow(/not writable/i);
354
+ expect(() => Zcl.Utils.processAttributeWrite(Zcl.Utils.getClusterAttribute(cluster, "currentLevel", undefined)!, 0x01)).toThrow(
355
+ /not writable/i,
356
+ );
335
357
  });
336
358
 
337
359
  it("rssi location attributes coordinate1 and pathLossExponent", () => {
338
360
  const cluster = Zcl.Utils.getCluster("genRssiLocation");
339
- let result = Zcl.Utils.processAttributeWrite(cluster.getAttribute("coordinate1")!, -0x8000);
361
+ let result = Zcl.Utils.processAttributeWrite(Zcl.Utils.getClusterAttribute(cluster, "coordinate1", undefined)!, -0x8000);
340
362
  expect(result).toStrictEqual(-0x8000);
341
- result = Zcl.Utils.processAttributeWrite(cluster.getAttribute("coordinate1")!, 0x7fff);
363
+ result = Zcl.Utils.processAttributeWrite(Zcl.Utils.getClusterAttribute(cluster, "coordinate1", undefined)!, 0x7fff);
342
364
  expect(result).toStrictEqual(0x7fff);
343
- result = Zcl.Utils.processAttributeWrite(cluster.getAttribute("coordinate1")!, 0x0012);
365
+ result = Zcl.Utils.processAttributeWrite(Zcl.Utils.getClusterAttribute(cluster, "coordinate1", undefined)!, 0x0012);
344
366
  expect(result).toStrictEqual(0x0012);
345
- result = Zcl.Utils.processAttributeWrite(cluster.getAttribute("pathLossExponent")!, 0xff);
367
+ result = Zcl.Utils.processAttributeWrite(Zcl.Utils.getClusterAttribute(cluster, "pathLossExponent", undefined)!, 0xff);
346
368
  expect(result).toStrictEqual(0xff);
347
- result = Zcl.Utils.processAttributeWrite(cluster.getAttribute("pathLossExponent")!, Number.NaN);
369
+ result = Zcl.Utils.processAttributeWrite(Zcl.Utils.getClusterAttribute(cluster, "pathLossExponent", undefined)!, Number.NaN);
348
370
  expect(result).toStrictEqual(0xffff);
349
371
  });
350
372
  });
@@ -405,39 +427,41 @@ describe("ZCL Utils", () => {
405
427
  it("basic attributes zclVersion and powerSource", () => {
406
428
  const cluster = Zcl.Utils.getCluster("genBasic");
407
429
  // max: 0xff
408
- let result = Zcl.Utils.processAttributePostRead(cluster.getAttribute("zclVersion")!, 0xff);
430
+ let result = Zcl.Utils.processAttributePostRead(Zcl.Utils.getClusterAttribute(cluster, "zclVersion", undefined)!, 0xff);
409
431
  expect(result).toStrictEqual(0xff);
410
432
  // default: 0xff
411
- result = Zcl.Utils.processAttributePostRead(cluster.getAttribute("powerSource")!, 0xff);
433
+ result = Zcl.Utils.processAttributePostRead(Zcl.Utils.getClusterAttribute(cluster, "powerSource", undefined)!, 0xff);
412
434
  expect(result).toStrictEqual(0xff);
413
- result = Zcl.Utils.processAttributePostRead(cluster.getAttribute("zclVersion")!, 0x02);
435
+ result = Zcl.Utils.processAttributePostRead(Zcl.Utils.getClusterAttribute(cluster, "zclVersion", undefined)!, 0x02);
414
436
  expect(result).toStrictEqual(0x02);
415
- result = Zcl.Utils.processAttributePostRead(cluster.getAttribute("powerSource")!, 0x03);
437
+ result = Zcl.Utils.processAttributePostRead(Zcl.Utils.getClusterAttribute(cluster, "powerSource", undefined)!, 0x03);
416
438
  expect(result).toStrictEqual(0x03);
417
439
  });
418
440
 
419
441
  it("device temperature config attribute currentTemperature", () => {
420
442
  const cluster = Zcl.Utils.getCluster("genDeviceTempCfg");
421
- let result = Zcl.Utils.processAttributePostRead(cluster.getAttribute("currentTemperature")!, -32768);
443
+ let result = Zcl.Utils.processAttributePostRead(Zcl.Utils.getClusterAttribute(cluster, "currentTemperature", undefined)!, -32768);
422
444
  expect(Number.isNaN(result)).toStrictEqual(true);
423
- result = Zcl.Utils.processAttributePostRead(cluster.getAttribute("currentTemperature")!, 200);
445
+ result = Zcl.Utils.processAttributePostRead(Zcl.Utils.getClusterAttribute(cluster, "currentTemperature", undefined)!, 200);
424
446
  expect(result).toStrictEqual(200);
425
- result = Zcl.Utils.processAttributePostRead(cluster.getAttribute("currentTemperature")!, -200);
447
+ result = Zcl.Utils.processAttributePostRead(Zcl.Utils.getClusterAttribute(cluster, "currentTemperature", undefined)!, -200);
426
448
  expect(result).toStrictEqual(-200);
427
- expect(() => Zcl.Utils.processAttributePostRead(cluster.getAttribute("currentTemperature")!, 201)).toThrow(/requires max/i);
449
+ expect(() => Zcl.Utils.processAttributePostRead(Zcl.Utils.getClusterAttribute(cluster, "currentTemperature", undefined)!, 201)).toThrow(
450
+ /requires max/i,
451
+ );
428
452
  });
429
453
 
430
454
  it("level control for lighting attributes currentLevel and options", () => {
431
455
  const cluster = Zcl.Utils.getCluster("genLevelCtrl");
432
- let result = Zcl.Utils.processAttributePostRead(cluster.getAttribute("currentLevel")!, 0xff);
456
+ let result = Zcl.Utils.processAttributePostRead(Zcl.Utils.getClusterAttribute(cluster, "currentLevel", undefined)!, 0xff);
433
457
  expect(Number.isNaN(result)).toStrictEqual(false); // technically should be true for genLevelCtrlForLighting but handling left to ZHC
434
- result = Zcl.Utils.processAttributePostRead(cluster.getAttribute("currentLevel")!, 0xfe);
458
+ result = Zcl.Utils.processAttributePostRead(Zcl.Utils.getClusterAttribute(cluster, "currentLevel", undefined)!, 0xfe);
435
459
  expect(result).toStrictEqual(0xfe);
436
- result = Zcl.Utils.processAttributePostRead(cluster.getAttribute("currentLevel")!, 200);
460
+ result = Zcl.Utils.processAttributePostRead(Zcl.Utils.getClusterAttribute(cluster, "currentLevel", undefined)!, 200);
437
461
  expect(result).toStrictEqual(200);
438
- result = Zcl.Utils.processAttributePostRead(cluster.getAttribute("options")!, 0x00);
462
+ result = Zcl.Utils.processAttributePostRead(Zcl.Utils.getClusterAttribute(cluster, "options", undefined)!, 0x00);
439
463
  expect(result).toStrictEqual(0x00);
440
- result = Zcl.Utils.processAttributePostRead(cluster.getAttribute("options")!, 0xff);
464
+ result = Zcl.Utils.processAttributePostRead(Zcl.Utils.getClusterAttribute(cluster, "options", undefined)!, 0xff);
441
465
  expect(result).toStrictEqual(0xff);
442
466
  });
443
467
  });
@@ -453,7 +477,7 @@ describe("ZCL Utils", () => {
453
477
 
454
478
  it("rssi location cmd setAbsolute parameters coordinate1 and pathLossExponent", () => {
455
479
  const cluster = Zcl.Utils.getCluster("genRssiLocation");
456
- const cmd = cluster.getCommand("setAbsolute")!;
480
+ const cmd = Zcl.Utils.getClusterCommand(cluster, "setAbsolute")!;
457
481
  const paramCoordinate1 = cmd.parameters.find((p) => p.name === "coordinate1")!;
458
482
  const paramPathLossExponent = cmd.parameters.find((p) => p.name === "pathLossExponent")!;
459
483
  let result = Zcl.Utils.processParameterWrite(paramCoordinate1, -0x8000);
@@ -517,7 +541,7 @@ describe("ZCL Utils", () => {
517
541
 
518
542
  it("rssi location cmd rsp locationDataNotification parameters coordinate1 and pathLossExponent", () => {
519
543
  const cluster = Zcl.Utils.getCluster("genRssiLocation");
520
- const cmd = cluster.getCommandResponse("locationDataNotification")!;
544
+ const cmd = Zcl.Utils.getClusterCommandResponse(cluster, "locationDataNotification")!;
521
545
  const paramCoordinate1 = cmd.parameters.find((p) => p.name === "coordinate1")!;
522
546
  const paramPathLossExponent = cmd.parameters.find((p) => p.name === "pathLossExponent")!;
523
547
  let result = Zcl.Utils.processParameterRead(paramCoordinate1, -0x8000);
package/tsconfig.json CHANGED
@@ -12,7 +12,6 @@
12
12
  "declaration": true,
13
13
  "declarationMap": true,
14
14
  "outDir": "dist",
15
- "baseUrl": ".",
16
15
  "resolveJsonModule": true,
17
16
  "incremental": true,
18
17
  "composite": true,