zigbee-herdsman 6.0.1 → 6.0.3
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/CHANGELOG.md +16 -0
- package/dist/adapter/ezsp/driver/uart.js +1 -1
- package/dist/adapter/ezsp/driver/uart.js.map +1 -1
- package/dist/adapter/z-stack/adapter/zStackAdapter.js +4 -4
- package/dist/adapter/z-stack/adapter/zStackAdapter.js.map +1 -1
- package/dist/adapter/zigate/adapter/zigateAdapter.js +4 -4
- package/dist/adapter/zigate/adapter/zigateAdapter.js.map +1 -1
- package/dist/controller/model/device.d.ts.map +1 -1
- package/dist/controller/model/device.js +1 -0
- package/dist/controller/model/device.js.map +1 -1
- package/package.json +14 -6
- package/.github/ISSUE_TEMPLATE/config.yml +0 -5
- package/.github/dependabot.yml +0 -22
- package/.github/workflows/ci.yml +0 -64
- package/.github/workflows/release-please.yml +0 -18
- package/.github/workflows/stale.yml +0 -20
- package/.github/workflows/typedoc.yaml +0 -47
- package/.release-please-manifest.json +0 -3
- package/.vscode/extensions.json +0 -3
- package/.vscode/settings.json +0 -11
- package/biome.json +0 -98
- package/examples/join-and-log.js +0 -24
- package/release-please-config.json +0 -9
- package/src/adapter/adapter.ts +0 -189
- package/src/adapter/adapterDiscovery.ts +0 -666
- package/src/adapter/const.ts +0 -12
- package/src/adapter/deconz/adapter/deconzAdapter.ts +0 -877
- package/src/adapter/deconz/driver/constants.ts +0 -246
- package/src/adapter/deconz/driver/driver.ts +0 -1540
- package/src/adapter/deconz/driver/frame.ts +0 -11
- package/src/adapter/deconz/driver/frameParser.ts +0 -753
- package/src/adapter/deconz/driver/parser.ts +0 -45
- package/src/adapter/deconz/driver/writer.ts +0 -22
- package/src/adapter/deconz/types.d.ts +0 -13
- package/src/adapter/ember/adapter/emberAdapter.ts +0 -2265
- package/src/adapter/ember/adapter/endpoints.ts +0 -86
- package/src/adapter/ember/adapter/oneWaitress.ts +0 -324
- package/src/adapter/ember/adapter/tokensManager.ts +0 -782
- package/src/adapter/ember/consts.ts +0 -178
- package/src/adapter/ember/enums.ts +0 -1746
- package/src/adapter/ember/ezsp/buffalo.ts +0 -1392
- package/src/adapter/ember/ezsp/consts.ts +0 -148
- package/src/adapter/ember/ezsp/enums.ts +0 -1114
- package/src/adapter/ember/ezsp/ezsp.ts +0 -9061
- package/src/adapter/ember/ezspError.ts +0 -10
- package/src/adapter/ember/types.ts +0 -866
- package/src/adapter/ember/uart/ash.ts +0 -1960
- package/src/adapter/ember/uart/consts.ts +0 -109
- package/src/adapter/ember/uart/enums.ts +0 -192
- package/src/adapter/ember/uart/parser.ts +0 -48
- package/src/adapter/ember/uart/queues.ts +0 -247
- package/src/adapter/ember/uart/writer.ts +0 -53
- package/src/adapter/ember/utils/initters.ts +0 -58
- package/src/adapter/ember/utils/math.ts +0 -73
- package/src/adapter/events.ts +0 -21
- package/src/adapter/ezsp/adapter/backup.ts +0 -109
- package/src/adapter/ezsp/adapter/ezspAdapter.ts +0 -614
- package/src/adapter/ezsp/driver/commands.ts +0 -2497
- package/src/adapter/ezsp/driver/consts.ts +0 -11
- package/src/adapter/ezsp/driver/driver.ts +0 -1002
- package/src/adapter/ezsp/driver/ezsp.ts +0 -802
- package/src/adapter/ezsp/driver/frame.ts +0 -101
- package/src/adapter/ezsp/driver/index.ts +0 -4
- package/src/adapter/ezsp/driver/multicast.ts +0 -78
- package/src/adapter/ezsp/driver/parser.ts +0 -81
- package/src/adapter/ezsp/driver/types/basic.ts +0 -201
- package/src/adapter/ezsp/driver/types/index.ts +0 -239
- package/src/adapter/ezsp/driver/types/named.ts +0 -2330
- package/src/adapter/ezsp/driver/types/struct.ts +0 -844
- package/src/adapter/ezsp/driver/uart.ts +0 -460
- package/src/adapter/ezsp/driver/utils/crc16ccitt.ts +0 -44
- package/src/adapter/ezsp/driver/utils/index.ts +0 -32
- package/src/adapter/ezsp/driver/writer.ts +0 -64
- package/src/adapter/index.ts +0 -3
- package/src/adapter/serialPort.ts +0 -58
- package/src/adapter/socketPortUtils.ts +0 -16
- package/src/adapter/tstype.ts +0 -78
- package/src/adapter/z-stack/adapter/adapter-backup.ts +0 -519
- package/src/adapter/z-stack/adapter/adapter-nv-memory.ts +0 -457
- package/src/adapter/z-stack/adapter/endpoints.ts +0 -57
- package/src/adapter/z-stack/adapter/manager.ts +0 -543
- package/src/adapter/z-stack/adapter/tstype.ts +0 -6
- package/src/adapter/z-stack/adapter/zStackAdapter.ts +0 -1190
- package/src/adapter/z-stack/constants/af.ts +0 -27
- package/src/adapter/z-stack/constants/common.ts +0 -285
- package/src/adapter/z-stack/constants/dbg.ts +0 -23
- package/src/adapter/z-stack/constants/index.ts +0 -11
- package/src/adapter/z-stack/constants/mac.ts +0 -128
- package/src/adapter/z-stack/constants/sapi.ts +0 -25
- package/src/adapter/z-stack/constants/sys.ts +0 -72
- package/src/adapter/z-stack/constants/util.ts +0 -82
- package/src/adapter/z-stack/constants/utils.ts +0 -14
- package/src/adapter/z-stack/constants/zdo.ts +0 -103
- package/src/adapter/z-stack/models/startup-options.ts +0 -13
- package/src/adapter/z-stack/structs/entries/address-manager-entry.ts +0 -44
- package/src/adapter/z-stack/structs/entries/address-manager-table.ts +0 -19
- package/src/adapter/z-stack/structs/entries/aps-link-key-data-entry.ts +0 -12
- package/src/adapter/z-stack/structs/entries/aps-link-key-data-table.ts +0 -21
- package/src/adapter/z-stack/structs/entries/aps-tc-link-key-entry.ts +0 -19
- package/src/adapter/z-stack/structs/entries/aps-tc-link-key-table.ts +0 -21
- package/src/adapter/z-stack/structs/entries/channel-list.ts +0 -8
- package/src/adapter/z-stack/structs/entries/has-configured.ts +0 -16
- package/src/adapter/z-stack/structs/entries/index.ts +0 -16
- package/src/adapter/z-stack/structs/entries/nib.ts +0 -66
- package/src/adapter/z-stack/structs/entries/nwk-key-descriptor.ts +0 -15
- package/src/adapter/z-stack/structs/entries/nwk-key.ts +0 -13
- package/src/adapter/z-stack/structs/entries/nwk-pan-id.ts +0 -8
- package/src/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-entry.ts +0 -20
- package/src/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-table.ts +0 -19
- package/src/adapter/z-stack/structs/entries/security-manager-entry.ts +0 -33
- package/src/adapter/z-stack/structs/entries/security-manager-table.ts +0 -22
- package/src/adapter/z-stack/structs/index.ts +0 -4
- package/src/adapter/z-stack/structs/serializable-memory-object.ts +0 -14
- package/src/adapter/z-stack/structs/struct.ts +0 -367
- package/src/adapter/z-stack/structs/table.ts +0 -198
- package/src/adapter/z-stack/unpi/constants.ts +0 -33
- package/src/adapter/z-stack/unpi/frame.ts +0 -62
- package/src/adapter/z-stack/unpi/index.ts +0 -4
- package/src/adapter/z-stack/unpi/parser.ts +0 -56
- package/src/adapter/z-stack/unpi/writer.ts +0 -21
- package/src/adapter/z-stack/utils/channel-list.ts +0 -40
- package/src/adapter/z-stack/utils/index.ts +0 -2
- package/src/adapter/z-stack/utils/network-options.ts +0 -26
- package/src/adapter/z-stack/znp/buffaloZnp.ts +0 -175
- package/src/adapter/z-stack/znp/definition.ts +0 -2713
- package/src/adapter/z-stack/znp/index.ts +0 -2
- package/src/adapter/z-stack/znp/parameterType.ts +0 -22
- package/src/adapter/z-stack/znp/tstype.ts +0 -44
- package/src/adapter/z-stack/znp/utils.ts +0 -10
- package/src/adapter/z-stack/znp/znp.ts +0 -342
- package/src/adapter/z-stack/znp/zpiObject.ts +0 -148
- package/src/adapter/zboss/adapter/zbossAdapter.ts +0 -526
- package/src/adapter/zboss/commands.ts +0 -1184
- package/src/adapter/zboss/consts.ts +0 -9
- package/src/adapter/zboss/driver.ts +0 -422
- package/src/adapter/zboss/enums.ts +0 -360
- package/src/adapter/zboss/frame.ts +0 -227
- package/src/adapter/zboss/reader.ts +0 -65
- package/src/adapter/zboss/types.ts +0 -0
- package/src/adapter/zboss/uart.ts +0 -428
- package/src/adapter/zboss/utils.ts +0 -58
- package/src/adapter/zboss/writer.ts +0 -49
- package/src/adapter/zigate/adapter/patchZdoBuffaloBE.ts +0 -27
- package/src/adapter/zigate/adapter/zigateAdapter.ts +0 -618
- package/src/adapter/zigate/driver/LICENSE +0 -17
- package/src/adapter/zigate/driver/buffaloZiGate.ts +0 -212
- package/src/adapter/zigate/driver/commandType.ts +0 -418
- package/src/adapter/zigate/driver/constants.ts +0 -150
- package/src/adapter/zigate/driver/frame.ts +0 -197
- package/src/adapter/zigate/driver/messageType.ts +0 -287
- package/src/adapter/zigate/driver/parameterType.ts +0 -32
- package/src/adapter/zigate/driver/ziGateObject.ts +0 -146
- package/src/adapter/zigate/driver/zigate.ts +0 -423
- package/src/adapter/zoh/adapter/utils.ts +0 -27
- package/src/adapter/zoh/adapter/zohAdapter.ts +0 -838
- package/src/buffalo/buffalo.ts +0 -342
- package/src/buffalo/index.ts +0 -1
- package/src/controller/controller.ts +0 -1022
- package/src/controller/database.ts +0 -124
- package/src/controller/events.ts +0 -52
- package/src/controller/greenPower.ts +0 -603
- package/src/controller/helpers/index.ts +0 -1
- package/src/controller/helpers/installCodes.ts +0 -107
- package/src/controller/helpers/request.ts +0 -96
- package/src/controller/helpers/requestQueue.ts +0 -125
- package/src/controller/helpers/zclFrameConverter.ts +0 -47
- package/src/controller/helpers/zclTransactionSequenceNumber.ts +0 -19
- package/src/controller/index.ts +0 -6
- package/src/controller/model/device.ts +0 -1248
- package/src/controller/model/endpoint.ts +0 -1105
- package/src/controller/model/entity.ts +0 -23
- package/src/controller/model/group.ts +0 -424
- package/src/controller/model/index.ts +0 -5
- package/src/controller/model/zigbeeEntity.ts +0 -30
- package/src/controller/touchlink.ts +0 -189
- package/src/controller/tstype.ts +0 -274
- package/src/index.ts +0 -12
- package/src/models/backup-storage-legacy.ts +0 -48
- package/src/models/backup-storage-unified.ts +0 -47
- package/src/models/backup.ts +0 -37
- package/src/models/index.ts +0 -5
- package/src/models/network-options.ts +0 -11
- package/src/utils/backup.ts +0 -152
- package/src/utils/index.ts +0 -5
- package/src/utils/logger.ts +0 -20
- package/src/utils/patchBigIntSerialization.ts +0 -8
- package/src/utils/queue.ts +0 -76
- package/src/utils/types.d.ts +0 -3
- package/src/utils/utils.ts +0 -19
- package/src/utils/wait.ts +0 -5
- package/src/utils/waitress.ts +0 -96
- package/src/zspec/consts.ts +0 -84
- package/src/zspec/enums.ts +0 -22
- package/src/zspec/index.ts +0 -3
- package/src/zspec/tstypes.ts +0 -18
- package/src/zspec/utils.ts +0 -247
- package/src/zspec/zcl/buffaloZcl.ts +0 -1220
- package/src/zspec/zcl/definition/cluster.ts +0 -5915
- package/src/zspec/zcl/definition/clusters-typegen.ts +0 -588
- package/src/zspec/zcl/definition/clusters-types.ts +0 -7331
- package/src/zspec/zcl/definition/consts.ts +0 -24
- package/src/zspec/zcl/definition/enums.ts +0 -203
- package/src/zspec/zcl/definition/foundation.ts +0 -329
- package/src/zspec/zcl/definition/manufacturerCode.ts +0 -729
- package/src/zspec/zcl/definition/status.ts +0 -69
- package/src/zspec/zcl/definition/tstype.ts +0 -377
- package/src/zspec/zcl/index.ts +0 -11
- package/src/zspec/zcl/utils.ts +0 -321
- package/src/zspec/zcl/zclFrame.ts +0 -356
- package/src/zspec/zcl/zclHeader.ts +0 -102
- package/src/zspec/zcl/zclStatusError.ts +0 -10
- package/src/zspec/zdo/buffaloZdo.ts +0 -2336
- package/src/zspec/zdo/definition/clusters.ts +0 -722
- package/src/zspec/zdo/definition/consts.ts +0 -16
- package/src/zspec/zdo/definition/enums.ts +0 -99
- package/src/zspec/zdo/definition/status.ts +0 -105
- package/src/zspec/zdo/definition/tstypes.ts +0 -1062
- package/src/zspec/zdo/index.ts +0 -7
- package/src/zspec/zdo/utils.ts +0 -76
- package/src/zspec/zdo/zdoStatusError.ts +0 -10
- package/test/adapter/adapter.test.ts +0 -1062
- package/test/adapter/ember/ash.test.ts +0 -337
- package/test/adapter/ember/consts.ts +0 -131
- package/test/adapter/ember/emberAdapter.test.ts +0 -3449
- package/test/adapter/ember/ezsp.test.ts +0 -385
- package/test/adapter/ember/ezspBuffalo.test.ts +0 -93
- package/test/adapter/ember/ezspError.test.ts +0 -12
- package/test/adapter/ember/math.test.ts +0 -206
- package/test/adapter/ezsp/frame.test.ts +0 -30
- package/test/adapter/ezsp/uart.test.ts +0 -181
- package/test/adapter/z-stack/adapter.test.ts +0 -3984
- package/test/adapter/z-stack/constants.test.ts +0 -33
- package/test/adapter/z-stack/structs.test.ts +0 -115
- package/test/adapter/z-stack/unpi.test.ts +0 -213
- package/test/adapter/z-stack/znp.test.ts +0 -1284
- package/test/adapter/zboss/fixZdoResponse.test.ts +0 -179
- package/test/adapter/zigate/patchZdoBuffaloBE.test.ts +0 -81
- package/test/adapter/zigate/zdo.test.ts +0 -187
- package/test/adapter/zoh/utils.test.ts +0 -36
- package/test/adapter/zoh/zohAdapter.test.ts +0 -1307
- package/test/buffalo.test.ts +0 -431
- package/test/controller.bench.ts +0 -193
- package/test/controller.test.ts +0 -8702
- package/test/greenpower.test.ts +0 -1408
- package/test/mockAdapters.ts +0 -65
- package/test/mockDevices.ts +0 -598
- package/test/requests.bench.ts +0 -206
- package/test/testUtils.ts +0 -20
- package/test/tsconfig.json +0 -9
- package/test/utils/math.ts +0 -19
- package/test/utils.test.ts +0 -279
- package/test/vitest.config.mts +0 -27
- package/test/zcl.test.ts +0 -2831
- package/test/zspec/utils.test.ts +0 -68
- package/test/zspec/zcl/buffalo.test.ts +0 -1374
- package/test/zspec/zcl/frame.test.ts +0 -960
- package/test/zspec/zcl/utils.test.ts +0 -273
- package/test/zspec/zdo/buffalo.test.ts +0 -1850
- package/test/zspec/zdo/utils.test.ts +0 -241
- package/tsconfig.json +0 -24
|
@@ -1,614 +0,0 @@
|
|
|
1
|
-
/* v8 ignore start */
|
|
2
|
-
|
|
3
|
-
import assert from "node:assert";
|
|
4
|
-
|
|
5
|
-
import type * as Models from "../../../models";
|
|
6
|
-
import {Queue, Waitress, wait} from "../../../utils";
|
|
7
|
-
import {logger} from "../../../utils/logger";
|
|
8
|
-
import * as ZSpec from "../../../zspec";
|
|
9
|
-
import * as Zcl from "../../../zspec/zcl";
|
|
10
|
-
import * as Zdo from "../../../zspec/zdo";
|
|
11
|
-
import type * as ZdoTypes from "../../../zspec/zdo/definition/tstypes";
|
|
12
|
-
import Adapter from "../../adapter";
|
|
13
|
-
import type {ZclPayload} from "../../events";
|
|
14
|
-
import type {AdapterOptions, CoordinatorVersion, NetworkOptions, NetworkParameters, SerialPortOptions, StartResult} from "../../tstype";
|
|
15
|
-
import {Driver, type EmberIncomingMessage} from "../driver";
|
|
16
|
-
import {EmberEUI64, EmberStatus} from "../driver/types";
|
|
17
|
-
|
|
18
|
-
const NS = "zh:ezsp";
|
|
19
|
-
|
|
20
|
-
interface WaitressMatcher {
|
|
21
|
-
address?: number | string;
|
|
22
|
-
endpoint: number;
|
|
23
|
-
transactionSequenceNumber?: number;
|
|
24
|
-
clusterID: number;
|
|
25
|
-
commandIdentifier: number;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export class EZSPAdapter extends Adapter {
|
|
29
|
-
private driver: Driver;
|
|
30
|
-
private waitress: Waitress<ZclPayload, WaitressMatcher>;
|
|
31
|
-
private interpanLock: boolean;
|
|
32
|
-
private queue: Queue;
|
|
33
|
-
private closing: boolean;
|
|
34
|
-
|
|
35
|
-
public constructor(networkOptions: NetworkOptions, serialPortOptions: SerialPortOptions, backupPath: string, adapterOptions: AdapterOptions) {
|
|
36
|
-
super(networkOptions, serialPortOptions, backupPath, adapterOptions);
|
|
37
|
-
this.hasZdoMessageOverhead = true;
|
|
38
|
-
this.manufacturerID = Zcl.ManufacturerCode.SILICON_LABORATORIES;
|
|
39
|
-
|
|
40
|
-
this.waitress = new Waitress<ZclPayload, WaitressMatcher>(this.waitressValidator, this.waitressTimeoutFormatter);
|
|
41
|
-
this.interpanLock = false;
|
|
42
|
-
this.closing = false;
|
|
43
|
-
|
|
44
|
-
const concurrent = adapterOptions?.concurrent ? adapterOptions.concurrent : 8;
|
|
45
|
-
logger.debug(`Adapter concurrent: ${concurrent}`, NS);
|
|
46
|
-
this.queue = new Queue(concurrent);
|
|
47
|
-
|
|
48
|
-
this.driver = new Driver(this.serialPortOptions, this.networkOptions, backupPath);
|
|
49
|
-
this.driver.on("close", this.onDriverClose.bind(this));
|
|
50
|
-
this.driver.on("deviceJoined", this.handleDeviceJoin.bind(this));
|
|
51
|
-
this.driver.on("deviceLeft", this.handleDeviceLeft.bind(this));
|
|
52
|
-
this.driver.on("incomingMessage", this.processMessage.bind(this));
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
private processMessage(frame: EmberIncomingMessage): void {
|
|
56
|
-
logger.debug(() => `processMessage: ${JSON.stringify(frame)}`, NS);
|
|
57
|
-
|
|
58
|
-
if (frame.apsFrame.profileId === Zdo.ZDO_PROFILE_ID) {
|
|
59
|
-
if (frame.apsFrame.clusterId >= 0x8000 /* response only */) {
|
|
60
|
-
// biome-ignore lint/style/noNonNullAssertion: ignored using `--suppress`
|
|
61
|
-
this.emit("zdoResponse", frame.apsFrame.clusterId, frame.zdoResponse!);
|
|
62
|
-
}
|
|
63
|
-
} else if (frame.apsFrame.profileId === ZSpec.HA_PROFILE_ID || frame.apsFrame.profileId === 0xffff) {
|
|
64
|
-
const payload: ZclPayload = {
|
|
65
|
-
clusterID: frame.apsFrame.clusterId,
|
|
66
|
-
header: Zcl.Header.fromBuffer(frame.message),
|
|
67
|
-
data: frame.message,
|
|
68
|
-
address: frame.sender,
|
|
69
|
-
endpoint: frame.apsFrame.sourceEndpoint,
|
|
70
|
-
linkquality: frame.lqi,
|
|
71
|
-
groupID: frame.apsFrame.groupId ?? 0,
|
|
72
|
-
wasBroadcast: false, // TODO
|
|
73
|
-
destinationEndpoint: frame.apsFrame.destinationEndpoint,
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
this.waitress.resolve(payload);
|
|
77
|
-
this.emit("zclPayload", payload);
|
|
78
|
-
} else if (frame.apsFrame.profileId === ZSpec.TOUCHLINK_PROFILE_ID && frame.senderEui64) {
|
|
79
|
-
// ZLL Frame
|
|
80
|
-
const payload: ZclPayload = {
|
|
81
|
-
clusterID: frame.apsFrame.clusterId,
|
|
82
|
-
header: Zcl.Header.fromBuffer(frame.message),
|
|
83
|
-
data: frame.message,
|
|
84
|
-
address: `0x${frame.senderEui64.toString()}`,
|
|
85
|
-
endpoint: 0xfe,
|
|
86
|
-
linkquality: frame.lqi,
|
|
87
|
-
groupID: 0,
|
|
88
|
-
wasBroadcast: false,
|
|
89
|
-
destinationEndpoint: 1,
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
this.waitress.resolve(payload);
|
|
93
|
-
this.emit("zclPayload", payload);
|
|
94
|
-
} else if (frame.apsFrame.profileId === ZSpec.GP_PROFILE_ID) {
|
|
95
|
-
// GP Frame
|
|
96
|
-
// Only handle when clusterId == 33 (greenPower), some devices send messages with this profileId
|
|
97
|
-
// while the cluster is not greenPower
|
|
98
|
-
// https://github.com/Koenkk/zigbee2mqtt/issues/20838
|
|
99
|
-
if (frame.apsFrame.clusterId === Zcl.Clusters.greenPower.ID) {
|
|
100
|
-
const payload: ZclPayload = {
|
|
101
|
-
header: Zcl.Header.fromBuffer(frame.message),
|
|
102
|
-
clusterID: frame.apsFrame.clusterId,
|
|
103
|
-
data: frame.message,
|
|
104
|
-
address: frame.sender,
|
|
105
|
-
endpoint: frame.apsFrame.sourceEndpoint,
|
|
106
|
-
linkquality: frame.lqi,
|
|
107
|
-
groupID: 0,
|
|
108
|
-
wasBroadcast: true,
|
|
109
|
-
destinationEndpoint: frame.apsFrame.sourceEndpoint,
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
this.waitress.resolve(payload);
|
|
113
|
-
this.emit("zclPayload", payload);
|
|
114
|
-
} else {
|
|
115
|
-
logger.debug("Ignoring GP frame because clusterId is not greenPower", NS);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
private handleDeviceJoin(nwk: number, ieee: EmberEUI64): void {
|
|
121
|
-
logger.debug(() => `Device join request received: ${nwk} ${ieee.toString()}`, NS);
|
|
122
|
-
|
|
123
|
-
this.emit("deviceJoined", {
|
|
124
|
-
networkAddress: nwk,
|
|
125
|
-
ieeeAddr: `0x${ieee.toString()}`,
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
private handleDeviceLeft(nwk: number, ieee: EmberEUI64): void {
|
|
130
|
-
logger.debug(() => `Device left network request received: ${nwk} ${ieee.toString()}`, NS);
|
|
131
|
-
|
|
132
|
-
this.emit("deviceLeave", {
|
|
133
|
-
networkAddress: nwk,
|
|
134
|
-
ieeeAddr: `0x${ieee.toString()}`,
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Adapter methods
|
|
140
|
-
*/
|
|
141
|
-
public async start(): Promise<StartResult> {
|
|
142
|
-
logger.warning(
|
|
143
|
-
`'ezsp' driver is deprecated and will only remain to provide support for older firmware (pre 7.4.x). Migration to 'ember' is recommended. If using Zigbee2MQTT see https://github.com/Koenkk/zigbee2mqtt/discussions/21462`,
|
|
144
|
-
NS,
|
|
145
|
-
);
|
|
146
|
-
return await this.driver.startup(this.adapterOptions.transmitPower);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
public async stop(): Promise<void> {
|
|
150
|
-
this.closing = true;
|
|
151
|
-
await this.driver.stop();
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
public onDriverClose(): void {
|
|
155
|
-
logger.debug("onDriverClose()", NS);
|
|
156
|
-
|
|
157
|
-
if (!this.closing) {
|
|
158
|
-
this.emit("disconnected");
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
public async getCoordinatorIEEE(): Promise<string> {
|
|
163
|
-
return await Promise.resolve(`0x${this.driver.ieee.toString()}`);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
public async permitJoin(seconds: number, networkAddress?: number): Promise<void> {
|
|
167
|
-
if (!this.driver.ezsp.isInitialized()) {
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const clusterId = Zdo.ClusterId.PERMIT_JOINING_REQUEST;
|
|
172
|
-
|
|
173
|
-
if (networkAddress) {
|
|
174
|
-
// specific device that is not `Coordinator`
|
|
175
|
-
await this.queue.execute<void>(async () => {
|
|
176
|
-
this.checkInterpanLock();
|
|
177
|
-
await this.driver.preJoining(seconds);
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
// `authentication`: TC significance always 1 (zb specs)
|
|
181
|
-
const zdoPayload = Zdo.Buffalo.buildRequest(this.hasZdoMessageOverhead, clusterId, seconds, 1, []);
|
|
182
|
-
|
|
183
|
-
const result = await this.sendZdo(ZSpec.BLANK_EUI64, networkAddress, clusterId, zdoPayload, false);
|
|
184
|
-
|
|
185
|
-
if (!Zdo.Buffalo.checkStatus<Zdo.ClusterId.PERMIT_JOINING_RESPONSE>(result)) {
|
|
186
|
-
// TODO: will disappear once moved upstream
|
|
187
|
-
throw new Zdo.StatusError(result[0]);
|
|
188
|
-
}
|
|
189
|
-
} else {
|
|
190
|
-
// coordinator-only (0), or all
|
|
191
|
-
await this.queue.execute<void>(async () => {
|
|
192
|
-
this.checkInterpanLock();
|
|
193
|
-
await this.driver.preJoining(seconds);
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
const result = await this.driver.permitJoining(seconds);
|
|
197
|
-
|
|
198
|
-
if (result.status !== EmberStatus.SUCCESS) {
|
|
199
|
-
throw new Error(`[ZDO] Failed coordinator permit joining request with status=${result.status}.`);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
logger.debug(`Permit joining on coordinator for ${seconds} sec.`, NS);
|
|
203
|
-
|
|
204
|
-
// broadcast permit joining ZDO
|
|
205
|
-
if (networkAddress === undefined) {
|
|
206
|
-
// `authentication`: TC significance always 1 (zb specs)
|
|
207
|
-
const zdoPayload = Zdo.Buffalo.buildRequest(this.hasZdoMessageOverhead, clusterId, seconds, 1, []);
|
|
208
|
-
|
|
209
|
-
await this.sendZdo(ZSpec.BLANK_EUI64, ZSpec.BroadcastAddress.DEFAULT, clusterId, zdoPayload, true);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
public async getCoordinatorVersion(): Promise<CoordinatorVersion> {
|
|
215
|
-
return await Promise.resolve({type: `EZSP v${this.driver.version.product}`, meta: this.driver.version});
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
public async addInstallCode(ieeeAddress: string, key: Buffer, hashed: boolean): Promise<void> {
|
|
219
|
-
if ([8, 10, 14, 16, 18].indexOf(key.length) === -1) {
|
|
220
|
-
throw new Error("Wrong install code length");
|
|
221
|
-
}
|
|
222
|
-
await this.driver.addInstallCode(ieeeAddress, key, hashed);
|
|
223
|
-
}
|
|
224
|
-
public async reset(_type: "soft" | "hard"): Promise<void> {
|
|
225
|
-
return await Promise.reject(new Error("Not supported"));
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
public async sendZdo(
|
|
229
|
-
ieeeAddress: string,
|
|
230
|
-
networkAddress: number,
|
|
231
|
-
clusterId: Zdo.ClusterId,
|
|
232
|
-
payload: Buffer,
|
|
233
|
-
disableResponse: true,
|
|
234
|
-
): Promise<void>;
|
|
235
|
-
public async sendZdo<K extends keyof ZdoTypes.RequestToResponseMap>(
|
|
236
|
-
ieeeAddress: string,
|
|
237
|
-
networkAddress: number,
|
|
238
|
-
clusterId: K,
|
|
239
|
-
payload: Buffer,
|
|
240
|
-
disableResponse: false,
|
|
241
|
-
): Promise<ZdoTypes.RequestToResponseMap[K]>;
|
|
242
|
-
public async sendZdo<K extends keyof ZdoTypes.RequestToResponseMap>(
|
|
243
|
-
ieeeAddress: string,
|
|
244
|
-
networkAddress: number,
|
|
245
|
-
clusterId: K,
|
|
246
|
-
payload: Buffer,
|
|
247
|
-
disableResponse: boolean,
|
|
248
|
-
): Promise<ZdoTypes.RequestToResponseMap[K] | undefined> {
|
|
249
|
-
return await this.queue.execute(async () => {
|
|
250
|
-
this.checkInterpanLock();
|
|
251
|
-
|
|
252
|
-
const clusterName = Zdo.ClusterId[clusterId];
|
|
253
|
-
const frame = this.driver.makeApsFrame(clusterId, disableResponse);
|
|
254
|
-
payload[0] = frame.sequence;
|
|
255
|
-
let waiter: ReturnType<typeof this.driver.waitFor> | undefined;
|
|
256
|
-
let responseClusterId: number | undefined;
|
|
257
|
-
|
|
258
|
-
if (!disableResponse) {
|
|
259
|
-
responseClusterId = Zdo.Utils.getResponseClusterId(clusterId);
|
|
260
|
-
|
|
261
|
-
if (responseClusterId) {
|
|
262
|
-
waiter = this.driver.waitFor(
|
|
263
|
-
responseClusterId === Zdo.ClusterId.NETWORK_ADDRESS_RESPONSE ? ieeeAddress : networkAddress,
|
|
264
|
-
responseClusterId,
|
|
265
|
-
frame.sequence,
|
|
266
|
-
);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if (ZSpec.Utils.isBroadcastAddress(networkAddress)) {
|
|
271
|
-
logger.debug(() => `~~~> [ZDO ${clusterName} BROADCAST to=${networkAddress} payload=${payload.toString("hex")}]`, NS);
|
|
272
|
-
|
|
273
|
-
const req = await this.driver.brequest(networkAddress, frame, payload);
|
|
274
|
-
|
|
275
|
-
logger.debug("~~~> [SENT ZDO BROADCAST]", NS);
|
|
276
|
-
|
|
277
|
-
if (!req) {
|
|
278
|
-
waiter?.cancel();
|
|
279
|
-
throw new Error(`~x~> [ZDO ${clusterName} BROADCAST to=${networkAddress}] Failed to send request.`);
|
|
280
|
-
}
|
|
281
|
-
} else {
|
|
282
|
-
logger.debug(() => `~~~> [ZDO ${clusterName} UNICAST to=${ieeeAddress}:${networkAddress} payload=${payload.toString("hex")}]`, NS);
|
|
283
|
-
|
|
284
|
-
const req = await this.driver.request(networkAddress, frame, payload);
|
|
285
|
-
|
|
286
|
-
logger.debug("~~~> [SENT ZDO UNICAST]", NS);
|
|
287
|
-
|
|
288
|
-
if (!req) {
|
|
289
|
-
waiter?.cancel();
|
|
290
|
-
throw new Error(`~x~> [ZDO ${clusterName} UNICAST to=${ieeeAddress}:${networkAddress}] Failed to send request.`);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
if (waiter && responseClusterId !== undefined) {
|
|
295
|
-
const response = await waiter.start().promise;
|
|
296
|
-
|
|
297
|
-
logger.debug(
|
|
298
|
-
() =>
|
|
299
|
-
`<~~ [ZDO ${Zdo.ClusterId[responseClusterId]} ${
|
|
300
|
-
// biome-ignore lint/style/noNonNullAssertion: ignored using `--suppress`
|
|
301
|
-
JSON.stringify(response.zdoResponse!)
|
|
302
|
-
}]`,
|
|
303
|
-
NS,
|
|
304
|
-
);
|
|
305
|
-
|
|
306
|
-
// biome-ignore lint/style/noNonNullAssertion: ignored using `--suppress`
|
|
307
|
-
return response.zdoResponse! as ZdoTypes.RequestToResponseMap[K];
|
|
308
|
-
}
|
|
309
|
-
}, networkAddress);
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
public async sendZclFrameToEndpoint(
|
|
313
|
-
ieeeAddr: string,
|
|
314
|
-
networkAddress: number,
|
|
315
|
-
endpoint: number,
|
|
316
|
-
zclFrame: Zcl.Frame,
|
|
317
|
-
timeout: number,
|
|
318
|
-
disableResponse: boolean,
|
|
319
|
-
disableRecovery: boolean,
|
|
320
|
-
sourceEndpoint?: number,
|
|
321
|
-
): Promise<ZclPayload | undefined> {
|
|
322
|
-
return await this.queue.execute<ZclPayload | undefined>(async () => {
|
|
323
|
-
this.checkInterpanLock();
|
|
324
|
-
return await this.sendZclFrameToEndpointInternal(
|
|
325
|
-
ieeeAddr,
|
|
326
|
-
networkAddress,
|
|
327
|
-
endpoint,
|
|
328
|
-
sourceEndpoint || 1,
|
|
329
|
-
zclFrame,
|
|
330
|
-
timeout,
|
|
331
|
-
disableResponse,
|
|
332
|
-
disableRecovery,
|
|
333
|
-
0,
|
|
334
|
-
0,
|
|
335
|
-
);
|
|
336
|
-
}, networkAddress);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
private async sendZclFrameToEndpointInternal(
|
|
340
|
-
ieeeAddr: string | undefined,
|
|
341
|
-
networkAddress: number,
|
|
342
|
-
endpoint: number,
|
|
343
|
-
sourceEndpoint: number,
|
|
344
|
-
zclFrame: Zcl.Frame,
|
|
345
|
-
timeout: number,
|
|
346
|
-
disableResponse: boolean,
|
|
347
|
-
disableRecovery: boolean,
|
|
348
|
-
responseAttempt: number,
|
|
349
|
-
dataRequestAttempt: number,
|
|
350
|
-
): Promise<ZclPayload | undefined> {
|
|
351
|
-
if (ieeeAddr == null) {
|
|
352
|
-
ieeeAddr = `0x${this.driver.ieee.toString()}`;
|
|
353
|
-
}
|
|
354
|
-
logger.debug(
|
|
355
|
-
`sendZclFrameToEndpointInternal ${ieeeAddr}:${networkAddress}/${endpoint} ` +
|
|
356
|
-
`(${responseAttempt},${dataRequestAttempt},${this.queue.count()}), timeout=${timeout}`,
|
|
357
|
-
NS,
|
|
358
|
-
);
|
|
359
|
-
let response = null;
|
|
360
|
-
const command = zclFrame.command;
|
|
361
|
-
if (command.response !== undefined && disableResponse === false) {
|
|
362
|
-
response = this.waitForInternal(
|
|
363
|
-
networkAddress,
|
|
364
|
-
endpoint,
|
|
365
|
-
zclFrame.header.transactionSequenceNumber,
|
|
366
|
-
zclFrame.cluster.ID,
|
|
367
|
-
command.response,
|
|
368
|
-
timeout,
|
|
369
|
-
);
|
|
370
|
-
} else if (!zclFrame.header.frameControl.disableDefaultResponse) {
|
|
371
|
-
response = this.waitForInternal(
|
|
372
|
-
networkAddress,
|
|
373
|
-
endpoint,
|
|
374
|
-
zclFrame.header.transactionSequenceNumber,
|
|
375
|
-
zclFrame.cluster.ID,
|
|
376
|
-
Zcl.Foundation.defaultRsp.ID,
|
|
377
|
-
timeout,
|
|
378
|
-
);
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
const frame = this.driver.makeApsFrame(zclFrame.cluster.ID, disableResponse || zclFrame.header.frameControl.disableDefaultResponse);
|
|
382
|
-
frame.profileId = ZSpec.HA_PROFILE_ID;
|
|
383
|
-
frame.sourceEndpoint = sourceEndpoint || 0x01;
|
|
384
|
-
frame.destinationEndpoint = endpoint;
|
|
385
|
-
frame.groupId = 0;
|
|
386
|
-
|
|
387
|
-
this.driver.setNode(networkAddress, new EmberEUI64(ieeeAddr));
|
|
388
|
-
const dataConfirmResult = await this.driver.request(networkAddress, frame, zclFrame.toBuffer());
|
|
389
|
-
if (!dataConfirmResult) {
|
|
390
|
-
if (response != null) {
|
|
391
|
-
response.cancel();
|
|
392
|
-
}
|
|
393
|
-
throw new Error("sendZclFrameToEndpointInternal error");
|
|
394
|
-
}
|
|
395
|
-
if (response !== null) {
|
|
396
|
-
try {
|
|
397
|
-
const result = await response.start().promise;
|
|
398
|
-
return result;
|
|
399
|
-
} catch (error) {
|
|
400
|
-
logger.debug(`Response timeout (${ieeeAddr}:${networkAddress},${responseAttempt})`, NS);
|
|
401
|
-
if (responseAttempt < 1 && !disableRecovery) {
|
|
402
|
-
return await this.sendZclFrameToEndpointInternal(
|
|
403
|
-
ieeeAddr,
|
|
404
|
-
networkAddress,
|
|
405
|
-
endpoint,
|
|
406
|
-
sourceEndpoint,
|
|
407
|
-
zclFrame,
|
|
408
|
-
timeout,
|
|
409
|
-
disableResponse,
|
|
410
|
-
disableRecovery,
|
|
411
|
-
responseAttempt + 1,
|
|
412
|
-
dataRequestAttempt,
|
|
413
|
-
);
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
throw error;
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
public async sendZclFrameToGroup(groupID: number, zclFrame: Zcl.Frame): Promise<void> {
|
|
422
|
-
return await this.queue.execute<void>(async () => {
|
|
423
|
-
this.checkInterpanLock();
|
|
424
|
-
const frame = this.driver.makeApsFrame(zclFrame.cluster.ID, false);
|
|
425
|
-
frame.profileId = ZSpec.HA_PROFILE_ID;
|
|
426
|
-
frame.sourceEndpoint = 0x01;
|
|
427
|
-
frame.destinationEndpoint = 0x01;
|
|
428
|
-
frame.groupId = groupID;
|
|
429
|
-
|
|
430
|
-
await this.driver.mrequest(frame, zclFrame.toBuffer());
|
|
431
|
-
/**
|
|
432
|
-
* As a group command is not confirmed and thus immidiately returns
|
|
433
|
-
* (contrary to network address requests) we will give the
|
|
434
|
-
* command some time to 'settle' in the network.
|
|
435
|
-
*/
|
|
436
|
-
await wait(200);
|
|
437
|
-
});
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
public async sendZclFrameToAll(
|
|
441
|
-
endpoint: number,
|
|
442
|
-
zclFrame: Zcl.Frame,
|
|
443
|
-
sourceEndpoint: number,
|
|
444
|
-
destination: ZSpec.BroadcastAddress,
|
|
445
|
-
): Promise<void> {
|
|
446
|
-
return await this.queue.execute<void>(async () => {
|
|
447
|
-
this.checkInterpanLock();
|
|
448
|
-
const frame = this.driver.makeApsFrame(zclFrame.cluster.ID, false);
|
|
449
|
-
frame.profileId = sourceEndpoint === ZSpec.GP_ENDPOINT && endpoint === ZSpec.GP_ENDPOINT ? ZSpec.GP_PROFILE_ID : ZSpec.HA_PROFILE_ID;
|
|
450
|
-
frame.sourceEndpoint = sourceEndpoint;
|
|
451
|
-
frame.destinationEndpoint = endpoint;
|
|
452
|
-
frame.groupId = destination;
|
|
453
|
-
|
|
454
|
-
// XXX: should be:
|
|
455
|
-
// await this.driver.brequest(destination, frame, zclFrame.toBuffer())
|
|
456
|
-
await this.driver.mrequest(frame, zclFrame.toBuffer());
|
|
457
|
-
|
|
458
|
-
/**
|
|
459
|
-
* As a broadcast command is not confirmed and thus immidiately returns
|
|
460
|
-
* (contrary to network address requests) we will give the
|
|
461
|
-
* command some time to 'settle' in the network.
|
|
462
|
-
*/
|
|
463
|
-
await wait(200);
|
|
464
|
-
});
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
public async getNetworkParameters(): Promise<NetworkParameters> {
|
|
468
|
-
return await Promise.resolve({
|
|
469
|
-
panID: this.driver.networkParams.panId,
|
|
470
|
-
extendedPanID: ZSpec.Utils.eui64LEBufferToHex(this.driver.networkParams.extendedPanId),
|
|
471
|
-
channel: this.driver.networkParams.radioChannel,
|
|
472
|
-
nwkUpdateID: this.driver.networkParams.nwkUpdateId,
|
|
473
|
-
});
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
public async supportsBackup(): Promise<boolean> {
|
|
477
|
-
return await Promise.resolve(true);
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
public async backup(): Promise<Models.Backup> {
|
|
481
|
-
assert(this.driver.ezsp.isInitialized(), "Cannot make backup when ezsp is not initialized");
|
|
482
|
-
return await this.driver.backupMan.createBackup();
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
public async restoreChannelInterPAN(): Promise<void> {
|
|
486
|
-
return await this.queue.execute<void>(async () => {
|
|
487
|
-
const channel = (await this.getNetworkParameters()).channel;
|
|
488
|
-
await this.driver.setChannel(channel);
|
|
489
|
-
// Give adapter some time to restore, otherwise stuff crashes
|
|
490
|
-
await wait(3000);
|
|
491
|
-
this.interpanLock = false;
|
|
492
|
-
});
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
private checkInterpanLock(): void {
|
|
496
|
-
if (this.interpanLock) {
|
|
497
|
-
throw new Error("Cannot execute command, in Inter-PAN mode");
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
public async sendZclFrameInterPANToIeeeAddr(zclFrame: Zcl.Frame, ieeeAddr: string): Promise<void> {
|
|
502
|
-
return await this.queue.execute<void>(async () => {
|
|
503
|
-
logger.debug(`sendZclFrameInterPANToIeeeAddr to ${ieeeAddr}`, NS);
|
|
504
|
-
const frame = this.driver.makeEmberIeeeRawFrame();
|
|
505
|
-
frame.ieeeFrameControl = 0xcc21;
|
|
506
|
-
frame.destPanId = 0xffff;
|
|
507
|
-
frame.destAddress = new EmberEUI64(ieeeAddr);
|
|
508
|
-
frame.sourcePanId = this.driver.networkParams.panId;
|
|
509
|
-
frame.sourceAddress = this.driver.ieee;
|
|
510
|
-
frame.nwkFrameControl = 0x000b;
|
|
511
|
-
frame.appFrameControl = 0x03;
|
|
512
|
-
frame.clusterId = zclFrame.cluster.ID;
|
|
513
|
-
frame.profileId = 0xc05e;
|
|
514
|
-
|
|
515
|
-
await this.driver.ieeerawrequest(frame, zclFrame.toBuffer());
|
|
516
|
-
});
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
public async sendZclFrameInterPANBroadcast(zclFrame: Zcl.Frame, timeout: number): Promise<ZclPayload> {
|
|
520
|
-
return await this.queue.execute<ZclPayload>(async () => {
|
|
521
|
-
logger.debug("sendZclFrameInterPANBroadcast", NS);
|
|
522
|
-
const command = zclFrame.command;
|
|
523
|
-
|
|
524
|
-
if (command.response === undefined) {
|
|
525
|
-
throw new Error(`Command '${command.name}' has no response, cannot wait for response`);
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
const response = this.waitForInternal(undefined, 0xfe, undefined, zclFrame.cluster.ID, command.response, timeout);
|
|
529
|
-
|
|
530
|
-
try {
|
|
531
|
-
const frame = this.driver.makeEmberRawFrame();
|
|
532
|
-
frame.ieeeFrameControl = 0xc801;
|
|
533
|
-
frame.destPanId = 0xffff;
|
|
534
|
-
frame.destNodeId = 0xffff;
|
|
535
|
-
frame.sourcePanId = this.driver.networkParams.panId;
|
|
536
|
-
frame.ieeeAddress = this.driver.ieee;
|
|
537
|
-
frame.nwkFrameControl = 0x000b;
|
|
538
|
-
frame.appFrameControl = 0x0b;
|
|
539
|
-
frame.clusterId = zclFrame.cluster.ID;
|
|
540
|
-
frame.profileId = 0xc05e;
|
|
541
|
-
|
|
542
|
-
await this.driver.rawrequest(frame, zclFrame.toBuffer());
|
|
543
|
-
} catch (error) {
|
|
544
|
-
response.cancel();
|
|
545
|
-
throw error;
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
return await response.start().promise;
|
|
549
|
-
});
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
public async setChannelInterPAN(channel: number): Promise<void> {
|
|
553
|
-
return await this.queue.execute<void>(async () => {
|
|
554
|
-
this.interpanLock = true;
|
|
555
|
-
await this.driver.setChannel(channel);
|
|
556
|
-
});
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
private waitForInternal(
|
|
560
|
-
networkAddress: number | undefined,
|
|
561
|
-
endpoint: number,
|
|
562
|
-
transactionSequenceNumber: number | undefined,
|
|
563
|
-
clusterID: number,
|
|
564
|
-
commandIdentifier: number,
|
|
565
|
-
timeout: number,
|
|
566
|
-
): {start: () => {promise: Promise<ZclPayload>}; cancel: () => void} {
|
|
567
|
-
const waiter = this.waitress.waitFor(
|
|
568
|
-
{
|
|
569
|
-
address: networkAddress,
|
|
570
|
-
endpoint,
|
|
571
|
-
clusterID,
|
|
572
|
-
commandIdentifier,
|
|
573
|
-
transactionSequenceNumber,
|
|
574
|
-
},
|
|
575
|
-
timeout,
|
|
576
|
-
);
|
|
577
|
-
const cancel = (): void => this.waitress.remove(waiter.ID);
|
|
578
|
-
return {start: waiter.start, cancel};
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
public waitFor(
|
|
582
|
-
networkAddress: number | undefined,
|
|
583
|
-
endpoint: number,
|
|
584
|
-
_frameType: Zcl.FrameType,
|
|
585
|
-
_direction: Zcl.Direction,
|
|
586
|
-
transactionSequenceNumber: number | undefined,
|
|
587
|
-
clusterID: number,
|
|
588
|
-
commandIdentifier: number,
|
|
589
|
-
timeout: number,
|
|
590
|
-
): {promise: Promise<ZclPayload>; cancel: () => void} {
|
|
591
|
-
const waiter = this.waitForInternal(networkAddress, endpoint, transactionSequenceNumber, clusterID, commandIdentifier, timeout);
|
|
592
|
-
|
|
593
|
-
return {cancel: waiter.cancel, promise: waiter.start().promise};
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
private waitressTimeoutFormatter(matcher: WaitressMatcher, timeout: number): string {
|
|
597
|
-
return (
|
|
598
|
-
`Timeout - ${matcher.address} - ${matcher.endpoint}` +
|
|
599
|
-
` - ${matcher.transactionSequenceNumber} - ${matcher.clusterID}` +
|
|
600
|
-
` - ${matcher.commandIdentifier} after ${timeout}ms`
|
|
601
|
-
);
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
private waitressValidator(payload: ZclPayload, matcher: WaitressMatcher): boolean {
|
|
605
|
-
return Boolean(
|
|
606
|
-
payload.header &&
|
|
607
|
-
(!matcher.address || payload.address === matcher.address) &&
|
|
608
|
-
payload.endpoint === matcher.endpoint &&
|
|
609
|
-
(!matcher.transactionSequenceNumber || payload.header.transactionSequenceNumber === matcher.transactionSequenceNumber) &&
|
|
610
|
-
payload.clusterID === matcher.clusterID &&
|
|
611
|
-
matcher.commandIdentifier === payload.header.commandIdentifier,
|
|
612
|
-
);
|
|
613
|
-
}
|
|
614
|
-
}
|