zigbee-herdsman 5.0.4 → 6.0.1
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 +3 -0
- package/.github/workflows/ci.yml +1 -1
- package/.github/workflows/typedoc.yaml +1 -1
- package/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +29 -0
- package/biome.json +1 -1
- package/dist/adapter/ember/ezsp/buffalo.d.ts +0 -2
- package/dist/adapter/ember/ezsp/buffalo.d.ts.map +1 -1
- package/dist/adapter/ember/ezsp/buffalo.js +0 -4
- package/dist/adapter/ember/ezsp/buffalo.js.map +1 -1
- package/dist/adapter/ember/uart/ash.d.ts.map +1 -1
- package/dist/adapter/ember/uart/ash.js +0 -2
- package/dist/adapter/ember/uart/ash.js.map +1 -1
- package/dist/buffalo/buffalo.d.ts +5 -0
- package/dist/buffalo/buffalo.d.ts.map +1 -1
- package/dist/buffalo/buffalo.js +7 -0
- package/dist/buffalo/buffalo.js.map +1 -1
- package/dist/controller/controller.d.ts.map +1 -1
- package/dist/controller/controller.js +8 -11
- package/dist/controller/controller.js.map +1 -1
- package/dist/controller/events.d.ts +2 -1
- package/dist/controller/events.d.ts.map +1 -1
- package/dist/controller/helpers/request.d.ts.map +1 -1
- package/dist/controller/helpers/request.js +2 -1
- package/dist/controller/helpers/request.js.map +1 -1
- package/dist/controller/helpers/zclFrameConverter.d.ts +2 -4
- package/dist/controller/helpers/zclFrameConverter.d.ts.map +1 -1
- package/dist/controller/helpers/zclFrameConverter.js +2 -0
- package/dist/controller/helpers/zclFrameConverter.js.map +1 -1
- package/dist/controller/model/device.d.ts +13 -24
- package/dist/controller/model/device.d.ts.map +1 -1
- package/dist/controller/model/device.js +88 -129
- package/dist/controller/model/device.js.map +1 -1
- package/dist/controller/model/endpoint.d.ts +17 -16
- package/dist/controller/model/endpoint.d.ts.map +1 -1
- package/dist/controller/model/endpoint.js +31 -16
- package/dist/controller/model/endpoint.js.map +1 -1
- package/dist/controller/model/group.d.ts +6 -6
- package/dist/controller/model/group.d.ts.map +1 -1
- package/dist/controller/model/group.js +5 -3
- package/dist/controller/model/group.js.map +1 -1
- package/dist/controller/model/index.d.ts +1 -0
- package/dist/controller/model/index.d.ts.map +1 -1
- package/dist/controller/model/index.js +3 -1
- package/dist/controller/model/index.js.map +1 -1
- package/dist/controller/model/zigbeeEntity.d.ts +8 -0
- package/dist/controller/model/zigbeeEntity.d.ts.map +1 -0
- package/dist/controller/model/zigbeeEntity.js +11 -0
- package/dist/controller/model/zigbeeEntity.js.map +1 -0
- package/dist/controller/tstype.d.ts +39 -0
- package/dist/controller/tstype.d.ts.map +1 -1
- package/dist/zspec/zcl/buffaloZcl.d.ts +32 -17
- package/dist/zspec/zcl/buffaloZcl.d.ts.map +1 -1
- package/dist/zspec/zcl/buffaloZcl.js +257 -121
- package/dist/zspec/zcl/buffaloZcl.js.map +1 -1
- package/dist/zspec/zcl/definition/cluster.d.ts.map +1 -1
- package/dist/zspec/zcl/definition/cluster.js +156 -33
- package/dist/zspec/zcl/definition/cluster.js.map +1 -1
- package/dist/zspec/zcl/definition/clusters-typegen.d.ts +2 -0
- package/dist/zspec/zcl/definition/clusters-typegen.d.ts.map +1 -0
- package/dist/zspec/zcl/definition/clusters-typegen.js +348 -0
- package/dist/zspec/zcl/definition/clusters-typegen.js.map +1 -0
- package/dist/zspec/zcl/definition/clusters-types.d.ts +7238 -0
- package/dist/zspec/zcl/definition/clusters-types.d.ts.map +1 -0
- package/dist/zspec/zcl/definition/clusters-types.js +3 -0
- package/dist/zspec/zcl/definition/clusters-types.js.map +1 -0
- package/dist/zspec/zcl/definition/enums.d.ts +14 -6
- package/dist/zspec/zcl/definition/enums.d.ts.map +1 -1
- package/dist/zspec/zcl/definition/enums.js +15 -6
- package/dist/zspec/zcl/definition/enums.js.map +1 -1
- package/dist/zspec/zcl/definition/foundation.d.ts.map +1 -1
- package/dist/zspec/zcl/definition/foundation.js +43 -15
- package/dist/zspec/zcl/definition/foundation.js.map +1 -1
- package/dist/zspec/zcl/definition/tstype.d.ts +105 -11
- package/dist/zspec/zcl/definition/tstype.d.ts.map +1 -1
- package/dist/zspec/zcl/index.d.ts +1 -0
- package/dist/zspec/zcl/index.d.ts.map +1 -1
- package/dist/zspec/zcl/index.js.map +1 -1
- package/dist/zspec/zcl/utils.d.ts +1 -1
- package/dist/zspec/zcl/utils.d.ts.map +1 -1
- package/dist/zspec/zcl/utils.js +1 -1
- package/dist/zspec/zcl/utils.js.map +1 -1
- package/dist/zspec/zcl/zclFrame.d.ts.map +1 -1
- package/dist/zspec/zcl/zclFrame.js +32 -20
- package/dist/zspec/zcl/zclFrame.js.map +1 -1
- package/dist/zspec/zdo/buffaloZdo.d.ts +0 -6
- package/dist/zspec/zdo/buffaloZdo.d.ts.map +1 -1
- package/dist/zspec/zdo/buffaloZdo.js +0 -8
- package/dist/zspec/zdo/buffaloZdo.js.map +1 -1
- package/package.json +3 -3
- package/src/adapter/ember/ezsp/buffalo.ts +0 -5
- package/src/adapter/ember/uart/ash.ts +0 -2
- package/src/adapter/ezsp/driver/driver.ts +1 -1
- package/src/buffalo/buffalo.ts +8 -0
- package/src/controller/controller.ts +13 -16
- package/src/controller/events.ts +2 -1
- package/src/controller/greenPower.ts +4 -4
- package/src/controller/helpers/request.ts +3 -1
- package/src/controller/helpers/zclFrameConverter.ts +13 -17
- package/src/controller/model/device.ts +103 -148
- package/src/controller/model/endpoint.ts +112 -64
- package/src/controller/model/group.ts +33 -9
- package/src/controller/model/index.ts +1 -0
- package/src/controller/model/zigbeeEntity.ts +30 -0
- package/src/controller/tstype.ts +251 -16
- package/src/zspec/zcl/buffaloZcl.ts +323 -238
- package/src/zspec/zcl/definition/cluster.ts +156 -33
- package/src/zspec/zcl/definition/clusters-typegen.ts +588 -0
- package/src/zspec/zcl/definition/clusters-types.ts +7331 -0
- package/src/zspec/zcl/definition/enums.ts +14 -5
- package/src/zspec/zcl/definition/foundation.ts +43 -15
- package/src/zspec/zcl/definition/tstype.ts +118 -8
- package/src/zspec/zcl/index.ts +1 -0
- package/src/zspec/zcl/utils.ts +1 -1
- package/src/zspec/zcl/zclFrame.ts +37 -19
- package/src/zspec/zdo/buffaloZdo.ts +0 -9
- package/test/controller.test.ts +356 -896
- package/test/greenpower.test.ts +0 -12
- package/test/zcl.test.ts +13 -11
- package/test/zspec/zcl/buffalo.test.ts +216 -74
- package/test/zspec/zcl/frame.test.ts +62 -28
- package/test/zspec/zcl/utils.test.ts +4 -4
package/test/controller.test.ts
CHANGED
|
@@ -199,9 +199,12 @@ let iasZoneReadState170Count = 0;
|
|
|
199
199
|
let enroll170 = true;
|
|
200
200
|
let configureReportStatus = 0;
|
|
201
201
|
let configureReportDefaultRsp = false;
|
|
202
|
+
let lastSentZclFrameToEndpoint: Buffer | undefined;
|
|
202
203
|
|
|
203
204
|
const restoreMocksendZclFrameToEndpoint = () => {
|
|
204
205
|
mocksendZclFrameToEndpoint.mockImplementation((_ieeeAddr, networkAddress, endpoint, frame: Zcl.Frame) => {
|
|
206
|
+
lastSentZclFrameToEndpoint = frame.toBuffer();
|
|
207
|
+
|
|
205
208
|
if (
|
|
206
209
|
frame.header.isGlobal &&
|
|
207
210
|
frame.isCommand("read") &&
|
|
@@ -401,6 +404,7 @@ const mocksRestore = [mockAdapterPermitJoin, mockAdapterStop, mocksendZclFrameTo
|
|
|
401
404
|
const events: {
|
|
402
405
|
deviceJoined: Events.DeviceJoinedPayload[];
|
|
403
406
|
deviceInterview: Events.DeviceInterviewPayload[];
|
|
407
|
+
deviceInterviewRaw: Events.DeviceInterviewPayload[];
|
|
404
408
|
adapterDisconnected: number[];
|
|
405
409
|
deviceAnnounce: Events.DeviceAnnouncePayload[];
|
|
406
410
|
deviceLeave: Events.DeviceLeavePayload[];
|
|
@@ -411,6 +415,7 @@ const events: {
|
|
|
411
415
|
} = {
|
|
412
416
|
deviceJoined: [],
|
|
413
417
|
deviceInterview: [],
|
|
418
|
+
deviceInterviewRaw: [],
|
|
414
419
|
adapterDisconnected: [],
|
|
415
420
|
deviceAnnounce: [],
|
|
416
421
|
deviceLeave: [],
|
|
@@ -490,7 +495,10 @@ describe("Controller", () => {
|
|
|
490
495
|
controller = new Controller(options);
|
|
491
496
|
controller.on("permitJoinChanged", (data) => events.permitJoinChanged.push(data));
|
|
492
497
|
controller.on("deviceJoined", (data) => events.deviceJoined.push(data));
|
|
493
|
-
controller.on("deviceInterview", (data) =>
|
|
498
|
+
controller.on("deviceInterview", (data) => {
|
|
499
|
+
events.deviceInterview.push(deepClone(data));
|
|
500
|
+
events.deviceInterviewRaw.push(data);
|
|
501
|
+
});
|
|
494
502
|
controller.on("adapterDisconnected", () => events.adapterDisconnected.push(1));
|
|
495
503
|
controller.on("deviceAnnounce", (data) => events.deviceAnnounce.push(data));
|
|
496
504
|
controller.on("deviceLeave", (data) => events.deviceLeave.push(data));
|
|
@@ -1286,18 +1294,21 @@ describe("Controller", () => {
|
|
|
1286
1294
|
},
|
|
1287
1295
|
],
|
|
1288
1296
|
_manufacturerID: 1212,
|
|
1289
|
-
_manufacturerName: "KoenAndCo",
|
|
1290
|
-
_powerSource: "Mains (single phase)",
|
|
1291
|
-
_modelID: "myModelID",
|
|
1292
|
-
_applicationVersion: 2,
|
|
1293
|
-
_stackVersion: 101,
|
|
1294
|
-
_zclVersion: 1,
|
|
1295
|
-
_hardwareVersion: 3,
|
|
1296
|
-
_dateCode: "201901",
|
|
1297
|
-
_softwareBuildID: "1.01",
|
|
1298
1297
|
_interviewState: InterviewState.Successful,
|
|
1299
1298
|
};
|
|
1299
|
+
const deviceGenBasic = {
|
|
1300
|
+
manufacturerName: "KoenAndCo",
|
|
1301
|
+
powerSource: Zcl.PowerSource["Mains (single phase)"],
|
|
1302
|
+
modelId: "myModelID",
|
|
1303
|
+
appVersion: 2,
|
|
1304
|
+
stackVersion: 101,
|
|
1305
|
+
zclVersion: 1,
|
|
1306
|
+
hwVersion: 3,
|
|
1307
|
+
dateCode: "201901",
|
|
1308
|
+
swBuildId: "1.01",
|
|
1309
|
+
};
|
|
1300
1310
|
expect(events.deviceInterview[1]).toStrictEqual({status: "successful", device: device});
|
|
1311
|
+
expect(events.deviceInterviewRaw[1].device.genBasic).toStrictEqual(deviceGenBasic);
|
|
1301
1312
|
expect(deepClone(controller.getDeviceByNetworkAddress(129))).toStrictEqual(device);
|
|
1302
1313
|
expect(events.deviceInterview.length).toBe(2);
|
|
1303
1314
|
expect(databaseContents()).toStrictEqual(
|
|
@@ -1316,7 +1327,10 @@ describe("Controller", () => {
|
|
|
1316
1327
|
it("Join a device and explictly accept it", async () => {
|
|
1317
1328
|
controller = new Controller(options);
|
|
1318
1329
|
controller.on("deviceJoined", (device) => events.deviceJoined.push(device));
|
|
1319
|
-
controller.on("deviceInterview", (
|
|
1330
|
+
controller.on("deviceInterview", (data) => {
|
|
1331
|
+
events.deviceInterview.push(deepClone(data));
|
|
1332
|
+
events.deviceInterviewRaw.push(data);
|
|
1333
|
+
});
|
|
1320
1334
|
await controller.start();
|
|
1321
1335
|
expect(databaseContents().includes("0x129")).toBeFalsy();
|
|
1322
1336
|
await mockAdapterEvents.deviceJoined({networkAddress: 129, ieeeAddr: "0x129"});
|
|
@@ -1371,18 +1385,21 @@ describe("Controller", () => {
|
|
|
1371
1385
|
},
|
|
1372
1386
|
],
|
|
1373
1387
|
_manufacturerID: 1212,
|
|
1374
|
-
_manufacturerName: "KoenAndCo",
|
|
1375
|
-
_powerSource: "Mains (single phase)",
|
|
1376
|
-
_modelID: "myModelID",
|
|
1377
|
-
_applicationVersion: 2,
|
|
1378
|
-
_stackVersion: 101,
|
|
1379
|
-
_zclVersion: 1,
|
|
1380
|
-
_hardwareVersion: 3,
|
|
1381
|
-
_dateCode: "201901",
|
|
1382
|
-
_softwareBuildID: "1.01",
|
|
1383
1388
|
_interviewState: InterviewState.Successful,
|
|
1384
1389
|
};
|
|
1390
|
+
const deviceGenBasic = {
|
|
1391
|
+
manufacturerName: "KoenAndCo",
|
|
1392
|
+
powerSource: Zcl.PowerSource["Mains (single phase)"],
|
|
1393
|
+
modelId: "myModelID",
|
|
1394
|
+
appVersion: 2,
|
|
1395
|
+
stackVersion: 101,
|
|
1396
|
+
zclVersion: 1,
|
|
1397
|
+
hwVersion: 3,
|
|
1398
|
+
dateCode: "201901",
|
|
1399
|
+
swBuildId: "1.01",
|
|
1400
|
+
};
|
|
1385
1401
|
expect(events.deviceInterview[1]).toStrictEqual({status: "successful", device: device});
|
|
1402
|
+
expect(events.deviceInterviewRaw[1].device.genBasic).toStrictEqual(deviceGenBasic);
|
|
1386
1403
|
expect(deepClone(controller.getDeviceByIeeeAddr("0x129"))).toStrictEqual(device);
|
|
1387
1404
|
expect(events.deviceInterview.length).toBe(2);
|
|
1388
1405
|
expect(databaseContents().includes("0x129")).toBeTruthy();
|
|
@@ -1429,8 +1446,8 @@ describe("Controller", () => {
|
|
|
1429
1446
|
await controller.start();
|
|
1430
1447
|
await mockAdapterEvents.deviceJoined({networkAddress: 129, ieeeAddr: "0x129"});
|
|
1431
1448
|
const device = controller.getDeviceByIeeeAddr("0x129")!;
|
|
1432
|
-
device.powerSource = "
|
|
1433
|
-
expect(device.powerSource).toBe("
|
|
1449
|
+
device.powerSource = "DC Source";
|
|
1450
|
+
expect(device.powerSource).toBe("DC Source");
|
|
1434
1451
|
});
|
|
1435
1452
|
|
|
1436
1453
|
it("Get device should return same instance", async () => {
|
|
@@ -2245,8 +2262,7 @@ describe("Controller", () => {
|
|
|
2245
2262
|
expect(events.deviceInterview[1].status).toBe("successful");
|
|
2246
2263
|
// @ts-expect-error private but deep cloned
|
|
2247
2264
|
expect(events.deviceInterview[1].device._ieeeAddr).toBe("0x161");
|
|
2248
|
-
|
|
2249
|
-
expect(events.deviceInterview[1].device._modelID).toBe("myDevice9123");
|
|
2265
|
+
expect(events.deviceInterviewRaw[1].device.genBasic.modelId).toBe("myDevice9123");
|
|
2250
2266
|
});
|
|
2251
2267
|
|
|
2252
2268
|
it("Device joins with endpoints [2,1], as 2 is the only endpoint supporting genBasic it should read modelID from that", async () => {
|
|
@@ -2259,8 +2275,7 @@ describe("Controller", () => {
|
|
|
2259
2275
|
expect(events.deviceInterview[1].status).toBe("successful");
|
|
2260
2276
|
// @ts-expect-error private but deep cloned
|
|
2261
2277
|
expect(events.deviceInterview[1].device._ieeeAddr).toBe("0x162");
|
|
2262
|
-
|
|
2263
|
-
expect(events.deviceInterview[1].device._modelID).toBe("myDevice9124");
|
|
2278
|
+
expect(events.deviceInterviewRaw[1].device.genBasic.modelId).toBe("myDevice9124");
|
|
2264
2279
|
});
|
|
2265
2280
|
|
|
2266
2281
|
it("Device joins and interview iAs enrollment succeeds", async () => {
|
|
@@ -2456,77 +2471,8 @@ describe("Controller", () => {
|
|
|
2456
2471
|
const expected = {
|
|
2457
2472
|
cluster: "msOccupancySensing",
|
|
2458
2473
|
type: "attributeReport",
|
|
2459
|
-
device:
|
|
2460
|
-
|
|
2461
|
-
_events: {},
|
|
2462
|
-
_eventsCount: 0,
|
|
2463
|
-
_ieeeAddr: "0x129",
|
|
2464
|
-
_pendingRequestTimeout: 0,
|
|
2465
|
-
_networkAddress: 129,
|
|
2466
|
-
_lastSeen: Date.now(),
|
|
2467
|
-
_linkquality: 50,
|
|
2468
|
-
_skipDefaultResponse: false,
|
|
2469
|
-
_customClusters: {},
|
|
2470
|
-
_endpoints: [
|
|
2471
|
-
{
|
|
2472
|
-
ID: 1,
|
|
2473
|
-
_events: {},
|
|
2474
|
-
_eventsCount: 0,
|
|
2475
|
-
inputClusters: [0, 1],
|
|
2476
|
-
outputClusters: [2],
|
|
2477
|
-
pendingRequests: {id: 1, deviceIeeeAddress: "0x129", sendInProgress: false},
|
|
2478
|
-
_binds: [],
|
|
2479
|
-
_configuredReportings: [],
|
|
2480
|
-
meta: {},
|
|
2481
|
-
deviceNetworkAddress: 129,
|
|
2482
|
-
deviceIeeeAddress: "0x129",
|
|
2483
|
-
deviceID: 5,
|
|
2484
|
-
profileID: 99,
|
|
2485
|
-
clusters: {
|
|
2486
|
-
msOccupancySensing: {
|
|
2487
|
-
attributes: {
|
|
2488
|
-
occupancy: 1,
|
|
2489
|
-
},
|
|
2490
|
-
},
|
|
2491
|
-
},
|
|
2492
|
-
},
|
|
2493
|
-
],
|
|
2494
|
-
_type: "Router",
|
|
2495
|
-
_manufacturerID: 1212,
|
|
2496
|
-
_manufacturerName: "KoenAndCo",
|
|
2497
|
-
meta: {},
|
|
2498
|
-
_powerSource: "Mains (single phase)",
|
|
2499
|
-
_modelID: "myModelID",
|
|
2500
|
-
_applicationVersion: 2,
|
|
2501
|
-
_stackVersion: 101,
|
|
2502
|
-
_zclVersion: 1,
|
|
2503
|
-
_hardwareVersion: 3,
|
|
2504
|
-
_dateCode: "201901",
|
|
2505
|
-
_softwareBuildID: "1.01",
|
|
2506
|
-
_interviewState: InterviewState.Successful,
|
|
2507
|
-
},
|
|
2508
|
-
endpoint: {
|
|
2509
|
-
ID: 1,
|
|
2510
|
-
_events: {},
|
|
2511
|
-
_eventsCount: 0,
|
|
2512
|
-
deviceID: 5,
|
|
2513
|
-
inputClusters: [0, 1],
|
|
2514
|
-
outputClusters: [2],
|
|
2515
|
-
pendingRequests: {id: 1, deviceIeeeAddress: "0x129", sendInProgress: false},
|
|
2516
|
-
deviceNetworkAddress: 129,
|
|
2517
|
-
deviceIeeeAddress: "0x129",
|
|
2518
|
-
_binds: [],
|
|
2519
|
-
_configuredReportings: [],
|
|
2520
|
-
profileID: 99,
|
|
2521
|
-
meta: {},
|
|
2522
|
-
clusters: {
|
|
2523
|
-
msOccupancySensing: {
|
|
2524
|
-
attributes: {
|
|
2525
|
-
occupancy: 1,
|
|
2526
|
-
},
|
|
2527
|
-
},
|
|
2528
|
-
},
|
|
2529
|
-
},
|
|
2474
|
+
device: expect.any(Device),
|
|
2475
|
+
endpoint: expect.any(Endpoint),
|
|
2530
2476
|
data: {
|
|
2531
2477
|
occupancy: 1,
|
|
2532
2478
|
},
|
|
@@ -2541,9 +2487,11 @@ describe("Controller", () => {
|
|
|
2541
2487
|
frameType: 0,
|
|
2542
2488
|
manufacturerSpecific: false,
|
|
2543
2489
|
},
|
|
2490
|
+
manufacturerCode: undefined,
|
|
2491
|
+
rawData: expect.any(Buffer),
|
|
2544
2492
|
},
|
|
2545
2493
|
};
|
|
2546
|
-
expect(
|
|
2494
|
+
expect(events.message[0]).toStrictEqual(expected);
|
|
2547
2495
|
expect(controller.getDeviceByIeeeAddr("0x129")!.linkquality).toEqual(50);
|
|
2548
2496
|
});
|
|
2549
2497
|
|
|
@@ -2571,74 +2519,16 @@ describe("Controller", () => {
|
|
|
2571
2519
|
const expected = {
|
|
2572
2520
|
cluster: "genAlarms",
|
|
2573
2521
|
type: "raw",
|
|
2574
|
-
device:
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
_eventsCount: 0,
|
|
2578
|
-
_pendingRequestTimeout: 0,
|
|
2579
|
-
_ieeeAddr: "0x129",
|
|
2580
|
-
_networkAddress: 129,
|
|
2581
|
-
_lastSeen: Date.now(),
|
|
2582
|
-
_linkquality: 50,
|
|
2583
|
-
_skipDefaultResponse: false,
|
|
2584
|
-
_customClusters: {},
|
|
2585
|
-
_endpoints: [
|
|
2586
|
-
{
|
|
2587
|
-
ID: 1,
|
|
2588
|
-
_events: {},
|
|
2589
|
-
_eventsCount: 0,
|
|
2590
|
-
clusters: {},
|
|
2591
|
-
inputClusters: [0, 1],
|
|
2592
|
-
outputClusters: [2],
|
|
2593
|
-
pendingRequests: {id: 1, deviceIeeeAddress: "0x129", sendInProgress: false},
|
|
2594
|
-
deviceNetworkAddress: 129,
|
|
2595
|
-
deviceIeeeAddress: "0x129",
|
|
2596
|
-
_binds: [],
|
|
2597
|
-
_configuredReportings: [],
|
|
2598
|
-
meta: {},
|
|
2599
|
-
deviceID: 5,
|
|
2600
|
-
profileID: 99,
|
|
2601
|
-
},
|
|
2602
|
-
],
|
|
2603
|
-
_type: "Router",
|
|
2604
|
-
_manufacturerID: 1212,
|
|
2605
|
-
_manufacturerName: "KoenAndCo",
|
|
2606
|
-
meta: {},
|
|
2607
|
-
_powerSource: "Mains (single phase)",
|
|
2608
|
-
_modelID: "myModelID",
|
|
2609
|
-
_applicationVersion: 2,
|
|
2610
|
-
_stackVersion: 101,
|
|
2611
|
-
_zclVersion: 1,
|
|
2612
|
-
_hardwareVersion: 3,
|
|
2613
|
-
_dateCode: "201901",
|
|
2614
|
-
_softwareBuildID: "1.01",
|
|
2615
|
-
_interviewState: InterviewState.Successful,
|
|
2616
|
-
},
|
|
2617
|
-
endpoint: {
|
|
2618
|
-
_events: {},
|
|
2619
|
-
_eventsCount: 0,
|
|
2620
|
-
clusters: {},
|
|
2621
|
-
ID: 1,
|
|
2622
|
-
deviceID: 5,
|
|
2623
|
-
inputClusters: [0, 1],
|
|
2624
|
-
outputClusters: [2],
|
|
2625
|
-
pendingRequests: {id: 1, deviceIeeeAddress: "0x129", sendInProgress: false},
|
|
2626
|
-
deviceNetworkAddress: 129,
|
|
2627
|
-
deviceIeeeAddress: "0x129",
|
|
2628
|
-
_binds: [],
|
|
2629
|
-
_configuredReportings: [],
|
|
2630
|
-
profileID: 99,
|
|
2631
|
-
meta: {},
|
|
2632
|
-
},
|
|
2633
|
-
data: {
|
|
2634
|
-
data: [0, 1],
|
|
2635
|
-
type: "Buffer",
|
|
2636
|
-
},
|
|
2522
|
+
device: expect.any(Device),
|
|
2523
|
+
endpoint: expect.any(Endpoint),
|
|
2524
|
+
data: Buffer.from([0, 1]),
|
|
2637
2525
|
linkquality: 50,
|
|
2638
2526
|
groupID: 1,
|
|
2639
|
-
meta: {
|
|
2527
|
+
meta: {
|
|
2528
|
+
rawData: expect.any(Buffer),
|
|
2529
|
+
},
|
|
2640
2530
|
};
|
|
2641
|
-
expect(
|
|
2531
|
+
expect(events.message[0]).toStrictEqual(expected);
|
|
2642
2532
|
});
|
|
2643
2533
|
|
|
2644
2534
|
it("Receive raw data from unknown cluster", async () => {
|
|
@@ -2658,74 +2548,16 @@ describe("Controller", () => {
|
|
|
2658
2548
|
const expected = {
|
|
2659
2549
|
cluster: 99999999,
|
|
2660
2550
|
type: "raw",
|
|
2661
|
-
device:
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
_pendingRequestTimeout: 0,
|
|
2665
|
-
_networkAddress: 129,
|
|
2666
|
-
_lastSeen: Date.now(),
|
|
2667
|
-
_linkquality: 50,
|
|
2668
|
-
_skipDefaultResponse: false,
|
|
2669
|
-
_customClusters: {},
|
|
2670
|
-
_endpoints: [
|
|
2671
|
-
{
|
|
2672
|
-
ID: 1,
|
|
2673
|
-
_events: {},
|
|
2674
|
-
_eventsCount: 0,
|
|
2675
|
-
clusters: {},
|
|
2676
|
-
inputClusters: [0, 1],
|
|
2677
|
-
outputClusters: [2],
|
|
2678
|
-
pendingRequests: {id: 1, deviceIeeeAddress: "0x129", sendInProgress: false},
|
|
2679
|
-
deviceNetworkAddress: 129,
|
|
2680
|
-
deviceIeeeAddress: "0x129",
|
|
2681
|
-
_binds: [],
|
|
2682
|
-
_configuredReportings: [],
|
|
2683
|
-
meta: {},
|
|
2684
|
-
deviceID: 5,
|
|
2685
|
-
profileID: 99,
|
|
2686
|
-
},
|
|
2687
|
-
],
|
|
2688
|
-
_events: {},
|
|
2689
|
-
_eventsCount: 0,
|
|
2690
|
-
_type: "Router",
|
|
2691
|
-
_manufacturerID: 1212,
|
|
2692
|
-
_manufacturerName: "KoenAndCo",
|
|
2693
|
-
meta: {},
|
|
2694
|
-
_powerSource: "Mains (single phase)",
|
|
2695
|
-
_modelID: "myModelID",
|
|
2696
|
-
_applicationVersion: 2,
|
|
2697
|
-
_stackVersion: 101,
|
|
2698
|
-
_zclVersion: 1,
|
|
2699
|
-
_hardwareVersion: 3,
|
|
2700
|
-
_dateCode: "201901",
|
|
2701
|
-
_softwareBuildID: "1.01",
|
|
2702
|
-
_interviewState: InterviewState.Successful,
|
|
2703
|
-
},
|
|
2704
|
-
endpoint: {
|
|
2705
|
-
_events: {},
|
|
2706
|
-
_eventsCount: 0,
|
|
2707
|
-
clusters: {},
|
|
2708
|
-
ID: 1,
|
|
2709
|
-
deviceID: 5,
|
|
2710
|
-
inputClusters: [0, 1],
|
|
2711
|
-
outputClusters: [2],
|
|
2712
|
-
pendingRequests: {id: 1, deviceIeeeAddress: "0x129", sendInProgress: false},
|
|
2713
|
-
deviceNetworkAddress: 129,
|
|
2714
|
-
deviceIeeeAddress: "0x129",
|
|
2715
|
-
_binds: [],
|
|
2716
|
-
_configuredReportings: [],
|
|
2717
|
-
profileID: 99,
|
|
2718
|
-
meta: {},
|
|
2719
|
-
},
|
|
2720
|
-
data: {
|
|
2721
|
-
data: [0, 1, 2, 3],
|
|
2722
|
-
type: "Buffer",
|
|
2723
|
-
},
|
|
2551
|
+
device: expect.any(Device),
|
|
2552
|
+
endpoint: expect.any(Endpoint),
|
|
2553
|
+
data: Buffer.from([0, 1, 2, 3]),
|
|
2724
2554
|
linkquality: 50,
|
|
2725
2555
|
groupID: 1,
|
|
2726
|
-
meta: {
|
|
2556
|
+
meta: {
|
|
2557
|
+
rawData: Buffer.from([0, 1, 2, 3]),
|
|
2558
|
+
},
|
|
2727
2559
|
};
|
|
2728
|
-
expect(
|
|
2560
|
+
expect(events.message[0]).toStrictEqual(expected);
|
|
2729
2561
|
});
|
|
2730
2562
|
|
|
2731
2563
|
it("Receive zclData from unkonwn device shouldnt emit anything", async () => {
|
|
@@ -2767,90 +2599,9 @@ describe("Controller", () => {
|
|
|
2767
2599
|
const expected = {
|
|
2768
2600
|
cluster: "genBasic",
|
|
2769
2601
|
type: "readResponse",
|
|
2770
|
-
device:
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
_eventsCount: 0,
|
|
2774
|
-
_ieeeAddr: "0x129",
|
|
2775
|
-
_lastSeen: Date.now(),
|
|
2776
|
-
_pendingRequestTimeout: 0,
|
|
2777
|
-
_linkquality: 52,
|
|
2778
|
-
_skipDefaultResponse: false,
|
|
2779
|
-
_networkAddress: 129,
|
|
2780
|
-
_customClusters: {},
|
|
2781
|
-
_endpoints: [
|
|
2782
|
-
{
|
|
2783
|
-
clusters: {},
|
|
2784
|
-
ID: 1,
|
|
2785
|
-
_events: {},
|
|
2786
|
-
_eventsCount: 0,
|
|
2787
|
-
inputClusters: [0, 1],
|
|
2788
|
-
outputClusters: [2],
|
|
2789
|
-
pendingRequests: {id: 1, deviceIeeeAddress: "0x129", sendInProgress: false},
|
|
2790
|
-
deviceNetworkAddress: 129,
|
|
2791
|
-
deviceIeeeAddress: "0x129",
|
|
2792
|
-
_binds: [],
|
|
2793
|
-
_configuredReportings: [],
|
|
2794
|
-
deviceID: 5,
|
|
2795
|
-
profileID: 99,
|
|
2796
|
-
meta: {},
|
|
2797
|
-
},
|
|
2798
|
-
{
|
|
2799
|
-
ID: 3,
|
|
2800
|
-
_events: {},
|
|
2801
|
-
_eventsCount: 0,
|
|
2802
|
-
clusters: {
|
|
2803
|
-
genBasic: {
|
|
2804
|
-
attributes: {
|
|
2805
|
-
appVersion: 3,
|
|
2806
|
-
},
|
|
2807
|
-
},
|
|
2808
|
-
},
|
|
2809
|
-
inputClusters: [],
|
|
2810
|
-
outputClusters: [],
|
|
2811
|
-
pendingRequests: {id: 3, deviceIeeeAddress: "0x129", sendInProgress: false},
|
|
2812
|
-
deviceNetworkAddress: 129,
|
|
2813
|
-
deviceIeeeAddress: "0x129",
|
|
2814
|
-
_binds: [],
|
|
2815
|
-
_configuredReportings: [],
|
|
2816
|
-
meta: {},
|
|
2817
|
-
},
|
|
2818
|
-
],
|
|
2819
|
-
_type: "Router",
|
|
2820
|
-
_manufacturerID: 1212,
|
|
2821
|
-
_manufacturerName: "KoenAndCo",
|
|
2822
|
-
meta: {},
|
|
2823
|
-
_powerSource: "Mains (single phase)",
|
|
2824
|
-
_modelID: "myModelID",
|
|
2825
|
-
_applicationVersion: 3,
|
|
2826
|
-
_stackVersion: 101,
|
|
2827
|
-
_zclVersion: 1,
|
|
2828
|
-
_hardwareVersion: 3,
|
|
2829
|
-
_dateCode: "201901",
|
|
2830
|
-
_softwareBuildID: "1.01",
|
|
2831
|
-
_interviewState: InterviewState.Successful,
|
|
2832
|
-
_lastDefaultResponseSequenceNumber: 1,
|
|
2833
|
-
},
|
|
2834
|
-
endpoint: {
|
|
2835
|
-
ID: 3,
|
|
2836
|
-
_events: {},
|
|
2837
|
-
_eventsCount: 0,
|
|
2838
|
-
inputClusters: [],
|
|
2839
|
-
outputClusters: [],
|
|
2840
|
-
pendingRequests: {id: 3, deviceIeeeAddress: "0x129", sendInProgress: false},
|
|
2841
|
-
meta: {},
|
|
2842
|
-
deviceNetworkAddress: 129,
|
|
2843
|
-
deviceIeeeAddress: "0x129",
|
|
2844
|
-
_binds: [],
|
|
2845
|
-
_configuredReportings: [],
|
|
2846
|
-
clusters: {
|
|
2847
|
-
genBasic: {
|
|
2848
|
-
attributes: {
|
|
2849
|
-
appVersion: 3,
|
|
2850
|
-
},
|
|
2851
|
-
},
|
|
2852
|
-
},
|
|
2853
|
-
},
|
|
2602
|
+
device: expect.any(Device),
|
|
2603
|
+
endpoint: expect.any(Endpoint),
|
|
2604
|
+
groupID: undefined,
|
|
2854
2605
|
data: {
|
|
2855
2606
|
appVersion: 3,
|
|
2856
2607
|
},
|
|
@@ -2864,9 +2615,11 @@ describe("Controller", () => {
|
|
|
2864
2615
|
frameType: 0,
|
|
2865
2616
|
manufacturerSpecific: false,
|
|
2866
2617
|
},
|
|
2618
|
+
manufacturerCode: undefined,
|
|
2619
|
+
rawData: expect.any(Buffer),
|
|
2867
2620
|
},
|
|
2868
2621
|
};
|
|
2869
|
-
expect(
|
|
2622
|
+
expect(events.message[0]).toStrictEqual(expected);
|
|
2870
2623
|
expect(controller.getDeviceByIeeeAddr("0x129")!.endpoints.length).toBe(2);
|
|
2871
2624
|
});
|
|
2872
2625
|
|
|
@@ -2890,66 +2643,8 @@ describe("Controller", () => {
|
|
|
2890
2643
|
const expected = {
|
|
2891
2644
|
cluster: "genScenes",
|
|
2892
2645
|
type: "commandTradfriArrowSingle",
|
|
2893
|
-
device:
|
|
2894
|
-
|
|
2895
|
-
_events: {},
|
|
2896
|
-
_eventsCount: 0,
|
|
2897
|
-
_pendingRequestTimeout: 0,
|
|
2898
|
-
_lastSeen: Date.now(),
|
|
2899
|
-
_linkquality: 19,
|
|
2900
|
-
_skipDefaultResponse: false,
|
|
2901
|
-
_ieeeAddr: "0x129",
|
|
2902
|
-
_networkAddress: 129,
|
|
2903
|
-
_customClusters: {},
|
|
2904
|
-
_endpoints: [
|
|
2905
|
-
{
|
|
2906
|
-
ID: 1,
|
|
2907
|
-
_events: {},
|
|
2908
|
-
_eventsCount: 0,
|
|
2909
|
-
clusters: {},
|
|
2910
|
-
inputClusters: [0, 1],
|
|
2911
|
-
outputClusters: [2],
|
|
2912
|
-
pendingRequests: {id: 1, deviceIeeeAddress: "0x129", sendInProgress: false},
|
|
2913
|
-
deviceNetworkAddress: 129,
|
|
2914
|
-
deviceIeeeAddress: "0x129",
|
|
2915
|
-
_binds: [],
|
|
2916
|
-
_configuredReportings: [],
|
|
2917
|
-
meta: {},
|
|
2918
|
-
deviceID: 5,
|
|
2919
|
-
profileID: 99,
|
|
2920
|
-
},
|
|
2921
|
-
],
|
|
2922
|
-
_type: "Router",
|
|
2923
|
-
_manufacturerID: 1212,
|
|
2924
|
-
_manufacturerName: "KoenAndCo",
|
|
2925
|
-
meta: {},
|
|
2926
|
-
_powerSource: "Mains (single phase)",
|
|
2927
|
-
_modelID: "myModelID",
|
|
2928
|
-
_applicationVersion: 2,
|
|
2929
|
-
_stackVersion: 101,
|
|
2930
|
-
_zclVersion: 1,
|
|
2931
|
-
_hardwareVersion: 3,
|
|
2932
|
-
_dateCode: "201901",
|
|
2933
|
-
_softwareBuildID: "1.01",
|
|
2934
|
-
_interviewState: InterviewState.Successful,
|
|
2935
|
-
_lastDefaultResponseSequenceNumber: 29,
|
|
2936
|
-
},
|
|
2937
|
-
endpoint: {
|
|
2938
|
-
_events: {},
|
|
2939
|
-
_eventsCount: 0,
|
|
2940
|
-
ID: 1,
|
|
2941
|
-
clusters: {},
|
|
2942
|
-
inputClusters: [0, 1],
|
|
2943
|
-
outputClusters: [2],
|
|
2944
|
-
pendingRequests: {id: 1, deviceIeeeAddress: "0x129", sendInProgress: false},
|
|
2945
|
-
deviceNetworkAddress: 129,
|
|
2946
|
-
deviceIeeeAddress: "0x129",
|
|
2947
|
-
_binds: [],
|
|
2948
|
-
_configuredReportings: [],
|
|
2949
|
-
deviceID: 5,
|
|
2950
|
-
profileID: 99,
|
|
2951
|
-
meta: {},
|
|
2952
|
-
},
|
|
2646
|
+
device: expect.any(Device),
|
|
2647
|
+
endpoint: expect.any(Endpoint),
|
|
2953
2648
|
data: {
|
|
2954
2649
|
value: 256,
|
|
2955
2650
|
value2: 13,
|
|
@@ -2966,9 +2661,10 @@ describe("Controller", () => {
|
|
|
2966
2661
|
frameType: 1,
|
|
2967
2662
|
manufacturerSpecific: true,
|
|
2968
2663
|
},
|
|
2664
|
+
rawData: expect.any(Buffer),
|
|
2969
2665
|
},
|
|
2970
2666
|
};
|
|
2971
|
-
expect(
|
|
2667
|
+
expect(events.message[0]).toStrictEqual(expected);
|
|
2972
2668
|
});
|
|
2973
2669
|
|
|
2974
2670
|
it("Receive cluster command from unknown cluster", async () => {
|
|
@@ -3282,16 +2978,10 @@ describe("Controller", () => {
|
|
|
3282
2978
|
},
|
|
3283
2979
|
payload: [{attrId: 28, attrData: 3, dataType: 48, status: 0}],
|
|
3284
2980
|
cluster: null,
|
|
3285
|
-
command: {
|
|
2981
|
+
command: expect.objectContaining({
|
|
3286
2982
|
ID: 1,
|
|
3287
2983
|
name: "readRsp",
|
|
3288
|
-
|
|
3289
|
-
{name: "attrId", type: 33},
|
|
3290
|
-
{name: "status", type: 32},
|
|
3291
|
-
{name: "dataType", type: 32, conditions: [{type: "statusEquals", value: 0}]},
|
|
3292
|
-
{name: "attrData", type: 1000, conditions: [{type: "statusEquals", value: 0}]},
|
|
3293
|
-
],
|
|
3294
|
-
},
|
|
2984
|
+
}),
|
|
3295
2985
|
});
|
|
3296
2986
|
});
|
|
3297
2987
|
|
|
@@ -3432,12 +3122,20 @@ describe("Controller", () => {
|
|
|
3432
3122
|
],
|
|
3433
3123
|
_type: "EndDevice",
|
|
3434
3124
|
_manufacturerID: 4151,
|
|
3435
|
-
_manufacturerName: "LUMI",
|
|
3436
3125
|
meta: {},
|
|
3437
|
-
_powerSource: "Battery",
|
|
3438
|
-
_modelID: "lumi.occupancy",
|
|
3439
3126
|
_interviewState: InterviewState.Successful,
|
|
3440
3127
|
});
|
|
3128
|
+
expect(controller.getDeviceByIeeeAddr("0x150")?.genBasic).toStrictEqual({
|
|
3129
|
+
appVersion: undefined,
|
|
3130
|
+
dateCode: undefined,
|
|
3131
|
+
hwVersion: undefined,
|
|
3132
|
+
manufacturerName: "LUMI",
|
|
3133
|
+
modelId: "lumi.occupancy",
|
|
3134
|
+
powerSource: Zcl.PowerSource.Battery,
|
|
3135
|
+
stackVersion: undefined,
|
|
3136
|
+
swBuildId: undefined,
|
|
3137
|
+
zclVersion: undefined,
|
|
3138
|
+
});
|
|
3441
3139
|
});
|
|
3442
3140
|
|
|
3443
3141
|
it("Xiaomi end device joins (node descriptor succeeds, but active endpoint response fails)", async () => {
|
|
@@ -3485,12 +3183,20 @@ describe("Controller", () => {
|
|
|
3485
3183
|
],
|
|
3486
3184
|
_type: "EndDevice",
|
|
3487
3185
|
_manufacturerID: 1219,
|
|
3488
|
-
_manufacturerName: "LUMI",
|
|
3489
3186
|
meta: {},
|
|
3490
|
-
_powerSource: "Battery",
|
|
3491
|
-
_modelID: "lumi.occupancy",
|
|
3492
3187
|
_interviewState: InterviewState.Successful,
|
|
3493
3188
|
});
|
|
3189
|
+
expect(controller.getDeviceByIeeeAddr("0x151")?.genBasic).toStrictEqual({
|
|
3190
|
+
appVersion: undefined,
|
|
3191
|
+
dateCode: undefined,
|
|
3192
|
+
hwVersion: undefined,
|
|
3193
|
+
manufacturerName: "LUMI",
|
|
3194
|
+
modelId: "lumi.occupancy",
|
|
3195
|
+
powerSource: Zcl.PowerSource.Battery,
|
|
3196
|
+
stackVersion: undefined,
|
|
3197
|
+
swBuildId: undefined,
|
|
3198
|
+
zclVersion: undefined,
|
|
3199
|
+
});
|
|
3494
3200
|
});
|
|
3495
3201
|
|
|
3496
3202
|
it("Should use cached node descriptor when device is re-interviewed, but retrieve it when ignoreCache=true", async () => {
|
|
@@ -3549,97 +3255,8 @@ describe("Controller", () => {
|
|
|
3549
3255
|
const expected = {
|
|
3550
3256
|
cluster: "genBasic",
|
|
3551
3257
|
type: "attributeReport",
|
|
3552
|
-
device:
|
|
3553
|
-
|
|
3554
|
-
_eventsCount: 0,
|
|
3555
|
-
_lastSeen: Date.now(),
|
|
3556
|
-
_linkquality: 50,
|
|
3557
|
-
_skipDefaultResponse: false,
|
|
3558
|
-
ID: 2,
|
|
3559
|
-
_ieeeAddr: "0x129",
|
|
3560
|
-
_networkAddress: 129,
|
|
3561
|
-
_customClusters: {},
|
|
3562
|
-
_endpoints: [
|
|
3563
|
-
{
|
|
3564
|
-
_events: {},
|
|
3565
|
-
_eventsCount: 0,
|
|
3566
|
-
ID: 1,
|
|
3567
|
-
clusters: {
|
|
3568
|
-
genBasic: {
|
|
3569
|
-
attributes: {
|
|
3570
|
-
"65281": {
|
|
3571
|
-
"1": 3285,
|
|
3572
|
-
"10": 0,
|
|
3573
|
-
"100": 0,
|
|
3574
|
-
"3": 33,
|
|
3575
|
-
"4": 5032,
|
|
3576
|
-
"5": 43,
|
|
3577
|
-
"6": 327680,
|
|
3578
|
-
"8": 516,
|
|
3579
|
-
},
|
|
3580
|
-
modelId: "lumi.sensor_wleak.aq1",
|
|
3581
|
-
},
|
|
3582
|
-
},
|
|
3583
|
-
},
|
|
3584
|
-
inputClusters: [0, 1],
|
|
3585
|
-
outputClusters: [2],
|
|
3586
|
-
pendingRequests: {id: 1, deviceIeeeAddress: "0x129", sendInProgress: false},
|
|
3587
|
-
deviceNetworkAddress: 129,
|
|
3588
|
-
deviceIeeeAddress: "0x129",
|
|
3589
|
-
_binds: [],
|
|
3590
|
-
_configuredReportings: [],
|
|
3591
|
-
meta: {},
|
|
3592
|
-
deviceID: 5,
|
|
3593
|
-
profileID: 99,
|
|
3594
|
-
},
|
|
3595
|
-
],
|
|
3596
|
-
_type: "Router",
|
|
3597
|
-
_manufacturerID: 1212,
|
|
3598
|
-
_manufacturerName: "KoenAndCo",
|
|
3599
|
-
meta: {},
|
|
3600
|
-
_powerSource: "Mains (single phase)",
|
|
3601
|
-
_modelID: "lumi.sensor_wleak.aq1",
|
|
3602
|
-
_applicationVersion: 2,
|
|
3603
|
-
_stackVersion: 101,
|
|
3604
|
-
_zclVersion: 1,
|
|
3605
|
-
_hardwareVersion: 3,
|
|
3606
|
-
_dateCode: "201901",
|
|
3607
|
-
_pendingRequestTimeout: 0,
|
|
3608
|
-
_softwareBuildID: "1.01",
|
|
3609
|
-
_interviewState: InterviewState.Successful,
|
|
3610
|
-
},
|
|
3611
|
-
endpoint: {
|
|
3612
|
-
_events: {},
|
|
3613
|
-
_eventsCount: 0,
|
|
3614
|
-
ID: 1,
|
|
3615
|
-
deviceID: 5,
|
|
3616
|
-
inputClusters: [0, 1],
|
|
3617
|
-
outputClusters: [2],
|
|
3618
|
-
pendingRequests: {id: 1, deviceIeeeAddress: "0x129", sendInProgress: false},
|
|
3619
|
-
deviceNetworkAddress: 129,
|
|
3620
|
-
deviceIeeeAddress: "0x129",
|
|
3621
|
-
_binds: [],
|
|
3622
|
-
_configuredReportings: [],
|
|
3623
|
-
profileID: 99,
|
|
3624
|
-
meta: {},
|
|
3625
|
-
clusters: {
|
|
3626
|
-
genBasic: {
|
|
3627
|
-
attributes: {
|
|
3628
|
-
"65281": {
|
|
3629
|
-
"1": 3285,
|
|
3630
|
-
"10": 0,
|
|
3631
|
-
"100": 0,
|
|
3632
|
-
"3": 33,
|
|
3633
|
-
"4": 5032,
|
|
3634
|
-
"5": 43,
|
|
3635
|
-
"6": 327680,
|
|
3636
|
-
"8": 516,
|
|
3637
|
-
},
|
|
3638
|
-
modelId: "lumi.sensor_wleak.aq1",
|
|
3639
|
-
},
|
|
3640
|
-
},
|
|
3641
|
-
},
|
|
3642
|
-
},
|
|
3258
|
+
device: expect.any(Device),
|
|
3259
|
+
endpoint: expect.any(Endpoint),
|
|
3643
3260
|
data: {
|
|
3644
3261
|
"65281": {
|
|
3645
3262
|
"1": 3285,
|
|
@@ -3665,9 +3282,10 @@ describe("Controller", () => {
|
|
|
3665
3282
|
frameType: 0,
|
|
3666
3283
|
manufacturerSpecific: true,
|
|
3667
3284
|
},
|
|
3285
|
+
rawData: null,
|
|
3668
3286
|
},
|
|
3669
3287
|
};
|
|
3670
|
-
expect(
|
|
3288
|
+
expect(events.message[0]).toStrictEqual(expected);
|
|
3671
3289
|
});
|
|
3672
3290
|
|
|
3673
3291
|
it("Should allow to specify custom attributes for existing cluster", async () => {
|
|
@@ -4053,7 +3671,7 @@ describe("Controller", () => {
|
|
|
4053
3671
|
expect(call[2]).toBe(1);
|
|
4054
3672
|
expect(call[3].cluster.name).toBe("genPollCtrl");
|
|
4055
3673
|
expect(call[3].command.name).toBe("checkinRsp");
|
|
4056
|
-
expect(call[3].payload).toStrictEqual({startFastPolling:
|
|
3674
|
+
expect(call[3].payload).toStrictEqual({startFastPolling: 0, fastPollTimeout: 0});
|
|
4057
3675
|
});
|
|
4058
3676
|
|
|
4059
3677
|
it("Poll control unsupported", async () => {
|
|
@@ -4301,6 +3919,36 @@ describe("Controller", () => {
|
|
|
4301
3919
|
);
|
|
4302
3920
|
});
|
|
4303
3921
|
|
|
3922
|
+
it("throws when trying to configure reporting on endpoint with bad attribute", async () => {
|
|
3923
|
+
await controller.start();
|
|
3924
|
+
await mockAdapterEvents.deviceJoined({networkAddress: 129, ieeeAddr: "0x129"});
|
|
3925
|
+
const device = controller.getDeviceByIeeeAddr("0x129")!;
|
|
3926
|
+
const endpoint = device.getEndpoint(1)!;
|
|
3927
|
+
mocksendZclFrameToEndpoint.mockClear();
|
|
3928
|
+
|
|
3929
|
+
await expect(async () => {
|
|
3930
|
+
await endpoint.configureReporting("genPowerCfg", [
|
|
3931
|
+
{
|
|
3932
|
+
attribute: "doesnotexist",
|
|
3933
|
+
minimumReportInterval: 1,
|
|
3934
|
+
maximumReportInterval: 10,
|
|
3935
|
+
reportableChange: 1,
|
|
3936
|
+
},
|
|
3937
|
+
]);
|
|
3938
|
+
}).rejects.toThrow(`Invalid attribute 'doesnotexist' for cluster 'genPowerCfg'`);
|
|
3939
|
+
|
|
3940
|
+
await expect(async () => {
|
|
3941
|
+
await endpoint.configureReporting("genBasic", [
|
|
3942
|
+
{
|
|
3943
|
+
attribute: 99999,
|
|
3944
|
+
minimumReportInterval: 1,
|
|
3945
|
+
maximumReportInterval: 10,
|
|
3946
|
+
reportableChange: 1,
|
|
3947
|
+
},
|
|
3948
|
+
]);
|
|
3949
|
+
}).rejects.toThrow(`Invalid attribute '99999' for cluster 'genBasic'`);
|
|
3950
|
+
});
|
|
3951
|
+
|
|
4304
3952
|
it("Should replace legacy configured reportings without manufacturerCode", async () => {
|
|
4305
3953
|
await controller.start();
|
|
4306
3954
|
await mockAdapterEvents.deviceJoined({networkAddress: 129, ieeeAddr: "0x129"});
|
|
@@ -4813,14 +4461,10 @@ describe("Controller", () => {
|
|
|
4813
4461
|
},
|
|
4814
4462
|
payload: {payloadType: 0, queryJitter: 1},
|
|
4815
4463
|
cluster: expect.objectContaining({name: "genOta"}),
|
|
4816
|
-
command: {
|
|
4464
|
+
command: expect.objectContaining({
|
|
4817
4465
|
ID: 0,
|
|
4818
|
-
parameters: [
|
|
4819
|
-
{name: "payloadType", type: 32},
|
|
4820
|
-
{name: "queryJitter", type: 32},
|
|
4821
|
-
],
|
|
4822
4466
|
name: "imageNotify",
|
|
4823
|
-
},
|
|
4467
|
+
}),
|
|
4824
4468
|
};
|
|
4825
4469
|
expect(deepClone(mocksendZclFrameToEndpoint.mock.calls[0][3])).toStrictEqual(expected);
|
|
4826
4470
|
expect(mocksendZclFrameToEndpoint.mock.calls[0][4]).toBe(10000);
|
|
@@ -4868,6 +4512,24 @@ describe("Controller", () => {
|
|
|
4868
4512
|
expect(error).toStrictEqual(new Error("whoops!"));
|
|
4869
4513
|
});
|
|
4870
4514
|
|
|
4515
|
+
it("Endpoint waitForCommand frame fails to parse", async () => {
|
|
4516
|
+
await controller.start();
|
|
4517
|
+
await mockAdapterEvents.deviceJoined({networkAddress: 129, ieeeAddr: "0x129"});
|
|
4518
|
+
const device = controller.getDeviceByIeeeAddr("0x129")!;
|
|
4519
|
+
const endpoint = device.getEndpoint(1)!;
|
|
4520
|
+
mocksendZclFrameToEndpoint.mockClear();
|
|
4521
|
+
// The buffer below ([24, 169, 10, 0, 0, 24]) is intentionally malformed:
|
|
4522
|
+
// It is missing expected payload bytes for a valid ZCL frame, causing Zcl.Frame.fromBuffer to throw a parsing error.
|
|
4523
|
+
// This triggers the error handling path being tested.
|
|
4524
|
+
const buffer = Buffer.from([24, 169, 10, 0, 0, 24]);
|
|
4525
|
+
const header = Zcl.Header.fromBuffer(buffer);
|
|
4526
|
+
const promise = new Promise((resolve, _reject) => resolve({clusterID: Zcl.Utils.getCluster("msOccupancySensing").ID, data: buffer, header}));
|
|
4527
|
+
mockAdapterWaitFor.mockReturnValueOnce({promise, cancel: () => {}});
|
|
4528
|
+
await expect(endpoint.waitForCommand("genOta", "upgradeEndRequest", 10, 20).promise).rejects.toThrow(
|
|
4529
|
+
`The value of "offset" is out of range. It must be >= 0 and <= 5. Received 6`,
|
|
4530
|
+
);
|
|
4531
|
+
});
|
|
4532
|
+
|
|
4871
4533
|
it("Device without meta should set meta to {}", async () => {
|
|
4872
4534
|
Device.resetCache();
|
|
4873
4535
|
const line = JSON.stringify({
|
|
@@ -4907,8 +4569,6 @@ describe("Controller", () => {
|
|
|
4907
4569
|
_eventsCount: 0,
|
|
4908
4570
|
_pendingRequestTimeout: 0,
|
|
4909
4571
|
_skipDefaultResponse: false,
|
|
4910
|
-
_applicationVersion: 17,
|
|
4911
|
-
_dateCode: "20170302",
|
|
4912
4572
|
_customClusters: {},
|
|
4913
4573
|
_endpoints: [
|
|
4914
4574
|
{
|
|
@@ -4928,21 +4588,25 @@ describe("Controller", () => {
|
|
|
4928
4588
|
profileID: 49246,
|
|
4929
4589
|
},
|
|
4930
4590
|
],
|
|
4931
|
-
_hardwareVersion: 1,
|
|
4932
4591
|
_ieeeAddr: "0x90fd9ffffe4b64ae",
|
|
4933
4592
|
_interviewState: InterviewState.Successful,
|
|
4934
4593
|
_manufacturerID: 4476,
|
|
4935
|
-
_manufacturerName: "IKEA of Sweden",
|
|
4936
4594
|
meta: {},
|
|
4937
|
-
_modelID: "TRADFRI remote control",
|
|
4938
4595
|
_networkAddress: 19468,
|
|
4939
|
-
_powerSource: "Battery",
|
|
4940
|
-
_softwareBuildID: "1.2.214",
|
|
4941
|
-
_stackVersion: 87,
|
|
4942
4596
|
_type: "EndDevice",
|
|
4943
|
-
_zclVersion: 1,
|
|
4944
4597
|
};
|
|
4945
4598
|
expect(deepClone(controller.getDeviceByIeeeAddr("0x90fd9ffffe4b64ae"))).toStrictEqual(expected);
|
|
4599
|
+
expect(controller.getDeviceByIeeeAddr("0x90fd9ffffe4b64ae")?.genBasic).toStrictEqual({
|
|
4600
|
+
manufacturerName: "IKEA of Sweden",
|
|
4601
|
+
modelId: "TRADFRI remote control",
|
|
4602
|
+
powerSource: Zcl.PowerSource.Battery,
|
|
4603
|
+
swBuildId: "1.2.214",
|
|
4604
|
+
stackVersion: 87,
|
|
4605
|
+
zclVersion: 1,
|
|
4606
|
+
appVersion: 17,
|
|
4607
|
+
dateCode: "20170302",
|
|
4608
|
+
hwVersion: 1,
|
|
4609
|
+
});
|
|
4946
4610
|
});
|
|
4947
4611
|
|
|
4948
4612
|
it("Read from group", async () => {
|
|
@@ -4990,7 +4654,7 @@ describe("Controller", () => {
|
|
|
4990
4654
|
it("Write to group", async () => {
|
|
4991
4655
|
await controller.start();
|
|
4992
4656
|
const group = await controller.createGroup(2);
|
|
4993
|
-
await group.write("genBasic", {49: {value: 0x000b, type: 0x19}, deviceEnabled:
|
|
4657
|
+
await group.write("genBasic", {49: {value: 0x000b, type: 0x19}, deviceEnabled: 1}, {});
|
|
4994
4658
|
expect(mocksendZclFrameToGroup).toHaveBeenCalledTimes(1);
|
|
4995
4659
|
expect(mocksendZclFrameToGroup.mock.calls[0][0]).toBe(2);
|
|
4996
4660
|
expect(deepClone(mocksendZclFrameToGroup.mock.calls[0][1])).toStrictEqual(
|
|
@@ -5005,7 +4669,7 @@ describe("Controller", () => {
|
|
|
5005
4669
|
0,
|
|
5006
4670
|
[
|
|
5007
4671
|
{attrData: 11, attrId: 49, dataType: 25},
|
|
5008
|
-
{attrData:
|
|
4672
|
+
{attrData: 1, attrId: 18, dataType: 16},
|
|
5009
4673
|
],
|
|
5010
4674
|
{},
|
|
5011
4675
|
),
|
|
@@ -5019,7 +4683,7 @@ describe("Controller", () => {
|
|
|
5019
4683
|
const group = await controller.createGroup(2);
|
|
5020
4684
|
let error;
|
|
5021
4685
|
try {
|
|
5022
|
-
await group.write("genBasic", {UNKNOWN: {value: 0x000b, type: 0x19}, deviceEnabled:
|
|
4686
|
+
await group.write("genBasic", {UNKNOWN: {value: 0x000b, type: 0x19}, deviceEnabled: 1}, {});
|
|
5023
4687
|
} catch (e) {
|
|
5024
4688
|
error = e;
|
|
5025
4689
|
}
|
|
@@ -5710,8 +5374,6 @@ describe("Controller", () => {
|
|
|
5710
5374
|
_eventsCount: 0,
|
|
5711
5375
|
_pendingRequestTimeout: 0,
|
|
5712
5376
|
_skipDefaultResponse: false,
|
|
5713
|
-
_applicationVersion: 17,
|
|
5714
|
-
_dateCode: "20170331",
|
|
5715
5377
|
_customClusters: {},
|
|
5716
5378
|
_endpoints: [
|
|
5717
5379
|
{
|
|
@@ -5731,27 +5393,29 @@ describe("Controller", () => {
|
|
|
5731
5393
|
profileID: 49246,
|
|
5732
5394
|
},
|
|
5733
5395
|
],
|
|
5734
|
-
_hardwareVersion: 1,
|
|
5735
5396
|
_ieeeAddr: "0x000b57fffec6a5b2",
|
|
5736
5397
|
_interviewState: InterviewState.Successful,
|
|
5737
5398
|
_manufacturerID: 4476,
|
|
5738
|
-
_manufacturerName: "IKEA of Sweden",
|
|
5739
5399
|
meta: {reporting: 1},
|
|
5740
|
-
_modelID: "TRADFRI bulb E27 WS opal 980lm",
|
|
5741
5400
|
_networkAddress: 40369,
|
|
5742
|
-
_powerSource: "Mains (single phase)",
|
|
5743
|
-
_softwareBuildID: "1.2.217",
|
|
5744
|
-
_stackVersion: 87,
|
|
5745
5401
|
_type: "Router",
|
|
5746
|
-
|
|
5402
|
+
});
|
|
5403
|
+
expect(controller.getDeviceByIeeeAddr("0x000b57fffec6a5b2")?.genBasic).toStrictEqual({
|
|
5404
|
+
appVersion: 17,
|
|
5405
|
+
dateCode: "20170331",
|
|
5406
|
+
hwVersion: 1,
|
|
5407
|
+
manufacturerName: "IKEA of Sweden",
|
|
5408
|
+
modelId: "TRADFRI bulb E27 WS opal 980lm",
|
|
5409
|
+
powerSource: Zcl.PowerSource["Mains (single phase)"],
|
|
5410
|
+
swBuildId: "1.2.217",
|
|
5411
|
+
stackVersion: 87,
|
|
5412
|
+
zclVersion: 1,
|
|
5747
5413
|
});
|
|
5748
5414
|
expect(deepClone(controller.getDeviceByIeeeAddr("0x0017880104e45517"))).toStrictEqual({
|
|
5749
5415
|
ID: 4,
|
|
5750
5416
|
_events: {},
|
|
5751
5417
|
_eventsCount: 0,
|
|
5752
5418
|
_pendingRequestTimeout: 0,
|
|
5753
|
-
_applicationVersion: 2,
|
|
5754
|
-
_dateCode: "20160302",
|
|
5755
5419
|
_customClusters: {},
|
|
5756
5420
|
_endpoints: [
|
|
5757
5421
|
{
|
|
@@ -5787,30 +5451,32 @@ describe("Controller", () => {
|
|
|
5787
5451
|
pendingRequests: {id: 2, deviceIeeeAddress: "0x0017880104e45517", sendInProgress: false},
|
|
5788
5452
|
},
|
|
5789
5453
|
],
|
|
5790
|
-
_hardwareVersion: 1,
|
|
5791
5454
|
_ieeeAddr: "0x0017880104e45517",
|
|
5792
5455
|
_interviewState: InterviewState.Successful,
|
|
5793
5456
|
_lastSeen: 123,
|
|
5794
5457
|
_manufacturerID: 4107,
|
|
5795
|
-
_manufacturerName: "Philips",
|
|
5796
|
-
_modelID: "RWL021",
|
|
5797
5458
|
_networkAddress: 6538,
|
|
5798
|
-
_powerSource: "Battery",
|
|
5799
|
-
_softwareBuildID: "5.45.1.17846",
|
|
5800
|
-
_stackVersion: 1,
|
|
5801
5459
|
_type: "EndDevice",
|
|
5802
|
-
_zclVersion: 1,
|
|
5803
5460
|
_skipDefaultResponse: false,
|
|
5804
5461
|
meta: {configured: 1},
|
|
5805
5462
|
});
|
|
5463
|
+
expect(controller.getDeviceByIeeeAddr("0x0017880104e45517")?.genBasic).toStrictEqual({
|
|
5464
|
+
appVersion: 2,
|
|
5465
|
+
dateCode: "20160302",
|
|
5466
|
+
hwVersion: 1,
|
|
5467
|
+
manufacturerName: "Philips",
|
|
5468
|
+
modelId: "RWL021",
|
|
5469
|
+
powerSource: Zcl.PowerSource.Battery,
|
|
5470
|
+
swBuildId: "5.45.1.17846",
|
|
5471
|
+
stackVersion: 1,
|
|
5472
|
+
zclVersion: 1,
|
|
5473
|
+
});
|
|
5806
5474
|
expect(deepClone(controller.getDeviceByIeeeAddr("0x0017880104e45518"))).toStrictEqual({
|
|
5807
5475
|
ID: 6,
|
|
5808
5476
|
_checkinInterval: 123456,
|
|
5809
5477
|
_events: {},
|
|
5810
5478
|
_eventsCount: 0,
|
|
5811
5479
|
_pendingRequestTimeout: 123456000,
|
|
5812
|
-
_applicationVersion: 2,
|
|
5813
|
-
_dateCode: "20160302",
|
|
5814
5480
|
_customClusters: {},
|
|
5815
5481
|
_endpoints: [
|
|
5816
5482
|
{
|
|
@@ -5846,21 +5512,25 @@ describe("Controller", () => {
|
|
|
5846
5512
|
pendingRequests: {id: 2, deviceIeeeAddress: "0x0017880104e45518", sendInProgress: false},
|
|
5847
5513
|
},
|
|
5848
5514
|
],
|
|
5849
|
-
_hardwareVersion: 1,
|
|
5850
5515
|
_ieeeAddr: "0x0017880104e45518",
|
|
5851
5516
|
_interviewState: InterviewState.Successful,
|
|
5852
5517
|
_manufacturerID: 4107,
|
|
5853
|
-
_manufacturerName: "Philips",
|
|
5854
|
-
_modelID: "RWL021",
|
|
5855
5518
|
_networkAddress: 6536,
|
|
5856
|
-
_powerSource: "Battery",
|
|
5857
|
-
_softwareBuildID: "5.45.1.17846",
|
|
5858
|
-
_stackVersion: 1,
|
|
5859
5519
|
_type: "EndDevice",
|
|
5860
|
-
_zclVersion: 1,
|
|
5861
5520
|
_skipDefaultResponse: false,
|
|
5862
5521
|
meta: {configured: 1},
|
|
5863
5522
|
});
|
|
5523
|
+
expect(controller.getDeviceByIeeeAddr("0x0017880104e45518")?.genBasic).toStrictEqual({
|
|
5524
|
+
appVersion: 2,
|
|
5525
|
+
dateCode: "20160302",
|
|
5526
|
+
hwVersion: 1,
|
|
5527
|
+
manufacturerName: "Philips",
|
|
5528
|
+
modelId: "RWL021",
|
|
5529
|
+
powerSource: Zcl.PowerSource.Battery,
|
|
5530
|
+
swBuildId: "5.45.1.17846",
|
|
5531
|
+
stackVersion: 1,
|
|
5532
|
+
zclVersion: 1,
|
|
5533
|
+
});
|
|
5864
5534
|
expect((await controller.getGroups()).length).toBe(2);
|
|
5865
5535
|
|
|
5866
5536
|
const group1 = controller.getGroupByID(1)!;
|
|
@@ -6002,65 +5672,8 @@ describe("Controller", () => {
|
|
|
6002
5672
|
|
|
6003
5673
|
const expected = {
|
|
6004
5674
|
type: "read",
|
|
6005
|
-
device:
|
|
6006
|
-
|
|
6007
|
-
_applicationVersion: 2,
|
|
6008
|
-
_dateCode: "201901",
|
|
6009
|
-
_pendingRequestTimeout: 0,
|
|
6010
|
-
_customClusters: {},
|
|
6011
|
-
_endpoints: [
|
|
6012
|
-
{
|
|
6013
|
-
deviceID: 5,
|
|
6014
|
-
inputClusters: [0, 1],
|
|
6015
|
-
outputClusters: [2],
|
|
6016
|
-
pendingRequests: {id: 1, deviceIeeeAddress: "0x129", sendInProgress: false},
|
|
6017
|
-
profileID: 99,
|
|
6018
|
-
ID: 1,
|
|
6019
|
-
clusters: {},
|
|
6020
|
-
deviceIeeeAddress: "0x129",
|
|
6021
|
-
deviceNetworkAddress: 129,
|
|
6022
|
-
_binds: [],
|
|
6023
|
-
_configuredReportings: [],
|
|
6024
|
-
_events: {},
|
|
6025
|
-
_eventsCount: 0,
|
|
6026
|
-
meta: {},
|
|
6027
|
-
},
|
|
6028
|
-
],
|
|
6029
|
-
_hardwareVersion: 3,
|
|
6030
|
-
_events: {},
|
|
6031
|
-
_eventsCount: 0,
|
|
6032
|
-
_ieeeAddr: "0x129",
|
|
6033
|
-
_interviewState: InterviewState.Successful,
|
|
6034
|
-
_lastSeen: Date.now(),
|
|
6035
|
-
_linkquality: 19,
|
|
6036
|
-
_skipDefaultResponse: false,
|
|
6037
|
-
_manufacturerID: 1212,
|
|
6038
|
-
_manufacturerName: "KoenAndCo",
|
|
6039
|
-
_modelID: "myModelID",
|
|
6040
|
-
_networkAddress: 129,
|
|
6041
|
-
_powerSource: "Mains (single phase)",
|
|
6042
|
-
_softwareBuildID: "1.01",
|
|
6043
|
-
_stackVersion: 101,
|
|
6044
|
-
_type: "Router",
|
|
6045
|
-
_zclVersion: 1,
|
|
6046
|
-
meta: {},
|
|
6047
|
-
},
|
|
6048
|
-
endpoint: {
|
|
6049
|
-
deviceID: 5,
|
|
6050
|
-
inputClusters: [0, 1],
|
|
6051
|
-
outputClusters: [2],
|
|
6052
|
-
pendingRequests: {id: 1, deviceIeeeAddress: "0x129", sendInProgress: false},
|
|
6053
|
-
profileID: 99,
|
|
6054
|
-
ID: 1,
|
|
6055
|
-
clusters: {},
|
|
6056
|
-
deviceIeeeAddress: "0x129",
|
|
6057
|
-
deviceNetworkAddress: 129,
|
|
6058
|
-
_binds: [],
|
|
6059
|
-
_configuredReportings: [],
|
|
6060
|
-
_events: {},
|
|
6061
|
-
_eventsCount: 0,
|
|
6062
|
-
meta: {},
|
|
6063
|
-
},
|
|
5675
|
+
device: expect.any(Device),
|
|
5676
|
+
endpoint: expect.any(Endpoint),
|
|
6064
5677
|
data: ["mainsVoltage", 9999],
|
|
6065
5678
|
linkquality: 19,
|
|
6066
5679
|
groupID: 10,
|
|
@@ -6074,11 +5687,13 @@ describe("Controller", () => {
|
|
|
6074
5687
|
frameType: 0,
|
|
6075
5688
|
manufacturerSpecific: false,
|
|
6076
5689
|
},
|
|
5690
|
+
manufacturerCode: undefined,
|
|
5691
|
+
rawData: expect.any(Buffer),
|
|
6077
5692
|
},
|
|
6078
5693
|
};
|
|
6079
5694
|
|
|
6080
5695
|
expect(events.message.length).toBe(1);
|
|
6081
|
-
expect(
|
|
5696
|
+
expect(events.message[0]).toStrictEqual(expected);
|
|
6082
5697
|
});
|
|
6083
5698
|
|
|
6084
5699
|
it("Emit write from device", async () => {
|
|
@@ -6099,65 +5714,8 @@ describe("Controller", () => {
|
|
|
6099
5714
|
|
|
6100
5715
|
const expected = {
|
|
6101
5716
|
type: "write",
|
|
6102
|
-
device:
|
|
6103
|
-
|
|
6104
|
-
_events: {},
|
|
6105
|
-
_eventsCount: 0,
|
|
6106
|
-
_applicationVersion: 2,
|
|
6107
|
-
_dateCode: "201901",
|
|
6108
|
-
_pendingRequestTimeout: 0,
|
|
6109
|
-
_customClusters: {},
|
|
6110
|
-
_endpoints: [
|
|
6111
|
-
{
|
|
6112
|
-
meta: {},
|
|
6113
|
-
deviceID: 5,
|
|
6114
|
-
_events: {},
|
|
6115
|
-
_eventsCount: 0,
|
|
6116
|
-
inputClusters: [0, 1],
|
|
6117
|
-
outputClusters: [2],
|
|
6118
|
-
pendingRequests: {id: 1, deviceIeeeAddress: "0x129", sendInProgress: false},
|
|
6119
|
-
profileID: 99,
|
|
6120
|
-
ID: 1,
|
|
6121
|
-
clusters: {},
|
|
6122
|
-
deviceIeeeAddress: "0x129",
|
|
6123
|
-
deviceNetworkAddress: 129,
|
|
6124
|
-
_binds: [],
|
|
6125
|
-
_configuredReportings: [],
|
|
6126
|
-
},
|
|
6127
|
-
],
|
|
6128
|
-
_hardwareVersion: 3,
|
|
6129
|
-
_ieeeAddr: "0x129",
|
|
6130
|
-
_interviewState: InterviewState.Successful,
|
|
6131
|
-
_lastSeen: Date.now(),
|
|
6132
|
-
_linkquality: 19,
|
|
6133
|
-
_skipDefaultResponse: false,
|
|
6134
|
-
_manufacturerID: 1212,
|
|
6135
|
-
_manufacturerName: "KoenAndCo",
|
|
6136
|
-
_modelID: "myModelID",
|
|
6137
|
-
_networkAddress: 129,
|
|
6138
|
-
_powerSource: "Mains (single phase)",
|
|
6139
|
-
_softwareBuildID: "1.01",
|
|
6140
|
-
_stackVersion: 101,
|
|
6141
|
-
_type: "Router",
|
|
6142
|
-
_zclVersion: 1,
|
|
6143
|
-
meta: {},
|
|
6144
|
-
},
|
|
6145
|
-
endpoint: {
|
|
6146
|
-
_events: {},
|
|
6147
|
-
_eventsCount: 0,
|
|
6148
|
-
deviceID: 5,
|
|
6149
|
-
inputClusters: [0, 1],
|
|
6150
|
-
outputClusters: [2],
|
|
6151
|
-
pendingRequests: {id: 1, deviceIeeeAddress: "0x129", sendInProgress: false},
|
|
6152
|
-
profileID: 99,
|
|
6153
|
-
ID: 1,
|
|
6154
|
-
clusters: {},
|
|
6155
|
-
deviceIeeeAddress: "0x129",
|
|
6156
|
-
deviceNetworkAddress: 129,
|
|
6157
|
-
_binds: [],
|
|
6158
|
-
_configuredReportings: [],
|
|
6159
|
-
meta: {},
|
|
6160
|
-
},
|
|
5717
|
+
device: expect.any(Device),
|
|
5718
|
+
endpoint: expect.any(Endpoint),
|
|
6161
5719
|
data: {
|
|
6162
5720
|
"16389": 3,
|
|
6163
5721
|
},
|
|
@@ -6173,11 +5731,13 @@ describe("Controller", () => {
|
|
|
6173
5731
|
frameType: 0,
|
|
6174
5732
|
manufacturerSpecific: false,
|
|
6175
5733
|
},
|
|
5734
|
+
manufacturerCode: undefined,
|
|
5735
|
+
rawData: expect.any(Buffer),
|
|
6176
5736
|
},
|
|
6177
5737
|
};
|
|
6178
5738
|
|
|
6179
5739
|
expect(events.message.length).toBe(1);
|
|
6180
|
-
expect(
|
|
5740
|
+
expect(events.message[0]).toStrictEqual(expected);
|
|
6181
5741
|
});
|
|
6182
5742
|
|
|
6183
5743
|
it("Endpoint command error", async () => {
|
|
@@ -6401,13 +5961,13 @@ describe("Controller", () => {
|
|
|
6401
5961
|
mocksendZclFrameToEndpoint.mockRejectedValueOnce(new Error("timeout occurred"));
|
|
6402
5962
|
let error;
|
|
6403
5963
|
try {
|
|
6404
|
-
await endpoint.readResponse("genOnOff", 1,
|
|
5964
|
+
await endpoint.readResponse("genOnOff", 1, {onOff: 1});
|
|
6405
5965
|
} catch (e) {
|
|
6406
5966
|
error = e;
|
|
6407
5967
|
}
|
|
6408
5968
|
expect(error).toStrictEqual(
|
|
6409
5969
|
new Error(
|
|
6410
|
-
`ZCL command 0x129/1 genOnOff.readRsp(
|
|
5970
|
+
`ZCL command 0x129/1 genOnOff.readRsp({"onOff":1}, {"timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":true,"direction":1,"reservedBits":0,"transactionSequenceNumber":1,"writeUndiv":false}) failed (timeout occurred)`,
|
|
6411
5971
|
),
|
|
6412
5972
|
);
|
|
6413
5973
|
});
|
|
@@ -6484,25 +6044,23 @@ describe("Controller", () => {
|
|
|
6484
6044
|
});
|
|
6485
6045
|
|
|
6486
6046
|
it("Write structured", async () => {
|
|
6487
|
-
await controller.start();
|
|
6488
6047
|
await controller.start();
|
|
6489
6048
|
await mockAdapterEvents.deviceJoined({networkAddress: 129, ieeeAddr: "0x129"});
|
|
6490
6049
|
const device = controller.getDeviceByIeeeAddr("0x129")!;
|
|
6491
6050
|
const endpoint = device.getEndpoint(1)!;
|
|
6492
6051
|
mocksendZclFrameToEndpoint.mockReturnValueOnce(null);
|
|
6493
6052
|
|
|
6494
|
-
await endpoint.writeStructured("genPowerCfg",
|
|
6053
|
+
await endpoint.writeStructured("genPowerCfg", []);
|
|
6495
6054
|
});
|
|
6496
6055
|
|
|
6497
6056
|
it("Write structured with disable response", async () => {
|
|
6498
|
-
await controller.start();
|
|
6499
6057
|
await controller.start();
|
|
6500
6058
|
await mockAdapterEvents.deviceJoined({networkAddress: 129, ieeeAddr: "0x129"});
|
|
6501
6059
|
const device = controller.getDeviceByIeeeAddr("0x129")!;
|
|
6502
6060
|
const endpoint = device.getEndpoint(1)!;
|
|
6503
6061
|
mocksendZclFrameToEndpoint.mockReturnValueOnce(null);
|
|
6504
6062
|
|
|
6505
|
-
await endpoint.writeStructured("genPowerCfg",
|
|
6063
|
+
await endpoint.writeStructured("genPowerCfg", [], {disableResponse: true});
|
|
6506
6064
|
});
|
|
6507
6065
|
|
|
6508
6066
|
it("Write structured error", async () => {
|
|
@@ -6513,17 +6071,71 @@ describe("Controller", () => {
|
|
|
6513
6071
|
mocksendZclFrameToEndpoint.mockRejectedValueOnce(new Error("timeout occurred"));
|
|
6514
6072
|
let error;
|
|
6515
6073
|
try {
|
|
6516
|
-
await endpoint.writeStructured("genPowerCfg",
|
|
6074
|
+
await endpoint.writeStructured("genPowerCfg", []);
|
|
6517
6075
|
} catch (e) {
|
|
6518
6076
|
error = e;
|
|
6519
6077
|
}
|
|
6520
6078
|
expect(error).toStrictEqual(
|
|
6521
6079
|
new Error(
|
|
6522
|
-
`ZCL command 0x129/1 genPowerCfg.writeStructured(
|
|
6080
|
+
`ZCL command 0x129/1 genPowerCfg.writeStructured([], {"timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":true,"direction":0,"reservedBits":0,"writeUndiv":false}) failed (timeout occurred)`,
|
|
6523
6081
|
),
|
|
6524
6082
|
);
|
|
6525
6083
|
});
|
|
6526
6084
|
|
|
6085
|
+
it("Write with custom payload", async () => {
|
|
6086
|
+
await controller.start();
|
|
6087
|
+
await mockAdapterEvents.deviceJoined({networkAddress: 129, ieeeAddr: "0x129"});
|
|
6088
|
+
const device = controller.getDeviceByIeeeAddr("0x129")!;
|
|
6089
|
+
const endpoint = device.getEndpoint(1)!;
|
|
6090
|
+
|
|
6091
|
+
const writeOptions = {
|
|
6092
|
+
frameType: 0,
|
|
6093
|
+
manufacturerCode: 0x1ad2,
|
|
6094
|
+
disableDefaultResponse: true,
|
|
6095
|
+
disableResponse: true,
|
|
6096
|
+
reservedBits: 3,
|
|
6097
|
+
direction: 1,
|
|
6098
|
+
writeUndiv: true,
|
|
6099
|
+
transactionSequenceNumber: 0xe9,
|
|
6100
|
+
};
|
|
6101
|
+
|
|
6102
|
+
await endpoint.writeStructured(
|
|
6103
|
+
"genPowerCfg",
|
|
6104
|
+
[
|
|
6105
|
+
{
|
|
6106
|
+
attrId: 0x0000,
|
|
6107
|
+
// @ts-expect-error workaround write custom payload, special case "do not write anything"
|
|
6108
|
+
selector: null,
|
|
6109
|
+
elementData: [0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
|
|
6110
|
+
// dataType: undefined,
|
|
6111
|
+
},
|
|
6112
|
+
],
|
|
6113
|
+
writeOptions,
|
|
6114
|
+
);
|
|
6115
|
+
|
|
6116
|
+
expect(lastSentZclFrameToEndpoint).toStrictEqual(
|
|
6117
|
+
// Note: 0x00 before start of payload is from having dataType=undefined (gets written as zero)
|
|
6118
|
+
Buffer.from([0x7c, 0xd2, 0x1a, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
|
|
6119
|
+
);
|
|
6120
|
+
|
|
6121
|
+
await endpoint.write(
|
|
6122
|
+
"genPowerCfg",
|
|
6123
|
+
{
|
|
6124
|
+
// @ts-expect-error workaround write custom payload
|
|
6125
|
+
4865: {
|
|
6126
|
+
value: [0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
|
|
6127
|
+
// type: undefined,
|
|
6128
|
+
},
|
|
6129
|
+
},
|
|
6130
|
+
writeOptions,
|
|
6131
|
+
);
|
|
6132
|
+
|
|
6133
|
+
expect(lastSentZclFrameToEndpoint).toStrictEqual(
|
|
6134
|
+
// Note: 0x00 before start of payload is from having dataType=undefined (gets written as zero)
|
|
6135
|
+
Buffer.from([0x7c, 0xd2, 0x1a, 0xe9, 0x03, 0x01, 0x13, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
|
|
6136
|
+
);
|
|
6137
|
+
});
|
|
6138
|
+
|
|
6527
6139
|
it("Green power", async () => {
|
|
6528
6140
|
await controller.start();
|
|
6529
6141
|
const data = {
|
|
@@ -6624,7 +6236,6 @@ describe("Controller", () => {
|
|
|
6624
6236
|
_interviewState: InterviewState.Successful,
|
|
6625
6237
|
_lastSeen: Date.now(),
|
|
6626
6238
|
_linkquality: 50,
|
|
6627
|
-
_modelID: "GreenPower_2",
|
|
6628
6239
|
_networkAddress: 0xf4fe,
|
|
6629
6240
|
_type: "GreenPower",
|
|
6630
6241
|
meta: {},
|
|
@@ -6644,13 +6255,16 @@ describe("Controller", () => {
|
|
|
6644
6255
|
_eventsCount: 0,
|
|
6645
6256
|
_ieeeAddr: "0x000000000046f4fe",
|
|
6646
6257
|
_interviewState: InterviewState.Successful,
|
|
6647
|
-
_modelID: "GreenPower_2",
|
|
6648
6258
|
_networkAddress: 0xf4fe,
|
|
6649
6259
|
_type: "GreenPower",
|
|
6650
6260
|
meta: {},
|
|
6651
6261
|
_gpSecurityKey: [0xf1, 0xec, 0x92, 0xab, 0xff, 0x8f, 0x13, 0x63, 0xe1, 0x46, 0xbe, 0xb5, 0x18, 0xc9, 0x0c, 0xab],
|
|
6652
6262
|
},
|
|
6653
6263
|
});
|
|
6264
|
+
expect(deepClone(events.deviceInterviewRaw[0].device.genBasic)).toStrictEqual({
|
|
6265
|
+
modelId: "GreenPower_2",
|
|
6266
|
+
powerSource: 0,
|
|
6267
|
+
});
|
|
6654
6268
|
expect(controller.getDeviceByIeeeAddr("0x000000000046f4fe")!.networkAddress).toBe(0xf4fe);
|
|
6655
6269
|
expect(events.message.length).toBe(2);
|
|
6656
6270
|
|
|
@@ -6681,53 +6295,8 @@ describe("Controller", () => {
|
|
|
6681
6295
|
expect(events.message.length).toBe(1);
|
|
6682
6296
|
const expected = {
|
|
6683
6297
|
type: "commandNotification",
|
|
6684
|
-
device:
|
|
6685
|
-
|
|
6686
|
-
_events: {},
|
|
6687
|
-
_eventsCount: 0,
|
|
6688
|
-
_pendingRequestTimeout: 0,
|
|
6689
|
-
_customClusters: {},
|
|
6690
|
-
_endpoints: [
|
|
6691
|
-
{
|
|
6692
|
-
inputClusters: [],
|
|
6693
|
-
meta: {},
|
|
6694
|
-
outputClusters: [],
|
|
6695
|
-
pendingRequests: {id: ZSpec.GP_ENDPOINT, deviceIeeeAddress: "0x000000000046f4fe", sendInProgress: false},
|
|
6696
|
-
ID: ZSpec.GP_ENDPOINT,
|
|
6697
|
-
_events: {},
|
|
6698
|
-
_eventsCount: 0,
|
|
6699
|
-
clusters: {},
|
|
6700
|
-
deviceIeeeAddress: "0x000000000046f4fe",
|
|
6701
|
-
deviceNetworkAddress: 0xf4fe,
|
|
6702
|
-
_binds: [],
|
|
6703
|
-
_configuredReportings: [],
|
|
6704
|
-
},
|
|
6705
|
-
],
|
|
6706
|
-
_ieeeAddr: "0x000000000046f4fe",
|
|
6707
|
-
_interviewState: InterviewState.Successful,
|
|
6708
|
-
_lastSeen: Date.now(),
|
|
6709
|
-
_linkquality: 50,
|
|
6710
|
-
_skipDefaultResponse: false,
|
|
6711
|
-
_modelID: "GreenPower_2",
|
|
6712
|
-
_networkAddress: 0xf4fe,
|
|
6713
|
-
_type: "GreenPower",
|
|
6714
|
-
meta: {},
|
|
6715
|
-
_gpSecurityKey: [0xf1, 0xec, 0x92, 0xab, 0xff, 0x8f, 0x13, 0x63, 0xe1, 0x46, 0xbe, 0xb5, 0x18, 0xc9, 0x0c, 0xab],
|
|
6716
|
-
},
|
|
6717
|
-
endpoint: {
|
|
6718
|
-
inputClusters: [],
|
|
6719
|
-
meta: {},
|
|
6720
|
-
outputClusters: [],
|
|
6721
|
-
pendingRequests: {id: ZSpec.GP_ENDPOINT, deviceIeeeAddress: "0x000000000046f4fe", sendInProgress: false},
|
|
6722
|
-
ID: ZSpec.GP_ENDPOINT,
|
|
6723
|
-
_events: {},
|
|
6724
|
-
_eventsCount: 0,
|
|
6725
|
-
clusters: {},
|
|
6726
|
-
deviceIeeeAddress: "0x000000000046f4fe",
|
|
6727
|
-
deviceNetworkAddress: 0xf4fe,
|
|
6728
|
-
_binds: [],
|
|
6729
|
-
_configuredReportings: [],
|
|
6730
|
-
},
|
|
6298
|
+
device: expect.any(Device),
|
|
6299
|
+
endpoint: expect.any(Endpoint),
|
|
6731
6300
|
data: {options: 0, srcID: 0x46f4fe, frameCounter: 228, commandID: 34, payloadSize: 255, commandFrame: {}},
|
|
6732
6301
|
linkquality: 50,
|
|
6733
6302
|
groupID: 1,
|
|
@@ -6735,9 +6304,11 @@ describe("Controller", () => {
|
|
|
6735
6304
|
meta: {
|
|
6736
6305
|
zclTransactionSequenceNumber: 10,
|
|
6737
6306
|
frameControl: {reservedBits: 0, frameType: 1, direction: 0, disableDefaultResponse: true, manufacturerSpecific: false},
|
|
6307
|
+
manufacturerCode: undefined,
|
|
6308
|
+
rawData: expect.any(Buffer),
|
|
6738
6309
|
},
|
|
6739
6310
|
};
|
|
6740
|
-
expect(
|
|
6311
|
+
expect(events.message[0]).toStrictEqual(expected);
|
|
6741
6312
|
|
|
6742
6313
|
const identifyUnknownDeviceSpy = vi.spyOn(controller, "identifyUnknownDevice");
|
|
6743
6314
|
|
|
@@ -7262,13 +6833,13 @@ describe("Controller", () => {
|
|
|
7262
6833
|
_interviewState: InterviewState.Successful,
|
|
7263
6834
|
_lastSeen: Date.now(),
|
|
7264
6835
|
_linkquality: 50,
|
|
7265
|
-
_modelID: "GreenPower_2",
|
|
7266
6836
|
_networkAddress: 0x71f8,
|
|
7267
6837
|
_type: "GreenPower",
|
|
7268
6838
|
meta: {},
|
|
7269
6839
|
_gpSecurityKey: [0x21, 0x7f, 0x8c, 0xb2, 0x90, 0xd9, 0x90, 0x14, 0x15, 0xd0, 0x5c, 0xb1, 0x64, 0x7c, 0x44, 0x6c],
|
|
7270
6840
|
},
|
|
7271
6841
|
});
|
|
6842
|
+
expect(controller.getDeviceByIeeeAddr("0x00000000017171f8")?.genBasic.modelId).toStrictEqual("GreenPower_2");
|
|
7272
6843
|
expect(events.deviceInterview.length).toBe(3); // gpp[started] + gpp[successful] + gpd
|
|
7273
6844
|
expect(deepClone(events.deviceInterview[2])).toStrictEqual({
|
|
7274
6845
|
status: "successful",
|
|
@@ -7282,13 +6853,16 @@ describe("Controller", () => {
|
|
|
7282
6853
|
_endpoints: [],
|
|
7283
6854
|
_ieeeAddr: "0x00000000017171f8",
|
|
7284
6855
|
_interviewState: InterviewState.Successful,
|
|
7285
|
-
_modelID: "GreenPower_2",
|
|
7286
6856
|
_networkAddress: 0x71f8,
|
|
7287
6857
|
_type: "GreenPower",
|
|
7288
6858
|
meta: {},
|
|
7289
6859
|
_gpSecurityKey: [0x21, 0x7f, 0x8c, 0xb2, 0x90, 0xd9, 0x90, 0x14, 0x15, 0xd0, 0x5c, 0xb1, 0x64, 0x7c, 0x44, 0x6c],
|
|
7290
6860
|
},
|
|
7291
6861
|
});
|
|
6862
|
+
expect(deepClone(events.deviceInterviewRaw[2].device.genBasic)).toStrictEqual({
|
|
6863
|
+
modelId: "GreenPower_2",
|
|
6864
|
+
powerSource: Zcl.PowerSource.Unknown,
|
|
6865
|
+
});
|
|
7292
6866
|
expect(controller.getDeviceByIeeeAddr("0x00000000017171f8")!.networkAddress).toBe(0x71f8);
|
|
7293
6867
|
expect(events.message.length).toBe(2);
|
|
7294
6868
|
|
|
@@ -7320,53 +6894,8 @@ describe("Controller", () => {
|
|
|
7320
6894
|
expect(events.message.length).toBe(1);
|
|
7321
6895
|
const expected = {
|
|
7322
6896
|
type: "commandNotification",
|
|
7323
|
-
device:
|
|
7324
|
-
|
|
7325
|
-
_eventsCount: 0,
|
|
7326
|
-
ID: 3,
|
|
7327
|
-
_type: "GreenPower",
|
|
7328
|
-
_ieeeAddr: "0x00000000017171f8",
|
|
7329
|
-
_networkAddress: 29176,
|
|
7330
|
-
_customClusters: {},
|
|
7331
|
-
_endpoints: [
|
|
7332
|
-
{
|
|
7333
|
-
_events: {},
|
|
7334
|
-
_eventsCount: 0,
|
|
7335
|
-
ID: ZSpec.GP_ENDPOINT,
|
|
7336
|
-
inputClusters: [],
|
|
7337
|
-
outputClusters: [],
|
|
7338
|
-
deviceNetworkAddress: 29176,
|
|
7339
|
-
deviceIeeeAddress: "0x00000000017171f8",
|
|
7340
|
-
clusters: {},
|
|
7341
|
-
_binds: [],
|
|
7342
|
-
_configuredReportings: [],
|
|
7343
|
-
meta: {},
|
|
7344
|
-
pendingRequests: {sendInProgress: false, id: ZSpec.GP_ENDPOINT, deviceIeeeAddress: "0x00000000017171f8"},
|
|
7345
|
-
},
|
|
7346
|
-
],
|
|
7347
|
-
_modelID: "GreenPower_2",
|
|
7348
|
-
_interviewState: InterviewState.Successful,
|
|
7349
|
-
_skipDefaultResponse: false,
|
|
7350
|
-
meta: {},
|
|
7351
|
-
_gpSecurityKey: [0x21, 0x7f, 0x8c, 0xb2, 0x90, 0xd9, 0x90, 0x14, 0x15, 0xd0, 0x5c, 0xb1, 0x64, 0x7c, 0x44, 0x6c],
|
|
7352
|
-
_lastSeen: Date.now(),
|
|
7353
|
-
_pendingRequestTimeout: 0,
|
|
7354
|
-
_linkquality: 50,
|
|
7355
|
-
},
|
|
7356
|
-
endpoint: {
|
|
7357
|
-
_events: {},
|
|
7358
|
-
_eventsCount: 0,
|
|
7359
|
-
ID: ZSpec.GP_ENDPOINT,
|
|
7360
|
-
inputClusters: [],
|
|
7361
|
-
outputClusters: [],
|
|
7362
|
-
deviceNetworkAddress: 29176,
|
|
7363
|
-
deviceIeeeAddress: "0x00000000017171f8",
|
|
7364
|
-
clusters: {},
|
|
7365
|
-
_binds: [],
|
|
7366
|
-
_configuredReportings: [],
|
|
7367
|
-
meta: {},
|
|
7368
|
-
pendingRequests: {sendInProgress: false, id: ZSpec.GP_ENDPOINT, deviceIeeeAddress: "0x00000000017171f8"},
|
|
7369
|
-
},
|
|
6897
|
+
device: expect.any(Device),
|
|
6898
|
+
endpoint: expect.any(Endpoint),
|
|
7370
6899
|
data: {
|
|
7371
6900
|
options: 21640,
|
|
7372
6901
|
srcID: 24211960,
|
|
@@ -7383,9 +6912,11 @@ describe("Controller", () => {
|
|
|
7383
6912
|
meta: {
|
|
7384
6913
|
zclTransactionSequenceNumber: 10,
|
|
7385
6914
|
frameControl: {reservedBits: 0, frameType: 1, direction: 0, disableDefaultResponse: true, manufacturerSpecific: false},
|
|
6915
|
+
manufacturerCode: undefined,
|
|
6916
|
+
rawData: expect.any(Buffer),
|
|
7386
6917
|
},
|
|
7387
6918
|
};
|
|
7388
|
-
expect(
|
|
6919
|
+
expect(events.message[0]).toStrictEqual(expected);
|
|
7389
6920
|
|
|
7390
6921
|
// Remove green power device from network
|
|
7391
6922
|
const removeCommand = {
|
|
@@ -7431,12 +6962,12 @@ describe("Controller", () => {
|
|
|
7431
6962
|
_interviewState: InterviewState.Successful,
|
|
7432
6963
|
_lastSeen: Date.now(),
|
|
7433
6964
|
_linkquality: 50,
|
|
7434
|
-
_modelID: "GreenPower_2",
|
|
7435
6965
|
_networkAddress: 0x71f8,
|
|
7436
6966
|
_type: "GreenPower",
|
|
7437
6967
|
meta: {},
|
|
7438
6968
|
_gpSecurityKey: [0x21, 0x7f, 0x8c, 0xb2, 0x90, 0xd9, 0x90, 0x14, 0x15, 0xd0, 0x5c, 0xb1, 0x64, 0x7c, 0x44, 0x6c],
|
|
7439
6969
|
});
|
|
6970
|
+
expect(Device.byIeeeAddr("0x00000000017171f8", true)?.genBasic.modelId).toStrictEqual("GreenPower_2");
|
|
7440
6971
|
|
|
7441
6972
|
// Re-add device
|
|
7442
6973
|
vi.spyOn(Zcl.Frame, "fromBuffer").mockReturnValueOnce(expectedFrame); // Mock because no Buffalo write for 0xe0 is implemented
|
|
@@ -7478,12 +7009,12 @@ describe("Controller", () => {
|
|
|
7478
7009
|
_interviewState: InterviewState.Successful,
|
|
7479
7010
|
_lastSeen: Date.now(),
|
|
7480
7011
|
_linkquality: 50,
|
|
7481
|
-
_modelID: "GreenPower_2",
|
|
7482
7012
|
_networkAddress: 0x71f8,
|
|
7483
7013
|
_type: "GreenPower",
|
|
7484
7014
|
meta: {},
|
|
7485
7015
|
_gpSecurityKey: [0x21, 0x7f, 0x8c, 0xb2, 0x90, 0xd9, 0x90, 0x14, 0x15, 0xd0, 0x5c, 0xb1, 0x64, 0x7c, 0x44, 0x6c],
|
|
7486
7016
|
});
|
|
7017
|
+
expect(Device.byIeeeAddr("0x00000000017171f8")?.genBasic.modelId).toStrictEqual("GreenPower_2");
|
|
7487
7018
|
});
|
|
7488
7019
|
|
|
7489
7020
|
it("Get input/ouptut clusters", async () => {
|
|
@@ -8068,7 +7599,7 @@ describe("Controller", () => {
|
|
|
8068
7599
|
expect(checkinrsp[2]).toBe(1);
|
|
8069
7600
|
expect(checkinrsp[3].cluster.name).toBe("genPollCtrl");
|
|
8070
7601
|
expect(checkinrsp[3].command.name).toBe("checkinRsp");
|
|
8071
|
-
expect(checkinrsp[3].payload).toStrictEqual({startFastPolling:
|
|
7602
|
+
expect(checkinrsp[3].payload).toStrictEqual({startFastPolling: 1, fastPollTimeout: 0});
|
|
8072
7603
|
|
|
8073
7604
|
expect(await result).toBe(undefined);
|
|
8074
7605
|
|
|
@@ -8109,135 +7640,8 @@ describe("Controller", () => {
|
|
|
8109
7640
|
|
|
8110
7641
|
const expected = {
|
|
8111
7642
|
type: "read",
|
|
8112
|
-
device: {
|
|
8113
|
-
|
|
8114
|
-
_applicationVersion: 2,
|
|
8115
|
-
_dateCode: "201901",
|
|
8116
|
-
_pendingRequestTimeout: 0,
|
|
8117
|
-
_customClusters: {},
|
|
8118
|
-
_endpoints: [
|
|
8119
|
-
{
|
|
8120
|
-
deviceID: 5,
|
|
8121
|
-
inputClusters: [0, 1, 2],
|
|
8122
|
-
outputClusters: [2],
|
|
8123
|
-
profileID: 99,
|
|
8124
|
-
ID: 1,
|
|
8125
|
-
clusters: {},
|
|
8126
|
-
deviceIeeeAddress: "0x171",
|
|
8127
|
-
deviceNetworkAddress: 171,
|
|
8128
|
-
_binds: [],
|
|
8129
|
-
_configuredReportings: [],
|
|
8130
|
-
_events: {},
|
|
8131
|
-
_eventsCount: 0,
|
|
8132
|
-
meta: {},
|
|
8133
|
-
pendingRequests: {id: 1, deviceIeeeAddress: "0x171", sendInProgress: false},
|
|
8134
|
-
},
|
|
8135
|
-
{
|
|
8136
|
-
inputClusters: [],
|
|
8137
|
-
outputClusters: [],
|
|
8138
|
-
ID: 2,
|
|
8139
|
-
clusters: {},
|
|
8140
|
-
deviceIeeeAddress: "0x171",
|
|
8141
|
-
deviceNetworkAddress: 171,
|
|
8142
|
-
_binds: [],
|
|
8143
|
-
_configuredReportings: [],
|
|
8144
|
-
_events: {},
|
|
8145
|
-
_eventsCount: 0,
|
|
8146
|
-
meta: {},
|
|
8147
|
-
pendingRequests: {id: 2, deviceIeeeAddress: "0x171", sendInProgress: false},
|
|
8148
|
-
},
|
|
8149
|
-
{
|
|
8150
|
-
inputClusters: [],
|
|
8151
|
-
outputClusters: [],
|
|
8152
|
-
ID: 3,
|
|
8153
|
-
clusters: {},
|
|
8154
|
-
deviceIeeeAddress: "0x171",
|
|
8155
|
-
deviceNetworkAddress: 171,
|
|
8156
|
-
_binds: [],
|
|
8157
|
-
_configuredReportings: [],
|
|
8158
|
-
_events: {},
|
|
8159
|
-
_eventsCount: 0,
|
|
8160
|
-
meta: {},
|
|
8161
|
-
pendingRequests: {id: 3, deviceIeeeAddress: "0x171", sendInProgress: false},
|
|
8162
|
-
},
|
|
8163
|
-
{
|
|
8164
|
-
inputClusters: [],
|
|
8165
|
-
outputClusters: [],
|
|
8166
|
-
ID: 4,
|
|
8167
|
-
clusters: {},
|
|
8168
|
-
deviceIeeeAddress: "0x171",
|
|
8169
|
-
deviceNetworkAddress: 171,
|
|
8170
|
-
_binds: [],
|
|
8171
|
-
_configuredReportings: [],
|
|
8172
|
-
_events: {},
|
|
8173
|
-
_eventsCount: 0,
|
|
8174
|
-
meta: {},
|
|
8175
|
-
pendingRequests: {id: 4, deviceIeeeAddress: "0x171", sendInProgress: false},
|
|
8176
|
-
},
|
|
8177
|
-
{
|
|
8178
|
-
inputClusters: [],
|
|
8179
|
-
outputClusters: [],
|
|
8180
|
-
ID: 5,
|
|
8181
|
-
clusters: {},
|
|
8182
|
-
deviceIeeeAddress: "0x171",
|
|
8183
|
-
deviceNetworkAddress: 171,
|
|
8184
|
-
_binds: [],
|
|
8185
|
-
_configuredReportings: [],
|
|
8186
|
-
_events: {},
|
|
8187
|
-
_eventsCount: 0,
|
|
8188
|
-
meta: {},
|
|
8189
|
-
pendingRequests: {id: 5, deviceIeeeAddress: "0x171", sendInProgress: false},
|
|
8190
|
-
},
|
|
8191
|
-
{
|
|
8192
|
-
inputClusters: [],
|
|
8193
|
-
outputClusters: [],
|
|
8194
|
-
ID: 6,
|
|
8195
|
-
clusters: {},
|
|
8196
|
-
deviceIeeeAddress: "0x171",
|
|
8197
|
-
deviceNetworkAddress: 171,
|
|
8198
|
-
_binds: [],
|
|
8199
|
-
_configuredReportings: [],
|
|
8200
|
-
_events: {},
|
|
8201
|
-
_eventsCount: 0,
|
|
8202
|
-
meta: {},
|
|
8203
|
-
pendingRequests: {id: 6, deviceIeeeAddress: "0x171", sendInProgress: false},
|
|
8204
|
-
},
|
|
8205
|
-
],
|
|
8206
|
-
_events: {},
|
|
8207
|
-
_eventsCount: 0,
|
|
8208
|
-
_hardwareVersion: 3,
|
|
8209
|
-
_ieeeAddr: "0x171",
|
|
8210
|
-
_interviewState: InterviewState.Successful,
|
|
8211
|
-
_lastSeen: Date.now(),
|
|
8212
|
-
_manufacturerID: 1212,
|
|
8213
|
-
_manufacturerName: "Xioami",
|
|
8214
|
-
_modelID: "lumi.remote.b286opcn01",
|
|
8215
|
-
_networkAddress: 171,
|
|
8216
|
-
_powerSource: "Mains (single phase)",
|
|
8217
|
-
_softwareBuildID: "1.01",
|
|
8218
|
-
_stackVersion: 101,
|
|
8219
|
-
_type: "EndDevice",
|
|
8220
|
-
_zclVersion: 1,
|
|
8221
|
-
_linkquality: 19,
|
|
8222
|
-
_skipDefaultResponse: false,
|
|
8223
|
-
meta: {},
|
|
8224
|
-
},
|
|
8225
|
-
endpoint: {
|
|
8226
|
-
deviceID: 5,
|
|
8227
|
-
inputClusters: [0, 1, 2],
|
|
8228
|
-
outputClusters: [2],
|
|
8229
|
-
profileID: 99,
|
|
8230
|
-
ID: 1,
|
|
8231
|
-
clusters: {},
|
|
8232
|
-
deviceIeeeAddress: "0x171",
|
|
8233
|
-
deviceNetworkAddress: 171,
|
|
8234
|
-
_binds: [],
|
|
8235
|
-
_configuredReportings: [],
|
|
8236
|
-
_events: {},
|
|
8237
|
-
_eventsCount: 0,
|
|
8238
|
-
meta: {},
|
|
8239
|
-
pendingRequests: {id: 1, deviceIeeeAddress: "0x171", sendInProgress: false},
|
|
8240
|
-
},
|
|
7643
|
+
device: expect.objectContaining({_ieeeAddr: "0x171"}),
|
|
7644
|
+
endpoint: expect.objectContaining({deviceIeeeAddress: "0x171"}),
|
|
8241
7645
|
data: ["mainsVoltage", 9999],
|
|
8242
7646
|
linkquality: 19,
|
|
8243
7647
|
groupID: 171,
|
|
@@ -8245,10 +7649,12 @@ describe("Controller", () => {
|
|
|
8245
7649
|
meta: {
|
|
8246
7650
|
zclTransactionSequenceNumber: 40,
|
|
8247
7651
|
frameControl: {reservedBits: 0, frameType: 0, direction: 0, disableDefaultResponse: true, manufacturerSpecific: false},
|
|
7652
|
+
manufacturerCode: undefined,
|
|
7653
|
+
rawData: expect.any(Buffer),
|
|
8248
7654
|
},
|
|
8249
7655
|
};
|
|
8250
7656
|
expect(events.message.length).toBe(1);
|
|
8251
|
-
expect(
|
|
7657
|
+
expect(events.message[0]).toStrictEqual(expected);
|
|
8252
7658
|
});
|
|
8253
7659
|
|
|
8254
7660
|
it("Shouldnt throw error on coordinatorCheck when adapter doesnt support backups", async () => {
|
|
@@ -8961,6 +8367,12 @@ describe("Controller", () => {
|
|
|
8961
8367
|
});
|
|
8962
8368
|
|
|
8963
8369
|
it("reads/writes to group with custom cluster when common to all members", async () => {
|
|
8370
|
+
interface CustomManuHerdsman {
|
|
8371
|
+
attributes: {customAttr: number};
|
|
8372
|
+
commands: never;
|
|
8373
|
+
commandResponses: never;
|
|
8374
|
+
}
|
|
8375
|
+
|
|
8964
8376
|
await controller.start();
|
|
8965
8377
|
await mockAdapterEvents.deviceJoined({networkAddress: 177, ieeeAddr: "0x177"});
|
|
8966
8378
|
|
|
@@ -8977,8 +8389,8 @@ describe("Controller", () => {
|
|
|
8977
8389
|
|
|
8978
8390
|
group.addMember(device.getEndpoint(1)!);
|
|
8979
8391
|
|
|
8980
|
-
await group.write("manuHerdsman", {customAttr: 15}, {});
|
|
8981
|
-
await group.read("manuHerdsman", ["customAttr"], {});
|
|
8392
|
+
await group.write<"manuHerdsman", CustomManuHerdsman>("manuHerdsman", {customAttr: 15}, {});
|
|
8393
|
+
await group.read<"manuHerdsman", CustomManuHerdsman>("manuHerdsman", ["customAttr"], {});
|
|
8982
8394
|
|
|
8983
8395
|
expect(mocksendZclFrameToGroup).toHaveBeenCalledTimes(2);
|
|
8984
8396
|
expect(mocksendZclFrameToGroup.mock.calls[0][0]).toBe(34);
|
|
@@ -9037,22 +8449,22 @@ describe("Controller", () => {
|
|
|
9037
8449
|
await group.read("manuHerdsman", ["customAttr"], {});
|
|
9038
8450
|
}).rejects.toThrow(new Error(`Cluster with name 'manuHerdsman' does not exist`));
|
|
9039
8451
|
|
|
9040
|
-
await group.write("manuHerdsman", {customAttr: 14}, {direction: Zcl.Direction.SERVER_TO_CLIENT});
|
|
9041
|
-
await group.read("manuHerdsman", ["customAttr"], {direction: Zcl.Direction.SERVER_TO_CLIENT});
|
|
8452
|
+
await group.write<"manuHerdsman", CustomManuHerdsman>("manuHerdsman", {customAttr: 14}, {direction: Zcl.Direction.SERVER_TO_CLIENT});
|
|
8453
|
+
await group.read<"manuHerdsman", CustomManuHerdsman>("manuHerdsman", ["customAttr"], {direction: Zcl.Direction.SERVER_TO_CLIENT});
|
|
9042
8454
|
|
|
9043
8455
|
expect(mocksendZclFrameToGroup).toHaveBeenCalledTimes(4);
|
|
9044
8456
|
|
|
9045
8457
|
group.removeMember(device2.getEndpoint(2)!);
|
|
9046
8458
|
|
|
9047
|
-
await group.write("manuHerdsman", {customAttr: 16}, {});
|
|
9048
|
-
await group.read("manuHerdsman", ["customAttr"], {});
|
|
8459
|
+
await group.write<"manuHerdsman", CustomManuHerdsman>("manuHerdsman", {customAttr: 16}, {});
|
|
8460
|
+
await group.read<"manuHerdsman", CustomManuHerdsman>("manuHerdsman", ["customAttr"], {});
|
|
9049
8461
|
|
|
9050
8462
|
expect(mocksendZclFrameToGroup).toHaveBeenCalledTimes(6);
|
|
9051
8463
|
|
|
9052
8464
|
group.addMember(device2.getEndpoint(1)!);
|
|
9053
8465
|
|
|
9054
|
-
await group.write("manuHerdsman", {customAttr: 8}, {});
|
|
9055
|
-
await group.read("manuHerdsman", ["customAttr"], {});
|
|
8466
|
+
await group.write<"manuHerdsman", CustomManuHerdsman>("manuHerdsman", {customAttr: 8}, {});
|
|
8467
|
+
await group.read<"manuHerdsman", CustomManuHerdsman>("manuHerdsman", ["customAttr"], {});
|
|
9056
8468
|
|
|
9057
8469
|
expect(mocksendZclFrameToGroup).toHaveBeenCalledTimes(8);
|
|
9058
8470
|
|
|
@@ -9212,7 +8624,7 @@ describe("Controller", () => {
|
|
|
9212
8624
|
type: "commandIndividualLedEffect",
|
|
9213
8625
|
data: {
|
|
9214
8626
|
color: 0,
|
|
9215
|
-
duration:
|
|
8627
|
+
duration: null,
|
|
9216
8628
|
effect: 1,
|
|
9217
8629
|
led: 5,
|
|
9218
8630
|
level: 100,
|
|
@@ -9239,4 +8651,52 @@ describe("Controller", () => {
|
|
|
9239
8651
|
});
|
|
9240
8652
|
}).rejects.toThrow(new Error(`Cluster with name 'manuSpecificInovelli' does not exist`));
|
|
9241
8653
|
});
|
|
8654
|
+
|
|
8655
|
+
it("Updates a device genBasic properties", async () => {
|
|
8656
|
+
await controller.start();
|
|
8657
|
+
expect(databaseContents().includes("0x129")).toBeFalsy();
|
|
8658
|
+
await mockAdapterEvents.deviceJoined({networkAddress: 129, ieeeAddr: "0x129"});
|
|
8659
|
+
|
|
8660
|
+
const device = controller.getDeviceByIeeeAddr("0x129")!;
|
|
8661
|
+
|
|
8662
|
+
expect(device.applicationVersion).toStrictEqual(2);
|
|
8663
|
+
expect(device.dateCode).toStrictEqual("201901");
|
|
8664
|
+
expect(device.hardwareVersion).toStrictEqual(3);
|
|
8665
|
+
expect(device.manufacturerName).toStrictEqual("KoenAndCo");
|
|
8666
|
+
expect(device.modelID).toStrictEqual("myModelID");
|
|
8667
|
+
expect(device.powerSource).toStrictEqual("Mains (single phase)");
|
|
8668
|
+
expect(device.softwareBuildID).toStrictEqual("1.01");
|
|
8669
|
+
expect(device.stackVersion).toStrictEqual(101);
|
|
8670
|
+
expect(device.zclVersion).toStrictEqual(1);
|
|
8671
|
+
|
|
8672
|
+
device.applicationVersion = 3;
|
|
8673
|
+
device.dateCode = "202501";
|
|
8674
|
+
device.hardwareVersion = 4;
|
|
8675
|
+
device.manufacturerName = "Test";
|
|
8676
|
+
device.modelID = "Me";
|
|
8677
|
+
device.powerSource = "DC Source";
|
|
8678
|
+
device.softwareBuildID = "2.01";
|
|
8679
|
+
device.stackVersion = 202;
|
|
8680
|
+
device.zclVersion = 2;
|
|
8681
|
+
|
|
8682
|
+
expect(device.applicationVersion).toStrictEqual(3);
|
|
8683
|
+
expect(device.dateCode).toStrictEqual("202501");
|
|
8684
|
+
expect(device.hardwareVersion).toStrictEqual(4);
|
|
8685
|
+
expect(device.manufacturerName).toStrictEqual("Test");
|
|
8686
|
+
expect(device.modelID).toStrictEqual("Me");
|
|
8687
|
+
expect(device.powerSource).toStrictEqual("DC Source");
|
|
8688
|
+
expect(device.softwareBuildID).toStrictEqual("2.01");
|
|
8689
|
+
expect(device.stackVersion).toStrictEqual(202);
|
|
8690
|
+
expect(device.zclVersion).toStrictEqual(2);
|
|
8691
|
+
|
|
8692
|
+
expect(device.genBasic.appVersion).toStrictEqual(3);
|
|
8693
|
+
expect(device.genBasic.dateCode).toStrictEqual("202501");
|
|
8694
|
+
expect(device.genBasic.hwVersion).toStrictEqual(4);
|
|
8695
|
+
expect(device.genBasic.manufacturerName).toStrictEqual("Test");
|
|
8696
|
+
expect(device.genBasic.modelId).toStrictEqual("Me");
|
|
8697
|
+
expect(device.genBasic.powerSource).toStrictEqual(Zcl.PowerSource["DC Source"]);
|
|
8698
|
+
expect(device.genBasic.swBuildId).toStrictEqual("2.01");
|
|
8699
|
+
expect(device.genBasic.stackVersion).toStrictEqual(202);
|
|
8700
|
+
expect(device.genBasic.zclVersion).toStrictEqual(2);
|
|
8701
|
+
});
|
|
9242
8702
|
});
|