10 KiB
Migrating to v11
I've put this off for a while now. v10
has been pretty stable - we've never had anything close to .23
minor version before.
But Z-Wave JS is on the road to certification, and some of those requirements are forcing my hand.
Window Covering CC vs. Multilevel Switch CC
The Window Covering CC
allows for more granular control of covers to the point of making Multilevel Switch CC
redundant.
As a result, the Z-Wave specification forbids interacting with the Multilevel Switch CC
on devices that support the Window Covering CC
.
To avoid removing functionality for users, applications that plan on upgrading to v11
must make sure to have support for the Window Covering CC
.
Changed return types of Controller.firmwareUpdateOTA
and Controller.firmwareUpdateOTW
methods
These methods previously only returned a boolean
indicating success or failure. To get more information about the update result, applications had to listen to the firmware update finished
event in addition to awaiting the returned promise.
To make this easier:
firmwareUpdateOTA
now returns aPromise<FirmwareUpdateResult>
firmwareUpdateOTW
now returns aPromise<ControllerFirmwareUpdateResult>
both of which contain the same information as the corresponding firmware update finished
events.
Renamed methods on the ZWaveHost
interface
The getSafeCCVersionForEndpoint
method has been renamed to getSafeCCVersion
.
The getSupportedCCVersionForNode
method has been renamed to getSupportedCCVersion
.
These methods were inconsistently named and none of the other methods that accept a node ID and endpoint index specify that in their name.
paramInformation
in custom device configuration files can no longer be an object
In version 8.6.0
, we switched from defining config parameters as an array of objects with instead of an object. Parsing objects was still supported for user-defined config files, but this is no longer the case.
All config files must now use the new format. See this pull request for details on the change.
Added support for configuration parameters on endpoints
Configuration parameters on endpoints are now supported. For devices with config parameters on endpoints, the parameter numbers are likely not unique.
Applications that expect configuration parameters to only exist on the root device will have to be updated to support this change.
Removed preserveUnknownValues
driver option, distinguish between (known to be) unknown and not (yet) known states/values
Several CCs use the value 254 to indicate that a state is unknown. However this value often lies outside of the normal range of values, e.g. 0-99 for multilevel switches. Other CCs translate the raw numeric values to another type, e.g. boolean
for the Binary Switch CC
. So simply preserving the 254 isn't an option, because it would throw off applications which expect a value in the defined range or of the correct type.
Previously, Z-Wave JS used "unknown"
or undefined
(based on the driver option preserveUnknownValues
), which both have downsides aswell:
- The string
"unknown"
is obviously not a number or boolean, which could cause errors undefined
gets "filtered" out by the value DB, because it also means no value. As a result changes tounknown
would cause no eventsundefined
could also mean the data hasn't been queried yet, but it is impossible to distinguish from theunknown
case
To solve this dilemma, Z-Wave JS now uses two distinct values (and types using the same name):
NOT_KNOWN
is an alias forundefined
and indicates that a value is not known (yet), either for a value that has not been queried yet, or where no response was receivedUNKNOWN_STATE
is an alias fornull
and indicates that some information has been queried, but the corresponding state is (known to be) unknown. For example a multilevel device without intermediate position support - it knows that it is neither fully open, nor fully closed, but not the exact position.
Two related utility types have been introduced to preserve this distinction through the type system and replace the former Maybe<T>
type:
MaybeNotKnown<T>
isT | NOT_KNOWN
and indicates that something is either of the typeT
, orNOT_KNOWN = undefined
MaybeUnknown<T>
isT | UNKNOWN_STATE
and indicates that something is either of the typeT
, orUNKNOWN_STATE = null
Many method signatures and properties which previously used undefined
to indicate an uncertainty have been updated to use either of the previous types to make it clear what an absence of a value means. Likewise, several CC values can now be null / UNKNOWN_STATE
. The preserveUnknownValues
driver option has been removed.
Application developers should double-check their code for a common class of errors/bugs that could be introduced by this change, e.g.:
- The comparisons
== null
,== undefined
,!= null
and!= undefined
fail to distinguish betweenNOT_KNOWN
andUNKNOWN_STATE
. While it is generally recommended to use triple-equals comparison in JavaScript, in these cases, double-equals is a convenient way to compare against bothnull
andundefined
at the same time. - Likewise for nullish coalescing and optional chaining operators (
?.
,??
,??=
) - Expecting a
number
orboolean
when a CC value is notundefined
is no longer safe, because it could benull
.
Reworked BitField
config parameters to behave like partial parameters
Previously, BitField
config parameters were using JavaScript Set
s as values. This seemed like a good idea 4 years ago when the code was written, but until recently almost no devices used this type of config parameter. As it turns out, Set
s don't serialize well - meaning some of the queried information got lost on the way to the cache - and they are awkward to use for applications.
For config parameters that are defined in configuration files, we have had a better solution for quite some time now: partial parameters. Starting with v11
, BitField
config parameters will automatically be split into multiple single-bit partial parameters. This means applications which use value metadata to expose config parameters should be able to support them without any changes.
However, the type ConfigValue
has been changed to just number
, so we treat this as a breaking change.
Changed Node.setValue
and VirtualNode.setValue
to return a SetValueResult
Historically, these methods returned a boolean
indicating whether the value was successfully set or not. While convenient, simply returning true
or false
isn't very helpful, especially since Z-Wave JS started using Supervision wherever possible in v10.
For example, it is not possible to know from a simple true
whether the command was actually executed by the device or whether it just acknowledged an unsupervised command but didn't actually do anything.
Likewise, returning false
seems too generic when there are a multitude of possible reasons for this:
- A value was set on a non-existing endpoint
- The endpoint does not support the CC
- The CC is not implemented in Z-Wave JS
- There is no
setValue
implementation for the CC in Z-Wave JS - The command could not be sent
- The command was sent and received, but the device could not execute it
- An invalid value was provided
- ...
To solve this and help applications give better feedback to the user, Node.setValue
and VirtualNode.setValue
now return a SetValueResult
object with the following properties:
type SetValueResult = {
status: SetValueStatus;
remainingDuration?: Duration;
message?: string;
};
See the updated documentation for a more detailed explanation on working with SetValueResult
s.
Since the result now contains error information, calling setValue
will no longer emit an "error"
event in case of a usage error (unimplemented CC, invalid value).
It will however still throw an error if the communication fails.
The "node removed"
event callback now indicates why a node was removed
The signature of the callback has been changed from
(node: ZWaveNode, replaced: boolean) => void
to
(node: ZWaveNode, reason: RemoveNodeReason) => void
where the second argument has one of the following values:
enum RemoveNodeReason {
/** The node was excluded by the user or an inclusion controller */
Excluded,
/** The node was excluded by an inclusion controller */
ProxyExcluded,
/** The node was removed using the "remove failed node" feature */
RemoveFailed,
/** The node was replaced using the "replace failed node" feature */
Replaced,
/** The node was replaced by an inclusion controller */
ProxyReplaced,
/** The node was reset locally and was auto-removed */
Reset,
/** SmartStart inclusion failed, and the node was auto-removed as a result. */
SmartStartFailed,
}
[!NOTE] To comply with the Z-Wave specifications, applications MUST indicate that the node was reset locally and has left the network when the
reason
isRemoveNodeReason.Reset
.
Removed several deprecated method signatures, enums and properties
- The enum member
NodeType["Routing End Node"]
has been removed. This has been called"End Node"
sincev9.3.0
ConfigurationMetadata.name
was removed in favor oflabel
ConfigurationMetadata.info
was removed in favor ofdescription
Controller.getBroadcastNodeInsecure
andController.getBroadcastNodes
were removed in favor ofController.getBroadcastNode
Controller.getMulticastGroupInsecure
,Controller.getMulticastGroupS2
andController.getMulticastGroups
were removed in favor ofController.getMulticastGroup
Controller.beginOTAFirmwareUpdate
was removed in favor ofController.firmwareUpdateOTA
- The
Controller.beginExclusion
overloads accepting aboolean
or the string"inactive"
have been removed. Use the overload withExclusionOptions
instead. ZWaveNode.beginFirmwareUpdate
was removed in favor ofZWaveNode.updateFirmware
- The deprecated arguments of the
"firmware update progress"
and"firmware update finished"
event callbacks of theZWaveNode
class were removed. Theprogress
andresult
arguments are now in the 2nd place instead of in the 4th one.