11 KiB
Migrating to v13
As part of the ongoing efforts towards Z-Wave certification, I've found an issue in our Meter CC
implementation that required a breaking change. Therefore I've collected a few other changes that would be breaking and decided to bundle them all into a major release.
Changes to the Meter CC
implementation
It has been found that the encoding of the Meter CC Reset command in version 6 was different from the specification. As a result, the MeterCCResetOptions
type had to be changed, because all 4 fields are required to send a V6 command:
type: number;
scale: number;
rateType: RateType;
targetValue: number;
This also means calls to MeterCCAPI.reset(options: MeterCCResetOptions)
need to be updated.
In addition, the reset
values for single meters now refer to a combination of meter type/scale/rate type and are only created for accumulated scales, since others cannot be reset. This will leave some orphaned values that need a re-interview to be removed.
Moved several Z-Wave specific definitions out of the ConfigManager
Historically the ConfigManager
was used to parse Z-Wave specific definitions like Indicators, Scales, Meter types, etc. from disk. However it was found that Z-Wave JS updates at a much higher frequency than the Z-Wave specifications, so being able to statically reference certain definitions in code is far more useful than the possibility of updating config files outside of a driver update.
All types/methods below are exported from @zwave-js/core
. The corresponding exports from @zwave-js/config
have been removed.
Device Classes
BasicDeviceClass
is now an enum. "Slave" has been renamed to "End Node", "Routing Slave" to "Routing End Node". To get the corresponding string of a basic device class, use getEnumMemberName(BasicDeviceClass, value)
.
GenericDeviceClass
and SpecificDeviceClass
are no longer class instances, but simple objects.
All methods related to device classes have been removed from ConfigManager
. To look up a generic/specific device class, use the getGenericDeviceClass
or getSpecificDeviceClass
functions.
The constructor of the DeviceClass
class no longer takes an instance of a ConfigManager
.
All instances where the basic device class is used are now typed with the BasicDeviceClass
enum. This include node mocks, NIF, Z-Wave Protocol CC, and several serial API commands.
Indicators
Defined indicators are now exposed via the Indicator
enum. To get the corresponding string of an indicator ID, use getEnumMemberName(Indicator, indicatorId)
.
IndicatorProperty
is no longer a class instance, but a simple object.
All methods related to indicators have been removed from ConfigManager
. To look up an indicator property and its information, use the getIndicatorProperty
function. This is strongly typed, so you should see the indicator property information in your IDE at compile time.
To list all indicator properties, use getAllIndicatorProperties()
.
Meters
Meter
and MeterScale
are no longer class instances, but simple objects. MeterScale
now has an additional unit
field.
All methods related to meters have been removed from ConfigManager
. To look up a meter or meter scale, use the getMeter
or getMeterScale
functions. These are strongly typed, so you should see the definitions in your IDE at compile time.
To list all meters, use getAllMeters()
. To list all scales of a meter, use getAllMeterScales(meterType)
or iterate the scales
property of the meter definition returned by getMeter
.
Sensors and Scales
Scale
is no longer a class instances, but a simple object. SensorType
is now called Sensor
and also just a simple object type.
All named scales (e.g. "temperature") now have their type derived from the specific scale definition.
All methods related to sensors and scales have been removed from ConfigManager
. To look up a sensor or scale, use the getSensor
or getSensorScale
functions. To look up a group of named scales or a specific one, use getNamedScaleGroup
or getNamedScale
. All of these are strongly typed, so you should see the definitions in your IDE at compile time.
To list all named scale groups, use getAllNamedScaleGroups()
. To list all sensors, use getAllSensors()
. To list all scales of a sensor, use getAllSensorScales(sensorType)
or iterate the scales
property of the sensor definition returned by getSensor
.
Notifications
The types for notification definitions have been reworked and are all simple object types now instead of class instances. Applications might interact with the following ones:
Notification
: The definition for a single notification type, with all its variables and eventsNotificationVariable
: The definition for a (stateful) notification variable, which can have multiple states defined byNotificationState
NotificationEvent
: The definition for a (stateless) notification eventNotificationValue
: A generic notification value that can either be a state or an eventNotificationParameter
: A union of the possible notification parameter types, namelyNotificationParameterWithDuration
,NotificationParameterWithCommandClass
,NotificationParameterWithValue
,NotificationParameterWithEnum
. These can be distinguished by theirtype
property.
All methods related to notifications have been removed from ConfigManager
. To look up a notification or value, use the getNotification
or getNotificationValue
functions. getNotificationValue
needs access to the object returned by getNotification
.
To list all defined notifications, use getAllNotifications()
.
Removed files
The following files have been removed from the config
directory: deviceClasses.json
, indicators.json
, meters.json
, scales.json
, sensorTypes.json
. If you used them in custom configuration, those are no longer needed.
Replaced Controller.isAssociationAllowed
with Controller.checkAssociation
Previously, the information that was returned when adding an association was not allowed was not very helpful for end users. The isAssociationAllowed
method of the Controller
class has been replaced with checkAssociation
which returns a result with more detailed information why an association may not be added:
public checkAssociation(
source: AssociationAddress,
group: number,
destination: AssociationAddress,
): AssociationCheckResult;
enum AssociationCheckResult {
OK = 0x01,
/** The association is forbidden, because the destination is a ZWLR node. ZWLR does not support direct communication between end devices. */
Forbidden_DestinationIsLongRange,
/** The association is forbidden, because the source is a ZWLR node. ZWLR does not support direct communication between end devices. */
Forbidden_SourceIsLongRange,
/** The association is forbidden, because a node cannot be associated with itself. */
Forbidden_SelfAssociation,
/** The association is forbidden, because the source node's CC versions require the source and destination node to have the same (highest) security class. */
Forbidden_SecurityClassMismatch,
/** The association is forbidden, because the source node's CC versions require the source node to have the key for the destination node's highest security class. */
Forbidden_DestinationSecurityClassNotGranted,
/** The association is forbidden, because none of the CCs the source node sends are supported by the destination. */
Forbidden_NoSupportedCCs,
}
Although we recommend embracing the new return values, the old behavior can be restored by comparing the result with AssociationCheckResult.OK
.
Route health checks, neighbors and Z-Wave Long Range
Since Z-Wave Long Range (ZWLR) does not support routing, a few changes had to be made to methods that are concerned with routing and node neighbors:
- The route health check
node.checkRouteHealth(...)
now throws when either the source or target node is ZWLR. LifelineHealthCheckResult.numNeighbors
is now an optional property and may beundefined
. The number of neighbors is no longer considered when rating the lifeline health.Controller.getNodeNeighbors
now throws when the given node ID is for a ZWLR node.
It is recommended to check if node.protocol === Protocols.ZWaveLongRange
or isLongRangeNodeId(nodeId)
is true before calling any of these methods.
Rename "Master Code" to "Admin Code"
The Z-Wave specifications have been changed in language to replace "Master" with "Admin" where applicable. With this PR, we follow suit.
This requires some breaking API changes though:
- Renamed
DoorLockLoggingEventType.MasterCodeChanged
toDoorLockLoggingEventType.AdminCodeChanged
- Renamed the
UserCodeCommand
enum membersMasterCodeSet
,MasterCodeGet
,MasterCodeReport
toAdminCodeSet
,AdminCodeGet
,AdminCodeReport
respectively - Renamed the corresponding
User Code CC
subclasses toUserCodeCCAdminCodeSet
,UserCodeCCAdminCodeGet
andUserCodeCCAdminCodeReport
- Renamed all occurences of the
masterCode
property inUser Code CC
toadminCode
- Renamed
UserCodeCC.supportsMasterCodeDeactivationCached(...)
toUserCodeCC.supportsAdminCodeDeactivationCached(...)
- Renamed the User Code CC APIs
getMasterCode
andsetMasterCode
togetAdminCode
andsetAdminCode
, respectively
For end users, the property
of the Admin Code value ID has been changed from masterCode
to adminCode
, which means the old value will no longer be updated on changes.
Removed deprecated things
- The first (
secure: boolean
) parameter of the"inclusion started"
event has been replaced with the second parameter (strategy: InclusionStrategy
), which was unfortunately undocumented, except in types. To determine whether an inclusion is supposed to be secure, check ifstrategy !== InclusionStrategy.Insecure
. - The
noBulkSupport
property ofConfigurationMetadata
has been removed. There is no replacement, as it was never meant to be user-facing - The
enableSoftReset
property of theZWaveOptions
has been removed. Usefeatures.softReset
instead. - The
mandatorySupportedCCs
andmandatorControlledCCs
properties of theDeviceClass
class have been removed. There is no replacement.
Migrated to Yarn 4 and Corepack
The repository has been migrated to Yarn v4 and now uses Corepack to automatically install the correct package manager version, without having to check it into git. This should work out of the box, unless yarn
was previously installed globally as a system package on Linux. In that case, you may have to uninstall the Linux package and remove any additions to the PATH
environment variable.
It was found that Yarn 4 interacts with already-installed packages differently than Yarn 3. We patch typescript
and it seems that Yarn 4 always undoes this when executing yarn
or yarn install
. Therefore you should not install packages yourself, but rather use the yarn bootstrap
script to take care of everything.