node-zwave-js/docs/config-files/file-format.md

31 KiB

Configuration file format

The following properties are defined and should always be present in the same order for consistency among the config files:

Property Description
manufacturer The name of the manufacturer (or brand under which the device is sold)
manufacturerId The ID of the manufacturer (as defined in the Z-Wave specs) as a 4-digit hexadecimal string.
label A short label for the device
description A longer description of the device, usually the full name
devices An array of product type and product ID combinations, see below for details.
firmwareVersion The firmware version range this config file is valid for, see below for details.
preferred Mark this config file as preferred over others with the same IDs, but overlapping firmware versions. Can be used to have a default white-labeled configuration with re-branded versions, without having to split files too much.
endpoints Endpoint-specific configuration, see below for details. If this is present, associations must be specified on endpoint "0" instead of on the root level.
associations The association groups the device supports, see below for details. Only needs to be present if the device does not support Z-Wave+ or requires changes to the default association config.
paramInformation An array of the configuration parameters the device supports. See below for details.
proprietary A dictionary of settings for the proprietary CC. The settings depend on each proprietary CC implementation.
compat Compatibility flags used to influence the communication with non-compliant devices. See below for details.
metadata Metadata that is intended to help the user, like inclusion instructions etc. See below for details.

devices

Each device in the Z-Wave standard is identified by its product type and product ID. If a config file was imported from the Z-Wave Alliance database, their identifiers are noted here too. A config file that is valid for both 0x0123 / 0x1000 and 0x2345 / 0x0001 would have the following devices entry:

"devices": [
	{
		"productType": "0x0123",
		"productId": "0x1000"
	},
	{
		"productType": "0x2345",
		"productId": "0x0001",
		"zwaveAllianceId": 6789 // or an array, e.g. [6788, 6789]
	}
]

firmwareVersion

While it is possible to specify the firmware version covered by a file, doing so is deprecated. To define parameters that have changed over time, use conditional parameters. Separate files split by firmware should only be used in exceptional cases where a firmware split identifies a different device or where the parameter changes from one version to another are so different as to be impractical to represent with conditional parameters.

The default min version is 0.0 and the default max version is 255.255. Splitting device files by firmware version will only be allowed in exceptional cases, and only with developer approval.

firmwareVersion entry:

"firmwareVersion": {
	"min": "0.0",
	"max": "255.255"
}

If a range other than 0.0-255.255 is used, the firmware ranges should be reflected in the filename. This also means that 0.0- and -255.255 should not be part of the filename, as they are implied.

[!NOTE] Although some manufacturers tend to display firmware versions with leading zeroes, firmwares are interpreted as two numbers. This means 2.01 is equivalent to 2.1. Leading zeroes must not be used in config files to avoid confusion.

[!NOTE] Newer devices may have firmware versions of the form 1.2.3 as opposed to just 1.2, both forms are accepted. For comparisons, versions will be padded with a 0 patch version, e.g. 1.2 becomes 1.2.0.

metadata

Can be used to add instructions for the user to a device:

"metadata": {
	"wakeup": "How to wake up the device manually",
	"inclusion": "How to include this device",
	"exclusion": "How to exclude this device",
	"reset": "How to factory-reset this device",
	"manual": "A link to the device manual
}

endpoints

Optional endpoint-specific configuration. This includes associations, paramInformation and endpoint labels. Example:

"endpoints": {
	"0": {
		"associations": {
			// Association definitions for endpoint 0, see below for details
		}
	},
	"1": {
		"label": "Relay",
		"associations": {
			// Association definitions for endpoint 1, see below for details
		},
		"paramInformation": [
			// Config parameters that only exist on endpoint 1
		]
	},
	// etc.
}

associations

For devices which do not allow auto-discovering associations, the associations must be defined in the config file.

Before defining associations in a config file, please make sure that at least one of the following points applies:

  • The device does not support Z-Wave Plus CC and Association Group Info CC
  • The auto-discovered labels are bad (content or formatting wise), like GROUP_1 instead of something useful like Multilevel Sensor Reports
  • Additional lifelines besides the primary one are necessary to get all desired reports
  • zwave-js auto-assigns an endpoint association (node 1, endpoint 0) to the lifeline, but the device needs a node association (node 1, no endpoint) to report properly

The property looks as follows:

