Skip to content

Commit

Permalink
test: ensure that an unsolicited NIF causes re-interview to start
Browse files Browse the repository at this point in the history
  • Loading branch information
AlCalzone committed Oct 23, 2023
1 parent e2caca0 commit 6a8683d
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 0 deletions.
26 changes: 26 additions & 0 deletions packages/zwave-js/src/lib/controller/MockControllerBehaviors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,31 @@ const forwardCommandClassesToHost: MockControllerBehavior = {
},
};

const forwardUnsolicitedNIF: MockControllerBehavior = {
async onNodeFrame(host, controller, node, frame) {
if (
frame.type === MockZWaveFrameType.Request
&& frame.payload instanceof ZWaveProtocolCCNodeInformationFrame
) {
const updateRequest = new ApplicationUpdateRequestNodeInfoReceived(
host,
{
nodeInformation: {
...frame.payload,
nodeId: frame.payload.nodeId as number,
},
},
);
// Simulate a serialized frame being transmitted via radio
const data = updateRequest.serialize();
await wait(node.capabilities.txDelay);
// Then receive it
await controller.sendToHost(data);
return true;
}
},
};

/** Predefined default behaviors that are required for interacting with the driver correctly */
export function createDefaultBehaviors(): MockControllerBehavior[] {
return [
Expand All @@ -660,5 +685,6 @@ export function createDefaultBehaviors(): MockControllerBehavior[] {
handleRequestNodeInfo,
handleAssignSUCReturnRoute,
forwardCommandClassesToHost,
forwardUnsolicitedNIF,
];
}
4 changes: 4 additions & 0 deletions packages/zwave-js/src/lib/node/Node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1652,6 +1652,10 @@ export class ZWaveNode extends Endpoint
&& this.canSleep
&& this.supportsCC(CommandClasses["Wake Up"])
) {
this.driver.controllerLog.logNode(
this.nodeId,
"Re-interview scheduled, waiting for node to wake up...",
);
didWakeUp = await this.waitForWakeup()
.then(() => true)
.catch(() => false);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{"k":"cacheFormat","v":1}
{"k":"node.1.isListening","v":true}
{"k":"node.1.isFrequentListening","v":false}
{"k":"node.1.isRouting","v":true}
{"k":"node.1.supportedDataRates","v":[40000,9600,100000]}
{"k":"node.1.protocolVersion","v":3}
{"k":"node.1.nodeType","v":"Controller"}
{"k":"node.1.supportsSecurity","v":false}
{"k":"node.1.supportsBeaming","v":true}
{"k":"node.1.deviceClass","v":{"basic":2,"generic":2,"specific":7}}
{"k":"node.1.endpoint.0.commandClass.0x72","v":{"isSupported":true,"isControlled":false,"secure":false,"version":0}}
{"k":"node.1.endpoint.0.commandClass.0x86","v":{"isSupported":true,"isControlled":false,"secure":false,"version":0}}
{"k":"node.1.endpoint.0.commandClass.0x20","v":{"isSupported":false,"isControlled":true,"secure":false,"version":0}}
{"k":"node.1.endpoint.0.commandClass.0x60","v":{"isSupported":false,"isControlled":true,"secure":false,"version":0}}
{"k":"node.1.interviewStage","v":"Complete"}


{"k":"node.2.isListening","v":false}
{"k":"node.2.isFrequentListening","v":false}
{"k":"node.2.isRouting","v":true}
{"k":"node.2.supportedDataRates","v":[40000,9600,100000]}
{"k":"node.2.protocolVersion","v":3}
{"k":"node.2.nodeType","v":"End Node"}
{"k":"node.2.supportsSecurity","v":false}
{"k":"node.2.supportsBeaming","v":true}
{"k":"node.2.deviceClass","v":{"basic":4,"generic":6,"specific":1}}
// Version CC
{"k":"node.2.endpoint.0.commandClass.0x86","v":{"isSupported":true,"isControlled":false,"secure":false,"version":1}}
// Wake Up CC
{"k":"node.2.endpoint.0.commandClass.0x84","v":{"isSupported":true,"isControlled":false,"secure":false,"version":3}}

{"k":"node.2.securityClasses.S2_AccessControl","v":false}
{"k":"node.2.securityClasses.S2_Authenticated","v":false}
{"k":"node.2.securityClasses.S2_Unauthenticated","v":false}
{"k":"node.2.securityClasses.S0_Legacy","v":false}
{"k":"node.2.interviewStage","v":"Complete"}
{"k":"node.2.hasSUCReturnRoute","v":true}
54 changes: 54 additions & 0 deletions packages/zwave-js/src/lib/test/compat/reInterviewWakeUpNIF.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { ZWaveProtocolCCNodeInformationFrame } from "@zwave-js/cc";
import { CommandClasses } from "@zwave-js/core";
import { createMockZWaveRequestFrame } from "@zwave-js/testing";
import { wait } from "alcalzone-shared/async";
import path from "node:path";
import { integrationTest } from "../integrationTestSuite";

integrationTest(
"Re-interviews that wait for a wake-up start when receiving a NIF",
{
// debug: true,

provisioningDirectory: path.join(
__dirname,
"fixtures/reInterviewWakeUpNIF",
),

nodeCapabilities: {
isFrequentListening: false,
isListening: false,

commandClasses: [
CommandClasses["Wake Up"],
CommandClasses.Version,
],
},

async testBody(t, driver, node, mockController, mockNode) {
const promise = node.refreshInfo();

await wait(500);

// Send a NIF to trigger the re-interview
const cc = new ZWaveProtocolCCNodeInformationFrame(mockNode.host, {
nodeId: mockNode.id,
...mockNode.capabilities,
supportedCCs: [...mockNode.implementedCCs]
.filter(([, info]) => info.isSupported)
.map(([ccId]) => ccId),
});
await mockNode.sendToController(
createMockZWaveRequestFrame(cc, {
ackRequested: false,
}),
);

// The interview should now happen
await promise;

await wait(500);
t.pass();
},
},
);

0 comments on commit 6a8683d

Please sign in to comment.