Skip to content

Commit

Permalink
fix: split GetLongRangeNodes into own file, fix query loop
Browse files Browse the repository at this point in the history
  • Loading branch information
AlCalzone committed Jan 17, 2024
1 parent 683db90 commit ea170ce
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 112 deletions.
14 changes: 7 additions & 7 deletions packages/zwave-js/src/lib/controller/Controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ import {
GetControllerVersionRequest,
type GetControllerVersionResponse,
} from "../serialapi/capability/GetControllerVersionMessages";
import {
GetLongRangeNodesRequest,
type GetLongRangeNodesResponse,
} from "../serialapi/capability/GetLongRangeNodesMessages";
import {
GetProtocolVersionRequest,
type GetProtocolVersionResponse,
Expand All @@ -152,8 +156,6 @@ import {
type GetSerialApiCapabilitiesResponse,
} from "../serialapi/capability/GetSerialApiCapabilitiesMessages";
import {
GetLongRangeNodesRequest,
type GetLongRangeNodesResponse,
GetSerialApiInitDataRequest,
type GetSerialApiInitDataResponse,
} from "../serialapi/capability/GetSerialApiInitDataMessages";
Expand Down Expand Up @@ -1547,8 +1549,7 @@ export class ZWaveController
const nodeIds: number[] = [];

if (this.supportsLongRange) {
const segment = 0;
while (true) {
for (let segment = 0;; segment++) {
const nodesResponse = await this.driver.sendMessage<
GetLongRangeNodesResponse
>(
Expand All @@ -1557,9 +1558,8 @@ export class ZWaveController
}),
);
nodeIds.push(...nodesResponse.nodeIds);
if (!nodesResponse.moreNodes) {
break;
}

if (!nodesResponse.moreNodes) break;
}
}
return nodeIds;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import {
MessagePriority,
NUM_LR_NODEMASK_SEGMENT_BYTES,
NUM_LR_NODES_PER_SEGMENT,
encodeLongRangeNodeBitMask,
parseLongRangeNodeBitMask,
} from "@zwave-js/core";
import type { ZWaveHost } from "@zwave-js/host";
import {
FunctionType,
Message,
type MessageBaseOptions,
type MessageDeserializationOptions,
MessageType,
expectedResponse,
gotDeserializationOptions,
messageTypes,
priority,
} from "@zwave-js/serial";

export interface GetLongRangeNodesRequestOptions extends MessageBaseOptions {
segmentNumber: number;
}

@messageTypes(MessageType.Request, FunctionType.GetLongRangeNodes)
@expectedResponse(FunctionType.GetLongRangeNodes)
@priority(MessagePriority.Controller)
export class GetLongRangeNodesRequest extends Message {
public constructor(
host: ZWaveHost,
options:
| MessageDeserializationOptions
| GetLongRangeNodesRequestOptions,
) {
super(host, options);

if (gotDeserializationOptions(options)) {
this.segmentNumber = this.payload[0];
} else {
this.segmentNumber = options.segmentNumber;
}
}

public segmentNumber: number;

public serialize(): Buffer {
this.payload = Buffer.from([this.segmentNumber]);
return super.serialize();
}
}

export interface GetLongRangeNodesResponseOptions extends MessageBaseOptions {
moreNodes: boolean;
segmentNumber: number;
nodeIds: number[];
}

