zigbee-herdsman 1.0.1 → 2.0.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 (140) hide show
  1. package/.release-please-manifest.json +1 -1
  2. package/CHANGELOG.md +23 -0
  3. package/dist/adapter/adapter.d.ts +8 -12
  4. package/dist/adapter/adapter.d.ts.map +1 -1
  5. package/dist/adapter/adapter.js +3 -0
  6. package/dist/adapter/adapter.js.map +1 -1
  7. package/dist/adapter/deconz/adapter/deconzAdapter.d.ts +7 -15
  8. package/dist/adapter/deconz/adapter/deconzAdapter.d.ts.map +1 -1
  9. package/dist/adapter/deconz/adapter/deconzAdapter.js +154 -693
  10. package/dist/adapter/deconz/adapter/deconzAdapter.js.map +1 -1
  11. package/dist/adapter/deconz/driver/constants.d.ts +102 -56
  12. package/dist/adapter/deconz/driver/constants.d.ts.map +1 -1
  13. package/dist/adapter/deconz/driver/constants.js +1 -2
  14. package/dist/adapter/deconz/driver/constants.js.map +1 -1
  15. package/dist/adapter/deconz/driver/driver.d.ts.map +1 -1
  16. package/dist/adapter/deconz/driver/driver.js +46 -41
  17. package/dist/adapter/deconz/driver/driver.js.map +1 -1
  18. package/dist/adapter/deconz/driver/frameParser.d.ts.map +1 -1
  19. package/dist/adapter/deconz/driver/frameParser.js +174 -107
  20. package/dist/adapter/deconz/driver/frameParser.js.map +1 -1
  21. package/dist/adapter/ember/adapter/emberAdapter.d.ts +5 -22
  22. package/dist/adapter/ember/adapter/emberAdapter.d.ts.map +1 -1
  23. package/dist/adapter/ember/adapter/emberAdapter.js +92 -325
  24. package/dist/adapter/ember/adapter/emberAdapter.js.map +1 -1
  25. package/dist/adapter/ember/adapter/oneWaitress.d.ts +17 -14
  26. package/dist/adapter/ember/adapter/oneWaitress.d.ts.map +1 -1
  27. package/dist/adapter/ember/adapter/oneWaitress.js +16 -42
  28. package/dist/adapter/ember/adapter/oneWaitress.js.map +1 -1
  29. package/dist/adapter/events.d.ts +1 -9
  30. package/dist/adapter/events.d.ts.map +1 -1
  31. package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts +12 -19
  32. package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts.map +1 -1
  33. package/dist/adapter/ezsp/adapter/ezspAdapter.js +90 -272
  34. package/dist/adapter/ezsp/adapter/ezspAdapter.js.map +1 -1
  35. package/dist/adapter/ezsp/driver/driver.d.ts +6 -14
  36. package/dist/adapter/ezsp/driver/driver.d.ts.map +1 -1
  37. package/dist/adapter/ezsp/driver/driver.js +56 -37
  38. package/dist/adapter/ezsp/driver/driver.js.map +1 -1
  39. package/dist/adapter/ezsp/driver/ezsp.d.ts.map +1 -1
  40. package/dist/adapter/ezsp/driver/ezsp.js +3 -0
  41. package/dist/adapter/ezsp/driver/ezsp.js.map +1 -1
  42. package/dist/adapter/tstype.d.ts +1 -27
  43. package/dist/adapter/tstype.d.ts.map +1 -1
  44. package/dist/adapter/z-stack/adapter/manager.d.ts.map +1 -1
  45. package/dist/adapter/z-stack/adapter/manager.js +20 -10
  46. package/dist/adapter/z-stack/adapter/manager.js.map +1 -1
  47. package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts +7 -15
  48. package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts.map +1 -1
  49. package/dist/adapter/z-stack/adapter/zStackAdapter.js +128 -253
  50. package/dist/adapter/z-stack/adapter/zStackAdapter.js.map +1 -1
  51. package/dist/adapter/z-stack/znp/definition.d.ts.map +1 -1
  52. package/dist/adapter/z-stack/znp/definition.js +256 -302
  53. package/dist/adapter/z-stack/znp/definition.js.map +1 -1
  54. package/dist/adapter/z-stack/znp/tstype.d.ts +8 -8
  55. package/dist/adapter/z-stack/znp/tstype.d.ts.map +1 -1
  56. package/dist/adapter/z-stack/znp/utils.d.ts +3 -2
  57. package/dist/adapter/z-stack/znp/utils.d.ts.map +1 -1
  58. package/dist/adapter/z-stack/znp/utils.js +8 -7
  59. package/dist/adapter/z-stack/znp/utils.js.map +1 -1
  60. package/dist/adapter/z-stack/znp/znp.d.ts +3 -1
  61. package/dist/adapter/z-stack/znp/znp.d.ts.map +1 -1
  62. package/dist/adapter/z-stack/znp/znp.js +31 -14
  63. package/dist/adapter/z-stack/znp/znp.js.map +1 -1
  64. package/dist/adapter/z-stack/znp/zpiObject.d.ts +5 -6
  65. package/dist/adapter/z-stack/znp/zpiObject.d.ts.map +1 -1
  66. package/dist/adapter/z-stack/znp/zpiObject.js +28 -11
  67. package/dist/adapter/z-stack/znp/zpiObject.js.map +1 -1
  68. package/dist/adapter/zboss/adapter/zbossAdapter.d.ts +8 -16
  69. package/dist/adapter/zboss/adapter/zbossAdapter.d.ts.map +1 -1
  70. package/dist/adapter/zboss/adapter/zbossAdapter.js +124 -162
  71. package/dist/adapter/zboss/adapter/zbossAdapter.js.map +1 -1
  72. package/dist/adapter/zboss/commands.d.ts +3 -0
  73. package/dist/adapter/zboss/commands.d.ts.map +1 -1
  74. package/dist/adapter/zboss/commands.js +248 -205
  75. package/dist/adapter/zboss/commands.js.map +1 -1
  76. package/dist/adapter/zboss/driver.d.ts +4 -14
  77. package/dist/adapter/zboss/driver.d.ts.map +1 -1
  78. package/dist/adapter/zboss/driver.js +63 -89
  79. package/dist/adapter/zboss/driver.js.map +1 -1
  80. package/dist/adapter/zboss/enums.d.ts +24 -2
  81. package/dist/adapter/zboss/enums.d.ts.map +1 -1
  82. package/dist/adapter/zboss/enums.js +35 -3
  83. package/dist/adapter/zboss/enums.js.map +1 -1
  84. package/dist/adapter/zboss/frame.d.ts +6 -1
  85. package/dist/adapter/zboss/frame.d.ts.map +1 -1
  86. package/dist/adapter/zboss/frame.js +56 -11
  87. package/dist/adapter/zboss/frame.js.map +1 -1
  88. package/dist/adapter/zboss/uart.d.ts +1 -0
  89. package/dist/adapter/zboss/uart.d.ts.map +1 -1
  90. package/dist/adapter/zboss/uart.js +4 -2
  91. package/dist/adapter/zboss/uart.js.map +1 -1
  92. package/dist/adapter/zigate/adapter/patchZdoBuffaloBE.d.ts +5 -0
  93. package/dist/adapter/zigate/adapter/patchZdoBuffaloBE.d.ts.map +1 -0
  94. package/dist/adapter/zigate/adapter/patchZdoBuffaloBE.js +44 -0
  95. package/dist/adapter/zigate/adapter/patchZdoBuffaloBE.js.map +1 -0
  96. package/dist/adapter/zigate/adapter/zigateAdapter.d.ts +6 -10
  97. package/dist/adapter/zigate/adapter/zigateAdapter.d.ts.map +1 -1
  98. package/dist/adapter/zigate/adapter/zigateAdapter.js +99 -289
  99. package/dist/adapter/zigate/adapter/zigateAdapter.js.map +1 -1
  100. package/dist/adapter/zigate/driver/buffaloZiGate.d.ts.map +1 -1
  101. package/dist/adapter/zigate/driver/buffaloZiGate.js +2 -18
  102. package/dist/adapter/zigate/driver/buffaloZiGate.js.map +1 -1
  103. package/dist/adapter/zigate/driver/commandType.js +218 -218
  104. package/dist/adapter/zigate/driver/commandType.js.map +1 -1
  105. package/dist/adapter/zigate/driver/constants.d.ts +14 -8
  106. package/dist/adapter/zigate/driver/constants.d.ts.map +1 -1
  107. package/dist/adapter/zigate/driver/constants.js +36 -9
  108. package/dist/adapter/zigate/driver/constants.js.map +1 -1
  109. package/dist/adapter/zigate/driver/messageType.js +42 -42
  110. package/dist/adapter/zigate/driver/messageType.js.map +1 -1
  111. package/dist/adapter/zigate/driver/zigate.d.ts +17 -13
  112. package/dist/adapter/zigate/driver/zigate.d.ts.map +1 -1
  113. package/dist/adapter/zigate/driver/zigate.js +83 -18
  114. package/dist/adapter/zigate/driver/zigate.js.map +1 -1
  115. package/dist/controller/controller.d.ts +5 -0
  116. package/dist/controller/controller.d.ts.map +1 -1
  117. package/dist/controller/controller.js +143 -37
  118. package/dist/controller/controller.js.map +1 -1
  119. package/dist/controller/greenPower.js +3 -3
  120. package/dist/controller/greenPower.js.map +1 -1
  121. package/dist/controller/model/device.d.ts +8 -7
  122. package/dist/controller/model/device.d.ts.map +1 -1
  123. package/dist/controller/model/device.js +176 -72
  124. package/dist/controller/model/device.js.map +1 -1
  125. package/dist/controller/model/endpoint.d.ts +1 -0
  126. package/dist/controller/model/endpoint.d.ts.map +1 -1
  127. package/dist/controller/model/endpoint.js +27 -4
  128. package/dist/controller/model/endpoint.js.map +1 -1
  129. package/dist/zspec/zdo/buffaloZdo.d.ts +1 -139
  130. package/dist/zspec/zdo/buffaloZdo.d.ts.map +1 -1
  131. package/dist/zspec/zdo/buffaloZdo.js.map +1 -1
  132. package/dist/zspec/zdo/definition/tstypes.d.ts +168 -1
  133. package/dist/zspec/zdo/definition/tstypes.d.ts.map +1 -1
  134. package/dist/zspec/zdo/definition/tstypes.js +1 -0
  135. package/dist/zspec/zdo/definition/tstypes.js.map +1 -1
  136. package/dist/zspec/zdo/utils.d.ts +2 -3
  137. package/dist/zspec/zdo/utils.d.ts.map +1 -1
  138. package/dist/zspec/zdo/utils.js +3 -4
  139. package/dist/zspec/zdo/utils.js.map +1 -1
  140. package/package.json +5 -4
