node-openzwave
This is a node.js add-on which wraps the Open Z-Wave library to provide access to a Z-Wave network from JavaScript.
It is currently able to scan a Z-Wave network, report on connected devices, monitor the network for changes, and has rudimentary write support.
Install
The module currently builds only on OS X and Linux. On Linux you will need to ensure the libudev headers are installed first.
$ npm install openzwave
API
Start by loading the addon and creating a new instance, specifying a path to the USB device:
var OZW = ;var zwave = '/dev/ttyUSB0';
An optional object can be passed at creation time to alter the behavior of the ZWave module. The options currently supported and their defaults are:
var zwave = '/dev/ttyUSB0' logging: false // enable logging to OZW_Log.txt consoleoutput: false // copy logging to the console saveconfig: false // write an XML network layout driverattempts: 3 // try this many times before giving up pollinterval: 500 // interval between polls in milliseconds suppressrefresh: true // do not send updates if nothing changed;
The rest of the API is split into Functions and Events. Messages from the
Z-Wave network are handled by EventEmitter
, and you will need to listen for
specific events to correctly map the network.
Functions
Connecting to the network:
zwave; // initialise and start a new driver.zwave; // disconnect from the current connection
Modifying device state:
/* * Set a multi-level device to the specified level (between 0-99). */zwave; /* * Turn a binary switch on/off. */zwave;zwave; /* * Set arbitrary values. */zwave;
Writing to device metadata (stored on the device itself):
zwave; // arbitrary location stringzwave; // arbitrary name string
Polling a device for changes (not all devices require this):
zwave;zwave;
Reset the controller. Calling hardReset
will clear any associations, so use
carefully:
zwave; // destructive! will wipe out all known configurationzwave; // non-destructive, just resets the chip
Events
The supported events are:
.on('connected', function(){})
We have connected to an OpenZWave node.
.on('driver ready', function(homeid){})
The OpenZWave driver has initialised and scanning has started. Returns a
unique homeid
which identifies this particular network.
.on('driver failed', function(){})
The OpenZWave driver failed to initialise.
.on('node added', function(nodeid){})
A new node has been found on the network. At this point you can allocate resources to hold information about this node.
.on('value added', function(nodeid, commandclass, value){})
A new value has been discovered. Values are associated with a particular node, and are the parts of the device you can monitor or control.
Values are split into command classes. The classes currently supported and their unique identifiers are:
COMMAND_CLASS_SWITCH_BINARY
(37)COMMAND_CLASS_SWITCH_MULTILEVEL
(38)COMMAND_CLASS_VERSION
(134)
Binary switches can be controlled with .switchOn()
and .switchOff()
.
Multi-level devices can be set with .setLevel()
.
The version class is informational only and cannot be controlled.
The value
object differs between command classes, and contains all the useful
information about values stored for the particular class.
.on('value changed', function(nodeid, commandclass, value){})
A value has changed. Use this to keep track of value state across the network. When values are first discovered, the module enables polling on those values so that we will receive change messages.
Prior to the 'node ready' event, there may be 'value changed' events even when no values were actually changed.
.on('value removed', function(nodeid, commandclass, index){})
A value has been removed. Use the index to calculate the offset where a command class can contain multiple values.
.on('node ready', function(nodeid, nodeinfo){})
A node is now ready for operation, and information about the node is available
in the nodeinfo
object:
nodeinfo.manufacturer
nodeinfo.product
nodeinfo.type
nodeinfo.loc
(location, renamed to avoidlocation
keyword).
.on('scan complete', function(){})
The initial network scan has finished.
Example
The test program below connects to a Z-Wave network, scans for all nodes and
values, and prints out information about the network. It will then continue to
scan for changes until the user hits ^C
.
/* * OpenZWave test program. */ var OpenZWave = ; var zwave = '/dev/ttyUSB0' saveconfig: true;var nodes = ; zwave; zwave; zwave; zwave; zwave; zwave; zwave; zwave; zwave; zwave; process;
Sample output from this program:
$ node test.js 2>/dev/nullscanning homeid=0x161db5f...node1: Aeon Labs, Z-Stick S2node1: name="", type="Static PC Controller", location=""node1: class 32node1: Basic=0node11: Everspring, AD142 Plug-in Dimmer Modulenode11: name="", type="Multilevel Power Switch", location=""node11: class 32node11: class 38node11: Level=89node11: Bright=undefinednode11: Dim=undefinednode11: Ignore Start Level=truenode11: Start Level=0node11: class 39node11: Switch All=3073node11: class 115node11: Powerlevel=3073node11: Timeout=0node11: Set Powerlevel=undefinednode11: Test Node=0node11: Test Powerlevel=3072node11: Frame Count=0node11: Test=undefinednode11: Report=undefinednode11: Test Status=3072node11: Acked Frames=0node11: class 117node11: Protection=3072node11: class 134node11: Library Version=4node11: Protocol Version=2.64node11: Application Version=1.02node12: Wenzhou TKB Control System, product=0103, type=0101node12: name="", type="Binary Power Switch", location=""node12: class 32node12: class 37node12: Switch=truenode12: class 39node12: Switch All=3161node12: class 134node12: Library Version=6node12: Protocol Version=3.40node12: Application Version=1.04node13: Wenzhou TKB Control System, product=0103, type=0101node13: name="", type="Binary Power Switch", location=""node13: class 32node13: class 37node13: Switch=truenode13: class 39node13: Switch All=3073node13: class 134node13: Library Version=6node13: Protocol Version=3.40node13: Application Version=1.04node10: Popp / Duwi, ZW ESJ Blind Controlnode10: name="", type="Multiposition Motor", location=""node10: class 32node10: class 37node10: Switch=truenode10: class 38node10: Level=99node10: Bright=undefinednode10: Dim=undefinednode10: Ignore Start Level=truenode10: Start Level=0node10: class 39node10: Switch All=3073node10: class 117node10: Protection=3073node10: class 134node10: Library Version=6node10: Protocol Version=2.51node10: Application Version=1.00node10: class 135node10: Indicator=0scan complete, hit ^C to finish.^Cdisconnecting...
Remove 2>/dev/null
to get verbose output of all incoming notification types
and additional debug information.
License
The Open Z-Wave library that this module heavily relies upon is licensed under the LGPLv3.
Everything else (all the bits that I have written) is under the vastly more sensible ISC license.