@messageTypes(MessageType.Response, FunctionType.GetLongRangeNodes)
export class GetLongRangeNodesResponse extends Message {
public constructor(
host: ZWaveHost,
options:
| MessageDeserializationOptions
| GetLongRangeNodesResponseOptions,
) {
super(host, options);

if (gotDeserializationOptions(options)) {
this.moreNodes = this.payload[0] != 0;
this.segmentNumber = this.payload[1];
const listLength = this.payload[2];

const listStart = 3;
const listEnd = listStart + listLength;
if (listEnd <= this.payload.length) {
const nodeBitMask = this.payload.subarray(
listStart,
listEnd,
);
this.nodeIds = parseLongRangeNodeBitMask(
nodeBitMask,
this.listStartNode(),
);
} else {
this.nodeIds = [];
}
} else {
this.moreNodes = options.moreNodes;
this.segmentNumber = options.segmentNumber;
this.nodeIds = options.nodeIds;
}
}

public moreNodes: boolean;
public segmentNumber: number;
public nodeIds: readonly number[];

public serialize(): Buffer {
this.payload = Buffer.allocUnsafe(
3 + NUM_LR_NODEMASK_SEGMENT_BYTES,
);

this.payload[0] = this.moreNodes ? 1 : 0;
this.payload[1] = this.segmentNumber;
this.payload[2] = NUM_LR_NODEMASK_SEGMENT_BYTES;

const nodeBitMask = encodeLongRangeNodeBitMask(
this.nodeIds,
this.listStartNode(),
);
nodeBitMask.copy(this.payload, 3);

return super.serialize();
}

private listStartNode(): number {
return 256 + NUM_LR_NODES_PER_SEGMENT * this.segmentNumber;
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import {
MAX_NODES,
MessagePriority,
NUM_LR_NODEMASK_SEGMENT_BYTES,
NUM_LR_NODES_PER_SEGMENT,
NUM_NODEMASK_BYTES,
NodeType,
encodeBitMask,
encodeLongRangeNodeBitMask,
parseLongRangeNodeBitMask,
parseNodeBitMask,
} from "@zwave-js/core";
import type { ZWaveHost } from "@zwave-js/host";
Expand Down Expand Up @@ -219,104 +215,3 @@ export class GetSerialApiInitDataResponse extends Message {
// is SUC: true
// chip type: 7
// chip version: 0

// FIXME: Move these into their own file
export interface GetLongRangeNodesRequestOptions extends MessageBaseOptions {
segmentNumber: number;
}

@messageTypes(MessageType.Request, FunctionType.GetLongRangeNodes)
@expectedResponse(FunctionType.GetLongRangeNodes)
@priority(MessagePriority.Controller)
export class GetLongRangeNodesRequest extends Message {
public constructor(
host: ZWaveHost,
options:
| MessageDeserializationOptions
| GetLongRangeNodesRequestOptions,
) {
super(host, options);

if (gotDeserializationOptions(options)) {
this.segmentNumber = this.payload[0];
} else {
this.segmentNumber = options.segmentNumber;
}
}

public segmentNumber: number;

public serialize(): Buffer {
this.payload = Buffer.from([this.segmentNumber]);
return super.serialize();
}
}

export interface GetLongRangeNodesResponseOptions extends MessageBaseOptions {
moreNodes: boolean;
segmentNumber: number;
nodeIds: number[];
}

@messageTypes(MessageType.Response, FunctionType.GetLongRangeNodes)
export class GetLongRangeNodesResponse extends Message {
public constructor(
host: ZWaveHost,
options:
| MessageDeserializationOptions
| GetLongRangeNodesResponseOptions,
) {
super(host, options);

if (gotDeserializationOptions(options)) {
this.moreNodes = this.payload[0] != 0;
this.segmentNumber = this.payload[1];
const listLength = this.payload[2];

const listStart = 3;
const listEnd = listStart + listLength;
if (listEnd <= this.payload.length) {
const nodeBitMask = this.payload.subarray(
listStart,
listEnd,
);
this.nodeIds = parseLongRangeNodeBitMask(
nodeBitMask,
this.listStartNode(),
);
} else {
this.nodeIds = [];
}
} else {
this.moreNodes = options.moreNodes;
this.segmentNumber = options.segmentNumber;
this.nodeIds = options.nodeIds;
}
}

public moreNodes: boolean;
public segmentNumber: number;
public nodeIds: readonly number[];

public serialize(): Buffer {
this.payload = Buffer.allocUnsafe(
3 + NUM_LR_NODEMASK_SEGMENT_BYTES,
);

this.payload[0] = this.moreNodes ? 1 : 0;
this.payload[1] = this.segmentNumber;
this.payload[2] = NUM_LR_NODEMASK_SEGMENT_BYTES;

const nodeBitMask = encodeLongRangeNodeBitMask(
this.nodeIds,
this.listStartNode(),
);
nodeBitMask.copy(this.payload, 3);

return super.serialize();
}

private listStartNode(): number {
return 256 + NUM_LR_NODES_PER_SEGMENT * this.segmentNumber;
}
}

0 comments on commit ea170ce

Please sign in to comment.