@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
@@ -6,6 +6,7 @@ import {BroadcastAddress} from "../../zspec/enums";
6
6
  import type {Eui64} from "../../zspec/tstypes";
7
7
  import * as Zcl from "../../zspec/zcl";
8
8
  import type {TFoundation} from "../../zspec/zcl/definition/clusters-types";
9
+ import type {FoundationDefinition} from "../../zspec/zcl/definition/foundation";
9
10
  import type * as ZclTypes from "../../zspec/zcl/definition/tstype";
10
11
  import * as Zdo from "../../zspec/zdo";
11
12
  import Request from "../helpers/request";
@@ -67,7 +68,7 @@ interface OptionsWithDefaults extends Options {
67
68
  writeUndiv: boolean;
68
69
  }
69
70
 
70
- interface Clusters {
71
+ export interface Clusters {
71
72
  [cluster: string]: {
72
73
  attributes: {[attribute: string]: number | string};
73
74
  };
@@ -142,7 +143,7 @@ export class Endpoint extends ZigbeeEntity {
142
143
 
143
144
  return this._configuredReportings.map((entry, index) => {
144
145
  const cluster = Zcl.Utils.getCluster(entry.cluster, entry.manufacturerCode, device.customClusters);
145
- const attribute: ZclTypes.Attribute = cluster.getAttribute(entry.attrId) ?? {
146
+ const attribute: ZclTypes.Attribute = Zcl.Utils.getClusterAttribute(cluster, entry.attrId, entry.manufacturerCode) ?? {
146
147
  ID: entry.attrId,
147
148
  name: `attr${index}`,
148
149
  type: Zcl.DataType.UNKNOWN,
@@ -227,18 +228,14 @@ export class Endpoint extends ZigbeeEntity {
227
228
  * @returns {ZclTypes.Cluster[]}
228
229
  */
229
230
  public getInputClusters(): ZclTypes.Cluster[] {
230
- return this.clusterNumbersToClusters(this.inputClusters);
231
+ return this.inputClusters.map((c) => this.getCluster(c));
231
232
  }
232
233
 
233
234
  /**
234
235
  * @returns {ZclTypes.Cluster[]}
235
236
  */
236
237
  public getOutputClusters(): ZclTypes.Cluster[] {
237
- return this.clusterNumbersToClusters(this.outputClusters);
238
- }
239
-
240
- private clusterNumbersToClusters(clusterNumbers: number[]): ZclTypes.Cluster[] {
241
- return clusterNumbers.map((c) => this.getCluster(c));
238
+ return this.outputClusters.map((c) => this.getCluster(c));
242
239
  }
243
240
 
244
241
  /*
@@ -332,7 +329,7 @@ export class Endpoint extends ZigbeeEntity {
332
329
 
333
330
  if (this.clusters[cluster.name] && this.clusters[cluster.name].attributes) {
334
331
  // XXX: used to throw (behavior changed in #1455)
335
- const attribute = cluster.getAttribute(attributeKey);
332
+ const attribute = Zcl.Utils.getClusterAttribute(cluster, attributeKey, undefined);
336
333
 
337
334
  if (attribute) {
338
335
  return this.clusters[cluster.name].attributes[attribute.name];
@@ -477,7 +474,7 @@ export class Endpoint extends ZigbeeEntity {
477
474
  // TODO: handle `attr.report !== true`
478
475
 
479
476
  for (const nameOrID in attributes) {
480
- const attribute = cluster.getAttribute(nameOrID);
477
+ const attribute = Zcl.Utils.getClusterAttribute(cluster, nameOrID, options?.manufacturerCode);
481
478
 
482
479
  if (attribute) {
483
480
  payload.push({attrId: attribute.ID, attrData: attributes[nameOrID], dataType: attribute.type});
@@ -509,7 +506,7 @@ export class Endpoint extends ZigbeeEntity {
509
506
  const payload: TFoundation["write"] = [];
510
507
 
511
508
  for (const nameOrID in attributes) {
512
- const attribute = cluster.getAttribute(nameOrID);
509
+ const attribute = Zcl.Utils.getClusterAttribute(cluster, nameOrID, options?.manufacturerCode);
513
510
 
514
511
  if (attribute) {
515
512
  // TODO: handle `attr.writeOptional !== true`
@@ -544,7 +541,7 @@ export class Endpoint extends ZigbeeEntity {
544
541
  const value = attributes[nameOrID]!;
545
542
 
546
543
  if (value.status !== undefined) {
547
- const attribute = cluster.getAttribute(nameOrID);
544
+ const attribute = Zcl.Utils.getClusterAttribute(cluster, nameOrID, options?.manufacturerCode);
548
545
 
549
546
  if (attribute) {
550
547
  payload.push({attrId: attribute.ID, status: value.status});
@@ -590,7 +587,7 @@ export class Endpoint extends ZigbeeEntity {
590
587
  if (typeof attribute === "number") {
591
588
  payload.push({attrId: attribute});
592
589
  } else {
593
- const attr = cluster.getAttribute(attribute);
590
+ const attr = Zcl.Utils.getClusterAttribute(cluster, attribute, options?.manufacturerCode);
594
591
 
595
592
  if (attr) {
596
593
  Zcl.Utils.processAttributePreRead(attr);
@@ -609,6 +606,10 @@ export class Endpoint extends ZigbeeEntity {
609
606
  : ({} as ClusterOrRawWriteAttributes<Cl, Custom>);
610
607
  }
611
608
 
609
+ /**
610
+ * Sends a Foundation response to a read request.
611
+ * Any attribute with an `undefined` value will result in a sent record with status `UNSUPPORTED_ATTRIBUTE`
612
+ */
612
613
  public async readResponse<Cl extends number | string, Custom extends TCustomCluster | undefined = undefined>(
613
614
  clusterKey: Cl,
614
615
  transactionSequenceNumber: number,
@@ -621,14 +622,25 @@ export class Endpoint extends ZigbeeEntity {
621
622
  const payload: TFoundation["readRsp"] = [];
622
623
 
623
624
  for (const nameOrID in attributes) {
624
- const attribute = cluster.getAttribute(nameOrID);
625
+ const attribute = Zcl.Utils.getClusterAttribute(cluster, nameOrID, options?.manufacturerCode);
625
626
 
626
627
  if (attribute) {
627
- payload.push({attrId: attribute.ID, attrData: attributes[nameOrID], dataType: attribute.type, status: 0});
628
+ const attrData = attributes[nameOrID];
629
+
630
+ if (attrData === undefined) {
631
+ payload.push({attrId: attribute.ID, status: Zcl.Status.UNSUPPORTED_ATTRIBUTE});
632
+ } else {
633
+ payload.push({attrId: attribute.ID, attrData, dataType: attribute.type, status: Zcl.Status.SUCCESS});
634
+ }
628
635
  } else if (!Number.isNaN(Number(nameOrID))) {
629
636
  const value = attributes[nameOrID];
637
+ const attrData = value.value;
630
638
 
631
- payload.push({attrId: Number(nameOrID), attrData: value.value, dataType: value.type, status: 0});
639
+ if (attrData === undefined) {
640
+ payload.push({attrId: Number(nameOrID), status: Zcl.Status.UNSUPPORTED_ATTRIBUTE});
641
+ } else {
642
+ payload.push({attrId: Number(nameOrID), attrData, dataType: value.type, status: Zcl.Status.SUCCESS});
643
+ }
632
644
  } else {
633
645
  throw new Error(`Unknown attribute '${nameOrID}', specify either an existing attribute or a number`);
634
646
  }
@@ -638,7 +650,7 @@ export class Endpoint extends ZigbeeEntity {
638
650
  cluster,
639
651
  "readRsp",
640
652
  payload,
641
- {direction: Zcl.Direction.SERVER_TO_CLIENT, ...options, transactionSequenceNumber},
653
+ {direction: Zcl.Direction.SERVER_TO_CLIENT, disableDefaultResponse: true, ...options, transactionSequenceNumber},
642
654
  attributes,
643
655
  );
644
656
  }
@@ -849,7 +861,7 @@ export class Endpoint extends ZigbeeEntity {
849
861
  dataType = item.attribute.type;
850
862
  attrId = item.attribute.ID;
851
863
  } else {
852
- const attribute = cluster.getAttribute(item.attribute);
864
+ const attribute = Zcl.Utils.getClusterAttribute(cluster, item.attribute, optionsWithDefaults.manufacturerCode);
853
865
 
854
866
  if (attribute) {
855
867
  dataType = attribute.type;
@@ -919,7 +931,7 @@ export class Endpoint extends ZigbeeEntity {
919
931
  if (typeof item.attribute === "object") {
920
932
  payload.push({direction: item.direction ?? Zcl.Direction.CLIENT_TO_SERVER, attrId: item.attribute.ID});
921
933
  } else {
922
- const attribute = cluster.getAttribute(item.attribute);
934
+ const attribute = Zcl.Utils.getClusterAttribute(cluster, item.attribute, optionsWithDefaults.manufacturerCode);
923
935
 
924
936
  if (attribute) {
925
937
  payload.push({direction: item.direction ?? Zcl.Direction.CLIENT_TO_SERVER, attrId: attribute.ID});
@@ -974,7 +986,7 @@ export class Endpoint extends ZigbeeEntity {
974
986
 
975
987
  const device = this.getDevice();
976
988
  const cluster = this.getCluster(clusterKey, device, options?.manufacturerCode);
977
- const command = cluster.getCommandResponse(commandKey);
989
+ const command = Zcl.Utils.getClusterCommandResponse(cluster, commandKey);
978
990
  transactionSequenceNumber = transactionSequenceNumber ?? zclTransactionSequenceNumber.next();
979
991
  const optionsWithDefaults = this.getOptionsWithDefaults(options, true, Zcl.Direction.SERVER_TO_CLIENT, cluster.manufacturerCode);
980
992
 
@@ -1067,7 +1079,7 @@ export class Endpoint extends ZigbeeEntity {
1067
1079
  }
1068
1080
 
1069
1081
  // we fall back to caller|cluster provided manufacturerCode
1070
- const attribute = cluster.getAttribute(attributeID);
1082
+ const attribute = Zcl.Utils.getClusterAttribute(cluster, attributeID, undefined);
1071
1083
  const manufacturerCode = attribute
1072
1084
  ? attribute.manufacturerCode === undefined
1073
1085
  ? fallbackManufacturerCode
@@ -1138,7 +1150,7 @@ export class Endpoint extends ZigbeeEntity {
1138
1150
 
1139
1151
  public async zclCommand<Cl extends number | string, Co extends number | string, Custom extends TCustomCluster | undefined = undefined>(
1140
1152
  clusterKey: Cl | ZclTypes.Cluster,
1141
- commandKey: Co | ZclTypes.Command,
1153
+ commandKey: Co | ZclTypes.Command | FoundationDefinition,
1142
1154
  payload: ClusterOrRawPayload<Cl, Co, Custom> | FoundationOrRawPayload<Co>,
1143
1155
  options?: Options,
1144
1156
  logPayload?: KeyValue,
@@ -1152,7 +1164,7 @@ export class Endpoint extends ZigbeeEntity {
1152
1164
  ? commandKey
1153
1165
  : frameType === Zcl.FrameType.GLOBAL
1154
1166
  ? Zcl.Utils.getGlobalCommand(commandKey)
1155
- : cluster.getCommand(commandKey);
1167
+ : Zcl.Utils.getClusterCommand(cluster, commandKey);
1156
1168
  const hasResponse = frameType === Zcl.FrameType.GLOBAL ? true : command.response !== undefined;
1157
1169
  const optionsWithDefaults = this.getOptionsWithDefaults(options, hasResponse, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
1158
1170
 
@@ -1203,7 +1215,7 @@ export class Endpoint extends ZigbeeEntity {
1203
1215
  ): Promise<void> {
1204
1216
  const device = this.getDevice();
1205
1217
  const cluster = this.getCluster(clusterKey, device, options?.manufacturerCode);
1206
- const command = cluster.getCommand(commandKey);
1218
+ const command = Zcl.Utils.getClusterCommand(cluster, commandKey);
1207
1219
  const optionsWithDefaults = this.getOptionsWithDefaults(options, true, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
1208
1220
  const sourceEndpoint = optionsWithDefaults.srcEndpoint ?? this.ID;
1209
1221
 
@@ -44,7 +44,6 @@ export class Group extends ZigbeeEntity {
44
44
  // This lookup contains all groups that are queried from the database, this is to ensure that always
45
45
  // the same instance is returned.
46
46
  private static readonly groups: Map<number, Map<number, Group>> = new Map();
47
- private static loadedFromDatabase = false;
48
47
 
49
48
  /** Member endpoints with valid devices (not unknown/deleted) */
50
49
  get members(): Endpoint[] {
@@ -75,7 +74,6 @@ export class Group extends ZigbeeEntity {
75
74
  */
76
75
  public static resetCache(): void {
77
76
  Group.groups.clear();
78
- Group.loadedFromDatabase = false;
79
77
  }
80
78
 
81
79
  private static fromDatabaseEntry(entry: DatabaseEntry, databaseID: number): Group {
@@ -112,20 +110,16 @@ export class Group extends ZigbeeEntity {
112
110
  }
113
111
 
114
112
  private static loadFromDatabaseIfNecessary(): void {
115
- if (!Group.loadedFromDatabase) {
116
- Entity.databases.forEach(database => {
117
- if (!Group.groups.get(database.id)) {
118
- Group.groups.set(database.id, new Map());
119
- }
120
- const entries = database.getEntriesIterator(['Group']);
121
- for (const entry of entries) {
122
- const group = Group.fromDatabaseEntry(entry, database.id);
123
- Group.groups.get(database.id)?.set(group.groupID, group);
124
- }
125
- });
126
-
127
- Group.loadedFromDatabase = true;
128
- }
113
+ Entity.databases.forEach(database => {
114
+ if (!Group.groups.get(database.id)) {
115
+ Group.groups.set(database.id, new Map());
116
+ }
117
+ const entries = database.getEntriesIterator(['Group']);
118
+ for (const entry of entries) {
119
+ const group = Group.fromDatabaseEntry(entry, database.id);
120
+ Group.groups.get(database.id)?.set(group.groupID, group);
121
+ }
122
+ });
129
123
  }
130
124
 
131
125
  public static byGroupID(groupID: number, databaseID: number): Group | undefined {
@@ -285,7 +279,7 @@ export class Group extends ZigbeeEntity {
285
279
  const payload: TFoundation["write"] = [];
286
280
 
287
281
  for (const nameOrID in attributes) {
288
- const attribute = cluster.getAttribute(nameOrID);
282
+ const attribute = Zcl.Utils.getClusterAttribute(cluster, nameOrID, options?.manufacturerCode);
289
283
 
290
284
  if (attribute) {
291
285
  const attrData = Zcl.Utils.processAttributeWrite(attribute, attributes[nameOrID]);
@@ -345,7 +339,7 @@ export class Group extends ZigbeeEntity {
345
339
  if (typeof attribute === "number") {
346
340
  payload.push({attrId: attribute});
347
341
  } else {
348
- const attr = cluster.getAttribute(attribute);
342
+ const attr = Zcl.Utils.getClusterAttribute(cluster, attribute, options?.manufacturerCode);
349
343
 
350
344
  if (attr) {
351
345
  Zcl.Utils.processAttributePreRead(attr);
@@ -396,8 +390,8 @@ export class Group extends ZigbeeEntity {
396
390
  const optionsWithDefaults = this.getOptionsWithDefaults(options, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
397
391
  const command =
398
392
  optionsWithDefaults.direction === Zcl.Direction.CLIENT_TO_SERVER
399
- ? cluster.getCommand(commandKey)
400
- : cluster.getCommandResponse(commandKey);
393
+ ? Zcl.Utils.getClusterCommand(cluster, commandKey)
394
+ : Zcl.Utils.getClusterCommandResponse(cluster, commandKey);
401
395
 
402
396
  const createLogMessage = (): string => `Command ${this.groupID} ${cluster.name}.${command.name}(${JSON.stringify(payload)})`;
403
397
  logger.debug(createLogMessage, NS);
@@ -15,7 +15,7 @@ const createScanRequestFrame = (transaction: number): Zcl.Frame =>
15
15
  undefined,
16
16
  0,
17
17
  "scanRequest",
18
- Zcl.Clusters.touchlink.ID,
18
+ "touchlink",
19
19
  {transactionID: transaction, zigbeeInformation: 4, touchlinkInformation: 18},
20
20
  {},
21
21
  );
@@ -28,7 +28,7 @@ const createIdentifyRequestFrame = (transaction: number): Zcl.Frame =>
28
28
  undefined,
29
29
  0,
30
30
  "identifyRequest",
31
- Zcl.Clusters.touchlink.ID,
31
+ "touchlink",
32
32
  {transactionID: transaction, duration: 65535},
33
33
  {},
34
34
  );
@@ -41,7 +41,7 @@ const createResetFactoryNewRequestFrame = (transaction: number): Zcl.Frame =>
41
41
  undefined,
42
42
  0,
43
43
  "resetToFactoryNew",
44
- Zcl.Clusters.touchlink.ID,
44
+ "touchlink",
45
45
  {transactionID: transaction},
46
46
  {},
47
47
  );
@@ -122,8 +122,8 @@ export function getTimeClusterAttributes(): TClusterAttributes<"genTime"> {
122
122
  dstStart: cachedTimeData.dstStart,
123
123
  dstEnd: cachedTimeData.dstEnd,
124
124
  dstShift: cachedTimeData.dstShift,
125
- standardTime: standardTime,
126
- localTime: localTime,
125
+ standardTime,
126
+ localTime,
127
127
  lastSetTime: currentZigbeeUtcTime,
128
128
  validUntilTime: cachedTimeData.validUntilTime,
129
129
  };