Z-Ware HTTP POST API#

This lab exercise explores how to work with the Z-Ware RESTful HTTP post interface. This is the sixth exercise in the ‘Z-Wave controller training course’ series.

Introduction#

This exercise will modify the node information frame of Z/IP Gateway and see the consequences this modification has on the deep packet inspection. Furthermore, you will connect Z/IP Gateway to a cloud hosted instance of Z-Ware and study the zipgateway.log file to identify crucial debugging information.

Hardware Requirements#

  • 2 UZB Controllers

  • 1 Raspberry 3B (+)

  • 1 SD card

  • 1 IP Router with built in DHCP

  • 1 WSTK Main Development Board

  • 1 Z-Wave Radio Development Board: ZGM130S SiP Module

  • 1 USB Zniffer

Software Requirements#

Main Development Board with Z-Wave SiP Module

Prerequisites#

Familiarize yourself with the protocol by referring to the following materials:

Further the participants should have completed

  • Controller training session 1

  • Controller training lab exercise 1

  • Controller training session 2

  • Controller training lab exercise 2

  • Controller training session 3

  • Controller training lab exercise 3

  • Controller training session 4

  • Controller training lab exercise 4

  • Controller training session 5

  • Controller training lab exercise 5

  • Controller training session 6

You should be familiar with connecting to the Raspberry Pi.

Installing “posttest”#

This lab exercise relies on the posttest.html file, which can be downloaded here. The first step is to place this file on the Raspberry Pi. Transfer the file to the Raspberry Pi and go to the folder containing the file. Copy the file to the Z-Ware Web server:

$ sudo cp posttest.html ~/zwarelocal/install/zweb/htdocs/

Logging in#

Open the Raspberry Pi URL, raspberrypi.local, or its IP address in a browser and log in normally. Change the URL to end with “/posttest.html”, e.g., https://raspberripi.local/posttest.html This should open the posttest.html page and allow work with the restful API, one command at a time.

posttest.html

Enumerating the Network#

The first step when working with Z-Ware is to enumerate the network and discover all controllable resources in the network.

This exercise assumes that a node is included in the network. Use an always on node, such as the Switch on/off sample application and include it through the “pretty” UI, if not already included.

Nodes#

To discover the nodes in the network, the first step is to get a node list. Set the URIPREFIX to /cgi/zcgi/networks/ and the URI to /zwnet_get_node_list and click “Post”: Enumerating the Network Using posttest.html A lot of data is returned while it is quite hard to read. The data format is JSON, so it can easily be formatted using one of the many JSON formatters available online. Copy the data to e.g., https://jsonformatter.curiousconcept.com/ It results in this:

