@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
@@ -2,7 +2,7 @@ import { Events as AdapterEvents } from '../../adapter';
2
2
  import type { Eui64 } from "../../zspec/tstypes";
3
3
  import * as Zcl from "../../zspec/zcl";
4
4
  import type { TClusterCommandPayload, TPartialClusterAttributes } from "../../zspec/zcl/definition/clusters-types";
5
- import type { ClusterDefinition, CustomClusters } from "../../zspec/zcl/definition/tstype";
5
+ import type { Cluster, CustomClusters } from "../../zspec/zcl/definition/tstype";
6
6
  import type { BindingTableEntry, LQITableEntry, RoutingTableEntry } from "../../zspec/zdo/definition/tstypes";
7
7
  import type { ControllerEventMap } from "../controller";
8
8
  import type { DeviceType, KeyValue, OtaDataSettings, OtaExtraMetas, OtaSource, OtaUpdateAvailableResult, ZigbeeOtaImageMeta } from "../tstype";
@@ -68,6 +68,7 @@ export declare class Device extends Entity<ControllerEventMap> {
68
68
  get skipDefaultResponse(): boolean;
69
69
  set skipDefaultResponse(skipDefaultResponse: boolean);
70
70
  get customReadResponse(): CustomReadResponse | undefined;
71
+ /** If the set function returns true, the default read response behavior is skipped */
71
72
  set customReadResponse(customReadResponse: CustomReadResponse | undefined);
72
73
  get checkinInterval(): number | undefined;
73
74
  set checkinInterval(checkinInterval: number | undefined);
@@ -80,10 +81,15 @@ export declare class Device extends Entity<ControllerEventMap> {
80
81
  get otaInProgress(): boolean;
81
82
  meta: KeyValue;
82
83
  private static readonly devices;
83
- private static loadedFromDatabase;
84
84
  private static readonly deletedDevices;
85
85
  private static readonly nwkToIeeeCache;
86
86
  private constructor();
87
+ /**
88
+ * Reset transient data about the device.
89
+ * @param cache If true, reset some previously cached data.
90
+ * Should be set to true when device potentially changed its internal data to prevent mismatching state/config.
91
+ */
92
+ resetTransient(cache: boolean): void;
87
93
  createEndpoint(id: number): Endpoint;
88
94
  changeIeeeAddress(ieeeAddr: string): void;
89
95
  getEndpoint(id: number): Endpoint | undefined;
@@ -93,7 +99,7 @@ export declare class Device extends Entity<ControllerEventMap> {
93
99
  updateLastSeen(): void;
94
100
  private resetPendingRequestTimeout;
95
101
  private hasPendingRequests;
96
- onZclData(dataPayload: AdapterEvents.ZclPayload, frame: Zcl.Frame, endpoint: Endpoint): Promise<void>;
102
+ onZclData(dataPayload: AdapterEvents.ZclPayload, frame: Zcl.Frame, endpoint: Endpoint, defaultResponse: Zcl.Status | undefined): Promise<void>;
97
103
  /**
98
104
  * Reset runtime lookups.
99
105
  */
@@ -136,13 +142,17 @@ export declare class Device extends Entity<ControllerEventMap> {
136
142
  */
137
143
  clearAllBindings(eui64List: Eui64[]): Promise<void>;
138
144
  ping(disableRecovery?: boolean): Promise<void>;
139
- addCustomCluster(name: string, cluster: ClusterDefinition): void;
145
+ addCustomCluster(name: string, cluster: Cluster): void;
140
146
  findMatchingOtaImage(source: OtaSource, current: TClusterCommandPayload<"genOta", "queryNextImageRequest">, extraMetas: OtaExtraMetas): Promise<ZigbeeOtaImageMeta | undefined>;
141
147
  /**
142
148
  * If `current` is undefined, will automatically notify and reply to query with `NO_IMAGE_AVAILABLE` (stops device from doing further requests).
143
149
  */
144
150
  checkOta(source: OtaSource, current: TClusterCommandPayload<"genOta", "queryNextImageRequest"> | undefined, extraMetas: OtaExtraMetas, endpoint?: Endpoint | undefined): Promise<OtaUpdateAvailableResult>;
145
151
  updateOta(source: Readonly<OtaSource> | undefined, requestPayload: TClusterCommandPayload<"genOta", "queryNextImageRequest"> | undefined, requestTsn: number | undefined, extraMetas: Readonly<OtaExtraMetas>, onProgress: (progress: number, remaining: number) => void, dataSettings: OtaDataSettings, endpoint?: Endpoint | undefined): Promise<[from: OtaUpdateAvailableResult["current"], to: OtaUpdateAvailableResult["current"] | undefined]>;
152
+ /**
153
+ * Abort running OTA if any. Send `ABORT` with next block response to device.
154
+ */
155
+ abortOta(): void;
146
156
  scheduleOta(source: OtaSource): void;
147
157
  unscheduleOta(): void;
148
158
  }
@@ -1 +1 @@
1
- {"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../../src/controller/model/device.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../../src/controller/model/device.ts"],"names":[],"mappings":"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"}
@@ -61,6 +61,10 @@ const INTERVIEW_GENBASIC_ATTRIBUTES = [
61
61
  "dateCode",
62
62
  "swBuildId",
63
63
  ];
64
+ const GEN_BASIC_CLUSTER_ID = Zcl.Clusters.genBasic.ID;
65
+ const GEN_TIME_CLUSTER_ID = Zcl.Clusters.genTime.ID;
66
+ const GEN_POLL_CTRL_CLUSTER_ID = Zcl.Clusters.genPollCtrl.ID;
67
+ const GEN_OTA_CLUSTER_ID = Zcl.Clusters.genOta.ID;
64
68
  var InterviewState;
65
69
  (function (InterviewState) {
66
70
  InterviewState["Pending"] = "PENDING";
@@ -90,6 +94,7 @@ class Device extends entity_1.default {
90
94
  _gpSecurityKey;
91
95
  #scheduledOta;
92
96
  #otaInProgress = false;
97
+ #otaAbortController;
93
98
  // Getters/setters
94
99
  get ieeeAddr() {
95
100
  return this._ieeeAddr;
@@ -209,6 +214,7 @@ class Device extends entity_1.default {
209
214
  get customReadResponse() {
210
215
  return this._customReadResponse;
211
216
  }
217
+ /** If the set function returns true, the default read response behavior is skipped */
212
218
  set customReadResponse(customReadResponse) {
213
219
  this._customReadResponse = customReadResponse;
214
220
  }
@@ -244,7 +250,6 @@ class Device extends entity_1.default {
244
250
  // This lookup contains all devices that are queried from the database, this is to ensure that always
245
251
  // the same instance is returned.
246
252
  static devices = new Map();
247
- static loadedFromDatabase = false;
248
253
  static deletedDevices = new Map();
249
254
  static nwkToIeeeCache = new Map();
250
255
  constructor(databaseID, id, type, ieeeAddr, networkAddress, manufacturerID, endpoints, manufacturerName, powerSource, modelID, applicationVersion, stackVersion, zclVersion, hardwareVersion, dateCode, softwareBuildID, interviewState, meta, lastSeen, checkinInterval, pendingRequestTimeout, gpSecurityKey, scheduledOta) {
@@ -274,6 +279,19 @@ class Device extends entity_1.default {
274
279
  this._gpSecurityKey = gpSecurityKey;
275
280
  this.#scheduledOta = scheduledOta;
276
281
  }
282
+ /**
283
+ * Reset transient data about the device.
284
+ * @param cache If true, reset some previously cached data.
285
+ * Should be set to true when device potentially changed its internal data to prevent mismatching state/config.
286
+ */
287
+ resetTransient(cache) {
288
+ this._lastDefaultResponseSequenceNumber = undefined;
289
+ if (cache) {
290
+ // force retrieving this data again
291
+ this._checkinInterval = undefined;
292
+ this._pendingRequestTimeout = 0;
293
+ }
294
+ }
277
295
  createEndpoint(id) {
278
296
  if (this.getEndpoint(id)) {
279
297
  throw new Error(`Device '${this.ieeeAddr}' already has an endpoint '${id}'`);
@@ -319,62 +337,115 @@ class Device extends entity_1.default {
319
337
  hasPendingRequests() {
320
338
  return this.endpoints.find((e) => e.hasPendingRequests()) !== undefined;
321
339
  }
322
- async onZclData(dataPayload, frame, endpoint) {
340
+ async onZclData(dataPayload, frame, endpoint, defaultResponse) {
323
341
  if (!Device.devices.get(this.databaseID)?.has(this.ieeeAddr)) {
324
342
  // prevent race conditions where device gets deleted during processing
325
343
  return;
326
344
  }
327
- if (frame.header.isGlobal) {
328
- // Response to read requests
329
- if (frame.command.name === "read" && !this._customReadResponse?.(frame, endpoint)) {
330
- const attributes = {
331
- ...endpoint.clusters,
332
- };
333
- const isTimeReadRequest = dataPayload.clusterID === Zcl.Clusters.genTime.ID;
334
- if (isTimeReadRequest) {
335
- attributes.genTime = {
336
- attributes: timeService.getTimeClusterAttributes(),
337
- };
338
- }
339
- if (frame.cluster.name in attributes) {
345
+ if (this.type === "GreenPower") {
346
+ // nothing below applies
347
+ return;
348
+ }
349
+ const { header, command, cluster } = frame;
350
+ let sendDefaultResponse = !dataPayload.wasBroadcast && command.response === undefined;
351
+ let defaultResponseStatus = defaultResponse ?? Zcl.Status.SUCCESS;
352
+ if (header.isGlobal) {
353
+ // Response to read requests from device to coordinator
354
+ switch (command.name) {
355
+ case "read": {
356
+ // NOTE: `sendDefaultResponse` always false from `command.response === 0x01`
357
+ if (this._customReadResponse?.(frame, endpoint)) {
358
+ break;
359
+ }
340
360
  const response = {};
341
- for (const entry of frame.payload) {
342
- const name = frame.cluster.getAttribute(entry.attrId)?.name;
343
- if (name && name in attributes[frame.cluster.name].attributes) {
344
- response[name] = attributes[frame.cluster.name].attributes[name];
361
+ switch (dataPayload.clusterID) {
362
+ case GEN_TIME_CLUSTER_ID: {
363
+ // relax type to index by attr name, undefined results in non-success attr record
364
+ const timeAttrs = timeService.getTimeClusterAttributes();
365
+ for (const entry of frame.payload) {
366
+ // TODO: this.manufacturerID or frame.header.manufacturerCode
367
+ const name = Zcl.Utils.getClusterAttribute(cluster, entry.attrId, this.manufacturerID)?.name;
368
+ if (name === undefined) {
369
+ // UNSUPPORTED_ATTRIBUTE
370
+ response[entry.attrId] = { value: undefined, type: Zcl.DataType.NO_DATA };
371
+ }
372
+ else {
373
+ response[name] = timeAttrs[name];
374
+ }
375
+ }
376
+ break;
377
+ }
378
+ // NOTE: can add more clusters here to use defaults from spec as needed
379
+ case GEN_BASIC_CLUSTER_ID: {
380
+ for (const entry of frame.payload) {
381
+ // TODO: this.manufacturerID or frame.header.manufacturerCode
382
+ const attr = Zcl.Utils.getClusterAttribute(cluster, entry.attrId, this.manufacturerID);
383
+ if (attr?.default === undefined) {
384
+ // UNSUPPORTED_ATTRIBUTE
385
+ response[entry.attrId] = { value: undefined, type: Zcl.DataType.NO_DATA };
386
+ }
387
+ else {
388
+ response[attr.name] = attr.default;
389
+ }
390
+ }
391
+ break;
392
+ }
393
+ default: {
394
+ for (const entry of frame.payload) {
395
+ // UNSUPPORTED_ATTRIBUTE
396
+ response[entry.attrId] = { value: undefined, type: Zcl.DataType.NO_DATA };
397
+ }
398
+ break;
345
399
  }
346
400
  }
347
401
  try {
348
- await endpoint.readResponse(frame.cluster.ID, frame.header.transactionSequenceNumber, response, {
402
+ await endpoint.readResponse(cluster.ID, header.transactionSequenceNumber, response, {
349
403
  srcEndpoint: dataPayload.destinationEndpoint,
350
404
  });
351
405
  }
352
406
  catch (error) {
353
407
  logger_1.logger.error(`Read response to ${this.ieeeAddr} failed (${error.message})`, NS);
408
+ // XXX: technically, if `readResponse` fails before reaching the network (internal to ZH), we should send a default response
409
+ // currently not possible due to implementation (no distinction as to "where" it failed)
354
410
  }
411
+ break;
412
+ }
413
+ case "defaultRsp": {
414
+ sendDefaultResponse = false; // per spec
415
+ break;
355
416
  }
356
417
  }
357
418
  }
358
- else if (frame.header.isSpecific) {
359
- switch (frame.cluster.name) {
419
+ else if (header.isSpecific) {
420
+ switch (cluster.name) {
360
421
  case "ssIasZone": {
361
- if (frame.command.name === "enrollReq") {
422
+ if (command.name === "enrollReq") {
362
423
  // Respond to enroll requests
363
424
  logger_1.logger.debug(`IAS - '${this.ieeeAddr}' responding to enroll response`, NS);
364
- await endpoint.command("ssIasZone", "enrollRsp", { enrollrspcode: 0, zoneid: 23 }, { disableDefaultResponse: true });
425
+ try {
426
+ await endpoint.command("ssIasZone", "enrollRsp", { enrollrspcode: 0, zoneid: 23 }, { transactionSequenceNumber: header.transactionSequenceNumber, disableDefaultResponse: true });
427
+ sendDefaultResponse = false; // per spec, sending a specific response TODO: no "Effect on receipt" in spec, is this correct?
428
+ }
429
+ catch (error) {
430
+ logger_1.logger.error(`Handling of IAS zone enroll for ${this.ieeeAddr} failed (${error.message})`, NS);
431
+ defaultResponseStatus = Zcl.Status.FAILURE;
432
+ }
365
433
  }
366
434
  break;
367
435
  }
368
436
  case "genPollCtrl": {
369
- if (frame.command.name === "checkin") {
437
+ if (command.name === "checkin") {
438
+ let startedFastPolling = false;
370
439
  // Handle check-in from sleeping end devices
371
440
  try {
372
441
  if (this.hasPendingRequests() || this._checkinInterval === undefined) {
373
442
  logger_1.logger.debug(`check-in from ${this.ieeeAddr}: accepting fast-poll`, NS);
374
- await endpoint.command(frame.cluster.name, "checkinRsp", {
375
- startFastPolling: 1,
376
- fastPollTimeout: 0,
377
- }, { sendPolicy: "immediate" });
443
+ await endpoint.command(cluster.name, "checkinRsp", { startFastPolling: 1, fastPollTimeout: 0 }, {
444
+ transactionSequenceNumber: header.transactionSequenceNumber,
445
+ disableDefaultResponse: true,
446
+ sendPolicy: "immediate",
447
+ });
448
+ startedFastPolling = true;
378
449
  // This is a good time to read the checkin interval if we haven't stored it previously
379
450
  if (this._checkinInterval === undefined) {
380
451
  const pollPeriod = await endpoint.read("genPollCtrl", ["checkinInterval"], { sendPolicy: "immediate" });
@@ -383,21 +454,32 @@ class Device extends entity_1.default {
383
454
  logger_1.logger.debug(`Request Queue (${this.ieeeAddr}): default expiration timeout set to ${this.pendingRequestTimeout}`, NS);
384
455
  }
385
456
  await Promise.all(this.endpoints.map(async (e) => await e.sendPendingRequests(true)));
386
- // We *must* end fast-poll when we're done sending things. Otherwise
387
- // we cause undue power-drain.
388
- logger_1.logger.debug(`check-in from ${this.ieeeAddr}: stopping fast-poll`, NS);
389
- await endpoint.command(frame.cluster.name, "fastPollStop", {}, { sendPolicy: "immediate" });
390
457
  }
391
458
  else {
392
459
  logger_1.logger.debug(`check-in from ${this.ieeeAddr}: declining fast-poll`, NS);
393
- await endpoint.command(frame.cluster.name, "checkinRsp", {
394
- startFastPolling: 0,
395
- fastPollTimeout: 0,
396
- }, { sendPolicy: "immediate" });
460
+ await endpoint.command(cluster.name, "checkinRsp", { startFastPolling: 0, fastPollTimeout: 0 }, {
461
+ transactionSequenceNumber: header.transactionSequenceNumber,
462
+ disableDefaultResponse: true,
463
+ sendPolicy: "immediate",
464
+ });
397
465
  }
466
+ sendDefaultResponse = false; // per spec, sending a specific response
398
467
  }
399
468
  catch (error) {
400
469
  logger_1.logger.error(`Handling of poll check-in from ${this.ieeeAddr} failed (${error.message})`, NS);
470
+ defaultResponseStatus = Zcl.Status.FAILURE;
471
+ }
472
+ finally {
473
+ if (startedFastPolling) {
474
+ // We *must* end fast-poll when we're done sending things. Otherwise we cause undue power-drain.
475
+ logger_1.logger.debug(`check-in from ${this.ieeeAddr}: stopping fast-poll`, NS);
476
+ try {
477
+ await endpoint.command(cluster.name, "fastPollStop", {}, { sendPolicy: "immediate" });
478
+ }
479
+ catch (error) {
480
+ logger_1.logger.error(`Failed to stop fast poll for ${this.ieeeAddr} (${error.message})`, NS);
481
+ }
482
+ }
401
483
  }
402
484
  }
403
485
  break;
@@ -405,34 +487,23 @@ class Device extends entity_1.default {
405
487
  }
406
488
  }
407
489
  // Send a default response if necessary.
408
- const isDefaultResponse = frame.header.isGlobal && frame.command.name === "defaultRsp";
409
- const commandHasResponse = frame.command.response !== undefined;
410
- const disableDefaultResponse = frame.header.frameControl.disableDefaultResponse;
411
490
  /* v8 ignore next */
412
491
  const disableTuyaDefaultResponse = this.manufacturerName?.startsWith("_TZ") && process.env.DISABLE_TUYA_DEFAULT_RESPONSE;
413
492
  // Sometimes messages are received twice, prevent responding twice
414
- const alreadyResponded = this._lastDefaultResponseSequenceNumber === frame.header.transactionSequenceNumber;
415
- if (this.type !== "GreenPower" &&
416
- !dataPayload.wasBroadcast &&
417
- !disableDefaultResponse &&
418
- !isDefaultResponse &&
419
- !commandHasResponse &&
420
- !this._skipDefaultResponse &&
493
+ const alreadyResponded = this._lastDefaultResponseSequenceNumber === header.transactionSequenceNumber;
494
+ if (!this._skipDefaultResponse &&
495
+ sendDefaultResponse &&
496
+ (!header.frameControl.disableDefaultResponse || defaultResponseStatus !== Zcl.Status.SUCCESS) &&
421
497
  !alreadyResponded &&
422
498
  !disableTuyaDefaultResponse) {
423
499
  try {
424
- this._lastDefaultResponseSequenceNumber = frame.header.transactionSequenceNumber;
425
- // In the ZCL it is not documented what the direction of the default response should be
426
- // In https://github.com/Koenkk/zigbee2mqtt/issues/18096 a commandResponse (SERVER_TO_CLIENT)
427
- // is send and the device expects a CLIENT_TO_SERVER back.
428
- // Previously SERVER_TO_CLIENT was always used.
429
- // Therefore for non-global commands we inverse the direction.
430
- const direction = frame.header.isGlobal
500
+ this._lastDefaultResponseSequenceNumber = header.transactionSequenceNumber;
501
+ const direction = header.frameControl.direction === Zcl.Direction.CLIENT_TO_SERVER
431
502
  ? Zcl.Direction.SERVER_TO_CLIENT
432
- : frame.header.frameControl.direction === Zcl.Direction.CLIENT_TO_SERVER
433
- ? Zcl.Direction.SERVER_TO_CLIENT
434
- : Zcl.Direction.CLIENT_TO_SERVER;
435
- await endpoint.defaultResponse(frame.command.ID, 0, frame.cluster.ID, frame.header.transactionSequenceNumber, { direction });
503
+ : Zcl.Direction.CLIENT_TO_SERVER;
504
+ await endpoint.defaultResponse(command.ID, defaultResponseStatus, cluster.ID, header.transactionSequenceNumber, {
505
+ direction,
506
+ });
436
507
  }
437
508
  catch (error) {
438
509
  logger_1.logger.debug(`Default response to ${this.ieeeAddr} failed (${error})`, NS);
@@ -447,7 +518,6 @@ class Device extends entity_1.default {
447
518
  */
448
519
  static resetCache() {
449
520
  Device.devices.clear();
450
- Device.loadedFromDatabase = false;
451
521
  Device.deletedDevices.clear();
452
522
  Device.nwkToIeeeCache.clear();
453
523
  }
@@ -464,7 +534,7 @@ class Device extends entity_1.default {
464
534
  }
465
535
  // default: no timeout (messages expire immediately after first send attempt)
466
536
  let pendingRequestTimeout = 0;
467
- if (endpoints.filter((e) => e.inputClusters.includes(Zcl.Clusters.genPollCtrl.ID)).length > 0) {
537
+ if (endpoints.filter((e) => e.inputClusters.includes(GEN_POLL_CTRL_CLUSTER_ID)).length > 0) {
468
538
  // default for devices that support genPollCtrl cluster (RX off when idle): 1 day
469
539
  pendingRequestTimeout = 86400000;
470
540
  }
@@ -518,22 +588,19 @@ class Device extends entity_1.default {
518
588
  entity_1.default.getDatabaseByID(this.databaseID)?.update(this.toDatabaseEntry(), writeDatabase);
519
589
  }
520
590
  static loadFromDatabaseIfNecessary() {
521
- if (!Device.loadedFromDatabase) {
522
- entity_1.default.databases.forEach(database => {
523
- if (!Device.devices.has(database.id)) {
524
- Device.devices.set(database.id, new Map());
525
- Device.deletedDevices.set(database.id, new Map());
526
- Device.nwkToIeeeCache.set(database.id, new Map());
527
- const entries = database.getEntriesIterator(['Coordinator', 'EndDevice', 'Router', 'GreenPower', 'Unknown']);
528
- for (const entry of entries) {
529
- const device = Device.fromDatabaseEntry(entry, database.id);
530
- Device.devices.get(database.id).set(device.ieeeAddr, device);
531
- Device.nwkToIeeeCache.get(database.id).set(device.networkAddress, device.ieeeAddr);
532
- }
591
+ entity_1.default.databases.forEach(database => {
592
+ if (!Device.devices.has(database.id)) {
593
+ Device.devices.set(database.id, new Map());
594
+ Device.deletedDevices.set(database.id, new Map());
595
+ Device.nwkToIeeeCache.set(database.id, new Map());
596
+ const entries = database.getEntriesIterator(['Coordinator', 'EndDevice', 'Router', 'GreenPower', 'Unknown']);
597
+ for (const entry of entries) {
598
+ const device = Device.fromDatabaseEntry(entry, database.id);
599
+ Device.devices.get(database.id).set(device.ieeeAddr, device);
600
+ Device.nwkToIeeeCache.get(database.id).set(device.networkAddress, device.ieeeAddr);
533
601
  }
534
- });
535
- Device.loadedFromDatabase = true;
536
- }
602
+ }
603
+ });
537
604
  }
538
605
  static find(databaseID, ieeeOrNwkAddress, includeDeleted = false) {
539
606
  return typeof ieeeOrNwkAddress === "string"
@@ -1102,31 +1169,35 @@ class Device extends entity_1.default {
1102
1169
  // Zigbee does not have an official pinging mechanism. Use a read request
1103
1170
  // of a mandatory basic cluster attribute to keep it as lightweight as
1104
1171
  // possible.
1105
- const endpoint = this.endpoints.find((ep) => ep.inputClusters.includes(0)) ?? this.endpoints[0];
1172
+ const endpoint = this.endpoints.find((ep) => ep.inputClusters.includes(GEN_BASIC_CLUSTER_ID)) ?? this.endpoints[0];
1106
1173
  await endpoint.read("genBasic", ["zclVersion"], { disableRecovery, sendPolicy: "immediate" });
1107
1174
  }
1108
1175
  addCustomCluster(name, cluster) {
1109
- (0, node_assert_1.default)(![Zcl.Clusters.touchlink.ID, Zcl.Clusters.greenPower.ID].includes(cluster.ID), "Overriding of greenPower or touchlink cluster is not supported");
1176
+ (0, node_assert_1.default)(cluster.ID !== Zcl.Clusters.touchlink.ID && cluster.ID !== Zcl.Clusters.greenPower.ID, "Overriding of greenPower or touchlink cluster is not supported");
1110
1177
  if (Zcl.Utils.isClusterName(name)) {
1111
- const existingCluster = this._customClusters[name] ?? Zcl.Clusters[name];
1112
1178
  // Extend existing cluster
1179
+ const existingCluster = this._customClusters[name] ?? Zcl.Clusters[name];
1113
1180
  (0, node_assert_1.default)(existingCluster.ID === cluster.ID, `Custom cluster ID (${cluster.ID}) should match existing cluster ID (${existingCluster.ID})`);
1114
- cluster = {
1181
+ const extendedCluster = {
1182
+ name: cluster.name,
1115
1183
  ID: cluster.ID,
1116
1184
  manufacturerCode: cluster.manufacturerCode,
1117
1185
  attributes: { ...existingCluster.attributes, ...cluster.attributes },
1118
1186
  commands: { ...existingCluster.commands, ...cluster.commands },
1119
1187
  commandsResponse: { ...existingCluster.commandsResponse, ...cluster.commandsResponse },
1120
1188
  };
1189
+ this._customClusters[name] = extendedCluster;
1190
+ }
1191
+ else {
1192
+ this._customClusters[name] = cluster;
1121
1193
  }
1122
- this._customClusters[name] = cluster;
1123
1194
  }
1124
- #waitForOtaCommand(endpointId, commandId, transactionSequenceNumber, timeout) {
1195
+ #waitForOtaCommand(endpointId, commandId, defaultRspCommandId, timeout) {
1125
1196
  const adapter = entity_1.default.getAdapterByID(this.databaseID);
1126
1197
  if (!adapter) {
1127
1198
  throw new Error(`No adapter found for database ID ${this.databaseID}`);
1128
1199
  }
1129
- const waiter = adapter.waitFor(this.networkAddress, endpointId, Zcl.FrameType.SPECIFIC, Zcl.Direction.CLIENT_TO_SERVER, transactionSequenceNumber, Zcl.Clusters.genOta.ID, commandId, timeout);
1200
+ const waiter = adapter.waitFor(this.networkAddress, endpointId, Zcl.FrameType.SPECIFIC, Zcl.Direction.CLIENT_TO_SERVER, undefined, GEN_OTA_CLUSTER_ID, commandId, defaultRspCommandId, timeout);
1130
1201
  const promise = new Promise((resolve, reject) => {
1131
1202
  waiter.promise.then((payload) => {
1132
1203
  try {
@@ -1168,10 +1239,11 @@ class Device extends entity_1.default {
1168
1239
  }
1169
1240
  async #notifyOta(endpoint) {
1170
1241
  // Some devices (e.g. Insta) take a very long trying to discover the correct coordinator EP for OTA
1171
- const queryNextImageRequest = this.#waitForOtaCommand(endpoint.ID, Zcl.Clusters.genOta.commands.queryNextImageRequest.ID, undefined, 60000);
1242
+ const queryNextImageRequest = this.#waitForOtaCommand(endpoint.ID, Zcl.Clusters.genOta.commands.queryNextImageRequest.ID, Zcl.Clusters.genOta.commandsResponse.imageNotify.ID, 60000);
1172
1243
  try {
1173
1244
  await endpoint.commandResponse("genOta", "imageNotify", { payloadType: 0, queryJitter: 100 }, { sendPolicy: "immediate" });
1174
1245
  const response = await queryNextImageRequest.promise;
1246
+ (0, node_assert_1.default)(response.header.isSpecific);
1175
1247
  return [response.payload, response.header.transactionSequenceNumber];
1176
1248
  }
1177
1249
  catch {
@@ -1309,10 +1381,14 @@ class Device extends entity_1.default {
1309
1381
  const session = new ota_1.OtaSession(this.ieeeAddr, endpoint, image, onProgress, dataSettings, this.#waitForOtaCommand.bind(this));
1310
1382
  let endResult;
1311
1383
  try {
1312
- endResult = await session.run();
1384
+ this.#otaAbortController = new AbortController();
1385
+ const runEnd = await session.run(this.#otaAbortController.signal);
1386
+ (0, node_assert_1.default)(runEnd.header.isSpecific);
1387
+ endResult = runEnd;
1313
1388
  }
1314
1389
  finally {
1315
1390
  this.#otaInProgress = false;
1391
+ this.#otaAbortController = undefined;
1316
1392
  }
1317
1393
  logger_1.logger.debug(() => `Received upgrade end request for ${this.ieeeAddr}: ${JSON.stringify(endResult.payload)}`, NS);
1318
1394
  if (endResult.payload.status === Zcl.Status.SUCCESS) {
@@ -1367,7 +1443,7 @@ class Device extends entity_1.default {
1367
1443
  * response command with status of success and it SHALL wait for the client to reinitiate the upgrade process.
1368
1444
  */
1369
1445
  try {
1370
- await endpoint.defaultResponse(Zcl.Clusters.genOta.commands.upgradeEndRequest.ID, Zcl.Status.SUCCESS, Zcl.Clusters.genOta.ID, endResult.header.transactionSequenceNumber);
1446
+ await endpoint.defaultResponse(Zcl.Clusters.genOta.commands.upgradeEndRequest.ID, Zcl.Status.SUCCESS, GEN_OTA_CLUSTER_ID, endResult.header.transactionSequenceNumber);
1371
1447
  }
1372
1448
  catch (error) {
1373
1449
  logger_1.logger.debug(() => `OTA upgrade end request default response for ${this.ieeeAddr} failed: ${error.message}`, NS);
@@ -1376,6 +1452,12 @@ class Device extends entity_1.default {
1376
1452
  throw new Error(`OTA update of ${this.ieeeAddr} failed with reason: ${Zcl.Status[endResult.payload.status]}`);
1377
1453
  }
1378
1454
  }
1455
+ /**
1456
+ * Abort running OTA if any. Send `ABORT` with next block response to device.
1457
+ */
1458
+ abortOta() {
1459
+ this.#otaAbortController?.abort();
1460
+ }
1379
1461
  scheduleOta(source) {
1380
1462
  (0, node_assert_1.default)(this.endpoints.some((e) => e.supportsOutputCluster("genOta")), `No endpoint found with OTA cluster support for ${this.ieeeAddr}`);
1381
1463
  if (this.#scheduledOta) {