Skip to content

Commit a909f87

Browse files
authored
fix: Improve perf with ZCL getters, align manuf code behavior (#1456)
1 parent dcad2c5 commit a909f87

4 files changed

Lines changed: 138 additions & 111 deletions

File tree

src/controller/model/endpoint.ts

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ export class Endpoint extends Entity {
374374
}
375375

376376
public async report(clusterKey: number | string, attributes: KeyValue, options?: Options): Promise<void> {
377-
const cluster = this.getCluster(clusterKey);
377+
const cluster = this.getCluster(clusterKey, undefined, options?.manufacturerCode);
378378
const payload: {attrId: number; dataType: number; attrData: number | string | boolean}[] = [];
379379

380380
for (const [nameOrID, value] of Object.entries(attributes)) {
@@ -389,11 +389,11 @@ export class Endpoint extends Entity {
389389
}
390390
}
391391

392-
await this.zclCommand(clusterKey, "report", payload, options, attributes);
392+
await this.zclCommand(cluster, "report", payload, options, attributes);
393393
}
394394

395395
public async write(clusterKey: number | string, attributes: KeyValue, options?: Options): Promise<void> {
396-
const cluster = this.getCluster(clusterKey);
396+
const cluster = this.getCluster(clusterKey, undefined, options?.manufacturerCode);
397397
const optionsWithDefaults = this.getOptionsWithDefaults(options, true, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
398398
optionsWithDefaults.manufacturerCode = this.ensureManufacturerCodeIsUniqueAndGet(
399399
cluster,
@@ -415,7 +415,7 @@ export class Endpoint extends Entity {
415415
}
416416
}
417417

418-
await this.zclCommand(clusterKey, optionsWithDefaults.writeUndiv ? "writeUndiv" : "write", payload, optionsWithDefaults, attributes, true);
418+
await this.zclCommand(cluster, optionsWithDefaults.writeUndiv ? "writeUndiv" : "write", payload, optionsWithDefaults, attributes, true);
419419
}
420420

421421
public async writeResponse(
@@ -425,7 +425,7 @@ export class Endpoint extends Entity {
425425
options?: Options,
426426
): Promise<void> {
427427
assert(options?.transactionSequenceNumber === undefined, "Use parameter");
428-
const cluster = this.getCluster(clusterKey);
428+
const cluster = this.getCluster(clusterKey, undefined, options?.manufacturerCode);
429429
const payload: {status: number; attrId: number}[] = [];
430430

431431
for (const [nameOrID, value] of Object.entries(attributes)) {
@@ -445,7 +445,7 @@ export class Endpoint extends Entity {
445445
}
446446

447447
await this.zclCommand(
448-
clusterKey,
448+
cluster,
449449
"writeRsp",
450450
payload,
451451
{direction: Zcl.Direction.SERVER_TO_CLIENT, ...options, transactionSequenceNumber},
@@ -455,7 +455,7 @@ export class Endpoint extends Entity {
455455

456456
public async read(clusterKey: number | string, attributes: (string | number)[], options?: Options): Promise<KeyValue> {
457457
const device = this.getDevice();
458-
const cluster = this.getCluster(clusterKey, device);
458+
const cluster = this.getCluster(clusterKey, device, options?.manufacturerCode);
459459
const optionsWithDefaults = this.getOptionsWithDefaults(options, true, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
460460
optionsWithDefaults.manufacturerCode = this.ensureManufacturerCodeIsUniqueAndGet(
461461
cluster,
@@ -479,7 +479,7 @@ export class Endpoint extends Entity {
479479
}
480480
}
481481

482-
const resultFrame = await this.zclCommand(clusterKey, "read", payload, optionsWithDefaults, attributes, true);
482+
const resultFrame = await this.zclCommand(cluster, "read", payload, optionsWithDefaults, attributes, true);
483483

484484
if (resultFrame) {
485485
return ZclFrameConverter.attributeKeyValue(resultFrame, device.manufacturerID, device.customClusters);
@@ -496,7 +496,7 @@ export class Endpoint extends Entity {
496496
): Promise<void> {
497497
assert(options?.transactionSequenceNumber === undefined, "Use parameter");
498498

499-
const cluster = this.getCluster(clusterKey);
499+
const cluster = this.getCluster(clusterKey, undefined, options?.manufacturerCode);
500500
const payload: {attrId: number; status: number; dataType: number; attrData: number | string}[] = [];
501501
for (const [nameOrID, value] of Object.entries(attributes)) {
502502
const attribute = cluster.getAttribute(nameOrID);
@@ -511,7 +511,7 @@ export class Endpoint extends Entity {
511511
}
512512

513513
await this.zclCommand(
514-
clusterKey,
514+
cluster,
515515
"readRsp",
516516
payload,
517517
{direction: Zcl.Direction.SERVER_TO_CLIENT, ...options, transactionSequenceNumber},
@@ -696,7 +696,7 @@ export class Endpoint extends Entity {
696696
}
697697

698698
public async configureReporting(clusterKey: number | string, items: ConfigureReportingItem[], options?: Options): Promise<void> {
699-
const cluster = this.getCluster(clusterKey);
699+
const cluster = this.getCluster(clusterKey, undefined, options?.manufacturerCode);
700700
const optionsWithDefaults = this.getOptionsWithDefaults(options, true, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
701701
optionsWithDefaults.manufacturerCode = this.ensureManufacturerCodeIsUniqueAndGet(
702702
cluster,
@@ -731,7 +731,7 @@ export class Endpoint extends Entity {
731731
};
732732
});
733733

734-
await this.zclCommand(clusterKey, "configReport", payload, optionsWithDefaults, items, true);
734+
await this.zclCommand(cluster, "configReport", payload, optionsWithDefaults, items, true);
735735

736736
for (const e of payload) {
737737
this._configuredReportings = this._configuredReportings.filter(
@@ -787,7 +787,7 @@ export class Endpoint extends Entity {
787787
assert(options?.transactionSequenceNumber === undefined, "Use parameter");
788788

789789
const device = this.getDevice();
790-
const cluster = this.getCluster(clusterKey, device);
790+
const cluster = this.getCluster(clusterKey, device, options?.manufacturerCode);
791791
const command = cluster.getCommandResponse(commandKey);
792792
transactionSequenceNumber = transactionSequenceNumber || zclTransactionSequenceNumber.next();
793793
const optionsWithDefaults = this.getOptionsWithDefaults(options, true, Zcl.Direction.SERVER_TO_CLIENT, cluster.manufacturerCode);
@@ -798,8 +798,8 @@ export class Endpoint extends Entity {
798798
optionsWithDefaults.disableDefaultResponse,
799799
optionsWithDefaults.manufacturerCode,
800800
transactionSequenceNumber,
801-
command.name,
802-
cluster.name,
801+
command,
802+
cluster,
803803
payload,
804804
device.customClusters,
805805
optionsWithDefaults.reservedBits,
@@ -940,12 +940,16 @@ export class Endpoint extends Entity {
940940
group.addMember(this);
941941
}
942942

943-
private getCluster(clusterKey: number | string, device: Device | undefined = undefined): ZclTypes.Cluster {
943+
private getCluster(
944+
clusterKey: number | string,
945+
device: Device | undefined = undefined,
946+
manufacturerCode: number | undefined = undefined,
947+
): ZclTypes.Cluster {
944948
if (!device) {
945949
device = this.getDevice();
946950
}
947951

948-
return Zcl.Utils.getCluster(clusterKey, device.manufacturerID, device.customClusters);
952+
return Zcl.Utils.getCluster(clusterKey, manufacturerCode ?? device.manufacturerID, device.customClusters);
949953
}
950954

951955
/**
@@ -974,17 +978,22 @@ export class Endpoint extends Entity {
974978
}
975979

976980
public async zclCommand(
977-
clusterKey: number | string,
978-
commandKey: number | string,
981+
clusterKey: number | string | ZclTypes.Cluster,
982+
commandKey: number | string | ZclTypes.Command,
979983
payload: KeyValue,
980984
options?: Options,
981985
logPayload?: KeyValue,
982986
checkStatus = false,
983987
frameType: Zcl.FrameType = Zcl.FrameType.GLOBAL,
984988
): Promise<undefined | Zcl.Frame> {
985989
const device = this.getDevice();
986-
const cluster = this.getCluster(clusterKey, device);
987-
const command = frameType === Zcl.FrameType.GLOBAL ? Zcl.Utils.getGlobalCommand(commandKey) : cluster.getCommand(commandKey);
990+
const cluster = typeof clusterKey === "object" ? clusterKey : this.getCluster(clusterKey, device, options?.manufacturerCode);
991+
const command =
992+
typeof commandKey === "object"
993+
? commandKey
994+
: frameType === Zcl.FrameType.GLOBAL
995+
? Zcl.Utils.getGlobalCommand(commandKey)
996+
: cluster.getCommand(commandKey);
988997
const hasResponse = frameType === Zcl.FrameType.GLOBAL ? true : command.response !== undefined;
989998
const optionsWithDefaults = this.getOptionsWithDefaults(options, hasResponse, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
990999

@@ -994,8 +1003,8 @@ export class Endpoint extends Entity {
9941003
optionsWithDefaults.disableDefaultResponse,
9951004
optionsWithDefaults.manufacturerCode,
9961005
optionsWithDefaults.transactionSequenceNumber ?? zclTransactionSequenceNumber.next(),
997-
command.name,
998-
cluster.name,
1006+
command,
1007+
cluster,
9991008
payload,
10001009
device.customClusters,
10011010
optionsWithDefaults.reservedBits,
@@ -1034,7 +1043,7 @@ export class Endpoint extends Entity {
10341043
options?: Options,
10351044
): Promise<void> {
10361045
const device = this.getDevice();
1037-
const cluster = this.getCluster(clusterKey, device);
1046+
const cluster = this.getCluster(clusterKey, device, options?.manufacturerCode);
10381047
const command = cluster.getCommand(commandKey);
10391048
const optionsWithDefaults = this.getOptionsWithDefaults(options, true, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
10401049
const sourceEndpoint = optionsWithDefaults.srcEndpoint ?? this.ID;
@@ -1045,8 +1054,8 @@ export class Endpoint extends Entity {
10451054
true,
10461055
optionsWithDefaults.manufacturerCode,
10471056
optionsWithDefaults.transactionSequenceNumber ?? zclTransactionSequenceNumber.next(),
1048-
command.name,
1049-
cluster.name,
1057+
command,
1058+
cluster,
10501059
payload,
10511060
device.customClusters,
10521061
optionsWithDefaults.reservedBits,

src/controller/model/group.ts

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,9 @@ export class Group extends Entity {
255255
*/
256256

257257
public async write(clusterKey: number | string, attributes: KeyValue, options?: Options): Promise<void> {
258-
const optionsWithDefaults = this.getOptionsWithDefaults(options, Zcl.Direction.CLIENT_TO_SERVER);
259-
const customClusters = this.#customClusters[optionsWithDefaults.direction === Zcl.Direction.CLIENT_TO_SERVER ? 0 : 1];
260-
const cluster = Zcl.Utils.getCluster(clusterKey, undefined, customClusters);
258+
const customClusters = this.#customClusters[options?.direction === Zcl.Direction.SERVER_TO_CLIENT ? 1 : 0 /* default to CLIENT_TO_SERVER */];
259+
const cluster = Zcl.Utils.getCluster(clusterKey, options?.manufacturerCode, customClusters);
260+
const optionsWithDefaults = this.getOptionsWithDefaults(options, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
261261
const payload: {attrId: number; dataType: number; attrData: number | string | boolean}[] = [];
262262

263263
for (const [nameOrID, value] of Object.entries(attributes)) {
@@ -284,7 +284,7 @@ export class Group extends Entity {
284284
optionsWithDefaults.manufacturerCode,
285285
optionsWithDefaults.transactionSequenceNumber ?? zclTransactionSequenceNumber.next(),
286286
"write",
287-
cluster.ID,
287+
cluster,
288288
payload,
289289
customClusters,
290290
optionsWithDefaults.reservedBits,
@@ -303,9 +303,9 @@ export class Group extends Entity {
303303
}
304304

305305
public async read(clusterKey: number | string, attributes: (string | number)[], options?: Options): Promise<void> {
306-
const optionsWithDefaults = this.getOptionsWithDefaults(options, Zcl.Direction.CLIENT_TO_SERVER);
307-
const customClusters = this.#customClusters[optionsWithDefaults.direction === Zcl.Direction.CLIENT_TO_SERVER ? 0 : 1];
308-
const cluster = Zcl.Utils.getCluster(clusterKey, undefined, customClusters);
306+
const customClusters = this.#customClusters[options?.direction === Zcl.Direction.SERVER_TO_CLIENT ? 1 : 0 /* default to CLIENT_TO_SERVER */];
307+
const cluster = Zcl.Utils.getCluster(clusterKey, options?.manufacturerCode, customClusters);
308+
const optionsWithDefaults = this.getOptionsWithDefaults(options, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
309309
const payload: {attrId: number}[] = [];
310310

311311
for (const attribute of attributes) {
@@ -329,7 +329,7 @@ export class Group extends Entity {
329329
optionsWithDefaults.manufacturerCode,
330330
optionsWithDefaults.transactionSequenceNumber ?? zclTransactionSequenceNumber.next(),
331331
"read",
332-
cluster.ID,
332+
cluster,
333333
payload,
334334
customClusters,
335335
optionsWithDefaults.reservedBits,
@@ -353,9 +353,9 @@ export class Group extends Entity {
353353
}
354354

355355
public async command(clusterKey: number | string, commandKey: number | string, payload: KeyValue, options?: Options): Promise<void> {
356-
const optionsWithDefaults = this.getOptionsWithDefaults(options, Zcl.Direction.CLIENT_TO_SERVER);
357-
const customClusters = this.#customClusters[optionsWithDefaults.direction === Zcl.Direction.CLIENT_TO_SERVER ? 0 : 1];
358-
const cluster = Zcl.Utils.getCluster(clusterKey, undefined, customClusters);
356+
const customClusters = this.#customClusters[options?.direction === Zcl.Direction.SERVER_TO_CLIENT ? 1 : 0 /* default to CLIENT_TO_SERVER */];
357+
const cluster = Zcl.Utils.getCluster(clusterKey, options?.manufacturerCode, customClusters);
358+
const optionsWithDefaults = this.getOptionsWithDefaults(options, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
359359
const command =
360360
optionsWithDefaults.direction === Zcl.Direction.CLIENT_TO_SERVER
361361
? cluster.getCommand(commandKey)
@@ -371,8 +371,8 @@ export class Group extends Entity {
371371
true,
372372
optionsWithDefaults.manufacturerCode,
373373
optionsWithDefaults.transactionSequenceNumber || zclTransactionSequenceNumber.next(),
374-
command.ID,
375-
cluster.ID,
374+
command,
375+
cluster,
376376
payload,
377377
customClusters,
378378
optionsWithDefaults.reservedBits,
@@ -390,12 +390,16 @@ export class Group extends Entity {
390390
}
391391
}
392392

393-
private getOptionsWithDefaults(options: Options | undefined, direction: Zcl.Direction): OptionsWithDefaults {
393+
private getOptionsWithDefaults(
394+
options: Options | undefined,
395+
direction: Zcl.Direction,
396+
manufacturerCode: number | undefined,
397+
): OptionsWithDefaults {
394398
return {
395399
direction,
396400
srcEndpoint: undefined,
397401
reservedBits: 0,
398-
manufacturerCode: undefined,
402+
manufacturerCode,
399403
transactionSequenceNumber: undefined,
400404
...(options || {}),
401405
};

src/zspec/zcl/zclFrame.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,21 @@ export class ZclFrame {
4545
disableDefaultResponse: boolean,
4646
manufacturerCode: number | undefined,
4747
transactionSequenceNumber: number,
48-
commandKey: number | string,
49-
clusterKey: number | string,
48+
commandKey: number | string | Command,
49+
clusterKey: number | string | Cluster,
5050
payload: ZclPayload,
5151
customClusters: CustomClusters,
5252
reservedBits = 0,
5353
): ZclFrame {
54-
const cluster = Utils.getCluster(clusterKey, manufacturerCode, customClusters);
54+
const cluster = typeof clusterKey === "object" ? clusterKey : Utils.getCluster(clusterKey, manufacturerCode, customClusters);
5555
const command: Command =
56-
frameType === FrameType.GLOBAL
57-
? Utils.getGlobalCommand(commandKey)
58-
: direction === Direction.CLIENT_TO_SERVER
59-
? cluster.getCommand(commandKey)
60-
: cluster.getCommandResponse(commandKey);
56+
typeof commandKey === "object"
57+
? commandKey
58+
: frameType === FrameType.GLOBAL
59+
? Utils.getGlobalCommand(commandKey)
60+
: direction === Direction.CLIENT_TO_SERVER
61+
? cluster.getCommand(commandKey)
62+
: cluster.getCommandResponse(commandKey);
6163

6264
const header = new ZclHeader(
6365
{reservedBits, frameType, direction, disableDefaultResponse, manufacturerSpecific: manufacturerCode != null},

0 commit comments

Comments
 (0)