inventoresed
Version:
Z-Wave driver written entirely in JavaScript/TypeScript
166 lines (136 loc) • 4.87 kB
text/typescript
import { BasicCCValues } from "@zwave-js/cc/BasicCC";
import { MessageHeaders, MockSerialPort } from "@zwave-js/serial";
import { createThrowingMap, ThrowingMap } from "@zwave-js/shared";
import { wait } from "alcalzone-shared/async";
import type { Driver } from "../../driver/Driver";
import { ZWaveNode } from "../../node/Node";
import { createAndStartDriver } from "../utils";
import { isFunctionSupported_NoBridge } from "./fixtures";
describe("regression tests", () => {
let driver: Driver;
let serialport: MockSerialPort;
process.env.LOGLEVEL = "debug";
beforeEach(async () => {
({ driver, serialport } = await createAndStartDriver());
driver["_controller"] = {
ownNodeId: 1,
isFunctionSupported: isFunctionSupported_NoBridge,
nodes: createThrowingMap(),
incrementStatistics: () => {},
removeAllListeners: () => {},
} as any;
});
afterEach(async () => {
await driver.destroy();
driver.removeAllListeners();
});
it("unsolicited commands which need special handling are passed to Node.handleCommand", async () => {
// Repro from #4467
const node2 = new ZWaveNode(2, driver);
(driver.controller.nodes as ThrowingMap<number, ZWaveNode>).set(
2,
node2,
);
// Add event handlers for the nodes
for (const node of driver.controller.nodes.values()) {
driver["addNodeEventHandlers"](node);
}
node2["isListening"] = true;
node2["isFrequentListening"] = false;
node2.markAsAlive();
const valueId = BasicCCValues.currentValue.id;
expect(node2.getValue(valueId)).toBeUndefined();
const ACK = Buffer.from([MessageHeaders.ACK]);
serialport.receiveData(Buffer.from("01090004000203200105d7", "hex"));
// « [Node 002] [REQ] [ApplicationCommand]
// └─[BasicCCSet]
// target value: 5
expect(serialport.lastWrite).toEqual(ACK);
await wait(10);
expect(node2.getValue(valueId)).toEqual(5);
}, 5000);
it("unsolicited commands are passed to Node.handleCommand while waiting for a controller response", async () => {
// Repro from #4467
const node2 = new ZWaveNode(2, driver);
(driver.controller.nodes as ThrowingMap<number, ZWaveNode>).set(
2,
node2,
);
// Add event handlers for the nodes
for (const node of driver.controller.nodes.values()) {
driver["addNodeEventHandlers"](node);
}
node2["isListening"] = true;
node2["isFrequentListening"] = false;
node2.markAsAlive();
const valueId = BasicCCValues.currentValue.id;
expect(node2.getValue(valueId)).toBeUndefined();
const ACK = Buffer.from([MessageHeaders.ACK]);
// Step 1: Send a ping and receive the response
node2.ping();
await wait(1);
// » [Node 002] [REQ] [SendData]
// │ transmit options: 0x25
// │ callback id: 1
// └─[NoOperationCC]
expect(serialport.lastWrite).toEqual(
Buffer.from("010800130201002501c3", "hex"),
);
await wait(10);
serialport.receiveData(ACK);
await wait(10);
// We're now waiting for a response. The next command must not get lost
serialport.receiveData(Buffer.from("01090004000203200105d7", "hex"));
// « [Node 002] [REQ] [ApplicationCommand]
// └─[BasicCCSet]
// target value: 5
expect(serialport.lastWrite).toEqual(ACK);
await wait(10);
expect(node2.getValue(valueId)).toEqual(5);
}, 5000);
it("unsolicited commands are passed to Node.handleCommand while waiting for a controller callback", async () => {
// Repro from #4467
const node2 = new ZWaveNode(2, driver);
(driver.controller.nodes as ThrowingMap<number, ZWaveNode>).set(
2,
node2,
);
// Add event handlers for the nodes
for (const node of driver.controller.nodes.values()) {
driver["addNodeEventHandlers"](node);
}
node2["isListening"] = true;
node2["isFrequentListening"] = false;
node2.markAsAlive();
const valueId = BasicCCValues.currentValue.id;
expect(node2.getValue(valueId)).toBeUndefined();
const ACK = Buffer.from([MessageHeaders.ACK]);
// Step 1: Send a ping and receive the response
node2.ping();
await wait(1);
// » [Node 002] [REQ] [SendData]
// │ transmit options: 0x25
// │ callback id: 1
// └─[NoOperationCC]
expect(serialport.lastWrite).toEqual(
Buffer.from("010800130201002501c3", "hex"),
);
await wait(10);
serialport.receiveData(ACK);
await wait(10);
// « [RES] [SendData]
// was sent: true
serialport.receiveData(Buffer.from("0104011301e8", "hex"));
// » [ACK]
expect(serialport.lastWrite).toEqual(ACK);
await wait(10);
// We're now waiting for a callback. The next command must not get lost
serialport.receiveData(Buffer.from("01090004000203200105d7", "hex"));
// « [Node 002] [REQ] [ApplicationCommand]
// └─[BasicCCSet]
// target value: 5
expect(serialport.lastWrite).toEqual(ACK);
await wait(10);
expect(node2.getValue(valueId)).toEqual(5);
}, 5000);
});