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.
- package/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +23 -0
- package/dist/adapter/adapter.d.ts +8 -12
- package/dist/adapter/adapter.d.ts.map +1 -1
- package/dist/adapter/adapter.js +3 -0
- package/dist/adapter/adapter.js.map +1 -1
- package/dist/adapter/deconz/adapter/deconzAdapter.d.ts +7 -15
- package/dist/adapter/deconz/adapter/deconzAdapter.d.ts.map +1 -1
- package/dist/adapter/deconz/adapter/deconzAdapter.js +154 -693
- package/dist/adapter/deconz/adapter/deconzAdapter.js.map +1 -1
- package/dist/adapter/deconz/driver/constants.d.ts +102 -56
- package/dist/adapter/deconz/driver/constants.d.ts.map +1 -1
- package/dist/adapter/deconz/driver/constants.js +1 -2
- package/dist/adapter/deconz/driver/constants.js.map +1 -1
- package/dist/adapter/deconz/driver/driver.d.ts.map +1 -1
- package/dist/adapter/deconz/driver/driver.js +46 -41
- package/dist/adapter/deconz/driver/driver.js.map +1 -1
- package/dist/adapter/deconz/driver/frameParser.d.ts.map +1 -1
- package/dist/adapter/deconz/driver/frameParser.js +174 -107
- package/dist/adapter/deconz/driver/frameParser.js.map +1 -1
- package/dist/adapter/ember/adapter/emberAdapter.d.ts +5 -22
- package/dist/adapter/ember/adapter/emberAdapter.d.ts.map +1 -1
- package/dist/adapter/ember/adapter/emberAdapter.js +92 -325
- package/dist/adapter/ember/adapter/emberAdapter.js.map +1 -1
- package/dist/adapter/ember/adapter/oneWaitress.d.ts +17 -14
- package/dist/adapter/ember/adapter/oneWaitress.d.ts.map +1 -1
- package/dist/adapter/ember/adapter/oneWaitress.js +16 -42
- package/dist/adapter/ember/adapter/oneWaitress.js.map +1 -1
- package/dist/adapter/events.d.ts +1 -9
- package/dist/adapter/events.d.ts.map +1 -1
- package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts +12 -19
- package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts.map +1 -1
- package/dist/adapter/ezsp/adapter/ezspAdapter.js +90 -272
- package/dist/adapter/ezsp/adapter/ezspAdapter.js.map +1 -1
- package/dist/adapter/ezsp/driver/driver.d.ts +6 -14
- package/dist/adapter/ezsp/driver/driver.d.ts.map +1 -1
- package/dist/adapter/ezsp/driver/driver.js +56 -37
- package/dist/adapter/ezsp/driver/driver.js.map +1 -1
- package/dist/adapter/ezsp/driver/ezsp.d.ts.map +1 -1
- package/dist/adapter/ezsp/driver/ezsp.js +3 -0
- package/dist/adapter/ezsp/driver/ezsp.js.map +1 -1
- package/dist/adapter/tstype.d.ts +1 -27
- package/dist/adapter/tstype.d.ts.map +1 -1
- package/dist/adapter/z-stack/adapter/manager.d.ts.map +1 -1
- package/dist/adapter/z-stack/adapter/manager.js +20 -10
- package/dist/adapter/z-stack/adapter/manager.js.map +1 -1
- package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts +7 -15
- package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts.map +1 -1
- package/dist/adapter/z-stack/adapter/zStackAdapter.js +128 -253
- package/dist/adapter/z-stack/adapter/zStackAdapter.js.map +1 -1
- package/dist/adapter/z-stack/znp/definition.d.ts.map +1 -1
- package/dist/adapter/z-stack/znp/definition.js +256 -302
- package/dist/adapter/z-stack/znp/definition.js.map +1 -1
- package/dist/adapter/z-stack/znp/tstype.d.ts +8 -8
- package/dist/adapter/z-stack/znp/tstype.d.ts.map +1 -1
- package/dist/adapter/z-stack/znp/utils.d.ts +3 -2
- package/dist/adapter/z-stack/znp/utils.d.ts.map +1 -1
- package/dist/adapter/z-stack/znp/utils.js +8 -7
- package/dist/adapter/z-stack/znp/utils.js.map +1 -1
- package/dist/adapter/z-stack/znp/znp.d.ts +3 -1
- package/dist/adapter/z-stack/znp/znp.d.ts.map +1 -1
- package/dist/adapter/z-stack/znp/znp.js +31 -14
- package/dist/adapter/z-stack/znp/znp.js.map +1 -1
- package/dist/adapter/z-stack/znp/zpiObject.d.ts +5 -6
- package/dist/adapter/z-stack/znp/zpiObject.d.ts.map +1 -1
- package/dist/adapter/z-stack/znp/zpiObject.js +28 -11
- package/dist/adapter/z-stack/znp/zpiObject.js.map +1 -1
- package/dist/adapter/zboss/adapter/zbossAdapter.d.ts +8 -16
- package/dist/adapter/zboss/adapter/zbossAdapter.d.ts.map +1 -1
- package/dist/adapter/zboss/adapter/zbossAdapter.js +124 -162
- package/dist/adapter/zboss/adapter/zbossAdapter.js.map +1 -1
- package/dist/adapter/zboss/commands.d.ts +3 -0
- package/dist/adapter/zboss/commands.d.ts.map +1 -1
- package/dist/adapter/zboss/commands.js +248 -205
- package/dist/adapter/zboss/commands.js.map +1 -1
- package/dist/adapter/zboss/driver.d.ts +4 -14
- package/dist/adapter/zboss/driver.d.ts.map +1 -1
- package/dist/adapter/zboss/driver.js +63 -89
- package/dist/adapter/zboss/driver.js.map +1 -1
- package/dist/adapter/zboss/enums.d.ts +24 -2
- package/dist/adapter/zboss/enums.d.ts.map +1 -1
- package/dist/adapter/zboss/enums.js +35 -3
- package/dist/adapter/zboss/enums.js.map +1 -1
- package/dist/adapter/zboss/frame.d.ts +6 -1
- package/dist/adapter/zboss/frame.d.ts.map +1 -1
- package/dist/adapter/zboss/frame.js +56 -11
- package/dist/adapter/zboss/frame.js.map +1 -1
- package/dist/adapter/zboss/uart.d.ts +1 -0
- package/dist/adapter/zboss/uart.d.ts.map +1 -1
- package/dist/adapter/zboss/uart.js +4 -2
- package/dist/adapter/zboss/uart.js.map +1 -1
- package/dist/adapter/zigate/adapter/patchZdoBuffaloBE.d.ts +5 -0
- package/dist/adapter/zigate/adapter/patchZdoBuffaloBE.d.ts.map +1 -0
- package/dist/adapter/zigate/adapter/patchZdoBuffaloBE.js +44 -0
- package/dist/adapter/zigate/adapter/patchZdoBuffaloBE.js.map +1 -0
- package/dist/adapter/zigate/adapter/zigateAdapter.d.ts +6 -10
- package/dist/adapter/zigate/adapter/zigateAdapter.d.ts.map +1 -1
- package/dist/adapter/zigate/adapter/zigateAdapter.js +99 -289
- package/dist/adapter/zigate/adapter/zigateAdapter.js.map +1 -1
- package/dist/adapter/zigate/driver/buffaloZiGate.d.ts.map +1 -1
- package/dist/adapter/zigate/driver/buffaloZiGate.js +2 -18
- package/dist/adapter/zigate/driver/buffaloZiGate.js.map +1 -1
- package/dist/adapter/zigate/driver/commandType.js +218 -218
- package/dist/adapter/zigate/driver/commandType.js.map +1 -1
- package/dist/adapter/zigate/driver/constants.d.ts +14 -8
- package/dist/adapter/zigate/driver/constants.d.ts.map +1 -1
- package/dist/adapter/zigate/driver/constants.js +36 -9
- package/dist/adapter/zigate/driver/constants.js.map +1 -1
- package/dist/adapter/zigate/driver/messageType.js +42 -42
- package/dist/adapter/zigate/driver/messageType.js.map +1 -1
- package/dist/adapter/zigate/driver/zigate.d.ts +17 -13
- package/dist/adapter/zigate/driver/zigate.d.ts.map +1 -1
- package/dist/adapter/zigate/driver/zigate.js +83 -18
- package/dist/adapter/zigate/driver/zigate.js.map +1 -1
- package/dist/controller/controller.d.ts +5 -0
- package/dist/controller/controller.d.ts.map +1 -1
- package/dist/controller/controller.js +143 -37
- package/dist/controller/controller.js.map +1 -1
- package/dist/controller/greenPower.js +3 -3
- package/dist/controller/greenPower.js.map +1 -1
- package/dist/controller/model/device.d.ts +8 -7
- package/dist/controller/model/device.d.ts.map +1 -1
- package/dist/controller/model/device.js +176 -72
- package/dist/controller/model/device.js.map +1 -1
- package/dist/controller/model/endpoint.d.ts +1 -0
- package/dist/controller/model/endpoint.d.ts.map +1 -1
- package/dist/controller/model/endpoint.js +27 -4
- package/dist/controller/model/endpoint.js.map +1 -1
- package/dist/zspec/zdo/buffaloZdo.d.ts +1 -139
- package/dist/zspec/zdo/buffaloZdo.d.ts.map +1 -1
- package/dist/zspec/zdo/buffaloZdo.js.map +1 -1
- package/dist/zspec/zdo/definition/tstypes.d.ts +168 -1
- package/dist/zspec/zdo/definition/tstypes.d.ts.map +1 -1
- package/dist/zspec/zdo/definition/tstypes.js +1 -0
- package/dist/zspec/zdo/definition/tstypes.js.map +1 -1
- package/dist/zspec/zdo/utils.d.ts +2 -3
- package/dist/zspec/zdo/utils.d.ts.map +1 -1
- package/dist/zspec/zdo/utils.js +3 -4
- package/dist/zspec/zdo/utils.js.map +1 -1
- 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
|
|
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
|
-
|
|
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
|
|
179
|
-
|
|
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
|
|
235
|
-
|
|
236
|
-
const result = await
|
|
237
|
-
|
|
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
|
|
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
|
-
|
|
258
|
-
return result;
|
|
313
|
+
await this.znp.requestZdo(clusterId, payload, waiter?.ID);
|
|
259
314
|
}
|
|
260
315
|
catch (error) {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
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
|
-
|
|
269
|
-
|
|
270
|
-
|
|
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
|
-
|
|
546
|
+
// TODO: better way???
|
|
627
547
|
/* istanbul ignore else */
|
|
628
|
-
if (Zdo.Buffalo.checkStatus(
|
|
629
|
-
const
|
|
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 =
|
|
551
|
+
const isEndDevice = zdoPayload.capabilities.deviceType === 0;
|
|
635
552
|
if (isEndDevice) {
|
|
636
|
-
if (!this.deviceAnnounceRouteDiscoveryDebouncers.has(
|
|
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(
|
|
644
|
-
},
|
|
560
|
+
this.discoverRoute(zdoPayload.nwkAddress, false).catch(() => { });
|
|
561
|
+
}, zdoPayload.nwkAddress);
|
|
645
562
|
}, 60 * 1000, { immediate: true });
|
|
646
|
-
this.deviceAnnounceRouteDiscoveryDebouncers.set(
|
|
563
|
+
this.deviceAnnounceRouteDiscoveryDebouncers.set(zdoPayload.nwkAddress, debouncer);
|
|
647
564
|
}
|
|
648
|
-
const debouncer = this.deviceAnnounceRouteDiscoveryDebouncers.get(
|
|
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
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
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',
|
|
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
|
|
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),
|