f47d5341ae
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
---|---|---|
.devcontainer | ||
.github | ||
src | ||
.gitignore | ||
.nvmrc | ||
API_SCHEMA.md | ||
LICENSE | ||
README.md | ||
eslint.config.mjs | ||
example_config.js | ||
package-lock.json | ||
package.json | ||
tsconfig.json |
README.md
Z-Wave JS Server
Small server wrapper around Z-Wave JS to access it via a WebSocket.
Trying it out
These instructions are for development only. These CLIs will be available as zwave-server
and zwave-client
after installing the NPM package.
Start server
tsx src/bin/server.ts /dev/tty0
Opens server on ws://0.0.0.0:3000
.
You can specify a configuration file with --config
. This can be a JSON file or a JS file that exports the config. It needs to follow the Z-Wave JS config format.
NOTE: Unless specificed in the configuration file, the
emitValueUpdateAfterSetValue
configuration option will be set totrue
. This is recommended for multi-client setups and for cases where multiple applications are sharing access to the same driver, e.g. zwavejs2mqtt
You can specify a different port for the websocket server to listen on with --port
, as well as the interface to attach to using --host
, the default host is 0.0.0.0 i.e all interfaces.
If you don't have a USB stick, you can add --mock-driver
to use a fake stick.
DNS-SD is enabled in the server by default. If you would like to disable it, add --disable-dns-sd
.
Start client
Requires server to be running.
Default connects to ws://localhost:3000
:
tsx src/bin/client.ts
To specify different host:
tsx src/bin/client.ts ws://192.168.1.100:6000
To specify that it outputs each message on a single line so it can be replayed later:
tsx src/bin/client.ts --dump
You can filter the output by a specific node ID:
tsx src/bin/client.ts --node 52
To specify a schema version other than the latest (maxSchemaVersion
):
tsx src/bin/client.ts --schemaVersion 0
All these options can be combined.
API
When a client connects, the server will send the version.
interface {
type: "version";
driverVersion: string;
serverVersion: string;
homeId: number;
}
To set the schema version that the client supports as well as an optional user agent that will be added to web requests, the client should send the initialize
command.
interface {
messageId: string;
command: "initialize";
schemaVersion: number;
additionalUserAgentComponents?: Record<string, string>;
}
To start receive the state and get events, the client needs to send the start_listening
command.
interface {
messageId: string;
command: "start_listening";
}
The server will respond with the current state and start sending events.
interface {
type: "result";
messageId: string; // maps the `start_listening` command
success: true,
result: {
state: {
controller: Partial<ZWaveController>;
nodes: Partial<ZWaveNode>[];
}
};
}
After that, the client will be notified of each state change that happens inside Z-Wave JS.
Event keys follow the names/types as used by Z-Wave JS.
interface {
type: "event",
event: {
source: "driver" | "controller" | "node";
event: string;
[key: string]: unknown;
}
}
Client commands
Server level commands
Start listening to events
interface {
messageId: string;
command: "start_listening";
}
Set API schema version
[compatible with schema version: 0+]
interface {
messageId: string;
command: "set_api_schema";
schemaVersion: number;
}
Start listening to logging events
[compatible with schema version: 31+]
Start receiving logs as events. Look at the logging
event documentation for more information about the events. If filter
is included, only logs that match the filter
will be sent as events, the rest will be skipped.
interface {
messageId: string;
command: "start_listening_logs";
filter?: Partial<NodeLogContext| DriverLogContext | ControllerLogContext | SerialLogContext | ConfigLogContext>;
}
Stop listening to logging events
[compatible with schema version: 31+]
Stop receiving logs as events.
interface {
messageId: string;
command: "stop_listening_logs";
}
Driver level commands
Get the config of the driver
[compatible with schema version: 4+]
interface {
messageId: string;
command: "driver.get_config";
}
Returns:
interface {
config: {
logConfig: {
enabled: boolean;
level: string | number; // schema versions >= 3 use string, <= 2 use number
logToFile: boolean;
filename: string;
forceConsole: boolean;
};
statisticsEnabled: boolean;
}
}
Update the logging configuration
[compatible with schema version: 4+]
NOTE: You must provide at least one key/value pair as part of
config
interface {
messageId: string;
command: "driver.update_log_config";
config: {
enabled?: boolean;
level?: string | number;
logToFile?: boolean;
filename?: string;
forceConsole?: boolean;
}
}
Get the logging configuration
[compatible with schema version: 4+]
interface {
messageId: string;
command: "driver.get_log_config";
}
Returns:
interface {
config: {
enabled: boolean;
level: string | number; // schema versions >= 3 use string, <= 2 use number
logToFile: boolean;
filename: string;
forceConsole: boolean;
}
}
Enable data usage statistics collection
[compatible with schema version: 4+]
interface {
messageId: string;
command: "driver.enable_statistics";
applicationName: string;
applicationVersion: string;
}
Disable data usage statistics collection
[compatible with schema version: 4+]
interface {
messageId: string;
command: "driver.disable_statistics";
}
Get whether statistics are enabled
[compatible with schema version: 4+]
interface {
messageId: string;
command: "driver.is_statistics_enabled";
}
Returns:
interface {
statisticsEnabled: boolean;
}
Set preferred scales
[compatible with schema version: 6+]
Set preferred sensor scales. The scales
argument has the same type as preferences.scales
in ZWaveOptions
interface {
messageId: string;
command: "driver.set_preferred_scales";
scales: ZWaveOptions["preferences"]["scales"];
}
Check for config updates
[compatible with schema version: 5+]
interface {
messageId: string;
command: "driver.check_for_config_updates";
}
Install config update
[compatible with schema version: 5+]
interface {
messageId: string;
command: "driver.install_config_update";
}
Enable Error Reporting
[compatible with schema version: 16+]
interface {
messageId: string;
command: "driver.enable_error_reporting";
}
Peform a soft-reset (restart) on the controller
[compatible with schema version: 25+]
interface {
messageId: string;
command: "driver.soft_reset";
}
Attempt to perform a soft-reset (restart) on the controller
[compatible with schema version: 25+]
interface {
messageId: string;
command: "driver.try_soft_reset";
}
Shutdown
[compatible with schema version: 27+]
interface {
messageId: string;
command: "driver.shutdown";
}
Update Options
[compatible with schema version: 33+]
interface {
messageId: string;
command: "driver.update_options";
options: EditableZWaveOptions;
}
Perform a hard reset on the controller
[compatible with schema version: 25+]
interface {
messageId: string;
command: "driver.hard_reset";
}
Shutdown the Z-Wave API on the controller
[compatible with schema version: 36+]
interface {
messageId: string;
command: "driver.shutdown";
}
Update driver options
[compatible with schema version: 36+]
interface {
messageId: string;
command: "driver.update_options";
options: EditableZWaveOptions;
}
Send test frame to node
[compatible with schema version: 36+]
interface {
messageId: string;
command: "driver.send_test_frame";
nodeId: number;
powerlevel: Powerlevel;
}
Controller level commands
zwave-js-server
supports all of the controller methods listed in the Z-Wave JS documentation. zwave-js-server
uses snake casing for commands and prefixes every controller command with controller.
, so beginInclusion
is called using the controller.begin_inclusion
command.
NOTE: For the most part,
controller
commands have the same inputs as documented in the Z-Wave JS documentation. The exceptions are:
controller.begin_inclusion
: in addition to the input types that are documented, this command will also accept the QR code string directly and will convert the string to aQRProvisioningInformation
object automatically.controller.provision_smart_start_node
: in addition to the input types that are documented, this command will also accept the QR code string directly and will convert the string to aQRProvisioningInformation
object automatically.controller.backup_nvm_raw
: This command will return a base64 encoded string for the NVM data.controller.restore_nvm
: The NVM input should be a base64 encoded string.controller.firmware_update_otw
: This command accepts two required parameters (file
, a base64 representation of the file, andfilename
, the filename of the file) as well as an optional parameter (fileFormat
, which provides the format of the file to the server so the driver does not have to guess the format)
Get controller state
[compatible with schema version: 14+]
interface {
messageId: string;
command: "controller.get_state";
}
Node level commands
Set value on a node
[compatible with schema version: 0+]
interface {
messageId: string;
command: "node.set_value";
nodeId: number;
valueId: {
commandClass: CommandClasses;
endpoint?: number;
property: string | number;
propertyKey?: string | number;
};
value: any;
options?: SetValueAPIOptions;
}
Refresh node info
[compatible with schema version: 0+]
interface {
messageId: string;
command: "node.refresh_info";
nodeId: number;
options?: RefreshInfoOptions;
}
Get defined Value IDs
[compatible with schema version: 0+]
interface {
messageId: string;
command: "node.get_defined_value_ids";
nodeId: number;
}
Get value metadata
[compatible with schema version: 0+]
interface {
messageId: string;
command: "node.get_value_metadata";
nodeId: number;
valueId: {
commandClass: CommandClasses;
endpoint?: number;
property: string | number;
propertyKey?: string | number;
};
}
Get value
[compatible with schema version: 14+]
interface {
messageId: string;
command: "node.get_value";
nodeId: number;
valueId: {
commandClass: CommandClasses;
endpoint?: number;
property: string | number;
propertyKey?: string | number;
};
}
Get node state
[compatible with schema version: 14+]
interface {
messageId: string;
command: "node.get_state";
nodeId: number;
}
Update Firmware
[compatible with schema version: 24+]
If firmwareFileFormat
is not provided, the format will be guessed based on the filename and file payload.
interface {
messageId: string;
command: "node.begin_firmware_update";
nodeId: number;
updates: {
filename: string;
file: string; // use base64 encoding for the file
fileFormat?: FileFormat;
}[];
}
Abort Firmware Update
[compatible with schema version: 0+]
interface {
messageId: string;
command: "node.abort_firmware_update";
nodeId: number;
}
Get Firmware Update Capabilities
[compatible with schema version: 0+]
interface {
messageId: string;
command: "node.get_firmware_update_capabilities";
nodeId: number;
}
Get Firmware Update Capabilities Cached
[compatible with schema version: 21+]
interface {
messageId: string;
command: "node.get_firmware_update_capabilities_cached";
nodeId: number;
}
Poll value
[compatible with schema version: 1+]
interface {
messageId: string;
command: "node.poll_value";
nodeId: number;
valueId: {
commandClass: CommandClasses;
endpoint?: number;
property: string | number;
propertyKey?: string | number;
};
}
Set raw configuration parameter value (Advanced)
[compatible with schema version: 1+]
interface {
messageId: string;
command: "node.set_raw_config_parameter_value";
nodeId: number;
}
Refresh values
[compatible with schema version: 4+]
interface {
messageId: string;
command: "node.refresh_values";
nodeId: number;
}
Interview command class
[compatible with schema version: 14+]
interface {
messageId: string;
nodeId: number;
command: "node.interview_cc";
commandClass: CommandClasses;
}
Refresh command class values
[compatible with schema version: 4+]
interface {
messageId: string;
command: "node.refresh_cc_values";
nodeId: number;
commandClass: CommandClasses;
}
Ping
[compatible with schema version: 5+]
interface {
messageId: string;
command: "node.ping";
nodeId: number;
}
Check if node has security class
[compatible with schema version: 8+]
interface {
messageId: string;
command: "node.has_security_class";
nodeId: number;
securityClass: SecurityClass;
}
Return the highest security class the node has
[compatible with schema version: 8+]
interface {
messageId: string;
nodeId: number;
command: "node.get_highest_security_class";
}
Test Powerlevel
[compatible with schema version: 13+]
This command emits events.
interface {
messageId: string;
nodeId: number;
command: "node.test_powerlevel";
testNodeId: number;
powerlevel: Powerlevel;
testFrameCount: number;
}
Check Lifeline Health
[compatible with schema version: 13+]
This command emits events.
interface {
messageId: string;
nodeId: number;
command: "node.check_lifeline_health";
rounds?: number;
}
Check Route Health
[compatible with schema version: 13+]
This command emits events.
interface {
messageId: string;
nodeId: number;
command: "node.check_route_health";
targetNodeId: number;
rounds?: number;
}
Get endpoint count
[compatible with schema version: 14+]
interface {
messageId: string;
nodeId: number;
command: "node.get_endpoint_count";
}
Set name
[compatible with schema version: 14+]
interface {
messageId: string;
nodeId: number;
command: "node.set_name";
updateCC?: boolean = true;
}
Set location
[compatible with schema version: 14+]
interface {
messageId: string;
nodeId: number;
command: "node.set_location";
updateCC?: boolean = true;
}
Set keep awake
[compatible with schema version: 14+]
interface {
messageId: string;
nodeId: number;
command: "node.set_keep_awake";
}
Is Firmware Update In Progress
[compatible with schema version: 21+]
interface {
messageId: string;
nodeId: number;
command: "node.is_firmware_update_in_progress";
}
Wait for wakeup
[compatible with schema version: 18+]
interface {
messageId: string;
nodeId: number;
command: "node.wait_for_wakeup";
}
Interview
[compatible with schema version: 22+]
interface {
messageId: string;
nodeId: number;
command: "node.interview";
}
Get value timestamp
[compatible with schema version: 27+]
interface {
messageId: string;
command: "node.get_value_timestamp";
nodeId: number;
valueId: {
commandClass: CommandClasses;
endpoint?: number;
property: string | number;
propertyKey?: string | number;
};
}
Manually Idle Notification CC Value
[compatible with schema version: 39+]
This can be called in one of two ways:
Method 1:
interface {
messageId: string;
command: "node.manually_idle_notification_value";
valueId: ValueID;
}
Method 2:
interface {
messageId: string;
command: "node.manually_idle_notification_value";
nodeId: number;
notificationType: number;
prevValue: number;
endpointIndex?: number;
}
Set date and time
[compatible with schema version: 30+]
interface {
messageId: string;
command: "node.set_date_and_time";
nodeId: number;
date?: string; // use ISO 8601 date string format
}
Get date and time
[compatible with schema version: 31+]
interface {
messageId: string;
command: "node.get_date_and_time";
nodeId: number;
}
Is Health Check In Progress
[compatible with schema version: 31+]
interface {
messageId: string;
command: "node.is_health_check_in_progress";
nodeId: number;
}
Abort Health Check
[compatible with schema version: 31+]
interface {
messageId: string;
command: "node.abort_health_check";
nodeId: number;
}
Set Default Volume
[compatible with schema version: 31+]
interface {
messageId: string;
command: "node.set_default_volume";
nodeId: number;
defaultVolume?: number;
}
Set Default Transition Duration
[compatible with schema version: 31+]
interface {
messageId: string;
command: "node.set_default_transition_duration";
nodeId: number;
defaultTransitionDuration?: string; // Will be converted to a Duration object
}
Has Device Config Changed
[compatible with schema version: 31+]
interface {
messageId: string;
command: "node.has_device_config_changed";
nodeId: number;
}
Set Raw Config Parameter Value
[compatible with schema version: 33+]
interface {
messageId: string;
command: "node.set_raw_config_parameter_value";
nodeId: number;
parameter: number;
bitMask?: number;
value: ConfigValue;
valueSize?: 1 | 2 | 4; // valueSize and valueFormat should be used together.
valueFormat?: ConfigValueFormat;
}
Dump node debug data
[compatible with schema version: 36+]
interface {
messageId: string;
command: "node.create_dump";
}
Endpoint level commands
Invoke a Command Classes API method
[compatible with schema version: 7+]
You can find all of the CC API methods in the Z-Wave JS docs.
Example: Invoking UserCodeCC.set
Send the following JSON to the server to invoke UserCodeCC.set(1, UserIDStatus.Enabled, "1234")
:
{
"messageId": "invoke-usercode-cc-set",
"command": "endpoint.invoke_cc_api",
"nodeId": 2,
"endpoint": 1,
"commandClass": 99, // commandClass = CommandClasses["User Code"]
"methodName": "set",
"args": [
1, // userId = 1
1, // userIdStatus = UserIDStatus.Enabled
"1234", // userCode = "1234"
],
}
interface {
messageId: string;
command: "endpoint.invoke_cc_api";
nodeId: number;
endpoint?: number;
commandClass: CommandClasses;
methodName: string;
args: unknown[];
}
For Buffer
type arguments, use the following JSON format to represent the argument:
{
"type": "Buffer",
"data": [], // array of numbers
}
Check whether a given Command Classes API is supported by the above method
[compatible with schema version: 7+]
interface {
messageId: string;
command: "endpoint.supports_cc_api";
nodeId: number;
endpoint?: number;
commandClass: CommandClasses;
}
Check whether endpoint supports a given Command Class
[compatible with schema version: 23+]
interface {
messageId: string;
command: "endpoint.supports_cc";
nodeId: number;
endpoint?: number;
commandClass: CommandClasses;
}
Check whether endpoint controls a given Command Class
[compatible with schema version: 23+]
interface {
messageId: string;
command: "endpoint.controls_cc";
nodeId: number;
endpoint?: number;
commandClass: CommandClasses;
}
Check whether a given Command Class is secure
[compatible with schema version: 23+]
interface {
messageId: string;
command: "endpoint.is_cc_secure";
nodeId: number;
endpoint?: number;
commandClass: CommandClasses;
}
Check version of a given Command Class
[compatible with schema version: 23+]
interface {
messageId: string;
command: "endpoint.get_cc_version";
nodeId: number;
endpoint?: number;
commandClass: CommandClasses;
}
Get node from endpoint
[compatible with schema version: 40+]
interface {
messageId: string;
command: "endpoint.try_get_node";
nodeId: number;
endpoint?: number;
}
[compatible with schema version: 23+]
interface {
messageId: string;
command: "endpoint.get_node_unsafe";
nodeId: number;
endpoint?: number;
}
Get Raw Config Parameter Value
[compatible with schema version: 39+]
interface {
messageId: string;
command: "node.get_raw_config_parameter_value";
nodeId: number;
parameter: number;
bitMask?: number;
}
interface {
messageId: string;
command: "endpoint.get_raw_config_parameter_value";
nodeId: number;
endpoint?: number;
parameter: number;
bitMask?: number;
}
Set Raw Config Parameter Value
[compatible with schema version: 33+]
interface {
messageId: string;
command: "node.set_raw_config_parameter_value";
nodeId: number;
parameter: number;
bitMask?: number;
value: ConfigValue;
valueSize?: 1 | 2 | 4; // valueSize and valueFormat should be used together.
valueFormat?: ConfigValueFormat;
}
interface {
messageId: string;
command: "endpoint.set_raw_config_parameter_value";
nodeId: number;
endpoint?: number;
parameter: number;
bitMask?: number;
value: ConfigValue;
valueSize?: 1 | 2 | 4; // valueSize and valueFormat should be used together.
valueFormat?: ConfigValueFormat;
}
Multicasting
There are several commands available that can be multicast to multiple nodes simultaneously. If you would like to broadcast to all nodes, use the broadcast_node
prefix for the following commands. If you would like to multicast to a subset of nodes, use the multicast_group
prefix for the following commands, adding a nodeIDs
list as an input parameter:
interface IncomingCommandMulticastGroupBase extends IncomingCommandBase {
nodeIDs: number[];
}
As an example, here's how you would call the set_value
command for a multicast group (note the extra nodeIDs
input parameter):
interface {
messageId: string;
command: "multicast_group.set_value";
nodeIDs: number[];
valueId: {
commandClass: CommandClasses;
endpoint?: number;
property: string | number;
propertyKey?: string | number;
};
value: any;
options?: SetValueAPIOptions;
}
Set value
[compatible with schema version: 5+]
interface {
messageId: string;
command: "<prefix>.set_value";
valueId: {
commandClass: CommandClasses;
endpoint?: number;
property: string | number;
propertyKey?: string | number;
};
value: any;
options?: SetValueAPIOptions;
}
Get endpoint count
[compatible with schema version: 5+]
interface {
messageId: string;
command: "<prefix>.get_endpoint_count"
}
Check if endpoint supports a Command Class
[compatible with schema version: 5+]
interface {
messageId: string;
command: "<prefix>.supports_cc"
index: number
commandClass: CommandClasses
}
Get Command Class version on an endpoint
[compatible with schema version: 5+]
interface {
messageId: string;
command: "<prefix>.get_cc_version"
index: number
commandClass: CommandClasses
}
Invoke a Command Class specific API
[compatible with schema version: 5+]
interface {
messageId: string;
command: "<prefix>.invoke_cc_api"
index?: number; // Endpoint index
commandClass: CommandClasses;
methodName: string;
args: unknown[];
}
Check if a Command Class is supported by invoke_cc_api
[compatible with schema version: 5+]
interface {
messageId: string;
command: "<prefix>.get_cc_version"
index?: number; // Endpoint index
commandClass: CommandClasses;
}
Get defined value IDs
[compatible with schema version: 11+]
interface {
messageId: string;
command: "<prefix>.get_defined_value_ids"
}
Utility commands
zwave-js-server
supports all of the utility methods listed in the Z-Wave JS documentation. zwave-js-server
uses snake casing for commands and prefixes every controller command with utils.
, so parseQRCodeString
is called using the utils.parse_qr_code_string
command.
NOTE: While some string utility commands like
num2hex
,buffer2hex
, etc. are made available in the server due to their availability within the driver, this functionality works best when implemented locally and should not be used over WebSocket for any practical purpose.
Config manager commands
zwave-js-server
supports all of the config manager methods listed in the Z-Wave JS documentation. zwave-js-server
uses snake casing for commands and prefixes every controller command with config_manager.
, so lookupDevice
is called using the config_manager.lookup_device
command.
Zniffer commands
zwave-js-server
enables applications to interact with a Zniffer, and once started all events will be forwarded to clients. Note that the server deviates from the Z-Wave JS API slightly. See a description of the commands below.
Initialize Zniffer
Initialize the Zniffer. Security keys and log config will match what's configured for the driver, but all other zniffer options are configurable.
[compatible with schema version: 38+]
interface {
messageId: string;
command: "zniffer.init";
devicePath: "/path/to/device";
options: Omit<ZnifferOptions, "logConfig" | "securityKeys" | "securityKeysLongRange">;
}
Start Zniffer
Start the Zniffer. Must have initialized the Zniffer first.
[compatible with schema version: 38+]
interface {
messageId: string;
command: "zniffer.start";
}
Stop Zniffer
Stop the Zniffer instance.
[compatible with schema version: 38+]
interface {
messageId: string;
command: "zniffer.stop";
}
Destroy Zniffer
Destroy the Zniffer instance.
[compatible with schema version: 38+]
interface {
messageId: string;
command: "zniffer.destroy";
}
Get captured frames
Return list of captured frames.
[compatible with schema version: 38+]
interface {
messageId: string;
command: "zniffer.captured_frames";
}
Clear captured frames
Clear all captured frames.
[compatible with schema version: 38+]
interface {
messageId: string;
command: "zniffer.clear_captured_frames";
}
Get captured frames as ZLF Buffer
Returns captured frames in the ZLF file format as a JSON stringified Buffer.
[compatible with schema version: 38+]
interface {
messageId: string;
command: "zniffer.get_capture_as_zlf_buffer";
}
Get supported frequencies
Gets list of supported frequencies and their names.
[compatible with schema version: 38+]
interface {
messageId: string;
command: "zniffer.supported_frequencies";
}
Get current frequency
Gets list of current frequency.
[compatible with schema version: 38+]
interface {
messageId: string;
command: "zniffer.current_frequency";
}
Set frequency
Set Zniffer frequency.
[compatible with schema version: 38+]
interface {
messageId: string;
command: "zniffer.set_frequency";
frequency: number;
}
Events
zwave-js
Events
All zwave-js
events as documented are forwarded on to clients that have sent the start_listening
command.
interface {
type: "event";
event: {
source: "driver" | "controller" | "node" | "zniffer";
event: string;
... // Additional parameters dependent on the event, see zwave-js docs for more details
}
}
zwave-js-server
Node Events
test powerlevel progress
This event is sent after a node.test_powerlevel
command is issued and contains test results from the driver. See the zwave-js
docs on this command for more information.
interface {
type: "event";
event: {
source: "node";
event: "test powerlevel progress";
nodeId: number;
acknowledged: number;
total: number;
}
}
check lifeline health progress
This event is sent after a node.check_lifeline_health
command is issued and contains test results from the driver. See the zwave-js
docs on this command for more information.
interface {
type: "event";
event: {
source: "node";
event: "check lifeline health progress";
nodeId: number;
round: number;
totalRounds: number;
lastRating: number;
}
}
check route health progress
This event is sent after a node.check_route_health
command is issued and contains test results from the driver. See the zwave-js
docs on this command for more information.
interface {
type: "event";
event: {
source: "node";
event: "check route health progress";
nodeId: number;
rounds: number;
totalRounds: number;
lastRating: number;
}
}
zwave-js-server
Driver Events
driver ready
This event is sent whenever a the driver indicates it is ready to be used, e.g. after a hard reset.
interface {
type: "event";
event: {
source: "driver";
event: "driver ready";
}
}
log config updated
This event is sent whenever a client issues the driver.update_log_config
command with the updated log config.
interface {
type: "event";
event: {
source: "driver";
event: "log config updated";
config: Partial<LogConfig>; // Includes everything but `transports`
}
}
logging
This event is sent whenever zwave-js
logs a statement. Clients will only receive these events when they have issued the driver.start_listening_logs
command.
interface {
type: "event";
event: {
source: "driver";
event: "logging";
formattedMessage: string;
direction: string;
primaryTags?: string;
secondaryTags?: string;
secondaryTagPadding?: number;
multiline?: boolean;
timestamp?: string;
label?: string;
message: string | string[];
}
}
zwave-js-server
Controller Events
grant security classes
This event is sent as part of the node inclusion process (including when replacing a failed node). The event indicates to the client that the user needs to choose which security classes to grant the node.
interface {
type: "event";
event: {
source: "controller";
event: "grant security classes";
requested: InclusionGrant;
}
}
validate dsk and enter pin
This event is sent as part of the node inclusion process (including when replacing a failed node). The event indicates to the client that the user needs to confirm the provided DSK is valid and enter the PIN from the device.
interface {
type: "event";
event: {
source: "controller";
event: "validate dsk and enter pin";
dsk: string;
}
}
inclusion aborted
This event is sent as part of the node inclusion process (including when replacing a failed node). The event indicates to the client that the controller aborted the security bootstrapping process (this will occur after inclusion has already been successful). The logs may have more details on why this security bootstrapping process was aborted.
interface {
type: "event";
event: {
source: "controller";
event: "inclusion aborted";
}
}
nvm backup progress
This event is sent on progress updates to the NVM backup process when the controller.backup_nvm_raw
command is issued by a client to the server and a backup is in progress.
interface {
type: "event";
event: {
source: "controller";
event: "nvm backup progress";
bytesRead: number;
total: number;
}
}
nvm backup progress
This event is sent on progress updates to the NVM conversion process when the controller.restore_nvm
command is issued by a client to the server and the NVM file that was passed in is being converted to the right format.
interface {
type: "event";
event: {
source: "controller";
event: "nvm backup progress";
bytesRead: number;
total: number;
}
}
nvm restore progress
This event is sent on progress updates to the NVM restoration process when the controller.restore_nvm
command is issued by a client to the server and the NVM data is being restored to the controller.
interface {
type: "event";
event: {
source: "controller";
event: "nvm backup progress";
bytesWritten: number;
total: number;
}
}
Schema Version
In an attempt to keep compatibility between different server and client versions, we've introduced a (basic) API Schema Version.
-
client connects --> server sends back version info including the schema versions it can handle:
{ "type": "version", "driverVersion": "6.5.0", "serverVersion": "1.0.0", "homeId": 3967882672, "minSchemaVersion": 0, "maxSchemaVersion": 1 }
-
Client decides what to do based on supported schema version. For example drop connection if the supported server schema is too old or just handle the supported schema itself. For example most/all basic commands will just work but relatively new commands won't and the client decides to only not handle the stuff in the upgraded schema.
-
Client needs to tell the server what schema it wants to use. This is done with the "set_api_schema" command:
{ "command": "set_api_schema", "messageId": 1, "schemaVersion": 1 }
From this moment the server knows how to treat commands to/from this client. The server can handle multiple clients with different schema versions.
-
By default the server will use the minimum schema it supports (which is 0 at this time) if the
set_api_schema
command is omitted. -
If the client sends a schema version which is out of range, this will produce an error to the client and in the server's log:
{ "command": "set_api_schema", "messageId": 1, "schemaVersion": 3 } {"type":"result","success":false,"messageId":1,"errorCode":"schema_incompatible"}
-
When we make breaking changes in the api, we bump the schema version. When adding new commands/features, we also bump the api schema and note in both code comments and documentation to which schema version that feature is compatible with.
Errors
If a command results in an error, the following response is returned:
{
"type": "result",
"success": false,
"messageId": 1,
"errorCode": "schema_incompatible"
}
The following error codes exist:
code | description |
---|---|
unknown_command | Unknown command |
node_not_found | Node not found |
schema_incompatible | Incompatible Schema |
zwave_error | Error from Z-Wave JS |
unknown_error | Unknown exception |
In the case of zwave_error
, the extra keys zwaveErrorCode
and zwaveErrorMessage
will be added.
{ "type": "result", "success": false, "messageId": 1, "errorCode": "zwave_error", "zwaveErrorCode": 18, "zwaveErrorMessage": "The message cannot be sent because node 61 is dead" }
Authentication
Z-Wave JS Server does not handle authentication and allows all connections to the websocket API. If you want to add authentication, add authentication middleware to your Express instance or run NGINX in front of Express instance.