zigbee-herdsman 1.0.0 → 1.1.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 +14 -0
- package/dist/adapter/adapter.d.ts +6 -0
- package/dist/adapter/adapter.d.ts.map +1 -1
- package/dist/adapter/adapter.js.map +1 -1
- package/dist/adapter/deconz/adapter/deconzAdapter.d.ts +5 -3
- package/dist/adapter/deconz/adapter/deconzAdapter.d.ts.map +1 -1
- package/dist/adapter/deconz/adapter/deconzAdapter.js +261 -558
- 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 +4 -12
- package/dist/adapter/ember/adapter/emberAdapter.d.ts.map +1 -1
- package/dist/adapter/ember/adapter/emberAdapter.js +215 -249
- package/dist/adapter/ember/adapter/emberAdapter.js.map +1 -1
- package/dist/adapter/ember/adapter/oneWaitress.d.ts +16 -12
- package/dist/adapter/ember/adapter/oneWaitress.d.ts.map +1 -1
- package/dist/adapter/ember/adapter/oneWaitress.js +16 -41
- package/dist/adapter/ember/adapter/oneWaitress.js.map +1 -1
- package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts +10 -8
- package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts.map +1 -1
- package/dist/adapter/ezsp/adapter/ezspAdapter.js +241 -238
- 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/z-stack/adapter/manager.js +2 -2
- package/dist/adapter/z-stack/adapter/manager.js.map +1 -1
- package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts +4 -3
- package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts.map +1 -1
- package/dist/adapter/z-stack/adapter/zStackAdapter.js +258 -197
- 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 +7 -5
- package/dist/adapter/zboss/adapter/zbossAdapter.d.ts.map +1 -1
- package/dist/adapter/zboss/adapter/zbossAdapter.js +284 -138
- 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 +5 -0
- package/dist/adapter/zigate/adapter/zigateAdapter.d.ts.map +1 -1
- package/dist/adapter/zigate/adapter/zigateAdapter.js +247 -262
- 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 +1 -0
- package/dist/controller/controller.d.ts.map +1 -1
- package/dist/controller/controller.js +28 -0
- package/dist/controller/controller.js.map +1 -1
- package/dist/utils/patchBigIntSerialization.d.ts +2 -0
- package/dist/utils/patchBigIntSerialization.d.ts.map +1 -0
- package/dist/utils/patchBigIntSerialization.js +9 -0
- package/dist/utils/patchBigIntSerialization.js.map +1 -0
- package/dist/zspec/zcl/zclFrame.d.ts +1 -0
- package/dist/zspec/zcl/zclFrame.d.ts.map +1 -1
- package/dist/zspec/zcl/zclFrame.js +1 -0
- package/dist/zspec/zcl/zclFrame.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 +1 -1
|
@@ -30,7 +30,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
30
30
|
const assert_1 = __importDefault(require("assert"));
|
|
31
31
|
const utils_1 = require("../../../utils");
|
|
32
32
|
const logger_1 = require("../../../utils/logger");
|
|
33
|
+
const ZSpec = __importStar(require("../../../zspec"));
|
|
33
34
|
const Zcl = __importStar(require("../../../zspec/zcl"));
|
|
35
|
+
const Zdo = __importStar(require("../../../zspec/zdo"));
|
|
34
36
|
const adapter_1 = __importDefault(require("../../adapter"));
|
|
35
37
|
const serialPortUtils_1 = __importDefault(require("../../serialPortUtils"));
|
|
36
38
|
const socketPortUtils_1 = __importDefault(require("../../socketPortUtils"));
|
|
@@ -47,7 +49,6 @@ class EZSPAdapter extends adapter_1.default {
|
|
|
47
49
|
interpanLock;
|
|
48
50
|
queue;
|
|
49
51
|
closing;
|
|
50
|
-
deprecatedTimer;
|
|
51
52
|
constructor(networkOptions, serialPortOptions, backupPath, adapterOptions) {
|
|
52
53
|
super(networkOptions, serialPortOptions, backupPath, adapterOptions);
|
|
53
54
|
this.hasZdoMessageOverhead = true;
|
|
@@ -65,18 +66,12 @@ class EZSPAdapter extends adapter_1.default {
|
|
|
65
66
|
}
|
|
66
67
|
async processMessage(frame) {
|
|
67
68
|
logger_1.logger.debug(() => `processMessage: ${JSON.stringify(frame)}`, NS);
|
|
68
|
-
if (frame.apsFrame.profileId ==
|
|
69
|
-
if (frame.apsFrame.clusterId
|
|
70
|
-
|
|
71
|
-
// eslint-disable-next-line prefer-const
|
|
72
|
-
[nwk, rst] = types_1.uint16_t.deserialize(types_1.uint16_t, frame.message.subarray(1));
|
|
73
|
-
[ieee, rst] = types_1.EmberEUI64.deserialize(types_1.EmberEUI64, rst);
|
|
74
|
-
ieee = new types_1.EmberEUI64(ieee);
|
|
75
|
-
logger_1.logger.debug(`ZDO Device announce: ${nwk}, ${ieee.toString()}`, NS);
|
|
76
|
-
this.driver.handleNodeJoined(nwk, ieee);
|
|
69
|
+
if (frame.apsFrame.profileId == Zdo.ZDO_PROFILE_ID) {
|
|
70
|
+
if (frame.apsFrame.clusterId >= 0x8000 /* response only */) {
|
|
71
|
+
this.emit('zdoResponse', frame.apsFrame.clusterId, frame.zdoResponse);
|
|
77
72
|
}
|
|
78
73
|
}
|
|
79
|
-
else if (frame.apsFrame.profileId ==
|
|
74
|
+
else if (frame.apsFrame.profileId == ZSpec.HA_PROFILE_ID || frame.apsFrame.profileId == 0xffff) {
|
|
80
75
|
const payload = {
|
|
81
76
|
clusterID: frame.apsFrame.clusterId,
|
|
82
77
|
header: Zcl.Header.fromBuffer(frame.message),
|
|
@@ -91,7 +86,7 @@ class EZSPAdapter extends adapter_1.default {
|
|
|
91
86
|
this.waitress.resolve(payload);
|
|
92
87
|
this.emit('zclPayload', payload);
|
|
93
88
|
}
|
|
94
|
-
else if (frame.apsFrame.profileId ==
|
|
89
|
+
else if (frame.apsFrame.profileId == ZSpec.TOUCHLINK_PROFILE_ID && frame.senderEui64) {
|
|
95
90
|
// ZLL Frame
|
|
96
91
|
const payload = {
|
|
97
92
|
clusterID: frame.apsFrame.clusterId,
|
|
@@ -107,12 +102,12 @@ class EZSPAdapter extends adapter_1.default {
|
|
|
107
102
|
this.waitress.resolve(payload);
|
|
108
103
|
this.emit('zclPayload', payload);
|
|
109
104
|
}
|
|
110
|
-
else if (frame.apsFrame.profileId ==
|
|
105
|
+
else if (frame.apsFrame.profileId == ZSpec.GP_PROFILE_ID) {
|
|
111
106
|
// GP Frame
|
|
112
107
|
// Only handle when clusterId == 33 (greenPower), some devices send messages with this profileId
|
|
113
108
|
// while the cluster is not greenPower
|
|
114
109
|
// https://github.com/Koenkk/zigbee2mqtt/issues/20838
|
|
115
|
-
if (frame.apsFrame.clusterId ===
|
|
110
|
+
if (frame.apsFrame.clusterId === Zcl.Clusters.greenPower.ID) {
|
|
116
111
|
const payload = {
|
|
117
112
|
header: Zcl.Header.fromBuffer(frame.message),
|
|
118
113
|
clusterID: frame.apsFrame.clusterId,
|
|
@@ -132,47 +127,29 @@ class EZSPAdapter extends adapter_1.default {
|
|
|
132
127
|
}
|
|
133
128
|
}
|
|
134
129
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
logger_1.logger.debug(`Device join request received: ${nwk} ${ieee.toString('hex')}`, NS);
|
|
139
|
-
const payload = {
|
|
130
|
+
async handleDeviceJoin(nwk, ieee) {
|
|
131
|
+
logger_1.logger.debug(() => `Device join request received: ${nwk} ${ieee.toString()}`, NS);
|
|
132
|
+
this.emit('deviceJoined', {
|
|
140
133
|
networkAddress: nwk,
|
|
141
|
-
ieeeAddr: `0x${ieee.toString(
|
|
142
|
-
};
|
|
143
|
-
if (nwk == 0) {
|
|
144
|
-
await this.nodeDescriptor(nwk);
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
this.emit('deviceJoined', payload);
|
|
148
|
-
}
|
|
134
|
+
ieeeAddr: `0x${ieee.toString()}`,
|
|
135
|
+
});
|
|
149
136
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
logger_1.logger.debug(`Device left network request received: ${nwk} ${ieee}`, NS);
|
|
154
|
-
const payload = {
|
|
137
|
+
handleDeviceLeft(nwk, ieee) {
|
|
138
|
+
logger_1.logger.debug(() => `Device left network request received: ${nwk} ${ieee.toString()}`, NS);
|
|
139
|
+
this.emit('deviceLeave', {
|
|
155
140
|
networkAddress: nwk,
|
|
156
|
-
ieeeAddr: `0x${ieee.toString(
|
|
157
|
-
};
|
|
158
|
-
this.emit('deviceLeave', payload);
|
|
141
|
+
ieeeAddr: `0x${ieee.toString()}`,
|
|
142
|
+
});
|
|
159
143
|
}
|
|
160
144
|
/**
|
|
161
145
|
* Adapter methods
|
|
162
146
|
*/
|
|
163
147
|
async start() {
|
|
164
|
-
|
|
165
|
-
const message = `Deprecated driver 'ezsp' currently in use, 'ember' will become the officially supported EmberZNet ` +
|
|
166
|
-
`driver in next release. If using Zigbee2MQTT see https://github.com/Koenkk/zigbee2mqtt/discussions/21462`;
|
|
167
|
-
logger_1.logger.warning(message, NS);
|
|
168
|
-
};
|
|
169
|
-
logEzspDeprecated();
|
|
170
|
-
this.deprecatedTimer = setInterval(logEzspDeprecated, 60 * 60 * 1000); // Every 60 mins
|
|
148
|
+
logger_1.logger.warning(`'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`, NS);
|
|
171
149
|
return await this.driver.startup();
|
|
172
150
|
}
|
|
173
151
|
async stop() {
|
|
174
152
|
this.closing = true;
|
|
175
|
-
clearInterval(this.deprecatedTimer);
|
|
176
153
|
await this.driver.stop();
|
|
177
154
|
}
|
|
178
155
|
async onDriverClose() {
|
|
@@ -202,27 +179,20 @@ class EZSPAdapter extends adapter_1.default {
|
|
|
202
179
|
async getCoordinator() {
|
|
203
180
|
return await this.queue.execute(async () => {
|
|
204
181
|
this.checkInterpanLock();
|
|
205
|
-
const
|
|
206
|
-
const message = await this.driver.zdoRequest(networkAddress, types_1.EmberZDOCmd.Active_EP_req, types_1.EmberZDOCmd.Active_EP_rsp, {
|
|
207
|
-
dstaddr: networkAddress,
|
|
208
|
-
});
|
|
209
|
-
const activeEndpoints = message.activeeplist;
|
|
182
|
+
const message = await this.activeEndpoints(ZSpec.COORDINATOR_ADDRESS);
|
|
210
183
|
const endpoints = [];
|
|
211
|
-
for (const endpoint of
|
|
212
|
-
const descriptor = await this.
|
|
213
|
-
dstaddr: networkAddress,
|
|
214
|
-
targetEp: endpoint,
|
|
215
|
-
});
|
|
184
|
+
for (const endpoint of message.endpoints) {
|
|
185
|
+
const descriptor = await this.simpleDescriptor(ZSpec.COORDINATOR_ADDRESS, endpoint);
|
|
216
186
|
endpoints.push({
|
|
217
|
-
profileID: descriptor.
|
|
218
|
-
ID: descriptor.
|
|
219
|
-
deviceID: descriptor.
|
|
220
|
-
inputClusters: descriptor.
|
|
221
|
-
outputClusters: descriptor.
|
|
187
|
+
profileID: descriptor.profileID,
|
|
188
|
+
ID: descriptor.endpointID,
|
|
189
|
+
deviceID: descriptor.deviceID,
|
|
190
|
+
inputClusters: descriptor.inputClusters,
|
|
191
|
+
outputClusters: descriptor.outputClusters,
|
|
222
192
|
});
|
|
223
193
|
}
|
|
224
194
|
return {
|
|
225
|
-
networkAddress:
|
|
195
|
+
networkAddress: ZSpec.COORDINATOR_ADDRESS,
|
|
226
196
|
manufacturerID: 0,
|
|
227
197
|
ieeeAddr: `0x${this.driver.ieee.toString()}`,
|
|
228
198
|
endpoints,
|
|
@@ -230,20 +200,42 @@ class EZSPAdapter extends adapter_1.default {
|
|
|
230
200
|
});
|
|
231
201
|
}
|
|
232
202
|
async permitJoin(seconds, networkAddress) {
|
|
233
|
-
if (this.driver.ezsp.isInitialized()) {
|
|
234
|
-
return
|
|
203
|
+
if (!this.driver.ezsp.isInitialized()) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const clusterId = Zdo.ClusterId.PERMIT_JOINING_REQUEST;
|
|
207
|
+
if (networkAddress) {
|
|
208
|
+
// specific device that is not `Coordinator`
|
|
209
|
+
await this.queue.execute(async () => {
|
|
235
210
|
this.checkInterpanLock();
|
|
236
211
|
await this.driver.preJoining(seconds);
|
|
237
|
-
if (networkAddress) {
|
|
238
|
-
const result = await this.driver.zdoRequest(networkAddress, types_1.EmberZDOCmd.Mgmt_Permit_Joining_req, types_1.EmberZDOCmd.Mgmt_Permit_Joining_rsp, { duration: seconds, tcSignificant: false });
|
|
239
|
-
if (result.status !== types_1.EmberStatus.SUCCESS) {
|
|
240
|
-
throw new Error(`permitJoin for '${networkAddress}' failed`);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
else {
|
|
244
|
-
await this.driver.permitJoining(seconds);
|
|
245
|
-
}
|
|
246
212
|
});
|
|
213
|
+
// `authentication`: TC significance always 1 (zb specs)
|
|
214
|
+
const zdoPayload = Zdo.Buffalo.buildRequest(this.hasZdoMessageOverhead, clusterId, seconds, 1, []);
|
|
215
|
+
const result = await this.sendZdo(ZSpec.BLANK_EUI64, networkAddress, clusterId, zdoPayload, false);
|
|
216
|
+
/* istanbul ignore next */
|
|
217
|
+
if (!Zdo.Buffalo.checkStatus(result)) {
|
|
218
|
+
// TODO: will disappear once moved upstream
|
|
219
|
+
throw new Zdo.StatusError(result[0]);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
// coordinator-only (0), or all
|
|
224
|
+
await this.queue.execute(async () => {
|
|
225
|
+
this.checkInterpanLock();
|
|
226
|
+
await this.driver.preJoining(seconds);
|
|
227
|
+
});
|
|
228
|
+
const result = await this.driver.permitJoining(seconds);
|
|
229
|
+
if (result.status !== types_1.EmberStatus.SUCCESS) {
|
|
230
|
+
throw new Error(`[ZDO] Failed coordinator permit joining request with status=${result.status}.`);
|
|
231
|
+
}
|
|
232
|
+
logger_1.logger.debug(`Permit joining on coordinator for ${seconds} sec.`, NS);
|
|
233
|
+
// broadcast permit joining ZDO
|
|
234
|
+
if (networkAddress === undefined) {
|
|
235
|
+
// `authentication`: TC significance always 1 (zb specs)
|
|
236
|
+
const zdoPayload = Zdo.Buffalo.buildRequest(this.hasZdoMessageOverhead, clusterId, seconds, 1, []);
|
|
237
|
+
await this.sendZdo(ZSpec.BLANK_EUI64, ZSpec.BroadcastAddress.DEFAULT, clusterId, zdoPayload, true);
|
|
238
|
+
}
|
|
247
239
|
}
|
|
248
240
|
}
|
|
249
241
|
async getCoordinatorVersion() {
|
|
@@ -260,127 +252,169 @@ class EZSPAdapter extends adapter_1.default {
|
|
|
260
252
|
return await Promise.reject(new Error('Not supported'));
|
|
261
253
|
}
|
|
262
254
|
async lqi(networkAddress) {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}
|
|
273
|
-
return result;
|
|
274
|
-
};
|
|
275
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
276
|
-
const add = (list) => {
|
|
277
|
-
for (const entry of list) {
|
|
278
|
-
this.driver.setNode(entry.nodeid, entry.ieee);
|
|
255
|
+
const clusterId = Zdo.ClusterId.LQI_TABLE_REQUEST;
|
|
256
|
+
const neighbors = [];
|
|
257
|
+
const request = async (startIndex) => {
|
|
258
|
+
const zdoPayload = Zdo.Buffalo.buildRequest(this.hasZdoMessageOverhead, clusterId, startIndex);
|
|
259
|
+
const result = await this.sendZdo(ZSpec.BLANK_EUI64, networkAddress, clusterId, zdoPayload, false);
|
|
260
|
+
/* istanbul ignore else */
|
|
261
|
+
if (Zdo.Buffalo.checkStatus(result)) {
|
|
262
|
+
const payload = result[1];
|
|
263
|
+
for (const entry of payload.entryList) {
|
|
279
264
|
neighbors.push({
|
|
265
|
+
ieeeAddr: entry.eui64,
|
|
266
|
+
networkAddress: entry.nwkAddress,
|
|
280
267
|
linkquality: entry.lqi,
|
|
281
|
-
|
|
282
|
-
ieeeAddr: `0x${new types_1.EmberEUI64(entry.ieee).toString()}`,
|
|
283
|
-
relationship: (entry.packed >> 4) & 0x7,
|
|
268
|
+
relationship: entry.relationship,
|
|
284
269
|
depth: entry.depth,
|
|
285
270
|
});
|
|
286
271
|
}
|
|
287
|
-
|
|
288
|
-
let response = await request(0);
|
|
289
|
-
add(response.neighborlqilist.neighbors);
|
|
290
|
-
const size = response.neighborlqilist.entries;
|
|
291
|
-
let nextStartIndex = response.neighborlqilist.neighbors.length;
|
|
292
|
-
while (neighbors.length < size) {
|
|
293
|
-
response = await request(nextStartIndex);
|
|
294
|
-
add(response.neighborlqilist.neighbors);
|
|
295
|
-
nextStartIndex += response.neighborlqilist.neighbors.length;
|
|
272
|
+
return [payload.neighborTableEntries, payload.entryList.length];
|
|
296
273
|
}
|
|
297
|
-
|
|
298
|
-
|
|
274
|
+
else {
|
|
275
|
+
// TODO: will disappear once moved upstream
|
|
276
|
+
throw new Zdo.StatusError(result[0]);
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
let [tableEntries, entryCount] = await request(0);
|
|
280
|
+
const size = tableEntries;
|
|
281
|
+
let nextStartIndex = entryCount;
|
|
282
|
+
while (neighbors.length < size) {
|
|
283
|
+
[tableEntries, entryCount] = await request(nextStartIndex);
|
|
284
|
+
nextStartIndex += entryCount;
|
|
285
|
+
}
|
|
286
|
+
return { neighbors };
|
|
299
287
|
}
|
|
300
288
|
async routingTable(networkAddress) {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
const
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
}
|
|
311
|
-
return result;
|
|
312
|
-
};
|
|
313
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
314
|
-
const add = (list) => {
|
|
315
|
-
for (const entry of list) {
|
|
289
|
+
const clusterId = Zdo.ClusterId.ROUTING_TABLE_REQUEST;
|
|
290
|
+
const table = [];
|
|
291
|
+
const request = async (startIndex) => {
|
|
292
|
+
const zdoPayload = Zdo.Buffalo.buildRequest(this.hasZdoMessageOverhead, clusterId, startIndex);
|
|
293
|
+
const result = await this.sendZdo(ZSpec.BLANK_EUI64, networkAddress, clusterId, zdoPayload, false);
|
|
294
|
+
/* istanbul ignore else */
|
|
295
|
+
if (Zdo.Buffalo.checkStatus(result)) {
|
|
296
|
+
const payload = result[1];
|
|
297
|
+
for (const entry of payload.entryList) {
|
|
316
298
|
table.push({
|
|
317
|
-
destinationAddress: entry.
|
|
299
|
+
destinationAddress: entry.destinationAddress,
|
|
318
300
|
status: entry.status,
|
|
319
|
-
nextHop: entry.
|
|
301
|
+
nextHop: entry.nextHopAddress,
|
|
320
302
|
});
|
|
321
303
|
}
|
|
322
|
-
|
|
323
|
-
let response = await request(0);
|
|
324
|
-
add(response.routingtablelist.table);
|
|
325
|
-
const size = response.routingtablelist.entries;
|
|
326
|
-
let nextStartIndex = response.routingtablelist.table.length;
|
|
327
|
-
while (table.length < size) {
|
|
328
|
-
response = await request(nextStartIndex);
|
|
329
|
-
add(response.routingtablelist.table);
|
|
330
|
-
nextStartIndex += response.routingtablelist.table.length;
|
|
304
|
+
return [payload.routingTableEntries, payload.entryList.length];
|
|
331
305
|
}
|
|
332
|
-
|
|
333
|
-
|
|
306
|
+
else {
|
|
307
|
+
// TODO: will disappear once moved upstream
|
|
308
|
+
throw new Zdo.StatusError(result[0]);
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
let [tableEntries, entryCount] = await request(0);
|
|
312
|
+
const size = tableEntries;
|
|
313
|
+
let nextStartIndex = entryCount;
|
|
314
|
+
while (table.length < size) {
|
|
315
|
+
[tableEntries, entryCount] = await request(nextStartIndex);
|
|
316
|
+
nextStartIndex += entryCount;
|
|
317
|
+
}
|
|
318
|
+
return { table };
|
|
334
319
|
}
|
|
335
320
|
async nodeDescriptor(networkAddress) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
321
|
+
const clusterId = Zdo.ClusterId.NODE_DESCRIPTOR_REQUEST;
|
|
322
|
+
const zdoPayload = Zdo.Buffalo.buildRequest(this.hasZdoMessageOverhead, clusterId, networkAddress);
|
|
323
|
+
const result = await this.sendZdo(ZSpec.BLANK_EUI64, networkAddress, clusterId, zdoPayload, false);
|
|
324
|
+
/* istanbul ignore else */
|
|
325
|
+
if (Zdo.Buffalo.checkStatus(result)) {
|
|
326
|
+
const payload = result[1];
|
|
327
|
+
let type = 'Unknown';
|
|
328
|
+
switch (payload.logicalType) {
|
|
329
|
+
case 0x0:
|
|
330
|
+
type = 'Coordinator';
|
|
331
|
+
break;
|
|
332
|
+
case 0x1:
|
|
333
|
+
type = 'Router';
|
|
334
|
+
break;
|
|
335
|
+
case 0x2:
|
|
336
|
+
type = 'EndDevice';
|
|
337
|
+
break;
|
|
346
338
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
}
|
|
353
|
-
const logicaltype = descriptor.descriptor.byte1 & 0x07;
|
|
354
|
-
return {
|
|
355
|
-
manufacturerCode: descriptor.descriptor.manufacturer_code,
|
|
356
|
-
type: logicaltype == 0 ? 'Coordinator' : logicaltype == 1 ? 'Router' : 'EndDevice',
|
|
357
|
-
};
|
|
339
|
+
return { type, manufacturerCode: payload.manufacturerCode };
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
// TODO: will disappear once moved upstream
|
|
343
|
+
throw new Zdo.StatusError(result[0]);
|
|
344
|
+
}
|
|
358
345
|
}
|
|
359
346
|
async activeEndpoints(networkAddress) {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
347
|
+
const clusterId = Zdo.ClusterId.ACTIVE_ENDPOINTS_REQUEST;
|
|
348
|
+
const zdoPayload = Zdo.Buffalo.buildRequest(this.hasZdoMessageOverhead, clusterId, networkAddress);
|
|
349
|
+
const result = await this.sendZdo(ZSpec.BLANK_EUI64, networkAddress, clusterId, zdoPayload, false);
|
|
350
|
+
/* istanbul ignore else */
|
|
351
|
+
if (Zdo.Buffalo.checkStatus(result)) {
|
|
352
|
+
const payload = result[1];
|
|
353
|
+
return { endpoints: payload.endpointList };
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
// TODO: will disappear once moved upstream
|
|
357
|
+
throw new Zdo.StatusError(result[0]);
|
|
358
|
+
}
|
|
367
359
|
}
|
|
368
360
|
async simpleDescriptor(networkAddress, endpointID) {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
});
|
|
361
|
+
const clusterId = Zdo.ClusterId.SIMPLE_DESCRIPTOR_REQUEST;
|
|
362
|
+
const zdoPayload = Zdo.Buffalo.buildRequest(this.hasZdoMessageOverhead, clusterId, networkAddress, endpointID);
|
|
363
|
+
const result = await this.sendZdo(ZSpec.BLANK_EUI64, networkAddress, clusterId, zdoPayload, false);
|
|
364
|
+
/* istanbul ignore else */
|
|
365
|
+
if (Zdo.Buffalo.checkStatus(result)) {
|
|
366
|
+
const payload = result[1];
|
|
376
367
|
return {
|
|
377
|
-
profileID:
|
|
378
|
-
endpointID:
|
|
379
|
-
deviceID:
|
|
380
|
-
inputClusters:
|
|
381
|
-
outputClusters:
|
|
368
|
+
profileID: payload.profileId,
|
|
369
|
+
endpointID: payload.endpoint,
|
|
370
|
+
deviceID: payload.deviceId,
|
|
371
|
+
inputClusters: payload.inClusterList,
|
|
372
|
+
outputClusters: payload.outClusterList,
|
|
382
373
|
};
|
|
383
|
-
}
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
// TODO: will disappear once moved upstream
|
|
377
|
+
throw new Zdo.StatusError(result[0]);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
async sendZdo(ieeeAddress, networkAddress, clusterId, payload, disableResponse) {
|
|
381
|
+
return await this.queue.execute(async () => {
|
|
382
|
+
this.checkInterpanLock();
|
|
383
|
+
const clusterName = Zdo.ClusterId[clusterId];
|
|
384
|
+
const frame = this.driver.makeApsFrame(clusterId, disableResponse);
|
|
385
|
+
payload[0] = frame.sequence;
|
|
386
|
+
let waiter;
|
|
387
|
+
let responseClusterId;
|
|
388
|
+
if (!disableResponse) {
|
|
389
|
+
responseClusterId = Zdo.Utils.getResponseClusterId(clusterId);
|
|
390
|
+
if (responseClusterId) {
|
|
391
|
+
waiter = this.driver.waitFor(responseClusterId === Zdo.ClusterId.NETWORK_ADDRESS_RESPONSE ? ieeeAddress : networkAddress, responseClusterId, frame.sequence);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
if (ZSpec.Utils.isBroadcastAddress(networkAddress)) {
|
|
395
|
+
logger_1.logger.debug(() => `~~~> [ZDO ${clusterName} BROADCAST to=${networkAddress} payload=${payload.toString('hex')}]`, NS);
|
|
396
|
+
const req = await this.driver.brequest(networkAddress, frame, payload);
|
|
397
|
+
logger_1.logger.debug(`~~~> [SENT ZDO BROADCAST]`, NS);
|
|
398
|
+
if (!req) {
|
|
399
|
+
waiter?.cancel();
|
|
400
|
+
throw new Error(`~x~> [ZDO ${clusterName} BROADCAST to=${networkAddress}] Failed to send request.`);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
logger_1.logger.debug(() => `~~~> [ZDO ${clusterName} UNICAST to=${ieeeAddress}:${networkAddress} payload=${payload.toString('hex')}]`, NS);
|
|
405
|
+
const req = await this.driver.request(networkAddress, frame, payload);
|
|
406
|
+
logger_1.logger.debug(`~~~> [SENT ZDO UNICAST]`, NS);
|
|
407
|
+
if (!req) {
|
|
408
|
+
waiter?.cancel();
|
|
409
|
+
throw new Error(`~x~> [ZDO ${clusterName} UNICAST to=${ieeeAddress}:${networkAddress}] Failed to send request.`);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (waiter && responseClusterId !== undefined) {
|
|
413
|
+
const response = await waiter.start().promise;
|
|
414
|
+
logger_1.logger.debug(() => `<~~ [ZDO ${Zdo.ClusterId[responseClusterId]} ${JSON.stringify(response.zdoResponse)}]`, NS);
|
|
415
|
+
return response.zdoResponse;
|
|
416
|
+
}
|
|
417
|
+
}, networkAddress /* TODO: replace with ieeeAddress once zdo moved upstream */);
|
|
384
418
|
}
|
|
385
419
|
async sendZclFrameToEndpoint(ieeeAddr, networkAddress, endpoint, zclFrame, timeout, disableResponse, disableRecovery, sourceEndpoint) {
|
|
386
420
|
return await this.queue.execute(async () => {
|
|
@@ -403,7 +437,7 @@ class EZSPAdapter extends adapter_1.default {
|
|
|
403
437
|
response = this.waitForInternal(networkAddress, endpoint, zclFrame.header.transactionSequenceNumber, zclFrame.cluster.ID, Zcl.Foundation.defaultRsp.ID, timeout);
|
|
404
438
|
}
|
|
405
439
|
const frame = this.driver.makeApsFrame(zclFrame.cluster.ID, disableResponse || zclFrame.header.frameControl.disableDefaultResponse);
|
|
406
|
-
frame.profileId =
|
|
440
|
+
frame.profileId = ZSpec.HA_PROFILE_ID;
|
|
407
441
|
frame.sourceEndpoint = sourceEndpoint || 0x01;
|
|
408
442
|
frame.destinationEndpoint = endpoint;
|
|
409
443
|
frame.groupId = 0;
|
|
@@ -435,7 +469,7 @@ class EZSPAdapter extends adapter_1.default {
|
|
|
435
469
|
return await this.queue.execute(async () => {
|
|
436
470
|
this.checkInterpanLock();
|
|
437
471
|
const frame = this.driver.makeApsFrame(zclFrame.cluster.ID, false);
|
|
438
|
-
frame.profileId =
|
|
472
|
+
frame.profileId = ZSpec.HA_PROFILE_ID;
|
|
439
473
|
frame.sourceEndpoint = 0x01;
|
|
440
474
|
frame.destinationEndpoint = 0x01;
|
|
441
475
|
frame.groupId = groupID;
|
|
@@ -452,10 +486,12 @@ class EZSPAdapter extends adapter_1.default {
|
|
|
452
486
|
return await this.queue.execute(async () => {
|
|
453
487
|
this.checkInterpanLock();
|
|
454
488
|
const frame = this.driver.makeApsFrame(zclFrame.cluster.ID, false);
|
|
455
|
-
frame.profileId = sourceEndpoint ===
|
|
489
|
+
frame.profileId = sourceEndpoint === ZSpec.GP_ENDPOINT && endpoint === ZSpec.GP_ENDPOINT ? ZSpec.GP_PROFILE_ID : ZSpec.HA_PROFILE_ID;
|
|
456
490
|
frame.sourceEndpoint = sourceEndpoint;
|
|
457
491
|
frame.destinationEndpoint = endpoint;
|
|
458
492
|
frame.groupId = destination;
|
|
493
|
+
// XXX: should be:
|
|
494
|
+
// await this.driver.brequest(destination, frame, zclFrame.toBuffer())
|
|
459
495
|
await this.driver.mrequest(frame, zclFrame.toBuffer());
|
|
460
496
|
/**
|
|
461
497
|
* As a broadcast command is not confirmed and thus immidiately returns
|
|
@@ -466,73 +502,38 @@ class EZSPAdapter extends adapter_1.default {
|
|
|
466
502
|
});
|
|
467
503
|
}
|
|
468
504
|
async bind(destinationNetworkAddress, sourceIeeeAddress, sourceEndpoint, clusterID, destinationAddressOrGroup, type, destinationEndpoint) {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
}
|
|
480
|
-
else {
|
|
481
|
-
// 0x03 = 64-bit extended address for DstAddr and DstEndpoint present
|
|
482
|
-
destAddr = {
|
|
483
|
-
addrmode: 0x03,
|
|
484
|
-
ieee: new types_1.EmberEUI64(destinationAddressOrGroup),
|
|
485
|
-
endpoint: destinationEndpoint,
|
|
486
|
-
};
|
|
487
|
-
this.driver.setNode(destinationNetworkAddress, destAddr.ieee);
|
|
488
|
-
}
|
|
489
|
-
await this.driver.zdoRequest(destinationNetworkAddress, types_1.EmberZDOCmd.Bind_req, types_1.EmberZDOCmd.Bind_rsp, {
|
|
490
|
-
sourceEui: ieee,
|
|
491
|
-
sourceEp: sourceEndpoint,
|
|
492
|
-
clusterId: clusterID,
|
|
493
|
-
destAddr: destAddr,
|
|
494
|
-
});
|
|
495
|
-
}, destinationNetworkAddress);
|
|
505
|
+
const clusterId = Zdo.ClusterId.BIND_REQUEST;
|
|
506
|
+
const zdoPayload = Zdo.Buffalo.buildRequest(this.hasZdoMessageOverhead, clusterId, sourceIeeeAddress, sourceEndpoint, clusterID, type === 'group' ? Zdo.MULTICAST_BINDING : Zdo.UNICAST_BINDING, destinationAddressOrGroup, // not used with MULTICAST_BINDING
|
|
507
|
+
destinationAddressOrGroup, // not used with UNICAST_BINDING
|
|
508
|
+
destinationEndpoint ?? 0);
|
|
509
|
+
const result = await this.sendZdo(ZSpec.BLANK_EUI64, destinationNetworkAddress, clusterId, zdoPayload, false);
|
|
510
|
+
/* istanbul ignore next */
|
|
511
|
+
if (!Zdo.Buffalo.checkStatus(result)) {
|
|
512
|
+
// TODO: will disappear once moved upstream
|
|
513
|
+
throw new Zdo.StatusError(result[0]);
|
|
514
|
+
}
|
|
496
515
|
}
|
|
497
516
|
async unbind(destinationNetworkAddress, sourceIeeeAddress, sourceEndpoint, clusterID, destinationAddressOrGroup, type, destinationEndpoint) {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
}
|
|
509
|
-
else {
|
|
510
|
-
// 0x03 = 64-bit extended address for DstAddr and DstEndpoint present
|
|
511
|
-
destAddr = {
|
|
512
|
-
addrmode: 0x03,
|
|
513
|
-
ieee: new types_1.EmberEUI64(destinationAddressOrGroup),
|
|
514
|
-
endpoint: destinationEndpoint,
|
|
515
|
-
};
|
|
516
|
-
this.driver.setNode(destinationNetworkAddress, destAddr.ieee);
|
|
517
|
-
}
|
|
518
|
-
await this.driver.zdoRequest(destinationNetworkAddress, types_1.EmberZDOCmd.Unbind_req, types_1.EmberZDOCmd.Unbind_rsp, {
|
|
519
|
-
sourceEui: ieee,
|
|
520
|
-
sourceEp: sourceEndpoint,
|
|
521
|
-
clusterId: clusterID,
|
|
522
|
-
destAddr: destAddr,
|
|
523
|
-
});
|
|
524
|
-
}, destinationNetworkAddress);
|
|
517
|
+
const clusterId = Zdo.ClusterId.UNBIND_REQUEST;
|
|
518
|
+
const zdoPayload = Zdo.Buffalo.buildRequest(this.hasZdoMessageOverhead, clusterId, sourceIeeeAddress, sourceEndpoint, clusterID, type === 'group' ? Zdo.MULTICAST_BINDING : Zdo.UNICAST_BINDING, destinationAddressOrGroup, // not used with MULTICAST_BINDING
|
|
519
|
+
destinationAddressOrGroup, // not used with UNICAST_BINDING
|
|
520
|
+
destinationEndpoint ?? 0);
|
|
521
|
+
const result = await this.sendZdo(ZSpec.BLANK_EUI64, destinationNetworkAddress, clusterId, zdoPayload, false);
|
|
522
|
+
/* istanbul ignore next */
|
|
523
|
+
if (!Zdo.Buffalo.checkStatus(result)) {
|
|
524
|
+
// TODO: will disappear once moved upstream
|
|
525
|
+
throw new Zdo.StatusError(result[0]);
|
|
526
|
+
}
|
|
525
527
|
}
|
|
526
|
-
removeDevice(networkAddress, ieeeAddr) {
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
}, networkAddress);
|
|
528
|
+
async removeDevice(networkAddress, ieeeAddr) {
|
|
529
|
+
const clusterId = Zdo.ClusterId.LEAVE_REQUEST;
|
|
530
|
+
const zdoPayload = Zdo.Buffalo.buildRequest(this.hasZdoMessageOverhead, clusterId, ieeeAddr, Zdo.LeaveRequestFlags.WITHOUT_REJOIN);
|
|
531
|
+
const result = await this.sendZdo(ZSpec.BLANK_EUI64, networkAddress, clusterId, zdoPayload, false);
|
|
532
|
+
/* istanbul ignore next */
|
|
533
|
+
if (!Zdo.Buffalo.checkStatus(result)) {
|
|
534
|
+
// TODO: will disappear once moved upstream
|
|
535
|
+
throw new Zdo.StatusError(result[0]);
|
|
536
|
+
}
|
|
536
537
|
}
|
|
537
538
|
async getNetworkParameters() {
|
|
538
539
|
return {
|
|
@@ -606,9 +607,11 @@ class EZSPAdapter extends adapter_1.default {
|
|
|
606
607
|
return await response.start().promise;
|
|
607
608
|
});
|
|
608
609
|
}
|
|
609
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
610
610
|
async changeChannel(newChannel) {
|
|
611
|
-
|
|
611
|
+
const clusterId = Zdo.ClusterId.NWK_UPDATE_REQUEST;
|
|
612
|
+
const zdoPayload = Zdo.Buffalo.buildRequest(this.hasZdoMessageOverhead, clusterId, [newChannel], 0xfe, undefined, undefined, undefined);
|
|
613
|
+
await this.sendZdo(ZSpec.BLANK_EUI64, ZSpec.BroadcastAddress.SLEEPY, clusterId, zdoPayload, true /* handled below */);
|
|
614
|
+
await (0, utils_1.Wait)(12000);
|
|
612
615
|
}
|
|
613
616
|
async setTransmitPower(value) {
|
|
614
617
|
logger_1.logger.debug(`setTransmitPower to ${value}`, NS);
|