@willieee802/zigbee-herdsman 0.49.4 → 0.50.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/.github/dependabot.yml +0 -3
- package/.github/workflows/ci.yml +1 -2
- package/.github/workflows/release-please.yml +1 -1
- package/.github/workflows/typedoc.yaml +3 -3
- package/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +143 -0
- package/biome.json +1 -1
- package/dist/adapter/adapter.d.ts +14 -1
- package/dist/adapter/adapter.d.ts.map +1 -1
- package/dist/adapter/adapter.js +17 -0
- package/dist/adapter/adapter.js.map +1 -1
- package/dist/adapter/adapterDiscovery.d.ts.map +1 -1
- package/dist/adapter/adapterDiscovery.js.map +1 -1
- package/dist/adapter/deconz/adapter/deconzAdapter.d.ts +1 -3
- package/dist/adapter/deconz/adapter/deconzAdapter.d.ts.map +1 -1
- package/dist/adapter/deconz/adapter/deconzAdapter.js +14 -29
- package/dist/adapter/deconz/adapter/deconzAdapter.js.map +1 -1
- package/dist/adapter/deconz/driver/constants.d.ts +1 -1
- package/dist/adapter/deconz/driver/constants.d.ts.map +1 -1
- package/dist/adapter/ember/adapter/emberAdapter.d.ts +1 -1
- package/dist/adapter/ember/adapter/emberAdapter.d.ts.map +1 -1
- package/dist/adapter/ember/adapter/emberAdapter.js +19 -10
- package/dist/adapter/ember/adapter/emberAdapter.js.map +1 -1
- package/dist/adapter/ember/adapter/oneWaitress.d.ts +2 -0
- package/dist/adapter/ember/adapter/oneWaitress.d.ts.map +1 -1
- package/dist/adapter/ember/adapter/oneWaitress.js +13 -5
- package/dist/adapter/ember/adapter/oneWaitress.js.map +1 -1
- package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts +1 -3
- package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts.map +1 -1
- package/dist/adapter/ezsp/adapter/ezspAdapter.js +17 -30
- package/dist/adapter/ezsp/adapter/ezspAdapter.js.map +1 -1
- package/dist/adapter/ezsp/driver/index.d.ts +1 -1
- package/dist/adapter/ezsp/driver/index.d.ts.map +1 -1
- package/dist/adapter/ezsp/driver/index.js +1 -1
- package/dist/adapter/ezsp/driver/index.js.map +1 -1
- package/dist/adapter/ezsp/driver/types/index.d.ts +1 -1
- package/dist/adapter/ezsp/driver/types/index.d.ts.map +1 -1
- package/dist/adapter/ezsp/driver/types/index.js +3 -3
- package/dist/adapter/ezsp/driver/types/index.js.map +1 -1
- package/dist/adapter/serialPort.d.ts.map +1 -1
- package/dist/adapter/serialPort.js +7 -0
- package/dist/adapter/serialPort.js.map +1 -1
- package/dist/adapter/z-stack/adapter/adapter-backup.js +1 -1
- package/dist/adapter/z-stack/adapter/adapter-backup.js.map +1 -1
- package/dist/adapter/z-stack/adapter/adapter-nv-memory.js +1 -1
- package/dist/adapter/z-stack/adapter/adapter-nv-memory.js.map +1 -1
- package/dist/adapter/z-stack/adapter/manager.d.ts.map +1 -1
- package/dist/adapter/z-stack/adapter/manager.js +12 -2
- package/dist/adapter/z-stack/adapter/manager.js.map +1 -1
- package/dist/adapter/z-stack/adapter/tstype.d.ts.map +1 -1
- package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts +1 -3
- package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts.map +1 -1
- package/dist/adapter/z-stack/adapter/zStackAdapter.js +20 -34
- package/dist/adapter/z-stack/adapter/zStackAdapter.js.map +1 -1
- package/dist/adapter/z-stack/constants/index.d.ts +1 -1
- package/dist/adapter/z-stack/constants/index.d.ts.map +1 -1
- package/dist/adapter/z-stack/constants/index.js +1 -1
- package/dist/adapter/z-stack/constants/index.js.map +1 -1
- package/dist/adapter/z-stack/unpi/constants.d.ts +1 -1
- package/dist/adapter/z-stack/unpi/constants.d.ts.map +1 -1
- package/dist/adapter/z-stack/unpi/constants.js +1 -1
- package/dist/adapter/z-stack/unpi/constants.js.map +1 -1
- package/dist/adapter/zboss/adapter/zbossAdapter.d.ts +7 -8
- package/dist/adapter/zboss/adapter/zbossAdapter.d.ts.map +1 -1
- package/dist/adapter/zboss/adapter/zbossAdapter.js +12 -30
- package/dist/adapter/zboss/adapter/zbossAdapter.js.map +1 -1
- package/dist/adapter/zboss/driver.d.ts.map +1 -1
- package/dist/adapter/zboss/driver.js +8 -1
- package/dist/adapter/zboss/driver.js.map +1 -1
- package/dist/adapter/zboss/uart.d.ts.map +1 -1
- package/dist/adapter/zboss/uart.js +14 -2
- package/dist/adapter/zboss/uart.js.map +1 -1
- package/dist/adapter/zigate/adapter/zigateAdapter.d.ts +1 -3
- package/dist/adapter/zigate/adapter/zigateAdapter.d.ts.map +1 -1
- package/dist/adapter/zigate/adapter/zigateAdapter.js +8 -29
- package/dist/adapter/zigate/adapter/zigateAdapter.js.map +1 -1
- package/dist/adapter/zoh/adapter/zohAdapter.d.ts +1 -3
- package/dist/adapter/zoh/adapter/zohAdapter.d.ts.map +1 -1
- package/dist/adapter/zoh/adapter/zohAdapter.js +18 -33
- package/dist/adapter/zoh/adapter/zohAdapter.js.map +1 -1
- package/dist/controller/controller.d.ts.map +1 -1
- package/dist/controller/controller.js +10 -2
- package/dist/controller/controller.js.map +1 -1
- package/dist/controller/greenPower.d.ts.map +1 -1
- package/dist/controller/greenPower.js +15 -9
- package/dist/controller/greenPower.js.map +1 -1
- package/dist/controller/helpers/ota.d.ts +4 -4
- package/dist/controller/helpers/ota.d.ts.map +1 -1
- package/dist/controller/helpers/ota.js +28 -9
- package/dist/controller/helpers/ota.js.map +1 -1
- package/dist/controller/helpers/zclFrameConverter.d.ts.map +1 -1
- package/dist/controller/helpers/zclFrameConverter.js +17 -16
- package/dist/controller/helpers/zclFrameConverter.js.map +1 -1
- package/dist/controller/model/device.d.ts +14 -3
- package/dist/controller/model/device.d.ts.map +1 -1
- package/dist/controller/model/device.js +155 -68
- package/dist/controller/model/device.js.map +1 -1
- package/dist/controller/model/endpoint.d.ts +7 -3
- package/dist/controller/model/endpoint.d.ts.map +1 -1
- package/dist/controller/model/endpoint.js +34 -21
- package/dist/controller/model/endpoint.js.map +1 -1
- package/dist/controller/model/group.js +4 -4
- package/dist/controller/model/group.js.map +1 -1
- package/dist/controller/touchlink.js +3 -3
- package/dist/controller/touchlink.js.map +1 -1
- package/dist/utils/timeService.js +2 -2
- package/dist/utils/timeService.js.map +1 -1
- package/dist/zspec/zcl/buffaloZcl.d.ts +3 -3
- package/dist/zspec/zcl/buffaloZcl.d.ts.map +1 -1
- package/dist/zspec/zcl/buffaloZcl.js +198 -96
- package/dist/zspec/zcl/buffaloZcl.js.map +1 -1
- package/dist/zspec/zcl/definition/cluster.d.ts +2 -2
- package/dist/zspec/zcl/definition/cluster.d.ts.map +1 -1
- package/dist/zspec/zcl/definition/cluster.js +2699 -2808
- package/dist/zspec/zcl/definition/cluster.js.map +1 -1
- package/dist/zspec/zcl/definition/clusters-types.d.ts +63 -1109
- package/dist/zspec/zcl/definition/clusters-types.d.ts.map +1 -1
- package/dist/zspec/zcl/definition/enums.d.ts +0 -1
- package/dist/zspec/zcl/definition/enums.d.ts.map +1 -1
- package/dist/zspec/zcl/definition/enums.js +0 -1
- package/dist/zspec/zcl/definition/enums.js.map +1 -1
- package/dist/zspec/zcl/definition/foundation.d.ts +306 -7
- package/dist/zspec/zcl/definition/foundation.d.ts.map +1 -1
- package/dist/zspec/zcl/definition/foundation.js +552 -207
- package/dist/zspec/zcl/definition/foundation.js.map +1 -1
- package/dist/zspec/zcl/definition/status.d.ts +21 -10
- package/dist/zspec/zcl/definition/status.d.ts.map +1 -1
- package/dist/zspec/zcl/definition/status.js +11 -0
- package/dist/zspec/zcl/definition/status.js.map +1 -1
- package/dist/zspec/zcl/definition/tstype.d.ts +57 -48
- package/dist/zspec/zcl/definition/tstype.d.ts.map +1 -1
- package/dist/zspec/zcl/utils.d.ts +7 -4
- package/dist/zspec/zcl/utils.d.ts.map +1 -1
- package/dist/zspec/zcl/utils.js +133 -240
- package/dist/zspec/zcl/utils.js.map +1 -1
- package/dist/zspec/zcl/zclFrame.d.ts +4 -4
- package/dist/zspec/zcl/zclFrame.d.ts.map +1 -1
- package/dist/zspec/zcl/zclFrame.js +19 -103
- package/dist/zspec/zcl/zclFrame.js.map +1 -1
- package/dist/zspec/zcl/zclStatusError.d.ts +1 -1
- package/dist/zspec/zcl/zclStatusError.d.ts.map +1 -1
- package/dist/zspec/zcl/zclStatusError.js +2 -2
- package/dist/zspec/zcl/zclStatusError.js.map +1 -1
- package/package.json +1 -1
- package/scripts/clusters-typegen.ts +44 -139
- package/src/adapter/adapter.ts +38 -3
- package/src/adapter/adapterDiscovery.ts +2 -1
- package/src/adapter/deconz/adapter/deconzAdapter.ts +24 -51
- package/src/adapter/deconz/driver/constants.ts +1 -1
- package/src/adapter/ember/adapter/emberAdapter.ts +23 -10
- package/src/adapter/ember/adapter/oneWaitress.ts +16 -6
- package/src/adapter/ezsp/adapter/ezspAdapter.ts +27 -48
- package/src/adapter/ezsp/driver/index.ts +1 -1
- package/src/adapter/ezsp/driver/types/index.ts +99 -99
- package/src/adapter/serialPort.ts +9 -0
- package/src/adapter/z-stack/adapter/adapter-backup.ts +1 -1
- package/src/adapter/z-stack/adapter/adapter-nv-memory.ts +1 -1
- package/src/adapter/z-stack/adapter/manager.ts +16 -2
- package/src/adapter/z-stack/adapter/tstype.ts +1 -0
- package/src/adapter/z-stack/adapter/zStackAdapter.ts +34 -81
- package/src/adapter/z-stack/constants/index.ts +1 -1
- package/src/adapter/z-stack/unpi/constants.ts +1 -1
- package/src/adapter/zboss/adapter/zbossAdapter.ts +23 -54
- package/src/adapter/zboss/driver.ts +8 -1
- package/src/adapter/zboss/uart.ts +14 -1
- package/src/adapter/zigate/adapter/zigateAdapter.ts +17 -48
- package/src/adapter/zoh/adapter/zohAdapter.ts +27 -50
- package/src/controller/controller.ts +12 -2
- package/src/controller/greenPower.ts +16 -9
- package/src/controller/helpers/ota.ts +37 -11
- package/src/controller/helpers/zclFrameConverter.ts +20 -17
- package/src/controller/model/device.ts +192 -79
- package/src/controller/model/endpoint.ts +36 -24
- package/src/controller/model/group.ts +4 -4
- package/src/controller/touchlink.ts +3 -3
- package/src/utils/timeService.ts +2 -2
- package/src/zspec/zcl/buffaloZcl.ts +226 -100
- package/src/zspec/zcl/definition/cluster.ts +2713 -2822
- package/src/zspec/zcl/definition/clusters-types.ts +80 -1135
- package/src/zspec/zcl/definition/enums.ts +0 -1
- package/src/zspec/zcl/definition/foundation.ts +703 -216
- package/src/zspec/zcl/definition/status.ts +22 -11
- package/src/zspec/zcl/definition/tstype.ts +59 -58
- package/src/zspec/zcl/utils.ts +137 -264
- package/src/zspec/zcl/zclFrame.ts +25 -130
- package/src/zspec/zcl/zclStatusError.ts +2 -2
- package/test/adapter/ember/emberAdapter.test.ts +191 -4
- package/test/adapter/ezsp/uart.test.ts +10 -10
- package/test/adapter/z-stack/adapter.test.ts +88 -32
- package/test/adapter/zoh/zohAdapter.test.ts +4 -4
- package/test/controller.test.ts +822 -248
- package/test/device-ota.test.ts +141 -16
- package/test/device.test.ts +731 -0
- package/test/requests.bench.ts +2 -0
- package/test/zcl.test.ts +70 -95
- package/test/zspec/zcl/buffalo.test.ts +251 -11
- package/test/zspec/zcl/foundation.test.ts +990 -0
- package/test/zspec/zcl/frame.test.ts +84 -69
- package/test/zspec/zcl/utils.test.ts +105 -81
- package/tsconfig.json +0 -1
- package/scripts/check-clusters-changes.ts +0 -328
- package/scripts/clusters-changes.log +0 -584
- package/scripts/utils.ts +0 -88
- package/scripts/zap-update-clusters-report.json +0 -303
- package/scripts/zap-update-clusters.ts +0 -1520
- package/scripts/zap-update-types.ts +0 -707
- package/scripts/zap-xml-clusters-overrides-data.ts +0 -52
- package/scripts/zap-xml-clusters-overrides.ts +0 -400
- package/scripts/zap-xml-types.ts +0 -146
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {Buffalo} from "../../buffalo";
|
|
2
|
-
import {logger} from "../../utils/logger";
|
|
3
2
|
import {isNumberArray} from "../../utils/utils";
|
|
4
3
|
import {ZCL_TYPE_INVALID_BY_TYPE, ZclType} from "./definition/datatypes";
|
|
5
4
|
import {BuffaloZclDataType, DataType, StructuredIndicatorType} from "./definition/enums";
|
|
@@ -8,11 +7,16 @@ import type {
|
|
|
8
7
|
ExtensionFieldSet,
|
|
9
8
|
Gpd,
|
|
10
9
|
GpdAttributeReport,
|
|
10
|
+
GpdAttributeReporting,
|
|
11
11
|
GpdChannelConfiguration,
|
|
12
12
|
GpdChannelRequest,
|
|
13
13
|
GpdCommissioningReply,
|
|
14
14
|
GpdCustomReply,
|
|
15
|
-
|
|
15
|
+
GpdManufAttributeReport,
|
|
16
|
+
GpdManufMultiClusterAttributeReport,
|
|
17
|
+
GpdMultiClusterAttributeReport,
|
|
18
|
+
GpdReadAttributeResponse,
|
|
19
|
+
GpdRequestAttribute,
|
|
16
20
|
MiboxerZone,
|
|
17
21
|
Struct,
|
|
18
22
|
StructuredSelector,
|
|
@@ -24,8 +28,7 @@ import type {
|
|
|
24
28
|
ZoneInfo,
|
|
25
29
|
} from "./definition/tstype";
|
|
26
30
|
import * as Utils from "./utils";
|
|
27
|
-
|
|
28
|
-
const NS = "zh:zcl:buffalo";
|
|
31
|
+
import {getClusterAttribute} from "./utils";
|
|
29
32
|
|
|
30
33
|
const UINT8_NON_VALUE = ZCL_TYPE_INVALID_BY_TYPE[ZclType.Uint8] as number;
|
|
31
34
|
const UINT16_NON_VALUE = ZCL_TYPE_INVALID_BY_TYPE[ZclType.Uint16] as number;
|
|
@@ -376,7 +379,9 @@ export class BuffaloZcl extends Buffalo {
|
|
|
376
379
|
// 0xf6: ZCL Tunneling
|
|
377
380
|
}
|
|
378
381
|
|
|
379
|
-
private readGpdFrame(
|
|
382
|
+
private readGpdFrame(
|
|
383
|
+
options: BuffaloZclOptions,
|
|
384
|
+
): Gpd | GpdChannelRequest | GpdAttributeReporting | GpdRequestAttribute | GpdReadAttributeResponse | {raw: Buffer} | Record<string, never> {
|
|
380
385
|
if (options.payload?.payloadSize === undefined) {
|
|
381
386
|
throw new Error("Cannot read GPD_FRAME without required payload options specified");
|
|
382
387
|
}
|
|
@@ -388,137 +393,258 @@ export class BuffaloZcl extends Buffalo {
|
|
|
388
393
|
// ensure offset by options.payload.payloadSize (if any) at end of parsing to not cause issues with spec changes (until supported)
|
|
389
394
|
const startPosition = this.position;
|
|
390
395
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
396
|
+
switch (options.payload.commandID) {
|
|
397
|
+
case 0xe0: {
|
|
398
|
+
// Commisioning
|
|
399
|
+
const frame: Gpd = {
|
|
400
|
+
deviceID: this.readUInt8(),
|
|
401
|
+
options: this.readUInt8(),
|
|
402
|
+
extendedOptions: 0,
|
|
403
|
+
securityKey: Buffer.alloc(16) as Buffer<ArrayBufferLike>,
|
|
404
|
+
keyMic: 0,
|
|
405
|
+
outgoingCounter: 0,
|
|
406
|
+
applicationInfo: 0,
|
|
407
|
+
manufacturerID: 0,
|
|
408
|
+
modelID: 0,
|
|
409
|
+
numGpdCommands: 0,
|
|
410
|
+
gpdCommandIdList: Buffer.alloc(0) as Buffer<ArrayBufferLike>,
|
|
411
|
+
numServerClusters: 0,
|
|
412
|
+
numClientClusters: 0,
|
|
413
|
+
gpdServerClusters: Buffer.alloc(0) as Buffer<ArrayBufferLike>,
|
|
414
|
+
gpdClientClusters: Buffer.alloc(0) as Buffer<ArrayBufferLike>,
|
|
415
|
+
genericSwitchConfig: 0,
|
|
416
|
+
currentContactStatus: 0,
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
if (frame.options & 0x80) {
|
|
420
|
+
frame.extendedOptions = this.readUInt8();
|
|
421
|
+
}
|
|
412
422
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
423
|
+
if (frame.extendedOptions & 0x20) {
|
|
424
|
+
frame.securityKey = this.readBuffer(16);
|
|
425
|
+
}
|
|
416
426
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
427
|
+
if (frame.extendedOptions & 0x40) {
|
|
428
|
+
frame.keyMic = this.readUInt32();
|
|
429
|
+
}
|
|
420
430
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
431
|
+
if (frame.extendedOptions & 0x80) {
|
|
432
|
+
frame.outgoingCounter = this.readUInt32();
|
|
433
|
+
}
|
|
424
434
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
435
|
+
if (frame.options & 0x04) {
|
|
436
|
+
frame.applicationInfo = this.readUInt8();
|
|
437
|
+
}
|
|
428
438
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
439
|
+
if (frame.applicationInfo & 0x01) {
|
|
440
|
+
frame.manufacturerID = this.readUInt16();
|
|
441
|
+
}
|
|
432
442
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
443
|
+
if (frame.applicationInfo & 0x02) {
|
|
444
|
+
frame.modelID = this.readUInt16();
|
|
445
|
+
}
|
|
436
446
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
447
|
+
if (frame.applicationInfo & 0x04) {
|
|
448
|
+
frame.numGpdCommands = this.readUInt8();
|
|
449
|
+
frame.gpdCommandIdList = this.readBuffer(frame.numGpdCommands);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
if (frame.applicationInfo & 0x08) {
|
|
453
|
+
const len = this.readUInt8();
|
|
454
|
+
frame.numServerClusters = len & 0xf;
|
|
455
|
+
frame.numClientClusters = (len >> 4) & 0xf;
|
|
456
|
+
|
|
457
|
+
frame.gpdServerClusters = this.readBuffer(2 * frame.numServerClusters);
|
|
458
|
+
frame.gpdClientClusters = this.readBuffer(2 * frame.numClientClusters);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
if (frame.applicationInfo & 0x10) {
|
|
462
|
+
const len = this.readUInt8();
|
|
463
|
+
|
|
464
|
+
if (len >= 1) {
|
|
465
|
+
frame.genericSwitchConfig = this.readUInt8();
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
if (len >= 2) {
|
|
469
|
+
frame.currentContactStatus = this.readUInt8();
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
this.setPosition(startPosition + options.payload.payloadSize);
|
|
440
474
|
|
|
441
|
-
|
|
442
|
-
frame.numGpdCommands = this.readUInt8();
|
|
443
|
-
frame.gpdCommandIdList = this.readBuffer(frame.numGpdCommands);
|
|
475
|
+
return frame;
|
|
444
476
|
}
|
|
477
|
+
case 0xe3: {
|
|
478
|
+
// Channel Request
|
|
479
|
+
const channelOpts = this.readUInt8();
|
|
445
480
|
|
|
446
|
-
|
|
447
|
-
const len = this.readUInt8();
|
|
448
|
-
frame.numServerClusters = len & 0xf;
|
|
449
|
-
frame.numClientClusters = (len >> 4) & 0xf;
|
|
481
|
+
this.setPosition(startPosition + options.payload.payloadSize);
|
|
450
482
|
|
|
451
|
-
|
|
452
|
-
|
|
483
|
+
return {
|
|
484
|
+
nextChannel: channelOpts & 0xf,
|
|
485
|
+
nextNextChannel: channelOpts >> 4,
|
|
486
|
+
} satisfies GpdChannelRequest;
|
|
453
487
|
}
|
|
488
|
+
case 0xa0: {
|
|
489
|
+
// Attribute Reporting
|
|
490
|
+
const clusterID = this.readUInt16();
|
|
491
|
+
const cluster = Utils.getCluster(clusterID, undefined, {});
|
|
492
|
+
const frame: GpdAttributeReport = {
|
|
493
|
+
clusterID,
|
|
494
|
+
clusterName: cluster.name,
|
|
495
|
+
attributes: {},
|
|
496
|
+
};
|
|
454
497
|
|
|
455
|
-
|
|
456
|
-
|
|
498
|
+
while (this.position - startPosition < options.payload.payloadSize) {
|
|
499
|
+
const attributeId = this.readUInt16();
|
|
500
|
+
const dataType = this.readUInt8();
|
|
501
|
+
const attributeNameOrId = getClusterAttribute(cluster, attributeId, undefined)?.name ?? attributeId;
|
|
502
|
+
frame.attributes[attributeNameOrId] = this.read(dataType, options);
|
|
503
|
+
}
|
|
457
504
|
|
|
458
|
-
|
|
459
|
-
|
|
505
|
+
this.setPosition(startPosition + options.payload.payloadSize);
|
|
506
|
+
|
|
507
|
+
return frame;
|
|
508
|
+
}
|
|
509
|
+
case 0xa1: {
|
|
510
|
+
// Manufacturer-specific Attribute Reporting
|
|
511
|
+
const manufacturerCode = this.readUInt16();
|
|
512
|
+
const clusterID = this.readUInt16();
|
|
513
|
+
const cluster = Utils.getCluster(clusterID, manufacturerCode, {});
|
|
514
|
+
const frame: GpdManufAttributeReport = {
|
|
515
|
+
manufacturerCode,
|
|
516
|
+
clusterID,
|
|
517
|
+
clusterName: cluster.name,
|
|
518
|
+
attributes: {},
|
|
519
|
+
};
|
|
520
|
+
|
|
521
|
+
while (this.position - startPosition < options.payload.payloadSize) {
|
|
522
|
+
const attributeId = this.readUInt16();
|
|
523
|
+
const dataType = this.readUInt8();
|
|
524
|
+
// many times will fallback to ID since lots of unknown manu-specific attributes (handled in ZHC)
|
|
525
|
+
const attributeNameOrId = getClusterAttribute(cluster, attributeId, manufacturerCode)?.name ?? attributeId;
|
|
526
|
+
frame.attributes[attributeNameOrId] = this.read(dataType, options);
|
|
460
527
|
}
|
|
461
528
|
|
|
462
|
-
|
|
463
|
-
|
|
529
|
+
this.setPosition(startPosition + options.payload.payloadSize);
|
|
530
|
+
|
|
531
|
+
return frame;
|
|
532
|
+
}
|
|
533
|
+
case 0xa2: {
|
|
534
|
+
// Multi-Cluster Reporting
|
|
535
|
+
const frame: GpdMultiClusterAttributeReport = {reports: []};
|
|
536
|
+
|
|
537
|
+
while (this.position - startPosition < options.payload.payloadSize) {
|
|
538
|
+
const clusterID = this.readUInt16();
|
|
539
|
+
const cluster = Utils.getCluster(clusterID, undefined, {});
|
|
540
|
+
const attributeId = this.readUInt16();
|
|
541
|
+
const dataType = this.readUInt8();
|
|
542
|
+
const attributeNameOrId = getClusterAttribute(cluster, attributeId, undefined)?.name ?? attributeId;
|
|
543
|
+
const attrData = this.read(dataType, options);
|
|
544
|
+
const report: GpdMultiClusterAttributeReport["reports"][number] = {
|
|
545
|
+
clusterID,
|
|
546
|
+
clusterName: cluster.name,
|
|
547
|
+
attribute: attributeNameOrId,
|
|
548
|
+
attrData,
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
frame.reports.push(report);
|
|
464
552
|
}
|
|
465
|
-
}
|
|
466
553
|
|
|
467
|
-
|
|
554
|
+
this.setPosition(startPosition + options.payload.payloadSize);
|
|
555
|
+
|
|
556
|
+
return frame;
|
|
557
|
+
}
|
|
558
|
+
case 0xa3: {
|
|
559
|
+
// Manufacturer-specific Multi-Cluster Reporting
|
|
560
|
+
const manufacturerCode = this.readUInt16();
|
|
561
|
+
const frame: GpdManufMultiClusterAttributeReport = {manufacturerCode, reports: []};
|
|
562
|
+
|
|
563
|
+
while (this.position - startPosition < options.payload.payloadSize) {
|
|
564
|
+
const clusterID = this.readUInt16();
|
|
565
|
+
const cluster = Utils.getCluster(clusterID, manufacturerCode, {});
|
|
566
|
+
const attributeId = this.readUInt16();
|
|
567
|
+
const dataType = this.readUInt8();
|
|
568
|
+
// many times will fallback to ID since lots of unknown manu-specific attributes (handled in ZHC)
|
|
569
|
+
const attributeNameOrId = getClusterAttribute(cluster, attributeId, manufacturerCode)?.name ?? attributeId;
|
|
570
|
+
const attrData = this.read(dataType, options);
|
|
571
|
+
const report: GpdManufMultiClusterAttributeReport["reports"][number] = {
|
|
572
|
+
clusterID,
|
|
573
|
+
clusterName: cluster.name,
|
|
574
|
+
attribute: attributeNameOrId,
|
|
575
|
+
attrData,
|
|
576
|
+
};
|
|
577
|
+
|
|
578
|
+
frame.reports.push(report);
|
|
579
|
+
}
|
|
468
580
|
|
|
469
|
-
|
|
470
|
-
}
|
|
581
|
+
this.setPosition(startPosition + options.payload.payloadSize);
|
|
471
582
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
583
|
+
return frame;
|
|
584
|
+
}
|
|
585
|
+
case 0xa4: {
|
|
586
|
+
// Request Attributes
|
|
587
|
+
const frame: GpdRequestAttribute = {options: this.readUInt8(), manufacturerID: undefined, records: []};
|
|
475
588
|
|
|
476
|
-
|
|
589
|
+
// ignore multi-record bit, while loop automatically handles it
|
|
477
590
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
};
|
|
482
|
-
}
|
|
591
|
+
if (frame.options & 0x02) {
|
|
592
|
+
frame.manufacturerID = this.readUInt16();
|
|
593
|
+
}
|
|
483
594
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
manufacturerCode: this.readUInt16(),
|
|
489
|
-
clusterID: this.readUInt16(),
|
|
490
|
-
attributes: {} as KeyZclValue,
|
|
491
|
-
};
|
|
595
|
+
while (this.position - startPosition < options.payload.payloadSize) {
|
|
596
|
+
const clusterID = this.readUInt16();
|
|
597
|
+
const recordsLength = this.readUInt8();
|
|
598
|
+
const attributes = this.readListUInt16(recordsLength);
|
|
492
599
|
|
|
493
|
-
|
|
600
|
+
frame.records.push({clusterID, attributes});
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
this.setPosition(startPosition + options.payload.payloadSize);
|
|
494
604
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
605
|
+
return frame;
|
|
606
|
+
}
|
|
607
|
+
case 0xa5: {
|
|
608
|
+
// Read Attributes Response
|
|
609
|
+
const frame: GpdReadAttributeResponse = {options: this.readUInt8(), manufacturerID: undefined, records: []};
|
|
500
610
|
|
|
501
|
-
//
|
|
502
|
-
if (!attribute) {
|
|
503
|
-
// this is spammy because of the many manufacturer-specific attributes not currently used
|
|
504
|
-
logger.debug(`Unknown attribute ${attributeID} in cluster ${cluster.name}`, NS);
|
|
611
|
+
// ignore multi-record bit, while loop automatically handles it
|
|
505
612
|
|
|
506
|
-
|
|
613
|
+
if (frame.options & 0x02) {
|
|
614
|
+
frame.manufacturerID = this.readUInt16();
|
|
507
615
|
}
|
|
508
616
|
|
|
509
|
-
|
|
510
|
-
|
|
617
|
+
while (this.position - startPosition < options.payload.payloadSize) {
|
|
618
|
+
const clusterID = this.readUInt16();
|
|
619
|
+
const cluster = Utils.getCluster(clusterID, frame.manufacturerID, {});
|
|
620
|
+
const recordsLength = this.readUInt8();
|
|
621
|
+
const record: GpdReadAttributeResponse["records"][number] = {clusterID, clusterName: cluster.name, attributes: {}};
|
|
622
|
+
|
|
623
|
+
for (let i = 0; i < recordsLength; i++) {
|
|
624
|
+
const attributeId = this.readUInt16();
|
|
625
|
+
const status = this.readUInt8();
|
|
626
|
+
const dataType = this.readUInt8();
|
|
627
|
+
const attributeNameOrId = getClusterAttribute(cluster, attributeId, frame.manufacturerID)?.name ?? attributeId;
|
|
628
|
+
record.attributes[attributeNameOrId] = {
|
|
629
|
+
status,
|
|
630
|
+
attrData: this.read(dataType, options),
|
|
631
|
+
};
|
|
632
|
+
}
|
|
511
633
|
|
|
512
|
-
|
|
634
|
+
frame.records.push(record);
|
|
635
|
+
}
|
|
513
636
|
|
|
514
|
-
|
|
637
|
+
this.setPosition(startPosition + options.payload.payloadSize);
|
|
638
|
+
|
|
639
|
+
return frame;
|
|
640
|
+
}
|
|
515
641
|
}
|
|
516
642
|
|
|
517
643
|
// might contain `gppNwkAddr`, `gppGpdLink` & `mic` from ZCL cluster after this, so limit by `payloadSize`
|
|
518
644
|
return {raw: this.readBuffer(options.payload.payloadSize)};
|
|
519
645
|
}
|
|
520
646
|
|
|
521
|
-
|
|
647
|
+
public writeStructuredSelector(value: StructuredSelector): void {
|
|
522
648
|
if (value != null) {
|
|
523
649
|
const indexes = value.indexes || [];
|
|
524
650
|
const indicatorType = value.indicatorType || StructuredIndicatorType.Whole;
|
|
@@ -532,7 +658,7 @@ export class BuffaloZcl extends Buffalo {
|
|
|
532
658
|
}
|
|
533
659
|
}
|
|
534
660
|
|
|
535
|
-
|
|
661
|
+
public readStructuredSelector(): StructuredSelector {
|
|
536
662
|
/** [0-15] range */
|
|
537
663
|
const indicator = this.readUInt8();
|
|
538
664
|
|