{
"node":[
    {
        "zwnode_ext_ver":[
            {
            "zwnode_fw":[
                {
                    "target":"1",
                    "ver":"7",
                    "sub_ver":"13"
                },
                {
                    "target":"2",
                    "ver":"2",
                    "sub_ver":"3"
                }
            ],
            "hw_ver":"1"
            }
        ],
        "desc":"1",
        "id":"1",
        "property":"23",
        "vid":"0",
        "pid":"1",
        "type":"1",
        "category":"0",
        "alive":"3",
        "sec":"1",
        "sec_incl_failed":"0",
        "lib_type":"7",
        "proto_ver":"7.13",
        "app_ver":"7",
        "app_sub_ver":"13",
        "sensor":"0",
        "sleep_cap":"0",
        "s2_keys_valid":"1",
        "s2_grant_key":"135",
        "s2_dsk":""
    },
    {
        "zwnode_sw_ver":[
            {
            "type":"0",
            "major":"7",
            "minor":"13",
            "patch":"6",
            "build":"0"
            },
            {
            "type":"1",
            "major":"10",
            "minor":"13",
            "patch":"6",
            "build":"327"
            },
            {
            "type":"3",
            "major":"7",
            "minor":"13",
            "patch":"6",
            "build":"327"
            },
            {
            "type":"4",
            "major":"10",
            "minor":"13",
            "patch":"6",
            "build":"327"
            }
        ],
        "zwnode_ext_ver":[
            {
            "hw_ver":"1"
            }
        ],
        "desc":"7",
        "id":"7",
        "property":"23",
        "vid":"0",
        "pid":"2",
        "type":"4",
        "category":"0",
        "alive":"3",
        "sec":"1",
        "sec_incl_failed":"0",
        "lib_type":"3",
        "proto_ver":"7.13",
        "app_ver":"10",
        "app_sub_ver":"13",
        "sensor":"0",
        "sleep_cap":"0",
        "s2_keys_valid":"1",
        "s2_grant_key":"128",
        "s2_dsk":""
    }
],
"zwnet":[
    {
        "zwnode":[
            {
            "zwnode_ext_ver":[
                {
                    "zwnode_fw":[
                        {
                        "target":"1",
                        "ver":"7",
                        "sub_ver":"13"
                        },
                        {
                        "target":"2",
                        "ver":"2",
                        "sub_ver":"3"
                        }
                    ],
                    "hw_ver":"1"
                }
            ],
            "desc":"1",
            "id":"1",
            "property":"23",
            "vid":"0",
            "pid":"1",
            "type":"1",
            "category":"0",
            "alive":"3",
            "sec":"1",
            "sec_incl_failed":"0",
            "lib_type":"7",
            "proto_ver":"7.13",
            "app_ver":"7",
            "app_sub_ver":"13",
            "sensor":"0",
            "sleep_cap":"0",
            "s2_keys_valid":"1",
            "s2_grant_key":"135",
            "s2_dsk":""
            },
            {
            "zwnode_sw_ver":[
                {
                    "type":"0",
                    "major":"7",
                    "minor":"13",
                    "patch":"6",
                    "build":"0"
                },
                {
                    "type":"1",
                    "major":"10",
                    "minor":"13",
                    "patch":"6",
                    "build":"327"
                },
                {
                    "type":"3",
                    "major":"7",
                    "minor":"13",
                    "patch":"6",
                    "build":"327"
                },
                {
                    "type":"4",
                    "major":"10",
                    "minor":"13",
                    "patch":"6",
                    "build":"327"
                }
            ],
            "zwnode_ext_ver":[
                {
                    "hw_ver":"1"
                }
            ],
            "desc":"7",
            "id":"7",
            "property":"23",
            "vid":"0",
            "pid":"2",
            "type":"4",
            "category":"0",
            "alive":"3",
            "sec":"1",
            "sec_incl_failed":"0",
            "lib_type":"3",
            "proto_ver":"7.13",
            "app_ver":"10",
            "app_sub_ver":"13",
            "sensor":"0",
            "sleep_cap":"0",
            "s2_keys_valid":"1",
            "s2_grant_key":"128",
            "s2_dsk":""
            }
        ],
        "utime":"1594295572",
        "id":"01-02-03-04-05-06-07-08"
    }
]
}

Above is a very long list with details relating to each node currently in the network. The list does not indicate much other than there are two nodes, one with “ID” 1 and one with “ID” 7, and that they have a descriptor, “desc”. The descriptors are used to discover more properties about the nodes.

Endpoints#

To learn more about the node, you have to discover its endpoints. Change the URI to /zwnode_get_ep_list, and “BODY” to noded=7; the node descriptor found just before, in this example 7. Finally, click “Post”: Enumerating Endpoints Using posttest.html Reformatting the output results in:

{
"node":[
    {
        "ep":[
            {
            "desc":"263",
            "id":"0",
            "generic":"16",
            "specific":"0",
            "name":"DEVICE%207",
            "loc":"",
            "zwplus_ver":"2",
            "role_type":"5",
            "node_type":"0",
            "instr_icon":"1792",
            "usr_icon":"1792",
            "aggregated_ep_list":""
            }
        ],
        "desc":"7",
        "deprecated":"1"
    }
],
"zwnode":[
    {
        "zwep":[
            {
            "desc":"263",
            "id":"0",
            "generic":"16",
            "specific":"0",
            "name":"DEVICE%207",
            "loc":"",
            "zwplus_ver":"2",
            "role_type":"5",
            "node_type":"0",
            "instr_icon":"1792",
            "usr_icon":"1792",
            "aggregated_ep_list":""
            }
        ],
        "desc":"7"
    }
]
}

The device has one endpoint, endpoint 0, which means that it is not a multichannel device. Z-Ware also provides a descriptor to this endpoint allowing discovery of the endpoints capabilities its interfaces or command classes.

Interfaces#

Z-Ware refers to command class support as interfaces. To discover the interfaces supported by an endpoint, change the URI to /zwep_get_if_list and the “BODY” to epd=263, the endpoint descriptor found just before: Enumerating Interfaces Using posttest.html Reformatting the output results in the following:

