Develop Code for Z-Way

The Z-Wave device API only allows the management of the Z-Wave network and the control and management of the devices as such. No higher order logic except the so-called Z-Wave associations between two Z-Wave devices can be used.

For all automation and higher order logic a JavaScript automation engine is available. This engine is also shipped with Z-Way.

The JavaScript API on top of the JS engine mirrors all functions of the Z-Wave Device API but also allows access to third-party device APIs (e.g. EnOcean). This means the JS API is the common ground for all further application logic and user interfaces (with the exception of the Z-W AVE E XPERT U SER I NTERFACE that uses the Z-Wave Device API.

The JavaScript layer makes use of a JavaScript implementation provided by Google it is also used in Googles Chrome web browser. All JavaScript API functions can also be accessed using the embedded webserver. The beauty of this interface is that JavaScript can be executed on the server and on the client. Executing on the client makes sense for small changes to the data model or running small helper programs.

There are two important sub-portions of the JavaScript layer:


Z-Wave Device API

The Z-Wave Device API implements the direct access to the Z-Wave network. All Z-Wave devices are referred to by their unique identification in the wireless network—the Node ID. Z-Wave devices may have different instances of the same function, also called channels (for example sockets in a power strip). The Z-Wave Device API refers to them as daughter objects of the physical device object identified by an instance ID. In case there is only one instance, the instance is used.

All device variables and available commands in a Z-Wave device are grouped in the so-called command classes. The Z-Wave API allows direct access to all parameters, values and commands of these command class structures. Annex gives you the complete reference of the implemented command classes.

Beside the devices the Z-Wave Device API also offers access to the management interface of the network. Annex gives you a full reference of the implemented function classes.

The Z-Wave Device API can be accessed on the JSON API with any standard web browser using the URL

Device objects or commands of these objects are accessed by

The whole data tree of the Z-Wave network is accessed using

Please refer to the Z-Way for information about the context, the commands, and the data used. Section 11.3 provides more information about the API and the underlying data structure.

All acces ot the webserver require authentication of the user. Please refer to Chapter 13.1 for details how to authenticate.

The Z-Wave Device API or any other third-party technology API do not offer any higher order logic support but the pure access to functions and parameters of devices only.

Z-Way offers an automation engine to overcome this restriction. A server-side JavaScript runtime environment allows writing JavaScript modules that are executed within Z-Way (means on the server). The same time all functions of the JS API can also be accessed on the client side (the web browser). This offers some cool debug and test capabilities. Among others it is possible to write whole JS functions right into the URL or the browser.

The JS API can be accessed from the web browser with the URL

Among others the whole Z-Wave Device API is available within the JS API using the object “zway’‘. As a result, the following three statements refer to the very same function:

  1. http://YOURIP:8083/ZWaveAPI/Run/devices[3].* Client Side URL access using the Z-Wave Device API.
  2. http://YOURIP:8083/JS/Run/zway.devices[3].* : Client Side URL access using the JS API
  3. zway.devices[3].* : Server Side access using the JS and the public zway object

Due to the scripting nature of JavaScript it is possible to “inject’‘ code at run time using the interface. Here a nice example how to use the JavaScript setInterval function:

[Polling of device \#2] /JS/Run/setInterval(function() < zway.devices[2].Basic.Get(); >, 300*1000);

This code will, once “executed’‘ as URL within a web browser, call the Get() command of the command class Basic of Node ID 2 every 300 seconds.

A very powerful function of the JS API is the ability to bind functions to certain values of the device tree. They get then executed when the value changes. Here is an example for this binding. The device No. 3 has a command class SensorMultilevel that offers the variable “level.’’ The following call—both available on the client side and on the server side—will bind a simple alert function to the change of the variable.

[Bind a function] zway.devices[3].SensorMultilevel.data[1].val.bind( function() < debugPrint('CHANGED TO:' + this.value + '\n'); >);

Chapter 11.3 and 11.3.1 describe the whole JS API in detail. The names and IDs of the different command classes as well as their instance variables can be found in the Annex .

JavaScript modules can and will generate new functions that are accessible using the JSON interface. For simplification function calls on the API (means on the client side) are written in URL style starting with the word “ZAutomation’’:

/ZAutomation/JSfunction/JParameter == JSfunction(JParameter)

All functions and instances of a physical device, which are represented as daughter objects in the Z-Wave Device API, are enrolled into individual virtual devices.

In case the Z-Wave API shows one single physical device with two channels, the Virtual Device API will show two devices with similar functionality. In case the Z-Wave API shows a physical device with several functions (like a binary switch and an analog sensor in one device), the Virtual Device API (vDev API) will show them as several devices with one function each.

The vDev is accessed using the JSON API in a slightly different style than zDev API. All devices, variables, and commands are encoded into a URL style for easier handling in AJAX code. A typical client-side command in the vDev API looks like

“API’’ points to the vDev API function, “v1’’ is just a constant to allow future extensions. The devices are referred to by a name that is automatically generated from the Z-Wave Device API. The vDev also unifies the commands “command’’ and the parameters, here “off.’’

On the server side, the very same command would be encoded in a JavaScript style.

[Bind a function] dev = this.controller.devices.get('ZWayVDev\_6:0:37'); dev.command('off');

The vDev API also offers support for notifications, locations information, the use of other modules, etc.

Table 11.1 summarizes the functions of the different APIs.

Table 11.1: Different APIs of the Z-Way system
API Type Core Function Network Management Automation
Z-Wave Dev API (JSON) Access to physical network and physical devices via JSON Yes No
Z-Wave Dev API (C lib) Access to physical network and physical devices via C style calls Yes No
JavaScript API Access to physical network and devices plus JS type functions No Yes, via zDev
vDev API Unified Access to functions of devices, optimized for AJAX GUI No Yes


The Z-Wave Device (JSON) API in detail

This chapter describes the Z-Wave Device API and its use in detail All examples will use the HTTP/JSON API notation. Please note that the C library notation offers equal functionality.

The Z-Wave Device API is the north-bound interface of the Z-Wave Core. This Z-Wave core implement the whole control logic of the Z-Wave network. The two main functions are

The description of function classes and command Cclasses and their access using the JSON API complete the description of the Z-Wave Device API. For a full reference of function classes and command classes please refer to the Annex and .


The data model

Z-Way holds all data of the Z-Way network in a data holder structure. The data holder structure is a hierarchical tree of data elements.

Following the object-oriented software paradigm the different commands targeting the network or individual devices are also embedded into the data objects as object methods.

Each data element is handled in a data object that contains the data element and some contextual data.

Every time a command is issued that will have impact on a certain data holder value the time of the request is stored in "invalidateTime". This allows tracking when a new data value is requested from the network and when this new data value is provided by the network.

This is particularly true if Z-Way is sending a SET command. In this case the data value is invalidated with the "SET" commands and gets validated back when the result of the GET command was finally stored in the data model.

To maintain compatibility with JavaScript the data object has the following methods implemented:

These aliases are not enumerated if the dataholder is requested (data.level returns value: 255, name: "level", updatedTime: 12345678, invalidatedTime: 12345678).

Figure 11.2: Z-Way Object Tree Structure

Please note that all status variables accessible on the Z-Wave Device APIs are only proxy of the real value in the network.

To transport data between the real wireless device and the GUI multiple communication instances are involved. The complexity of this communication chain will be explained in the following example:

Figure 11.3: Z-Way Timings

Assuming the GUI shows the status of a remote switch and allows changing the switching state of this device. When the user hits the switching button, he expects to see the result of his action as a changing status of the device in the GUI. The first step is to hand over the command (SET) from the GUI to Z-Way using the JSON interface. Z-Way receives the command and will confirm the reception to the GUI. Z-Way recognizes that the execution of the switching command will likely result in a change of the status variable However Z-Way will not immediately change the status variable but invalidate the actual value (mark as outdated). This is the correct action because at the moment when the command was received the status on the remote device has not been changed yet but the status of the switch is now unknown. If the GUI polls the value it will still see the old value but marked as invalid. Z-Way will now hand over the switching command to the Z-Wave transceiver chip. Since it is possible that there are other command waiting for execution (sending) by the Z-Wave transceiver chip the job queue is queuing them and will handle certain priorities if needed. Z-Way has recognized that the command will likely change the status of the remote device and is therefore adding another command to call the actual status after the switching command was issued. The transceiver is confirming the reception of the command and this confirmation is noted in the job queue. This confirmation however only means that the transceiver (Z-Wave chip) has accepted the command and does neither indicate that the remote device has receives it nor even confirming that the remote device has executed accordingly. The transceiver will now try to send the command wirelessly to the remote device. A successful confirmation of the reception from the remote device is the only valid indicator that the remote device has received the command (again, not that it was executed!). The second command (GET) is now transmitted the very same way and confirmed by the remote device. This device will now sent a REPORT command back to Z-Way reporting the new status of the switching device. Now the transceiver has to confirm the reception. The transceiver will then send the new value to the Z-Way engine by issuing commands via the serial interface. Z-Way receives the report and will update the switching state and validate the value. From now on the GUI will receive a new state when polling.


Executing Commands

JSON API allows executing commands on the server side using HTTP POST or GET requests. The command to execute is taken from the URL.

All functions are executed in form

The best way to learn about the commands and the data is to use the Z-W AVE E XPERT U SER I NTERFACE plus a JavaScript Debugger to see the command the AJAX code of the Z-W AVE E XPERT U SER I NTERFACE sends to the Z-Way server backend. Additionally the Z-Wave Expert User Interface provides nice and convenient vizualization of all commends (both command classes and function classes).

All access to the webserver require authentication of the user. Please refer to Chapter 13.1 for details how to authenticate.

Figure 11.4: Z-Way Function Classes

Figure 11.4 shows the Controller Info Page in Network menu with a list of all function classes implemented. The complete reference of the parameters and return values of the functions classes you find in annex .

Assuming there is a function class “SerialAPIGetInitData’’ it is possible to call the function by calling the URL

in the web browser. In case the function was completed successfully, a simple “null’’ is returned; otherwise, an error code is provided.

Figure 11.5: Z-Way Expert Command Class Commands

In the same manner, it is possible to send a command to a device using one of its command classes. The Z-W AVE E XPERT U SER I NTERFACE provides a general menu item called Expert Commands as shown in Figure 11.5. Z-Way reads out all command classes and its functions and provides here a complete list of command lass-specific commands. The debug window will reveal the syntax if the complete command class reference in Annex is not available or too inconvenient to use.

For example, to switch ON a device no 2 using the command class BASIC, it is possible to write:

/ZWaveAPI/Run/devices[2].instances[0].commandClasses[0x20].Set(255)
/ZWaveAPI/Run/devices[2].instances[0].Basic.Set(255)

The Z-W AVE E XPERT U SER I NTERFACE has a JavaScript command

to simplify such operations. This function is accessible in the JavaScript console of your web browser (in Chrome you find the JavaScript console under View- > Debug- > JS Console). Using this feature, the command in JS console would look like

runCmd('devices[2].instances[0].Basic.Set(255)')

The usual way to access a command class is using the format
'devices[nodeId].instances[instanceId]. commandClasses[commandclassId]'. There are ways to simplify the syntax:

The data model or data holder object as described is Section 11.3.1 can be accessed completely using the Z-W AVE E XPERT U SER I NTERFACE . The two buttons Show controller Data and Show controllers device data in Network > Controller Info of Z-W AVE E XPERT U SER I NTERFACE as shown in Figure 11.4 lists all variables of the controller as such. One structure is controller-specific and one other structure is the data of the controller as node of the Z-Wave network. All nodes of the Z-Wave network have the very same data structure beside their individual array of instances and command classes per instance. This data model for the individual devices can be access using Configuration > Show Interview results in Z-W AVE E XPERT U SER I NTERFACE . Figure 11.6 shows this dialog. On the top of the window there is a button with the devices name. This button reveals the data structure of the individual device as shown in Figure 11.7.

Figure 11.6: Command Class Inerview overview Figure 11.7: Command Class Variables in Z-W AVE E XPERT U SER I NTERFACE

The dialog has the list of all command classes and clicking on the name of the command class will open a sub dialog showing the data of the commend class. Each command class has some permanent values:

Any data holder object has properties value, updateTime, invalidateTime, name, but for compatibility with JS and previous versions we have valueOf() method (allows omitting .value in JS code, hence write "data.level == 255"), updated (alias to updateTime), invalidated (alias to invalidateTime).

Returns an associative array of changes in Z-Way data tree since < timestamp >. The array consists of ( < path >: < JSON object >) object pairs. The client is supposed to assign the new < JSON object >to the subtree with the < path >discarding previous content of that subtree. Zero (0) can be used instead of < timestamp >to obtain the full Z-Way data tree.

The tree have same structure as the backend tree (Figure 11.2) with one additional root element "updateTime" which contains the time of latest update. This "updateTime" value should be used in the next request for changes. All timestamps (including updateTime) corresponds to server local time.

The object looks like:

[JSON Data Structure] \

Examples for Commands to update the data tree look like:

Get all data: /ZWaveAPI/Data/0
Get updates since 134500000 (Unix timestamp): /ZWaveAPI/Data/134500000

Please note that during data updates some values are updated by big subtrees. For example, in Meter Command Class value of a scale is always updated as a scale subtree by [scale].val object (containing scale and type descriptions).

This function is used to visualize the Z-Way job queue. This is for debugging only but very useful to understand the current state of Z-Way engine.

The information given on this page is only relevant for advanced Z-Wave developers and for debugging.

The table shows the active jobs with their respective status and additional information.

Table 11.2: Parameters of the Job Queue Vizualization
n This column shows the number of sending attempts for a specific job. Z-Way tries three times to dispatch a job to the transceiver.
W,S,D: This shows the status of the job. If no indicator is shown the job is in active state. This means that the controller just tries to execute the job. “W’’ states indicated that the controller believes that the target device of this job is in deep sleep state. Jobs in “W’’ state will remain in the queue to the moment when the target device announces its wakeup state by sending a wakeup notification to the controller. Jobs in “S’’ state remain in the waiting queue to the moment the security token for this secured information exchanged was validated. “D’’ marks a job as done. The job will remain in the queue for information purposes until a job garbage collection removed it from the queue.
ACK: shows if the Z-Wave transceiver has issued an ACK message to confirm that the message was successfully received by the transceiver. This ACK however does not confirm that the message was delivered successfully. A successful delivery of a message will result in a “D” state of this particular job. If the ACK field is blank, then no ACK is expected. A “.” indicates that the controller expects an ACK but the ACK was not received yet. A “+” indicates that an ACK was expected and was received.
RESP shows if a certain command was confirmed with a valid response. Commands are either answered by a response or a callback. If the RESP field is blank, then no response is expected. A “.’’ indicates that the controller expects a response, but the response has not been received yet. A “+’’ indicates that a response was expected and has been received.
Cbk If the Cbk field is blank, then no callback is expected. A “.” indicates that the controller expects a Callback but the Callback was not received yet. A “+” indicates that a Callback was expected and was received.
Timeout Shows the time left until the job is de queued
Node Id shows the ID of the target node. Communication concerning the network, like inclusion of new nodes, will have the controller nodeID as a target node ID. For command classes command the node ID of the destination Node is shown. For commands directed to control the network layer of the protocol, the nodeID is zero.
Description shows a verbal description of the job
Progress shows a success or error message depending on the delivery status of the message. Since Z-Way tries three times to deliver a job up to 3 failure messages may appear. Buffer: It shows the hex values of the command sent within this job

Table 11.2 summarizes the different values displayed on the Job Queue visualization. While this info is certainly not relevant for end users of the system it is a great debug tool.

A good design of a user interface is linking UI objects (label, textbox, slider, . ) to a certain path in the tree object. Any update of a subtree linked to user interface will then update the user interface too. This is called bindings.

For web applications Z-Way contains a library called jQuery.triggerPath (extention of jQuery written by Z-Wave.Me), that allows making such links between objects in the tree and HTML DOM objects. Use

jQuery.triggerPath.init(tree);

during web application initialization to attach the library to a tree object. Then run

jQuery([objects selector]).bindPath([path with regexp], [updater function], [additional arguments]);

to make binding between path changes and updater function. The updater function would be called upon changes in the desired object with this pointing to the DOM object itself, first argument pointing to the updated object in the tree, second argument is the exact path of this object (fulfilling the regexp) and all other arguments copies additional arguments. RegExp allows only few control characters: * is a wildcard, (1|2|3) - is 1 or 2 or 3.

Please note that the use of the triggerpath extension is one option to handle the incoming data. You can also extract all the interesting values right when the data is received and bind update functions to them.

Security S2 inclusion process require additional interaction with the user during inclusion process. In addition to putting the device in Learn Mode and Z-Way in Add mode the user will be asked to grant different Security S2 keys and enter the PIN code.


C-Library API and a general view on the Z-Way file structure


Files in the /zway folder

Z-Way keeps all files in one folder with exception of the log files. In Unix based platforms such as Linux PC, Raspberry Pi or open WRT the standard install folder is usually /opt/zway-server . The logfile is typically placed in /var/log/z-way-server.log but this location of the log file can be reconfigured in the config file.

On Windows, the installation wizard asked where to place Z-Way and where to place the log file.

Right after installation, the standard folder has the following content:

The main config file in the root folder has XML file format. If only allows setting the log level (0 = log all, 9 = log almost nothing), the path to the log file and a debug port if needed. Don't change the setting for automation folder unless you really know what you do and why.

This is an example for the standard config.xml displaying all log right into the console.

[config.xml] automation 0 0  

This subfolder has the following structure:




The file Defaults.xml allows defining various behavior of Z-Way, among them the appearance of Z-Way as secondary controller: