-
-
Notifications
You must be signed in to change notification settings - Fork 628
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: support Z-Wave Long Range #6401
Changes from all commits
666257e
acfb9ea
5f81ca9
b4ddd89
5eb0762
fcaacb3
29ef9af
1b56690
63d142b
6005dfa
cd27d02
8f15e3a
d1e23fc
70038ab
9b679c3
9637127
8223ee9
e8f9023
02052ef
c9184ef
d00b084
15bc808
7b268b4
1bb54b2
9b5c7ba
32c0c34
25908de
e8c3134
6e52505
e55e479
f0d0dde
2e7971d
8715fce
f9585f0
fe446eb
79b1a6a
8f22fd1
a42243d
683db90
ea170ce
f226a82
1e09888
098b8d1
c58c2fa
01039de
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Supporting Z-Wave Long Range in Applications | ||
|
||
Z-Wave Long Range (ZWLR) is an addition to Z-Wave, that allows for a massively increased transmission range and up to 4000 nodes in a single network. Z-Wave Long Range uses a star topology, where all nodes communicate directly with the controller. This means that ZWLR nodes cannot be used to route messages for non-ZWLR nodes. | ||
|
||
There are a few things applications need to be aware of to support Long Range using Z-Wave JS. | ||
|
||
1. ZWLR node IDs start at 256. This can be used to distinguish between ZWLR and classic Z-Wave nodes. | ||
2. ZWLR inclusion works exclusively through [Smart Start](getting-started/security-s2#smartstart). | ||
\ | ||
ZWLR nodes advertise support for Long Range in the `supportedProtocols` field of the `QRProvisioningInformation` object (see [here](api/utils#other-qr-codes)). When this field is present, the user **MUST** have the choice between the advertised protocols. Currently this means deciding between including the node via Z-Wave Classic (mesh) or Z-Wave Long Range (no mesh).\ | ||
To include a node via ZWLR, set the `protocol` field of the `PlannedProvisioningEntry` to `Protocols.ZWaveLongRange` when [provisioning the node](api/controller#provisionsmartstartnode). |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,8 @@ | ||
import { MAX_NODES, NUM_NODEMASK_BYTES } from "../consts"; | ||
import { | ||
MAX_NODES, | ||
NUM_LR_NODES_PER_SEGMENT, | ||
NUM_NODEMASK_BYTES, | ||
} from "../consts"; | ||
import { ZWaveError, ZWaveErrorCodes } from "../error/ZWaveError"; | ||
import { | ||
getBitMaskWidth, | ||
|
@@ -231,15 +235,17 @@ export function encodeFloatWithScale( | |
} | ||
|
||
/** Parses a bit mask into a numeric array */ | ||
export function parseBitMask(mask: Buffer, startValue: number = 1): number[] { | ||
const numBits = mask.length * 8; | ||
|
||
export function parseBitMask( | ||
mask: Buffer, | ||
startValue: number = 1, | ||
numBits: number = mask.length * 8, | ||
): number[] { | ||
const ret: number[] = []; | ||
for (let index = 1; index <= numBits; index++) { | ||
const byteNum = (index - 1) >>> 3; // id / 8 | ||
const bitNum = (index - 1) % 8; | ||
for (let index = 0; index < numBits; index++) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I personally found this confusing... we do 1 based indexing in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure why I did it this way. Maybe this was more in line with some texts in the specs. |
||
const byteNum = index >>> 3; // id / 8 | ||
const bitNum = index % 8; | ||
if ((mask[byteNum] & (2 ** bitNum)) !== 0) { | ||
ret.push(index + startValue - 1); | ||
ret.push(index + startValue); | ||
} | ||
} | ||
return ret; | ||
|
@@ -266,10 +272,28 @@ export function parseNodeBitMask(mask: Buffer): number[] { | |
return parseBitMask(mask.subarray(0, NUM_NODEMASK_BYTES)); | ||
} | ||
|
||
export function parseLongRangeNodeBitMask( | ||
mask: Buffer, | ||
startValue: number, | ||
): number[] { | ||
return parseBitMask(mask, startValue); | ||
} | ||
|
||
export function encodeNodeBitMask(nodeIDs: readonly number[]): Buffer { | ||
return encodeBitMask(nodeIDs, MAX_NODES); | ||
} | ||
|
||
export function encodeLongRangeNodeBitMask( | ||
nodeIDs: readonly number[], | ||
startValue: number, | ||
): Buffer { | ||
return encodeBitMask( | ||
nodeIDs, | ||
startValue + NUM_LR_NODES_PER_SEGMENT - 1, | ||
startValue, | ||
); | ||
} | ||
|
||
/** | ||
* Parses a partial value from a "full" value. Example: | ||
* ```txt | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where did you find the information you used to update this method? I'm not sure a change is necessary, as the controller should forward a properly formatted NIF, no matter if the protocol-level frame it received is using the Long Range CC or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See
specs\Z-Wave Stack Specifications\Z-Wave and Z-Wave Long Range Network Layer Specification.pdf
. Long Range added their own Node Information Frame Command in section 6.3.1.2. The non-long-range frame (section 4.3.2.1) has 3 bytes for Basic/Generic/Specific device classes, and then a list of command classes for the remainder of the packet.The long range frame has Generic and Specific device class bytes (no basic), and then a byte that is the "command list length" (in bytes, as I recall), and then the list of command classes.
Why they felt the need to replace these fields and add the seemingly redundant length, I'm not sure.
If we don't need/want the long range command class in this change (it wasn't needed to get pairing and comms to work). I think this stuff can be backed out.