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,22 +0,0 @@
|
|
|
1
|
-
enum ParameterType {
|
|
2
|
-
UINT8 = 0,
|
|
3
|
-
UINT16 = 1,
|
|
4
|
-
UINT32 = 2,
|
|
5
|
-
IEEEADDR = 3,
|
|
6
|
-
|
|
7
|
-
BUFFER = 4,
|
|
8
|
-
BUFFER8 = 5,
|
|
9
|
-
BUFFER16 = 6,
|
|
10
|
-
BUFFER18 = 7,
|
|
11
|
-
BUFFER32 = 8,
|
|
12
|
-
BUFFER42 = 9,
|
|
13
|
-
BUFFER100 = 10,
|
|
14
|
-
|
|
15
|
-
LIST_UINT8 = 11,
|
|
16
|
-
LIST_UINT16 = 12,
|
|
17
|
-
LIST_NETWORK = 16,
|
|
18
|
-
|
|
19
|
-
INT8 = 18,
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export default ParameterType;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import type {ClusterId as ZdoClusterId} from "../../../zspec/zdo";
|
|
2
|
-
import type {Type as CommandType} from "../unpi/constants";
|
|
3
|
-
import type ParameterType from "./parameterType";
|
|
4
|
-
|
|
5
|
-
export type MtType = number | number[] | string | Buffer | {[s: string]: number | string}[];
|
|
6
|
-
|
|
7
|
-
export interface MtParameter {
|
|
8
|
-
name: string;
|
|
9
|
-
parameterType: ParameterType;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
interface MtCmdBase {
|
|
13
|
-
name: string;
|
|
14
|
-
ID: number;
|
|
15
|
-
type: number;
|
|
16
|
-
request: MtParameter[];
|
|
17
|
-
response: MtParameter[];
|
|
18
|
-
zdoClusterId: ZdoClusterId;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
interface MtCmdAreq extends Omit<MtCmdBase, "response" | "zdoClusterId"> {
|
|
22
|
-
type: CommandType.AREQ;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
interface MtCmdSreq extends Omit<MtCmdBase, "zdoClusterId"> {
|
|
26
|
-
type: CommandType.SREQ;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface MtCmdAreqZdo extends Omit<MtCmdBase, "request" | "response"> {
|
|
30
|
-
type: CommandType.AREQ;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface MtCmdSreqZdo extends Omit<MtCmdBase, "request" | "response"> {
|
|
34
|
-
type: CommandType.SREQ;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export type MtCmd = MtCmdAreq | MtCmdSreq | MtCmdAreqZdo | MtCmdSreqZdo;
|
|
38
|
-
// biome-ignore lint/suspicious/noExplicitAny: API
|
|
39
|
-
export type ZpiObjectPayload = {[s: string]: any};
|
|
40
|
-
|
|
41
|
-
export interface BuffaloZnpOptions {
|
|
42
|
-
length?: number;
|
|
43
|
-
startIndex?: number;
|
|
44
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import {Type} from "../unpi/constants";
|
|
2
|
-
import type {MtCmd, MtCmdAreqZdo, MtCmdSreqZdo} from "./tstype";
|
|
3
|
-
|
|
4
|
-
export function isMtCmdAreqZdo(cmd: MtCmd): cmd is MtCmdAreqZdo {
|
|
5
|
-
return cmd.type === Type.AREQ && "zdoClusterId" in cmd;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function isMtCmdSreqZdo(cmd: MtCmd): cmd is MtCmdSreqZdo {
|
|
9
|
-
return cmd.type === Type.SREQ && "zdoClusterId" in cmd;
|
|
10
|
-
}
|
|
@@ -1,342 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert";
|
|
2
|
-
import events from "node:events";
|
|
3
|
-
import {Socket} from "node:net";
|
|
4
|
-
|
|
5
|
-
import {Queue, Waitress, wait} from "../../../utils";
|
|
6
|
-
import {logger} from "../../../utils/logger";
|
|
7
|
-
import {ClusterId as ZdoClusterId} from "../../../zspec/zdo";
|
|
8
|
-
import {SerialPort} from "../../serialPort";
|
|
9
|
-
import SocketPortUtils from "../../socketPortUtils";
|
|
10
|
-
import * as Constants from "../constants";
|
|
11
|
-
import {Frame as UnpiFrame, Parser as UnpiParser, Writer as UnpiWriter} from "../unpi";
|
|
12
|
-
import {Subsystem, Type} from "../unpi/constants";
|
|
13
|
-
import Definition from "./definition";
|
|
14
|
-
import type {ZpiObjectPayload} from "./tstype";
|
|
15
|
-
import {isMtCmdSreqZdo} from "./utils";
|
|
16
|
-
import {ZpiObject} from "./zpiObject";
|
|
17
|
-
|
|
18
|
-
const {
|
|
19
|
-
COMMON: {ZnpCommandStatus},
|
|
20
|
-
Utils: {statusDescription},
|
|
21
|
-
} = Constants;
|
|
22
|
-
|
|
23
|
-
const timeouts = {
|
|
24
|
-
SREQ: 6000,
|
|
25
|
-
reset: 30000,
|
|
26
|
-
default: 10000,
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const NS = "zh:zstack:znp";
|
|
30
|
-
|
|
31
|
-
interface WaitressMatcher {
|
|
32
|
-
type: Type;
|
|
33
|
-
subsystem: Subsystem;
|
|
34
|
-
command: string;
|
|
35
|
-
target?: number | string;
|
|
36
|
-
transid?: number;
|
|
37
|
-
state?: number;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export class Znp extends events.EventEmitter {
|
|
41
|
-
private path: string;
|
|
42
|
-
private baudRate: number;
|
|
43
|
-
private rtscts: boolean;
|
|
44
|
-
|
|
45
|
-
private serialPort?: SerialPort;
|
|
46
|
-
private socketPort?: Socket;
|
|
47
|
-
private unpiWriter: UnpiWriter;
|
|
48
|
-
private unpiParser: UnpiParser;
|
|
49
|
-
private initialized: boolean;
|
|
50
|
-
private queue: Queue;
|
|
51
|
-
private waitress: Waitress<ZpiObject, WaitressMatcher>;
|
|
52
|
-
|
|
53
|
-
public constructor(path: string, baudRate: number, rtscts: boolean) {
|
|
54
|
-
super();
|
|
55
|
-
|
|
56
|
-
this.path = path;
|
|
57
|
-
this.baudRate = typeof baudRate === "number" ? baudRate : 115200;
|
|
58
|
-
this.rtscts = typeof rtscts === "boolean" ? rtscts : false;
|
|
59
|
-
|
|
60
|
-
this.initialized = false;
|
|
61
|
-
|
|
62
|
-
this.queue = new Queue();
|
|
63
|
-
this.waitress = new Waitress<ZpiObject, WaitressMatcher>(this.waitressValidator, this.waitressTimeoutFormatter);
|
|
64
|
-
this.unpiWriter = new UnpiWriter();
|
|
65
|
-
this.unpiParser = new UnpiParser();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
private onUnpiParsed(frame: UnpiFrame): void {
|
|
69
|
-
try {
|
|
70
|
-
const object = ZpiObject.fromUnpiFrame(frame);
|
|
71
|
-
logger.debug(() => `<-- ${object.toString(object.subsystem !== Subsystem.ZDO)}`, NS);
|
|
72
|
-
this.waitress.resolve(object);
|
|
73
|
-
this.emit("received", object);
|
|
74
|
-
} catch (error) {
|
|
75
|
-
logger.error(`Error while parsing to ZpiObject '${error}'`, NS);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
public isInitialized(): boolean {
|
|
80
|
-
return this.initialized;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
private onPortError(error: Error): void {
|
|
84
|
-
logger.error(`Port error: ${error}`, NS);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
private onPortClose(): void {
|
|
88
|
-
logger.info("Port closed", NS);
|
|
89
|
-
this.initialized = false;
|
|
90
|
-
this.emit("close");
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
public async open(): Promise<void> {
|
|
94
|
-
return SocketPortUtils.isTcpPath(this.path) ? await this.openSocketPort() : await this.openSerialPort();
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
private async openSerialPort(): Promise<void> {
|
|
98
|
-
const options = {path: this.path, baudRate: this.baudRate, rtscts: this.rtscts, autoOpen: false};
|
|
99
|
-
|
|
100
|
-
logger.info(`Opening SerialPort with ${JSON.stringify(options)}`, NS);
|
|
101
|
-
this.serialPort = new SerialPort(options);
|
|
102
|
-
|
|
103
|
-
this.unpiWriter.pipe(this.serialPort);
|
|
104
|
-
this.serialPort.pipe(this.unpiParser);
|
|
105
|
-
this.unpiParser.on("parsed", this.onUnpiParsed.bind(this));
|
|
106
|
-
|
|
107
|
-
try {
|
|
108
|
-
await this.serialPort.asyncOpen();
|
|
109
|
-
logger.info("Serialport opened", NS);
|
|
110
|
-
|
|
111
|
-
this.serialPort.once("close", this.onPortClose.bind(this));
|
|
112
|
-
this.serialPort.once("error", this.onPortError.bind(this));
|
|
113
|
-
|
|
114
|
-
this.initialized = true;
|
|
115
|
-
|
|
116
|
-
await this.skipBootloader();
|
|
117
|
-
} catch (error) {
|
|
118
|
-
this.initialized = false;
|
|
119
|
-
|
|
120
|
-
if (this.serialPort.isOpen) {
|
|
121
|
-
this.serialPort.close();
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
throw error;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
private async openSocketPort(): Promise<void> {
|
|
129
|
-
const info = SocketPortUtils.parseTcpPath(this.path);
|
|
130
|
-
logger.info(`Opening TCP socket with ${info.host}:${info.port}`, NS);
|
|
131
|
-
|
|
132
|
-
this.socketPort = new Socket();
|
|
133
|
-
|
|
134
|
-
this.socketPort.setNoDelay(true);
|
|
135
|
-
this.socketPort.setKeepAlive(true, 15000);
|
|
136
|
-
this.unpiWriter.pipe(this.socketPort);
|
|
137
|
-
this.socketPort.pipe(this.unpiParser);
|
|
138
|
-
this.unpiParser.on("parsed", this.onUnpiParsed.bind(this));
|
|
139
|
-
|
|
140
|
-
return await new Promise((resolve, reject): void => {
|
|
141
|
-
// biome-ignore lint/style/noNonNullAssertion: ignored using `--suppress`
|
|
142
|
-
this.socketPort!.on("connect", () => {
|
|
143
|
-
logger.info("Socket connected", NS);
|
|
144
|
-
});
|
|
145
|
-
const self = this;
|
|
146
|
-
// biome-ignore lint/style/noNonNullAssertion: ignored using `--suppress`
|
|
147
|
-
this.socketPort!.on("ready", async () => {
|
|
148
|
-
logger.info("Socket ready", NS);
|
|
149
|
-
await self.skipBootloader();
|
|
150
|
-
self.initialized = true;
|
|
151
|
-
resolve();
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
// biome-ignore lint/style/noNonNullAssertion: ignored using `--suppress`
|
|
155
|
-
this.socketPort!.once("close", this.onPortClose.bind(this));
|
|
156
|
-
|
|
157
|
-
// biome-ignore lint/style/noNonNullAssertion: ignored using `--suppress`
|
|
158
|
-
this.socketPort!.on("error", (error) => {
|
|
159
|
-
logger.error(`Socket error ${error}`, NS);
|
|
160
|
-
reject(new Error("Error while opening socket"));
|
|
161
|
-
self.initialized = false;
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
// biome-ignore lint/style/noNonNullAssertion: ignored using `--suppress`
|
|
165
|
-
this.socketPort!.connect(info.port, info.host);
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
private async skipBootloader(): Promise<void> {
|
|
170
|
-
try {
|
|
171
|
-
await this.request(Subsystem.SYS, "ping", {capabilities: 1}, undefined, 250);
|
|
172
|
-
} catch {
|
|
173
|
-
// Skip bootloader on CC2530/CC2531
|
|
174
|
-
// Send magic byte: https://github.com/Koenkk/zigbee2mqtt/issues/1343 to bootloader
|
|
175
|
-
// and give ZNP 1 second to start.
|
|
176
|
-
try {
|
|
177
|
-
logger.info("Writing CC2530/CC2531 skip bootloader payload", NS);
|
|
178
|
-
this.unpiWriter.writeBuffer(Buffer.from([0xef]));
|
|
179
|
-
await wait(1000);
|
|
180
|
-
await this.request(Subsystem.SYS, "ping", {capabilities: 1}, undefined, 250 /* v8 ignore next */);
|
|
181
|
-
} catch {
|
|
182
|
-
// Skip bootloader on some CC2652 devices (e.g. zzh-p)
|
|
183
|
-
logger.info("Skip bootloader for CC2652/CC1352", NS);
|
|
184
|
-
if (this.serialPort) {
|
|
185
|
-
await this.serialPort.asyncSet({dtr: false, rts: false});
|
|
186
|
-
await wait(150);
|
|
187
|
-
await this.serialPort.asyncSet({dtr: false, rts: true});
|
|
188
|
-
await wait(150);
|
|
189
|
-
await this.serialPort.asyncSet({dtr: false, rts: false});
|
|
190
|
-
await wait(150);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
public async close(): Promise<void> {
|
|
197
|
-
logger.info("closing", NS);
|
|
198
|
-
this.queue.clear();
|
|
199
|
-
|
|
200
|
-
if (this.initialized) {
|
|
201
|
-
this.initialized = false;
|
|
202
|
-
|
|
203
|
-
if (this.serialPort) {
|
|
204
|
-
try {
|
|
205
|
-
await this.serialPort.asyncFlushAndClose();
|
|
206
|
-
} catch (error) {
|
|
207
|
-
this.emit("close");
|
|
208
|
-
|
|
209
|
-
throw error;
|
|
210
|
-
}
|
|
211
|
-
} else {
|
|
212
|
-
// biome-ignore lint/style/noNonNullAssertion: ignored using `--suppress`
|
|
213
|
-
this.socketPort!.destroy();
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
this.emit("close");
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
public async requestWithReply(
|
|
221
|
-
subsystem: Subsystem,
|
|
222
|
-
command: string,
|
|
223
|
-
payload: ZpiObjectPayload,
|
|
224
|
-
waiterID?: number,
|
|
225
|
-
timeout?: number,
|
|
226
|
-
expectedStatuses: Constants.COMMON.ZnpCommandStatus[] = [ZnpCommandStatus.SUCCESS],
|
|
227
|
-
): Promise<ZpiObject> {
|
|
228
|
-
const reply = await this.request(subsystem, command, payload, waiterID, timeout, expectedStatuses);
|
|
229
|
-
if (reply === undefined) {
|
|
230
|
-
throw new Error(`Command ${command} has no reply`);
|
|
231
|
-
}
|
|
232
|
-
return reply;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
public request(
|
|
236
|
-
subsystem: Subsystem,
|
|
237
|
-
command: string,
|
|
238
|
-
payload: ZpiObjectPayload,
|
|
239
|
-
waiterID?: number,
|
|
240
|
-
timeout?: number,
|
|
241
|
-
expectedStatuses: Constants.COMMON.ZnpCommandStatus[] = [ZnpCommandStatus.SUCCESS],
|
|
242
|
-
): Promise<ZpiObject | undefined> {
|
|
243
|
-
if (!this.initialized) {
|
|
244
|
-
throw new Error("Cannot request when znp has not been initialized yet");
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
const object = ZpiObject.createRequest(subsystem, command, payload);
|
|
248
|
-
|
|
249
|
-
return this.queue.execute<ZpiObject | undefined>(async () => {
|
|
250
|
-
logger.debug(() => `--> ${object}`, NS);
|
|
251
|
-
|
|
252
|
-
if (object.type === Type.SREQ) {
|
|
253
|
-
const t = object.command.name === "bdbStartCommissioning" || object.command.name === "startupFromApp" ? 40000 : timeouts.SREQ;
|
|
254
|
-
const waiter = this.waitress.waitFor({type: Type.SRSP, subsystem: object.subsystem, command: object.command.name}, timeout || t);
|
|
255
|
-
this.unpiWriter.writeFrame(object.unpiFrame);
|
|
256
|
-
const result = await waiter.start().promise;
|
|
257
|
-
if (result?.payload.status !== undefined && !expectedStatuses.includes(result.payload.status)) {
|
|
258
|
-
if (typeof waiterID === "number") {
|
|
259
|
-
this.waitress.remove(waiterID);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
throw new Error(
|
|
263
|
-
`--> '${object}' failed with status '${statusDescription(
|
|
264
|
-
result.payload.status,
|
|
265
|
-
)}' (expected '${expectedStatuses.map(statusDescription)}')`,
|
|
266
|
-
);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
return result;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
if (object.type === Type.AREQ && object.isResetCommand()) {
|
|
273
|
-
const waiter = this.waitress.waitFor({type: Type.AREQ, subsystem: Subsystem.SYS, command: "resetInd"}, timeout || timeouts.reset);
|
|
274
|
-
this.queue.clear();
|
|
275
|
-
this.unpiWriter.writeFrame(object.unpiFrame);
|
|
276
|
-
return await waiter.start().promise;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
if (object.type === Type.AREQ) {
|
|
280
|
-
this.unpiWriter.writeFrame(object.unpiFrame);
|
|
281
|
-
/* v8 ignore start */
|
|
282
|
-
} else {
|
|
283
|
-
throw new Error(`Unknown type '${object.type}'`);
|
|
284
|
-
}
|
|
285
|
-
/* v8 ignore stop */
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
public requestZdo(clusterId: ZdoClusterId, payload: Buffer, waiterID?: number): Promise<void> {
|
|
290
|
-
return this.queue.execute(async () => {
|
|
291
|
-
const cmd = Definition[Subsystem.ZDO].find((c) => isMtCmdSreqZdo(c) && c.zdoClusterId === clusterId);
|
|
292
|
-
assert(cmd, `Command for ZDO cluster ID '${clusterId}' not supported.`);
|
|
293
|
-
|
|
294
|
-
const unpiFrame = new UnpiFrame(Type.SREQ, Subsystem.ZDO, cmd.ID, payload);
|
|
295
|
-
const waiter = this.waitress.waitFor({type: Type.SRSP, subsystem: Subsystem.ZDO, command: cmd.name}, timeouts.SREQ);
|
|
296
|
-
|
|
297
|
-
this.unpiWriter.writeFrame(unpiFrame);
|
|
298
|
-
|
|
299
|
-
const result = await waiter.start().promise;
|
|
300
|
-
|
|
301
|
-
if (result?.payload.status !== undefined && result.payload.status !== ZnpCommandStatus.SUCCESS) {
|
|
302
|
-
if (waiterID !== undefined) {
|
|
303
|
-
this.waitress.remove(waiterID);
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
throw new Error(
|
|
307
|
-
`--> 'SREQ: ZDO - ${ZdoClusterId[clusterId]} - ${payload.toString("hex")}' failed with status '${statusDescription(result.payload.status)}'`,
|
|
308
|
-
);
|
|
309
|
-
}
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
private waitressTimeoutFormatter(matcher: WaitressMatcher, timeout: number): string {
|
|
314
|
-
return `${Type[matcher.type]} - ${Subsystem[matcher.subsystem]} - ${matcher.command} after ${timeout}ms`;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
public waitFor(
|
|
318
|
-
type: Type,
|
|
319
|
-
subsystem: Subsystem,
|
|
320
|
-
command: string,
|
|
321
|
-
target: number | string | undefined,
|
|
322
|
-
transid: number | undefined,
|
|
323
|
-
state: number | undefined,
|
|
324
|
-
timeout: number = timeouts.default,
|
|
325
|
-
): {start: () => {promise: Promise<ZpiObject>; ID: number}; ID: number} {
|
|
326
|
-
return this.waitress.waitFor({type, subsystem, command, target, transid, state}, timeout);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
private waitressValidator(zpiObject: ZpiObject, matcher: WaitressMatcher): boolean {
|
|
330
|
-
return (
|
|
331
|
-
matcher.type === zpiObject.type &&
|
|
332
|
-
matcher.subsystem === zpiObject.subsystem &&
|
|
333
|
-
matcher.command === zpiObject.command.name &&
|
|
334
|
-
(matcher.target === undefined ||
|
|
335
|
-
(typeof matcher.target === "number"
|
|
336
|
-
? matcher.target === zpiObject.payload.srcaddr
|
|
337
|
-
: matcher.target === zpiObject.payload.zdo?.[1]?.eui64)) &&
|
|
338
|
-
(matcher.transid === undefined || matcher.transid === zpiObject.payload.transid) &&
|
|
339
|
-
(matcher.state === undefined || matcher.state === zpiObject.payload.state)
|
|
340
|
-
);
|
|
341
|
-
}
|
|
342
|
-
}
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert";
|
|
2
|
-
|
|
3
|
-
import {ClusterId as ZdoClusterId} from "../../../zspec/zdo";
|
|
4
|
-
import {BuffaloZdo} from "../../../zspec/zdo/buffaloZdo";
|
|
5
|
-
import {Frame as UnpiFrame} from "../unpi";
|
|
6
|
-
import {MaxDataSize, Subsystem, Type} from "../unpi/constants";
|
|
7
|
-
import BuffaloZnp from "./buffaloZnp";
|
|
8
|
-
import Definition from "./definition";
|
|
9
|
-
import ParameterType from "./parameterType";
|
|
10
|
-
import type {BuffaloZnpOptions, MtCmd, MtParameter, MtType, ZpiObjectPayload} from "./tstype";
|
|
11
|
-
import {isMtCmdAreqZdo, isMtCmdSreqZdo} from "./utils";
|
|
12
|
-
|
|
13
|
-
const BufferAndListTypes = [
|
|
14
|
-
ParameterType.BUFFER,
|
|
15
|
-
ParameterType.BUFFER8,
|
|
16
|
-
ParameterType.BUFFER16,
|
|
17
|
-
ParameterType.BUFFER18,
|
|
18
|
-
ParameterType.BUFFER32,
|
|
19
|
-
ParameterType.BUFFER42,
|
|
20
|
-
ParameterType.BUFFER100,
|
|
21
|
-
ParameterType.LIST_UINT16,
|
|
22
|
-
ParameterType.LIST_NETWORK,
|
|
23
|
-
ParameterType.LIST_UINT8,
|
|
24
|
-
];
|
|
25
|
-
|
|
26
|
-
type ZpiObjectType = "Request" | "Response";
|
|
27
|
-
|
|
28
|
-
export class ZpiObject<T extends ZpiObjectType = "Response"> {
|
|
29
|
-
public readonly type: Type;
|
|
30
|
-
public readonly subsystem: Subsystem;
|
|
31
|
-
public readonly command: MtCmd;
|
|
32
|
-
public readonly payload: ZpiObjectPayload;
|
|
33
|
-
public readonly unpiFrame: T extends "Request" ? UnpiFrame : undefined;
|
|
34
|
-
|
|
35
|
-
private constructor(
|
|
36
|
-
type: Type,
|
|
37
|
-
subsystem: Subsystem,
|
|
38
|
-
command: MtCmd,
|
|
39
|
-
payload: ZpiObjectPayload,
|
|
40
|
-
unpiFrame: T extends "Request" ? UnpiFrame : undefined,
|
|
41
|
-
) {
|
|
42
|
-
this.type = type;
|
|
43
|
-
this.subsystem = subsystem;
|
|
44
|
-
this.command = command;
|
|
45
|
-
this.payload = payload;
|
|
46
|
-
this.unpiFrame = unpiFrame;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
public static createRequest(subsystem: Subsystem, command: string, payload: ZpiObjectPayload): ZpiObject<"Request"> {
|
|
50
|
-
if (!Definition[subsystem]) {
|
|
51
|
-
throw new Error(`Subsystem '${subsystem}' does not exist`);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const cmd = Definition[subsystem].find((c) => c.name === command);
|
|
55
|
-
|
|
56
|
-
if (cmd === undefined || isMtCmdAreqZdo(cmd) || isMtCmdSreqZdo(cmd) || cmd.request === undefined) {
|
|
57
|
-
throw new Error(`Command request '${command}' from subsystem '${subsystem}' not found`);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Create the UnpiFrame
|
|
61
|
-
const buffalo = new BuffaloZnp(Buffer.alloc(MaxDataSize));
|
|
62
|
-
|
|
63
|
-
for (const parameter of cmd.request) {
|
|
64
|
-
const value = payload[parameter.name];
|
|
65
|
-
buffalo.write(parameter.parameterType, value, {});
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const buffer = buffalo.getWritten();
|
|
69
|
-
const unpiFrame = new UnpiFrame(cmd.type, subsystem, cmd.ID, buffer);
|
|
70
|
-
|
|
71
|
-
return new ZpiObject(cmd.type, subsystem, cmd, payload, unpiFrame);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
public static fromUnpiFrame(frame: UnpiFrame): ZpiObject<"Response"> {
|
|
75
|
-
const cmd = Definition[frame.subsystem].find((c) => c.ID === frame.commandID);
|
|
76
|
-
|
|
77
|
-
if (!cmd) {
|
|
78
|
-
throw new Error(`CommandID '${frame.commandID}' from subsystem '${frame.subsystem}' not found`);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
let payload: ZpiObjectPayload = {};
|
|
82
|
-
|
|
83
|
-
// hotpath AREQ & SREQ ZDO since payload is identical (no need to instantiate BuffaloZnp or parse generically)
|
|
84
|
-
if (isMtCmdAreqZdo(cmd)) {
|
|
85
|
-
if (cmd.zdoClusterId === ZdoClusterId.NETWORK_ADDRESS_RESPONSE || cmd.zdoClusterId === ZdoClusterId.IEEE_ADDRESS_RESPONSE) {
|
|
86
|
-
// ZStack swaps the `startindex` and `numassocdev` compared to ZDO swap them back before handing to ZDO
|
|
87
|
-
const startIndex = frame.data[11];
|
|
88
|
-
const assocDevCount = frame.data[12];
|
|
89
|
-
frame.data[11] = assocDevCount;
|
|
90
|
-
frame.data[12] = startIndex;
|
|
91
|
-
payload.zdo = BuffaloZdo.readResponse(false, cmd.zdoClusterId, frame.data);
|
|
92
|
-
} else {
|
|
93
|
-
payload.srcaddr = frame.data.readUInt16LE(0);
|
|
94
|
-
payload.zdo = BuffaloZdo.readResponse(false, cmd.zdoClusterId, frame.data.subarray(2));
|
|
95
|
-
}
|
|
96
|
-
} else if (isMtCmdSreqZdo(cmd)) {
|
|
97
|
-
payload.status = frame.data.readUInt8(0);
|
|
98
|
-
} else {
|
|
99
|
-
const parameters = frame.type === Type.SRSP && cmd.type !== Type.AREQ ? cmd.response : cmd.request;
|
|
100
|
-
assert(
|
|
101
|
-
parameters,
|
|
102
|
-
`CommandID '${frame.commandID}' from subsystem '${frame.subsystem}' cannot be a ` +
|
|
103
|
-
`${frame.type === Type.SRSP ? "response" : "request"}`,
|
|
104
|
-
);
|
|
105
|
-
payload = ZpiObject.readParameters(frame.data, parameters);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// GC UnpiFrame as early as possible, no longer needed
|
|
109
|
-
return new ZpiObject(frame.type, frame.subsystem, cmd, payload, undefined);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
private static readParameters(buffer: Buffer, parameters: MtParameter[]): ZpiObjectPayload {
|
|
113
|
-
const buffalo = new BuffaloZnp(buffer);
|
|
114
|
-
const result: ZpiObjectPayload = {};
|
|
115
|
-
|
|
116
|
-
for (const parameter of parameters) {
|
|
117
|
-
const options: BuffaloZnpOptions = {};
|
|
118
|
-
|
|
119
|
-
if (BufferAndListTypes.includes(parameter.parameterType)) {
|
|
120
|
-
// When reading a buffer, assume that the previous parsed parameter contains
|
|
121
|
-
// the length of the buffer
|
|
122
|
-
const lengthParameter = parameters[parameters.indexOf(parameter) - 1];
|
|
123
|
-
const length: MtType = result[lengthParameter.name];
|
|
124
|
-
|
|
125
|
-
if (typeof length === "number") {
|
|
126
|
-
options.length = length;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
result[parameter.name] = buffalo.read(parameter.parameterType, options);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return result;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
public isResetCommand(): boolean {
|
|
137
|
-
return (
|
|
138
|
-
(this.command.name === "resetReq" && this.subsystem === Subsystem.SYS) ||
|
|
139
|
-
/* v8 ignore next */
|
|
140
|
-
(this.command.name === "systemReset" && this.subsystem === Subsystem.SAPI)
|
|
141
|
-
);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
public toString(includePayload = true): string {
|
|
145
|
-
const baseStr = `${Type[this.type]}: ${Subsystem[this.subsystem]} - ${this.command.name}`;
|
|
146
|
-
return includePayload ? `${baseStr} - ${JSON.stringify(this.payload)}` : baseStr;
|
|
147
|
-
}
|
|
148
|
-
}
|