{
"ep":[
    {
        "intf":[
            {
            "desc":"6160647",
            "id":"94",
            "name":"COMMAND_CLASS_ZWAVEPLUS_INFO",
            "ver":"2",
            "real_ver":"2",
            "sec":"0",
            "unsec":"1"
            },
            {
            "desc":"5570823",
            "id":"85",
            "name":"COMMAND_CLASS_TRANSPORT_SERVICE",
            "ver":"2",
            "real_ver":"2",
            "sec":"0",
            "unsec":"1"
            },
            {
            "desc":"9961735",
            "id":"152",
            "name":"COMMAND_CLASS_SECURITY",
            "ver":"1",
            "real_ver":"1",
            "sec":"0",
            "unsec":"1"
            },
            {
            "desc":"10420487",
            "id":"159",
            "name":"COMMAND_CLASS_SECURITY_2",
            "ver":"1",
            "real_ver":"1",
            "sec":"0",
            "unsec":"1"
            },
            {
            "desc":"7078151",
            "id":"108",
            "name":"COMMAND_CLASS_SUPERVISION",
            "ver":"1",
            "real_ver":"1",
            "sec":"0",
            "unsec":"1"
            },
            {
            "desc":"6816007",
            "id":"104",
            "name":"COMMAND_CLASS_ZIP_NAMING",
            "ver":"1",
            "real_ver":"1",
            "sec":"0",
            "unsec":"1"
            },
            {
            "desc":"2294023",
            "id":"35",
            "name":"COMMAND_CLASS_ZIP",
            "ver":"4",
            "real_ver":"4",
            "sec":"0",
            "unsec":"1"
            },
            {
            "desc":"8782087",
            "id":"134",
            "name":"COMMAND_CLASS_VERSION",
            "ver":"3",
            "real_ver":"3",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"2425095",
            "id":"37",
            "name":"COMMAND_CLASS_SWITCH_BINARY",
            "ver":"2",
            "real_ver":"2",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"8716551",
            "id":"133",
            "name":"COMMAND_CLASS_ASSOCIATION",
            "ver":"2",
            "real_ver":"2",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"6029575",
            "id":"92",
            "name":"COMMAND_CLASS_IP_ASSOCIATION",
            "ver":"1",
            "real_ver":"1",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"9306375",
            "id":"142",
            "name":"COMMAND_CLASS_MULTI_CHANNEL_ASSOCIATION",
            "ver":"3",
            "real_ver":"3",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"5832967",
            "id":"89",
            "name":"COMMAND_CLASS_ASSOCIATION_GRP_INFO",
            "ver":"3",
            "real_ver":"3",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"7471367",
            "id":"114",
            "name":"COMMAND_CLASS_MANUFACTURER_SPECIFIC",
            "ver":"2",
            "real_ver":"2",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"5898503",
            "id":"90",
            "name":"COMMAND_CLASS_DEVICE_RESET_LOCALLY",
            "ver":"1",
            "real_ver":"1",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"8847623",
            "id":"135",
            "name":"COMMAND_CLASS_INDICATOR",
            "ver":"3",
            "real_ver":"3",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"7536903",
            "id":"115",
            "name":"COMMAND_CLASS_POWERLEVEL",
            "ver":"1",
            "real_ver":"1",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"7995655",
            "id":"122",
            "name":"COMMAND_CLASS_FIRMWARE_UPDATE_MD",
            "ver":"5",
            "real_ver":"5",
            "sec":"1",
            "unsec":"0"
            }
        ],
        "desc":"263",
        "deprecated":"1"
    }
],
"zwep":[
    {
        "zwif":[
            {
            "desc":"6160647",
            "id":"94",
            "name":"COMMAND_CLASS_ZWAVEPLUS_INFO",
            "ver":"2",
            "real_ver":"2",
            "sec":"0",
            "unsec":"1"
            },
            {
            "desc":"5570823",
            "id":"85",
            "name":"COMMAND_CLASS_TRANSPORT_SERVICE",
            "ver":"2",
            "real_ver":"2",
            "sec":"0",
            "unsec":"1"
            },
            {
            "desc":"9961735",
            "id":"152",
            "name":"COMMAND_CLASS_SECURITY",
            "ver":"1",
            "real_ver":"1",
            "sec":"0",
            "unsec":"1"
            },
            {
            "desc":"10420487",
            "id":"159",
            "name":"COMMAND_CLASS_SECURITY_2",
            "ver":"1",
            "real_ver":"1",
            "sec":"0",
            "unsec":"1"
            },
            {
            "desc":"7078151",
            "id":"108",
            "name":"COMMAND_CLASS_SUPERVISION",
            "ver":"1",
            "real_ver":"1",
            "sec":"0",
            "unsec":"1"
            },
            {
            "desc":"6816007",
            "id":"104",
            "name":"COMMAND_CLASS_ZIP_NAMING",
            "ver":"1",
            "real_ver":"1",
            "sec":"0",
            "unsec":"1"
            },
            {
            "desc":"2294023",
            "id":"35",
            "name":"COMMAND_CLASS_ZIP",
            "ver":"4",
            "real_ver":"4",
            "sec":"0",
            "unsec":"1"
            },
            {
            "desc":"8782087",
            "id":"134",
            "name":"COMMAND_CLASS_VERSION",
            "ver":"3",
            "real_ver":"3",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"2425095",
            "id":"37",
            "name":"COMMAND_CLASS_SWITCH_BINARY",
            "ver":"2",
            "real_ver":"2",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"8716551",
            "id":"133",
            "name":"COMMAND_CLASS_ASSOCIATION",
            "ver":"2",
            "real_ver":"2",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"6029575",
            "id":"92",
            "name":"COMMAND_CLASS_IP_ASSOCIATION",
            "ver":"1",
            "real_ver":"1",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"9306375",
            "id":"142",
            "name":"COMMAND_CLASS_MULTI_CHANNEL_ASSOCIATION",
            "ver":"3",
            "real_ver":"3",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"5832967",
            "id":"89",
            "name":"COMMAND_CLASS_ASSOCIATION_GRP_INFO",
            "ver":"3",
            "real_ver":"3",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"7471367",
            "id":"114",
            "name":"COMMAND_CLASS_MANUFACTURER_SPECIFIC",
            "ver":"2",
            "real_ver":"2",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"5898503",
            "id":"90",
            "name":"COMMAND_CLASS_DEVICE_RESET_LOCALLY",
            "ver":"1",
            "real_ver":"1",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"8847623",
            "id":"135",
            "name":"COMMAND_CLASS_INDICATOR",
            "ver":"3",
            "real_ver":"3",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"7536903",
            "id":"115",
            "name":"COMMAND_CLASS_POWERLEVEL",
            "ver":"1",
            "real_ver":"1",
            "sec":"1",
            "unsec":"0"
            },
            {
            "desc":"7995655",
            "id":"122",
            "name":"COMMAND_CLASS_FIRMWARE_UPDATE_MD",
            "ver":"5",
            "real_ver":"5",
            "sec":"1",
            "unsec":"0"
            }
        ],
        "desc":"263"
    }
]
}"Post"