@@ -37,6 +37,8 @@ const adapter_1 = __importDefault(require("../../adapter"));
37
37
  const Constants = __importStar(require("../constants"));
38
38
  const unpi_1 = require("../unpi");
39
39
  const znp_1 = require("../znp");
40
+ const definition_1 = __importDefault(require("../znp/definition"));
41
+ const utils_2 = require("../znp/utils");
40
42
  const manager_1 = require("./manager");
41
43
  const tstype_1 = require("./tstype");
42
44
  const NS = 'zh:zstack';
@@ -79,6 +81,7 @@ class ZStackAdapter extends adapter_1.default {
79
81
  constructor(networkOptions, serialPortOptions, backupPath, adapterOptions) {
80
82
  super(networkOptions, serialPortOptions, backupPath, adapterOptions);
81
83
  this.hasZdoMessageOverhead = false;
84
+ this.manufacturerID = Zcl.ManufacturerCode.TEXAS_INSTRUMENTS;
82
85
  this.znp = new znp_1.Znp(this.serialPortOptions.path, this.serialPortOptions.baudRate, this.serialPortOptions.rtscts);
83
86
  this.transactionID = 0;
84
87
  this.deviceAnnounceRouteDiscoveryDebouncers = new Map();
@@ -150,45 +153,37 @@ class ZStackAdapter extends adapter_1.default {
150
153
  static async autoDetectPath() {
151
154
  return await znp_1.Znp.autoDetectPath();
152
155
  }
153
- async getCoordinator() {
156
+ async getCoordinatorIEEE() {
154
157
  return await this.queue.execute(async () => {
155
158
  this.checkInterpanLock();
156
- const activeEp = await this.activeEndpoints(0);
157
159
  const deviceInfo = await this.znp.requestWithReply(Subsystem.UTIL, 'getDeviceInfo', {});
158
- const endpoints = [];
159
- for (const endpoint of activeEp.endpoints) {
160
- const simpleDesc = await this.simpleDescriptor(0, endpoint);
161
- endpoints.push({
162
- ID: simpleDesc.endpointID,
163
- deviceID: simpleDesc.deviceID,
164
- profileID: simpleDesc.profileID,
165
- inputClusters: simpleDesc.inputClusters,
166
- outputClusters: simpleDesc.outputClusters,
167
- });
168
- }
169
- return {
170
- networkAddress: 0,
171
- manufacturerID: 0,
172
- ieeeAddr: deviceInfo.payload.ieeeaddr,
173
- endpoints,
174
- };
160
+ return deviceInfo.payload.ieeeaddr;
175
161
  });
176
162
  }
163
+ async getCoordinatorVersion() {
164
+ return { type: tstype_1.ZnpVersion[this.version.product], meta: this.version };
165
+ }
177
166
  async permitJoin(seconds, networkAddress) {
178
- const addrmode = networkAddress === undefined ? 0x0f : 0x02;
179
- const dstaddr = networkAddress || 0xfffc;
167
+ const clusterId = Zdo.ClusterId.PERMIT_JOINING_REQUEST;
168
+ // `authentication`: TC significance always 1 (zb specs)
169
+ const zdoPayload = Zdo.Buffalo.buildRequest(this.hasZdoMessageOverhead, clusterId, seconds, 1, []);
170
+ if (networkAddress === undefined) {
171
+ await this.sendZdo(ZSpec.BLANK_EUI64, ZSpec.BroadcastAddress.DEFAULT, clusterId, zdoPayload, true);
172
+ }
173
+ else {
174
+ // NOTE: `sendZdo` takes care of adjusting the payload as appropriate based on `networkAddress === 0` or not
175
+ const result = await this.sendZdo(ZSpec.BLANK_EUI64, networkAddress, clusterId, zdoPayload, false);
176
+ /* istanbul ignore next */
177
+ if (!Zdo.Buffalo.checkStatus(result)) {
178
+ // TODO: will disappear once moved upstream
179
+ throw new Zdo.StatusError(result[0]);
180
+ }
181
+ }
180
182
  await this.queue.execute(async () => {
181
183
  this.checkInterpanLock();
182
- const payload = { addrmode, dstaddr, duration: seconds, tcsignificance: 0 };
183
- const permitJoinRsp = this.waitForAreqZdo('mgmtPermitJoinRsp');
184
- await this.znp.request(Subsystem.ZDO, 'mgmtPermitJoinReq', payload);
185
- await permitJoinRsp.start();
186
184
  await this.setLED(seconds == 0 ? 'off' : 'on');
187
185
  });
188
186
  }
189
- async getCoordinatorVersion() {
190
- return { type: tstype_1.ZnpVersion[this.version.product], meta: this.version };
191
- }
192
187
  async reset(type) {
193
188
  if (type === 'soft') {
194
189
  await this.znp.request(Subsystem.SYS, 'resetReq', { type: Constants.SYS.resetType.SOFT });
@@ -231,10 +226,17 @@ class ZStackAdapter extends adapter_1.default {
231
226
  * this is currently not handled, the first nwkAddrRsp is taken.
232
227
  */
233
228
  logger_1.logger.debug(`Request network address of '${ieeeAddr}'`, NS);
234
- const response = this.waitForAreqZdo('nwkAddrRsp', { ieeeaddr: ieeeAddr });
235
- await this.znp.request(Subsystem.ZDO, 'nwkAddrReq', { ieeeaddr: ieeeAddr, reqtype: 0, startindex: 0 });
236
- const result = await response.start();
237
- return result.nwkAddress;
229
+ const clusterId = Zdo.ClusterId.NETWORK_ADDRESS_REQUEST;
230
+ const zdoPayload = Zdo.Buffalo.buildRequest(this.hasZdoMessageOverhead, clusterId, ieeeAddr, false, 0);
231
+ const result = await this.sendZdo(ieeeAddr, ZSpec.NULL_NODE_ID, clusterId, zdoPayload, false);
232
+ /* istanbul ignore else */
233
+ if (Zdo.Buffalo.checkStatus(result)) {
234
+ return result[1].nwkAddress;
235
+ }
236
+ else {
237
+ // TODO: will disappear once moved upstream
238
+ throw new Zdo.StatusError(result[0]);
239
+ }
238
240
  }
239
241
  supportsAssocRemove() {
240
242
  return this.version.product === tstype_1.ZnpVersion.zStack3x0 && parseInt(this.version.revision) >= 20200805;
@@ -250,67 +252,82 @@ class ZStackAdapter extends adapter_1.default {
250
252
  await (0, utils_1.Wait)(3000);
251
253
  }
252
254
  }
253
- async nodeDescriptor(networkAddress) {
255
+ async sendZdo(ieeeAddress, networkAddress, clusterId, payload, disableResponse) {
254
256
  return await this.queue.execute(async () => {
255
257
  this.checkInterpanLock();
258
+ // stack-specific requirements
259
+ switch (clusterId) {
260
+ case Zdo.ClusterId.PERMIT_JOINING_REQUEST: {
261
+ const finalPayload = Buffer.alloc(payload.length + 3);
262
+ finalPayload.writeUInt8(ZSpec.BroadcastAddress[networkAddress] ? AddressMode.ADDR_BROADCAST : AddressMode.ADDR_16BIT, 0);
263
+ // zstack uses AddressMode.ADDR_16BIT + ZSpec.BroadcastAddress.DEFAULT to signal "coordinator-only"
264
+ finalPayload.writeUInt16LE(networkAddress === 0 ? ZSpec.BroadcastAddress.DEFAULT : networkAddress, 1);
265
+ finalPayload.set(payload, 3);
266
+ payload = finalPayload;
267
+ break;
268
+ }
269
+ case Zdo.ClusterId.NWK_UPDATE_REQUEST: {
270
+ // extra zeroes for empty nwkManagerAddr if necessary
271
+ const zeroes = 9 - payload.length - 1; /* zstack doesn't have nwkUpdateId */
272
+ const finalPayload = Buffer.alloc(payload.length + 3 + zeroes);
273
+ finalPayload.writeUInt16LE(networkAddress, 0);
274
+ finalPayload.writeUInt8(ZSpec.BroadcastAddress[networkAddress] ? AddressMode.ADDR_BROADCAST : AddressMode.ADDR_16BIT, 2);
275
+ finalPayload.set(payload, 3);
276
+ payload = finalPayload;
277
+ break;
278
+ }
279
+ case Zdo.ClusterId.BIND_REQUEST:
280
+ case Zdo.ClusterId.UNBIND_REQUEST: {
281
+ // extra zeroes for uint16 (in place of ieee when MULTICAST) and endpoint (not used when MULTICAST)
282
+ const zeroes = 21 - payload.length;
283
+ const finalPayload = Buffer.alloc(payload.length + 2 + zeroes);
284
+ finalPayload.writeUInt16LE(networkAddress, 0);
285
+ finalPayload.set(payload, 2);
286
+ payload = finalPayload;
287
+ break;
288
+ }
289
+ case Zdo.ClusterId.NETWORK_ADDRESS_REQUEST:
290
+ case Zdo.ClusterId.IEEE_ADDRESS_REQUEST: {
291
+ // no modification necessary
292
+ break;
293
+ }
294
+ default: {
295
+ const finalPayload = Buffer.alloc(payload.length + 2);
296
+ finalPayload.writeUInt16LE(networkAddress, 0);
297
+ finalPayload.set(payload, 2);
298
+ payload = finalPayload;
299
+ break;
300
+ }
301
+ }
302
+ let waiter;
303
+ if (!disableResponse) {
304
+ const responseClusterId = Zdo.Utils.getResponseClusterId(clusterId);
305
+ /* istanbul ignore else */
306
+ if (responseClusterId) {
307
+ const cmd = definition_1.default[Subsystem.ZDO].find((c) => (0, utils_2.isMtCmdAreqZdo)(c) && c.zdoClusterId === responseClusterId);
308
+ (0, assert_1.default)(cmd, `Response for ZDO cluster ID '${responseClusterId}' not supported.`);
309
+ waiter = this.znp.waitFor(unpi_1.Constants.Type.AREQ, Subsystem.ZDO, cmd.name, responseClusterId === Zdo.ClusterId.NETWORK_ADDRESS_RESPONSE ? ieeeAddress : networkAddress, undefined, undefined);
310
+ }
311
+ }
256
312
  try {
257
- const result = await this.nodeDescriptorInternal(networkAddress);
258
- return result;
313
+ await this.znp.requestZdo(clusterId, payload, waiter?.ID);
259
314
  }
260
315
  catch (error) {
261
- logger_1.logger.debug(`Node descriptor request for '${networkAddress}' failed (${error}), retry`, NS);
262
- // Doing a route discovery after simple descriptor request fails makes it succeed sometimes.
263
- // https://github.com/Koenkk/zigbee2mqtt/issues/3276
264
- await this.discoverRoute(networkAddress);
265
- const result = await this.nodeDescriptorInternal(networkAddress);
266
- return result;
316
+ if (clusterId === Zdo.ClusterId.NODE_DESCRIPTOR_REQUEST) {
317
+ // Discover route when node descriptor request fails
318
+ // https://github.com/Koenkk/zigbee2mqtt/issues/3276
319
+ logger_1.logger.debug(`Discover route to '${networkAddress}' because node descriptor request failed`, NS);
320
+ await this.discoverRoute(networkAddress);
321
+ await this.znp.requestZdo(clusterId, payload, waiter?.ID);
322
+ }
323
+ else {
324
+ throw error;
325
+ }
267
326
  }
268
- }, networkAddress);
269
- }
270
- async nodeDescriptorInternal(networkAddress) {
271
- const response = this.waitForAreqZdo('nodeDescRsp', { srcaddr: networkAddress });
272
- const payload = { dstaddr: networkAddress, nwkaddrofinterest: networkAddress };
273
- await this.znp.request(Subsystem.ZDO, 'nodeDescReq', payload, response.ID);
274
- const descriptor = await response.start();
275
- let type = 'Unknown';
276
- const logicalType = descriptor.logicalType;
277
- for (const [key, value] of Object.entries(Constants.ZDO.deviceLogicalType)) {
278
- if (value === logicalType) {
279
- if (key === 'COORDINATOR')
280
- type = 'Coordinator';
281
- else if (key === 'ROUTER')
282
- type = 'Router';
283
- else if (key === 'ENDDEVICE')
284
- type = 'EndDevice';
285
- break;
327
+ if (waiter) {
328
+ const response = await waiter.start().promise;
329
+ return response.payload.zdo;
286
330
  }
287
- }
288
- return { manufacturerCode: descriptor.manufacturerCode, type };
289
- }
290
- async activeEndpoints(networkAddress) {
291
- return await this.queue.execute(async () => {
292
- this.checkInterpanLock();
293
- const response = this.waitForAreqZdo('activeEpRsp', { srcaddr: networkAddress });
294
- const payload = { dstaddr: networkAddress, nwkaddrofinterest: networkAddress };
295
- await this.znp.request(Subsystem.ZDO, 'activeEpReq', payload, response.ID);
296
- const activeEp = await response.start();
297
- return { endpoints: activeEp.endpointList };
298
- }, networkAddress);
299
- }
300
- async simpleDescriptor(networkAddress, endpointID) {
301
- return await this.queue.execute(async () => {
302
- this.checkInterpanLock();
303
- const response = this.waitForAreqZdo('simpleDescRsp', { srcaddr: networkAddress });
304
- const payload = { dstaddr: networkAddress, nwkaddrofinterest: networkAddress, endpoint: endpointID };
305
- await this.znp.request(Subsystem.ZDO, 'simpleDescReq', payload, response.ID);
306
- const descriptor = await response.start();
307
- return {
308
- profileID: descriptor.profileId,
309
- endpointID: descriptor.endpoint,
310
- deviceID: descriptor.deviceId,
311
- inputClusters: descriptor.inClusterList,
312
- outputClusters: descriptor.outClusterList,
313
- };
314
331
  }, networkAddress);
315
332
  }
316
333
  async sendZclFrameToEndpoint(ieeeAddr, networkAddress, endpoint, zclFrame, timeout, disableResponse, disableRecovery, sourceEndpoint) {
@@ -497,111 +514,11 @@ class ZStackAdapter extends adapter_1.default {
497
514
  await (0, utils_1.Wait)(200);
498
515
  });
499
516
  }
500
- async lqi(networkAddress) {
501
- return await this.queue.execute(async () => {
502
- this.checkInterpanLock();
503
- const neighbors = [];
504
- const request = async (startIndex) => {
505
- const response = this.waitForAreqZdo('mgmtLqiRsp', { srcaddr: networkAddress });
506
- await this.znp.request(Subsystem.ZDO, 'mgmtLqiReq', { dstaddr: networkAddress, startindex: startIndex }, response.ID);
507
- const result = await response.start();
508
- return result;
509
- };
510
- const add = (list) => {
511
- for (const entry of list) {
512
- neighbors.push({
513
- linkquality: entry.lqi,
514
- networkAddress: entry.nwkAddress,
515
- ieeeAddr: entry.eui64,
516
- relationship: entry.relationship,
517
- depth: entry.depth,
518
- });
519
- }
520
- };
521
- let response = await request(0);
522
- add(response.entryList);
523
- const size = response.neighborTableEntries;
524
- let nextStartIndex = response.entryList.length;
525
- while (neighbors.length < size) {
526
- response = await request(nextStartIndex);
527
- add(response.entryList);
528
- nextStartIndex += response.entryList.length;
529
- }
530
- return { neighbors };
531
- }, networkAddress);
532
- }
533
- async routingTable(networkAddress) {
534
- return await this.queue.execute(async () => {
535
- this.checkInterpanLock();
536
- const table = [];
537
- const request = async (startIndex) => {
538
- const response = this.waitForAreqZdo('mgmtRtgRsp', { srcaddr: networkAddress });
539
- await this.znp.request(Subsystem.ZDO, 'mgmtRtgReq', { dstaddr: networkAddress, startindex: startIndex }, response.ID);
540
- const result = await response.start();
541
- return result;
542
- };
543
- const add = (list) => {
544
- for (const entry of list) {
545
- table.push({
546
- destinationAddress: entry.destinationAddress,
547
- status: entry.status,
548
- nextHop: entry.nextHopAddress,
549
- });
550
- }
551
- };
552
- let response = await request(0);
553
- add(response.entryList);
554
- const size = response.routingTableEntries;
555
- let nextStartIndex = response.entryList.length;
556
- while (table.length < size) {
557
- response = await request(nextStartIndex);
558
- add(response.entryList);
559
- nextStartIndex += response.entryList.length;
560
- }
561
- return { table };
562
- }, networkAddress);
563
- }
564
517
  async addInstallCode(ieeeAddress, key) {
565
518
  (0, assert_1.default)(this.version.product !== tstype_1.ZnpVersion.zStack12, 'Install code is not supported for ZStack 1.2 adapter');
566
519
  const payload = { installCodeFormat: key.length === 18 ? 1 : 2, ieeeaddr: ieeeAddress, installCode: key };
567
520
  await this.znp.request(Subsystem.APP_CNF, 'bdbAddInstallCode', payload);
568
521
  }
569
- async bind(destinationNetworkAddress, sourceIeeeAddress, sourceEndpoint, clusterID, destinationAddressOrGroup, type, destinationEndpoint) {
570
- await this.bindInternal('bind', destinationNetworkAddress, sourceIeeeAddress, sourceEndpoint, clusterID, destinationAddressOrGroup, type, destinationEndpoint);
571
- }
572
- async unbind(destinationNetworkAddress, sourceIeeeAddress, sourceEndpoint, clusterID, destinationAddressOrGroup, type, destinationEndpoint) {
573
- await this.bindInternal('unbind', destinationNetworkAddress, sourceIeeeAddress, sourceEndpoint, clusterID, destinationAddressOrGroup, type, destinationEndpoint);
574
- }
575
- async bindInternal(bindType, destinationNetworkAddress, sourceIeeeAddress, sourceEndpoint, clusterID, destinationAddressOrGroup, targetType, destinationEndpoint) {
576
- return await this.queue.execute(async () => {
577
- this.checkInterpanLock();
578
- const response = this.waitForAreqZdo(`${bindType}Rsp`, { srcaddr: destinationNetworkAddress });
579
- const payload = {
580
- dstaddr: destinationNetworkAddress,
581
- srcaddr: sourceIeeeAddress,
582
- srcendpoint: sourceEndpoint,
583
- clusterid: clusterID,
584
- dstaddrmode: targetType === 'group' ? AddressMode.ADDR_GROUP : AddressMode.ADDR_64BIT,
585
- dstaddress: this.toAddressString(destinationAddressOrGroup),
586
- dstendpoint: targetType === 'group' ? 0xff : destinationEndpoint,
587
- };
588
- await this.znp.request(Subsystem.ZDO, `${bindType}Req`, payload, response.ID);
589
- await response.start();
590
- }, destinationNetworkAddress);
591
- }
592
- removeDevice(networkAddress, ieeeAddr) {
593
- return this.queue.execute(async () => {
594
- this.checkInterpanLock();
595
- const response = this.waitForAreqZdo('mgmtLeaveRsp', { srcaddr: networkAddress });
596
- const payload = {
597
- dstaddr: networkAddress,
598
- deviceaddress: ieeeAddr,
599
- removechildrenRejoin: 0,
600
- };
601
- await this.znp.request(Subsystem.ZDO, 'mgmtLeaveReq', payload, response.ID);
602
- await response.start();
603
- }, networkAddress);
604
- }
605
522
  /**
606
523
  * Event handlers
607
524
  */
@@ -615,6 +532,9 @@ class ZStackAdapter extends adapter_1.default {
615
532
  return;
616
533
  }
617
534
  if (object.subsystem === Subsystem.ZDO) {
535
+ if ((0, utils_2.isMtCmdAreqZdo)(object.command)) {
536
+ this.emit('zdoResponse', object.command.zdoClusterId, object.payload.zdo);
537
+ }
618
538
  if (object.command.name === 'tcDeviceInd') {
619
539
  const payload = {
620
540
  networkAddress: object.payload.nwkaddr,
@@ -623,44 +543,29 @@ class ZStackAdapter extends adapter_1.default {
623
543
  this.emit('deviceJoined', payload);
624
544
  }
625
545
  else if (object.command.name === 'endDeviceAnnceInd') {
626
- const zdoResult = object.parseZdoPayload();
546
+ // TODO: better way???
627
547
  /* istanbul ignore else */
628
- if (Zdo.Buffalo.checkStatus(zdoResult)) {
629
- const payload = {
630
- networkAddress: zdoResult[1].nwkAddress,
631
- ieeeAddr: zdoResult[1].eui64,
632
- };
548
+ if (Zdo.Buffalo.checkStatus(object.payload.zdo)) {
549
+ const zdoPayload = object.payload.zdo[1];
633
550
  // Only discover routes to end devices, if bit 1 of capabilities === 0 it's an end device.
634
- const isEndDevice = zdoResult[1].capabilities.deviceType === 0;
551
+ const isEndDevice = zdoPayload.capabilities.deviceType === 0;
635
552
  if (isEndDevice) {
636
- if (!this.deviceAnnounceRouteDiscoveryDebouncers.has(payload.networkAddress)) {
553
+ if (!this.deviceAnnounceRouteDiscoveryDebouncers.has(zdoPayload.nwkAddress)) {
637
554
  // If a device announces multiple times in a very short time, it makes no sense
638
555
  // to rediscover the route every time.
639
556
  const debouncer = (0, debounce_1.default)(() => {
640
557
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
641
558
  this.queue.execute(async () => {
642
559
  /* istanbul ignore next */
643
- this.discoverRoute(payload.networkAddress, false).catch(() => { });
644
- }, payload.networkAddress);
560
+ this.discoverRoute(zdoPayload.nwkAddress, false).catch(() => { });
561
+ }, zdoPayload.nwkAddress);
645
562
  }, 60 * 1000, { immediate: true });
646
- this.deviceAnnounceRouteDiscoveryDebouncers.set(payload.networkAddress, debouncer);
563
+ this.deviceAnnounceRouteDiscoveryDebouncers.set(zdoPayload.nwkAddress, debouncer);
647
564
  }
648
- const debouncer = this.deviceAnnounceRouteDiscoveryDebouncers.get(payload.networkAddress);
565
+ const debouncer = this.deviceAnnounceRouteDiscoveryDebouncers.get(zdoPayload.nwkAddress);
649
566
  (0, assert_1.default)(debouncer);
650
567
  debouncer();
651
568
  }
652
- this.emit('deviceAnnounce', payload);
653
- }
654
- }
655
- else if (object.command.name === 'nwkAddrRsp') {
656
- const zdoResult = object.parseZdoPayload();
657
- /* istanbul ignore else */
658
- if (Zdo.Buffalo.checkStatus(zdoResult)) {
659
- const payload = {
660
- networkAddress: zdoResult[1].nwkAddress,
661
- ieeeAddr: zdoResult[1].eui64,
662
- };
663
- this.emit('networkAddress', payload);
664
569
  }
665
570
  }
666
571
  else if (object.command.name === 'concentratorIndCb') {
@@ -674,11 +579,15 @@ class ZStackAdapter extends adapter_1.default {
674
579
  // mappings.
675
580
  // https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/158/4403.zstacktask.c
676
581
  // https://github.com/Koenkk/zigbee-herdsman/issues/74
677
- const payload = {
678
- networkAddress: object.payload.srcaddr,
679
- ieeeAddr: object.payload.extaddr,
680
- };
681
- this.emit('networkAddress', payload);
582
+ this.emit('zdoResponse', Zdo.ClusterId.NETWORK_ADDRESS_RESPONSE, [
583
+ Zdo.Status.SUCCESS,
584
+ {
585
+ eui64: object.payload.extaddr,
586
+ nwkAddress: object.payload.srcaddr,
587
+ startIndex: 0,
588
+ assocDevList: [],
589
+ },
590
+ ]);
682
591
  }
683
592
  else {
684
593
  /* istanbul ignore else */
@@ -773,47 +682,11 @@ class ZStackAdapter extends adapter_1.default {
773
682
  this.interpanLock = false;
774
683
  });
775
684
  }
776
- async changeChannel(newChannel) {
777
- return await this.queue.execute(async () => {
778
- this.checkInterpanLock();
779
- const payload = {
780
- dstaddr: 0xffff, // broadcast with sleepy
781
- dstaddrmode: AddressMode.ADDR_BROADCAST,
782
- channelmask: [newChannel].reduce((a, c) => a + (1 << c), 0),
783
- scanduration: 0xfe, // change channel
784
- scancount: 0,
785
- nwkmanageraddr: 0,
786
- };
787
- await this.znp.request(Subsystem.ZDO, 'mgmtNwkUpdateReq', payload);
788
- // wait for the broadcast to propagate and the adapter to actually change
789
- await (0, utils_1.Wait)(10000);
790
- });
791
- }
792
685
  async setTransmitPower(value) {
793
686
  return await this.queue.execute(async () => {
794
687
  await this.znp.request(Subsystem.SYS, 'stackTune', { operation: 0, value });
795
688
  });
796
689
  }
797
- waitForAreqZdo(command, payload) {
798
- const result = this.znp.waitFor(unpi_1.Constants.Type.AREQ, Subsystem.ZDO, command, payload);
799
- const start = () => {
800
- const startResult = result.start();
801
- return new Promise((resolve, reject) => {
802
- startResult.promise
803
- .then((response) => {
804
- const [status, payload] = response.parseZdoPayload();
805
- if (status === Zdo.Status.SUCCESS) {
806
- resolve(payload);
807
- }
808
- else {
809
- reject(new Zdo.StatusError(status));
810
- }
811
- })
812
- .catch(reject);
813
- });
814
- };
815
- return { start, ID: result.ID };
816
- }
817
690
  waitForInternal(networkAddress, endpoint, frameType, direction, transactionSequenceNumber, clusterID, commandIdentifier, timeout) {
818
691
  const payload = {
819
692
  address: networkAddress,
@@ -837,7 +710,7 @@ class ZStackAdapter extends adapter_1.default {
837
710
  */
838
711
  async dataRequest(destinationAddress, destinationEndpoint, sourceEndpoint, clusterID, radius, data, timeout) {
839
712
  const transactionID = this.nextTransactionID();
840
- const response = this.znp.waitFor(Type.AREQ, Subsystem.AF, 'dataConfirm', { transid: transactionID }, timeout);
713
+ const response = this.znp.waitFor(Type.AREQ, Subsystem.AF, 'dataConfirm', undefined, transactionID, undefined, timeout);
841
714
  await this.znp.request(Subsystem.AF, 'dataRequest', {
842
715
  dstaddr: destinationAddress,
843
716
  destendpoint: destinationEndpoint,
@@ -861,7 +734,9 @@ class ZStackAdapter extends adapter_1.default {
861
734
  }
862
735
  async dataRequestExtended(addressMode, destinationAddressOrGroupID, destinationEndpoint, panID, sourceEndpoint, clusterID, radius, data, timeout, confirmation, attemptsLeft = 5) {
863
736
  const transactionID = this.nextTransactionID();
864
- const response = confirmation ? this.znp.waitFor(Type.AREQ, Subsystem.AF, 'dataConfirm', { transid: transactionID }, timeout) : undefined;
737
+ const response = confirmation
738
+ ? this.znp.waitFor(Type.AREQ, Subsystem.AF, 'dataConfirm', undefined, transactionID, undefined, timeout)
739
+ : undefined;
865
740
  await this.znp.request(Subsystem.AF, 'dataRequestExt', {
866
741
  dstaddrmode: addressMode,
867
742
  dstaddr: this.toAddressString(destinationAddressOrGroupID),