"associations": {
	// One entry for each association group
	"1": {
		"label": "Label for group #1", // required
		"maxNodes": 5 // How many nodes may be in that group, required
	},
	"2": {
		"label": "Label for group #2",
		"description": "A description what group #2 does", // optional, only add this if it adds additional value
		"maxNodes": 1, // SHOULD be 1 for the lifeline, some devices support more nodes
		"isLifeline": true, // Whether this is the Lifeline group. SHOULD exist exactly once, some nodes require more groups to report everything
		"multiChannel": false, // Set this to false to force node id associations for this group, even if endpoint associations are supported. Default: `true`
	},
	// ... more groups ...
}

The isLifeline key is used to determine which group sends the controller device status updates.

To define associations for other endpoints than the root endpoint, you must specify "associations" inside the "endpoints" property. If the same associations exist on the root endpoint and other endpoints, it is recommended to self-reference them via $imports.

[!ATTENTION] Make sure to disable the isLifeline flag on endpoints if the same lifeline group is shared between multiple endpoints.

Example:

"endpoints": {
	"0": {
		"associations": {
			"1": {
				"label": "Lifeline",
				"maxNodes": 5,
				"isLifeline": true
			},
			"2": {
				"label": "Button 1",
				"maxNodes": 5
			},
			"3": {
				"label": "Button 2",
				"maxNodes": 5
			},
		}
	},
	"1": {
		"associations": {
			"1": {
				// This group is shared with the root endpoint. Reference it from there, but don't auto-assign multiple times.
				"$import": "#endpoints/0/associations/1",
				"isLifeline": false
			},
			"2": {
				// This association also exists as group 2 on the root endpoint, so we reference it
				"$import": "#endpoints/0/associations/2"
			}
		}
	},
	"2": {
		"associations": {
			"1": {
				// This group is shared with the root endpoint. Reference it from there, but don't auto-assign multiple times.
				"$import": "#endpoints/0/associations/1",
				"isLifeline": false
			},
			"2": {
				// This association also exists as group 3 on the root endpoint, so we reference it
				"$import": "#endpoints/0/associations/3"
			},
			"3": {
				// This association only exists on endpoint 2
				"label": "Button 2: Double Tap",
				"maxNodes": 5
			}
		}
	}
}

paramInformation

This property defines all the existing configuration parameters. It looks like this

"paramInformation": [
	{
		"#": "1",
		// parameter #1 definition
	},
	{
		"#": "2",
		// parameter #2 definition
	}
	// ... more parameters ...
]

where each parameter definition has the following properties:

Parameter property Type Required? Description
# string yes The parameter number (e.g. "1", "2", ...).
For partial parameters, this includes the bitmask (e.g. "5[0xff00]")
label string yes A short name for the parameter.
This must not include unnecessary white-space, such as newlines or tabs.
description string no An optional longer description of what the parameter does.
If a description does not add significant value (for example if it just repeats the allowed values), it should be removed instead.
This must not include unnecessary white-space, such as newlines or tabs.
valueSize number yes How many bytes the device uses for this value
minValue number yes The minimum allowed value for this parameter
maxValue number yes The maximum allowed value for this parameter
defaultValue number maybe The factory default value of this parameter. This is required unless the parameter is readOnly.
unit string no The unit for this parameter's values, e.g. minutes, seconds, %, kWh, 0.1 °C, etc...
unsigned boolean no Whether this parameter is interpreted as an unsigned value by the device (default: false). This simplifies usage for the end user.
readOnly boolean no Whether this parameter can only be read
writeOnly boolean no Whether this parameter can only be written
allowManualEntry boolean no Whether this parameter accepts any value between minValue and maxValue. Defaults to true for writable parameters and false for readOnly parameters. If this is false, options must be used to specify the allowed values.
options array no If allowManualEntry is omitted or false and the value is writable, this property must contain an array of objects of the form {"label": string, "value": number}. Each entry defines one allowed value.

Partial parameters

Some devices use a single parameter number to configure several, sometimes unrelated, options. For convenience, node-zwave-js provides a simple way to define these values as multiple (partial) configuration parameters. For an in-depth explanation, see the guide on partial parameters.

For example,