Controlling Z-Wave Nodes#

In the above list, identify a controllable command class, for example binary switch, COMMAND_CLASS_SWITCH_BINARY with the descriptor 2425095. The Z-Ware SDK includes the document INS14430 which explains the control of different interface types. The description for binary switch is found in section 8, which outlines the commands.

Getting Status#

Two methods for getting the status from a Z-Wave device are “passive”, which returns the value cached by Z-Ware, and “active”, which actively gets the value from the Z-Wave device when requested. Choosing the appropriate method to use depends on the use case, whether freshness of data is prioritized over generating more network traffic. To get the active value, change the URI to /zwif_switch, “BODY” to cmd=2&ifd=2425095 where cmd=2 is CMD_BSWITCH_GET, from INS14430. Getting Active Status Using posttest.html

{
"intf":[
    {
        "bin_sw":[
            {
            "update":"1594295585",
            "state":"0",
            "target_state":"0",
            "duration":"0",
            "state_num":"2"
            }
        ],
        "desc":"2425095",
        "deprecated":"1"
    }
],
"zwif":[
    {
        "switch":[
            {
            "utime":"1594295585",
            "state":"0",
            "target_state":"0",
            "duration":"0",
            "state_num":"2"
            }
        ],
        "desc":"2425095"
    }
]
}

Here, you can see that the current state is zero, the switch is off, and data is time stamped with a unix epoch time stamp, allowing you to know when data was last cached. Sending a passive get is similar to the active, but the command is instead CMD_BSWITCH_REPORT, 3. Getting Passive Status Using posttest.html

Sending this command yields the same result. However, one major difference is that the time stamp does not change for the passive get, while it is updated for each active get.

Setting Status#

Change the “BODY” field to cmd=4&ifd=2425095&value=255, with cmd=4=CMD_BSWITCH_SET, and appending a value field, here set to 255 as the switch previously was off. It should change with the set command. Click “Post” and observe the switch changing.