Z-Ware C API Training#
The purpose of this training is to explain how to use the Z-Ware C API and enable the user to modify the Z-Ware C API sample apps.
Topics covered:
Explanation of the sample app functionality
Brief overview of the sample app code
Documentation Resources
Building the library
Building the sample apps
How to modify a sample app
In the Lab Exercise, the following tasks will be performed.
Build library and apps
Connect the sample app to Z/IP gateway
Do basic control of Z-Wave devices
Modify the sample app to receive the notification command class
Introduction#
The Z-Ware C API is the lowest level way to use Z-Ware. After you build it, use sample apps to see how it works and how to use it.
The sample apps are located in the Z-Ware source tree. The path to the sample apps is zware/v7.xx/src/zwportal/zwave/hcapi/demos.
The C API abstracts Z-Wave command classes into a controllable and monitorable API. The C API uses callbacks to notify the upper level application about events and status changes.
Example Apps Included#
gw_discovery will find any Z/IP gateways on the network and display the IP address. zwnet_gw_discvr_start finds gateways and a callback, and zwnet_gw_discvr_cb is called upon completion.
add_node can be used to include a new node
rm_node can be used to exclude a node
nw_reset resets the network
basic sends the basic set command
bin_switch controls a binary switch
bin_sensor gets data from a binary sensor
controller_app combines many of these examples together and has a command line menu to access the many features
Most of these apps have a configuration file in the directory that should contain the IP address of Z/IP gateway and the DTLS key.
Mandatory Setup Functions#
To ensure that the Z-Ware C API functions properly, some functions must be called at initialization. For example, all the example apps call zwnet_init inside a local function called lib_init.
Additionally, the following functions must be called.
zwnet_local_addr_get gets the local IP address used by Z-Ware for communicating with Z/IP gateway
zwnet_listen_port_get gets the local port used by Z-Ware for incoming unsolicited communication from Z/IP gateway
zwif_gw_unsolicit_set push Z-Ware's IP address and listening port to Z/IP gateway as unsolicited destination
An example is included in the bin_sensor app and is shown below.
//Get local Z/IP client listening address and port
result = zwnet_local_addr_get(hl_appl->zwnet, hl_appl->zip_gw_ip, local_ip, hl_appl->use_ipv4);
if (result != 0)
{
printf("Error: couldn't get local Z/IP client listening address: %d\n", result);
return result;
}
local_port = zwnet_listen_port_get(hl_appl->zwnet);
if (hl_appl->use_ipv4)
{ //Convert to IPv4-mapped IPv6 address
uint8_t unsolicit_ipv4[4];
//Save the IPv4 address
memcpy(unsolicit_ipv4, local_ip, 4);
//Convert the IPv4 address to IPv4-mapped IPv6 address
memset(local_ip, 0, 10);
local_ip[10] = 0xFF;
local_ip[11] = 0xFF;
memcpy(&local_ip[12], unsolicit_ipv4, 4);
}
result = gw_intf_get(hl_appl->zwnet, &gw_ifd);
if (result != 0)
{
printf("Error: couldn't find Z/IP gateway interface: %d\n", result);
return result;
}
result = zwif_gw_unsolicit_set(&gw_ifd, local_ip, local_port);
if (result != 0)
{
printf("Error: couldn't set unsolicited address: %d\n", result);
}
Enumerating Z-Ware Nodes#
In Z-Ware, you must iterate through the nodes to find the one you are looking for. To control Z-Wave devices, you iterate to find the interface in the device you want to control.
Starting from the network, you must iterate through the list of nodes using the following functions.
zwnet_get_node
zwnode_get_next
zwnode_get_ep
zwep_get_next
zwep_get_if
zwif_get_next
Starting from an interface, you can iterate in reverse using the following functions.
zwif_get_ep
zwep_get_node
zwnode_get_net
For example, to find a binary switch interface you could iterate through the network as follows.
//Get first node (controller node)
result = zwnet_get_node(net, &node);
if (result != 0)
{
return result;
}
while (!zwnode_get_next(&node, &node))//get next node
{
if (!zwnode_get_ep(&node, &ep)) //get first endpoint of the node
{
do
{
if (!zwep_get_if(&ep, &intf)) //get first interface of the endpoint
{
do
{
if (intf.cls == COMMAND_CLASS_SWITCH_BINARY)
{ //Found a binary switch so return
*bin_sw_if = intf;
return 0;
}
}while (!zwif_get_next(&intf, &intf)); //get next interface
}
}while (!zwep_get_next(&ep, &ep)); //get next endpoint
}
}
return ZW_ERR_INTF_NOT_FOUND;
Controlling Z-Wave Devices#
These functions are described in detail in the C API reference but as a quick reminder of how to control Z-Wave nodes see the following functions.
zwif_xxx_rpt_set registers a callback for interface xxx. For example, to set up a callback for binary sensor data, see the following code. The callback is then called when data is received.
// set up binary sensor callback
zwif_bsensor_rpt_set(&bin_sensor_if, hl_bin_snsr_rep_cb);
// binary sensor callback function
void hl_bin_snsr_rep_cb(zwifd_p ifd, uint8_t state, uint8_t type, time_t ts)
{
if (ts == 0)
{
printf("\nBinary sensor report: no cached data. Report get: type=%u\n", type);
return;
}
if (type > ZW_BSENSOR_TYPE_GLASS_BRK)
{
type = 0;
}
printf("\nBinary sensor (%s) state :%s", bsensor_type_str[type], (state == 0)? "idle" : "event detected");
printf("\nTime stamp:%s\n", ctime(&ts));
}
zwif_xxx_get issue a get command to interface xxx. This can be used to read sensor data. For example, see below.
zwif_bsensor_get(&bin_sensor_if, sensor_type, (choice == '3')? ZWIF_GET_BMSK_LIVE : ZWIF_GET_BMSK_CACHE);
zwif_xxx_set set a value to interface xxx. This is used to set values, such as to turn a switch on or off. For example, see below from the bin_switch app.
zwif_switch_set(&bin_sw_if, (choice == '1')? 1:0, 0, NULL, NULL);
Sample Apps Code#
gw_discovery is the first sample app a new user should run. It will display the detected gateway IP address, which can then be entered into the app.cfg file for the rest of the sample apps.
Z-Ware C API Documentation Resources#
For the Z-Ware C API, see the following documents:
The C API Reference lists all the C API functions and their arguments.
The Library User Guide is higher level functional description of the Z-Ware library.
Building the Library and Sample Apps#
See the Lab Exercise to build the library and modify a sample app on a Raspberry Pi. The steps to build the library are also listed in the gateway Getting Started Guide.