{
	"#": "40[0x01]",
	"label": "Button 1: behavior",
	/* parameter definition */
},
{
	"#": "40[0x02]",
	"label": "Button 1: notifications",
	/* parameter definition */
},
{
	"#": "40[0x04]",
	"label": "Button 2: behavior",
	/* parameter definition */
},
{
	"#": "40[0x08]",
	"label": "Button 2: notifications",
	/* parameter definition */
},

defines 4 partial parameters that each switch a single bit of parameter #40. Using the appended bit mask (e.g. [0x01]), you can configure which bits each partial parameter affects.

Partial parameters must follow these rules:

  1. The valueSize must be the actual size of the parameter, as defined in the device manual (not just the part of the bitmask). Each partial parameter must have the same valueSize.
  2. Each bitmask must fit into the configured valueSize of the parameter.
  3. The minValue, maxValue and defaultValue as well as options values are relative to the lowest bit the bit mask. If the bit mask is 0xC (binary 1100), these properties must be in the range 0...3 (2 bits). Any required bit shifts are automatically done.

Bitmask calculator

compat

While the Z-Wave specs define how the protocol works and how devices must behave, the reality is different. zwave-js tries to be smart about this, but sometimes that is not enough. The following compat flags are available to influence how zwave-js communicates with these devices:

alarmMapping

This option is used to translate V1 alarmType and alarmLevel to V2+ notifications. Although the V1 values are not standardized, some manufacturers use the same values for all of their devices. This property has the following shape:

"compat": {
	"alarmMapping": [
		{
			"from": {
				"alarmType": 21, // or any other number between 0 and 255
				"alarmLevel": 2, // or any other number between 0 and 255 (optional)
			},
			"to": {
				"notificationType": 6, // or any other standardized notification type
				"notificationEvent": 5, // or any other standardized notification event
				"eventParameters": {
					// Additional event parameters for this notification event (optional)
					"someProperty": 1, // either a fixed number
					"userId": "alarmLevel", // or the reported alarmLevel
				}
			}
		}
	]
}

From the array of single mappings, the first one with a matching alarmType and alarmLevel is selected. You can leave out the alarmLevel to not match against it. One use case for this is to use the alarmLevel as the userId in the eventParameters.

Single alarm mappings may be $imported from templates.

commandClasses.add

If a device does not report some CCs in its NIF, this can be used to add them. This property has the following shape:

"compat": {
	"commandClasses": {
		"add": {
			// Adds the CC Anti-Theft
			"0x5d": {
				// CCs can be added to the root endpoint (0)...
				/** Whether the endpoint or node can react to this CC */
				"isSupported": true, // or false (optional)
				/** Whether the endpoint or node can control other nodes with this CC */
				"isControlled": true, // or false (optional)
				/** Whether this CC is ONLY supported securely */
				"secure": true, // or false (optional)
				/** The maximum version of the CC that is supported or controlled */
				"version": 2, // optional, default: 1

				// ... or to single endpoints
				"endpoints": {
					"1": {
						// same properties (isSupported, ...) as above
					},
					// ... more endpoints
				}
			}
		}
	}
}

commandClasses.remove

If a device reports support for a CCs but does not correctly support it, this can be used to remove them. This property has the following shape:

"compat": {
	"commandClasses": {
		"remove": {
			// Removes the CC Anti-Theft from the node and all endpoints
			"0x5d": {
				"endpoints": "*"
			},
			// Removes the CC Battery from the node (endpoint 0) and endpoint 2
			"0x80": {
				"endpoints": [0, 2]
			}
		}
	}
}

disableAutoRefresh

Several command classes are refreshed regularly (every couple of hours) if they do not report all of their values automatically. It has been found that some devices respond with invalid reports when queried. By setting disableAutoRefresh to true, this feature can be disabled.

disableCallbackFunctionTypeCheck

By default, responses or callbacks for Serial API commands must have the same function type (command identifier) in order to be recognized. However, in some situations, certain controllers send a callback with an invalid function type. In this case, the faulty commands may be listed in the disableCallbackFunctionTypeCheck array to disable the check for a matching function type.

[!NOTE] This compat flag requires command-specific support and is not a generic escape hatch.

disableStrictEntryControlDataValidation

The specifications mandate strict rules for the data and sequence numbers in Entry Control CC Notifications, which some devices do not follow, causing the notifications to get dropped. Setting disableStrictEntryControlDataValidation to true disables these strict checks.

disableStrictMeasurementValidation

Without the additional integrity checks that encapsulation CCs like CRC-16, Security S0 or Security S2 provide, multilevel sensors and meters are prone to report and accumulate nonsensical measurements over time due to partially corrupted radio frames. For devices which report their supported meter or sensor types and scales, Z-Wave JS checks that the reported measurements belong to a supported meter or sensor type and/or scale. Invalid measurements are dropped.

Some devices incorrectly encode this support information though, making the checks discard otherwise correct data. To disable the checks, set disableStrictMeasurementValidation to true.

encodeCCsUsingTargetVersion

Because command classes are extended in a backwards-compatible way, the Z-Wave specifications recommend encoding command classes using the version the sender supports, regardless of the receiver's version. However it has been found that some devices do not correctly parse commands from a newer version and do not react to them. When encodeCCsUsingTargetVersion is set to true for a device, Z-Wave JS will encode commands using the version the receiver supports instead.

forceNotificationIdleReset

Version 8 of the Notification CC added the requirement that devices must issue an idle notification after a notification variable is no longer active. Several legacy devices and some misbehaving V8 devices do not return their variables to idle automatically. By setting forceNotificationIdleReset to true, zwave-js auto-idles supporting notification variables after 5 minutes.

forceSceneControllerGroupCount

The specifications mandate that each Scene Controller Configuration CC Group ID corresponds to exactly one association group. Some devices ignore this rule, and as a result not all scenes can be configured. Using the forceSceneControllerGroupCount flag, the actual number of scenes of these devices can be configured.

manualValueRefreshDelayMs

Some legacy devices emit an NIF when a local event occurs (e.g. a button press) to signal that the controller should request a status update. However, some of these devices require a delay before they are ready to respond to this request. manualValueRefreshDelayMs specifies that delay, expressed in milliseconds. If unset, there will be no delay.

mapBasicReport

Basic CC::Report commands are like their name implies, Basic. They contain no information about what they are reporting. By default, Z-Wave JS uses the device type to map these commands to a more appropriate CC. The mapBasicReport can influence this behavior. It has the following options:

  • false: treat the report verbatim without mapping
  • "auto" (default): Depending on the device type (Binary Switch, Multilevel Switch, or Binary Sensor), the command is mapped to the corresponding report for that device type. If no matching mapping is found, the command is treated verbatim without mapping.
  • "Binary Sensor": Regardless of the device type, the command is treated like a Binary Sensor CC::Report.

mapBasicSet

Basic CC::Set commands are meant to control other devices, yet some devices use them to "report" their status or expose secondary functionality. The mapBasicSet flag defines how Z-Wave JS should handle these commands:

  • "report" (default): The command is treated like a Basic CC::Report, but the target value is used as the current value.
  • "auto": Depending on the device type (Binary Switch, Multilevel Switch, or Binary Sensor), the command is mapped to the corresponding report for that device type. If no matching mapping is found, the command is treated like a Basic CC::Report, but the target value is used as the current value.
  • "event": Emit a value event for the Basic "event" property.
  • "Binary Sensor": Regardless of the device type, the command is treated like a Binary Sensor CC::Report.

mapRootReportsToEndpoint

Some multi-channel devices incorrectly report state changes for one of their endpoints via the root device, however there is no way to automatically detect for which endpoint these reports are meant. The flag mapRootReportsToEndpoint can be used to specify which endpoint these reports are mapped to. Without this flag, reports to the root device are silently ignored, unless preserveRootApplicationCCValueIDs is true.

overrideQueries

A frequent reason for device not "working" correctly is that they respond to queries incorrectly, e.g. RGB bulbs not reporting support for the blue color channel, or thermostats reporting the wrong supported modes. Using overrideQueries, the responses to these queries can be overridden, so they are not queried from the device anymore. Example:

"overrideQueries": {
	// For which CC the queries should be overridden. Also accepts the decimal or hexadecimal CC ID.
	"Schedule Entry Lock": [
		{
			// Which endpoint the query should be overridden for (optional).
			// Defaults to the root endpoint 0
			"endpoint": 1,
			// Which API method should be overridden. Available methods depend on the CC.
			"method": "getNumSlots",
			// Multiple overrides can optionally be specified for the same method, distinguished
			// by the method arguments. If `matchArgs` is not specified, the override
			// is used for all calls to the method.
			// The arguments must be exactly the same as in the API call and are
			// compared using equality (===)
			"matchArgs": [1, 2, 3]
			// The result that should be returned by the API method when called.
			"result": {
				"numWeekDaySlots": 0,
				"numYearDaySlots": 0,
				"numDailyRepeatingSlots": 1
			},
			// Which values should be stored in the value DB when the API method is called (optional).
			// The keys are the names of the predefined values of the given CC,
			// see the CC documentation for available values.
			"persistValues": {
				"numWeekDaySlots": 0,
				"numYearDaySlots": 0,
				"numDailyRepeatingSlots": 1,
				// To pass arguments for dynamic CC values, put them in round brackets (must be parseable by `JSON.parse()`)
				"userEnabled(1)": true
			},
			// Which metadata should be stored in the value DB when the API method is called (optional).
			// The keys are the names of the predefined values of the given CC,
			// see the CC documentation for available values.
			"extendMetadata": {
				"numWeekDaySlots": {
					// This metadata will be merged with the statically defined metadata
					"states": {
						"0": "none",
						"1": "one",
						// ...
					}
				},
			},
		}
	]
}

preserveEndpoints

Many devices unnecessarily use endpoints when they could (or do) provide all functionality via the root device. zwave-js tries to detect these cases and ignore all endpoints. To opt out of this behavior or to preserve single endpoints, preserveEndpoints can be used. Example:

"preserveEndpoints": "*",    // to preserve all endpoints
"preserveEndpoints": [2, 3], // to preserve endpoints 2 and 3, but ignore endpoint 1

preserveRootApplicationCCValueIDs

The Z-Wave+ specs mandate that the root endpoint must mirror the application functionality of endpoint 1 (and potentially others). For this reason, zwave-js hides these superfluous values. However, some legacy devices offer additional functionality through the root endpoint, which should not be hidden. To achieve this, set preserveRootApplicationCCValueIDs to true.

removeEndpoints

Some devices expose endpoints which are not needed or don't behave correctly. Using this flag, they can be ignored/hidden from applications. Example:

"removeEndpoints": "*",    // to remove all endpoints and only preserve the root device
"removeEndpoints": [3, 5], // to remove endpoints 3 and 5

Note that this setting has precedence over preserveEndpoints.

reportTimeout

By default, the driver determines the time to wait for a response from a node using the RTT of the request (including nonce exchange if needed) and adds 1s to it. While 1s is recommended by the specs and a good default, some devices have been found to sometimes respond slower. Instead of increasing the timeout for all devices with the driver option, the reportTimeout compat flag can be used to increase the timeout for a specific device.

skipConfigurationNameQuery

Some devices spam the network with lots of ConfigurationCC::NameReports in response to the NameGet command. Set this flag to true to skip this query for affected devices.

skipConfigurationInfoQuery

Some devices spam the network with lots of (sometimes invalid) ConfigurationCC::InfoReports in response to the InfoGet command. Set this flag to true to skip this query for affected devices.

treatMultilevelSwitchSetAsEvent

By default, Multilevel Switch CC::Set commands are ignored, because they are meant to control end devices. This flag causes the driver to emit a value event for the "event" property instead, so applications can react to these commands, e.g. for remotes.

treatSetAsReport

By default, many Set CC commands are ignored, because they are meant to control end devices. For some devices, those commands are the only way to receive updates about some values though. This flag causes the driver treat the listed commands as a report instead and issue a value report, so applications can react to them.

[!NOTE] This mapping is CC specific and must be implemented for every CC that needs it. Currently, only BinarySwitchCCSet and ThermostatModeCCSet are supported.

treatDestinationEndpointAsSource

Some devices incorrectly use the multi channel destination endpoint in reports to indicate the source endpoint the report originated from. When this flag is true, the destination endpoint is instead interpreted to be the source and the original source endpoint gets ignored.

useUTCInTimeParametersCC

When a device exposes no other way to configure timezone information, Z-Wave JS uses local time for setting the date and time using Time Parameters CC. Per the specification, UTC should be used for this, but it has been found that without timezone information, devices tend to falsely interpret UTC as local time in this case. By setting useUTCInTimeParametersCC to true, UTC is used anyways, so devices that get their timezone information from other sources can be configured correctly.