Introduction to Z-wave and OpenZWave

1 Requirements of a system for home control

• Reliability of the • Security of communication • Low emission : issues like electromagnetic emission need to be taken into account. • Simple usage • Adequate price • Protection of investment • Interoperability

For more details, read “Z-Wave Technical Basics” document (sections 1.1 and 1.2)

2 Alternatives for wireless home control

Z-Wave En- Proprietary Power Line Zigbee Ocean Protocols Reliability Partly ??

Security Partly ??

Low radio emission Simple usage - Low price Not yet

Protection of - Investment Interoperability

For more details, read “Z-Wave Technical Basics” document (sections 1.1 and 1.2

3 Plan

• Z-Wave • Python OpenZWave

4 Z-wave

• Z-Wave is an international standard for wireless home automation. • Home automation allows to interconnect all functions dealing with electricity such as light, heating, cooking, cooling, security etc. with each other and to apply automation of these functions. • Z-Wave uses low-powered radio waves. • Its mesh network covers all areas of the home, as the radio waves travel easily through walls, floors, making connectivity 100% reliable.

5 Z-wave history

• End of the nineties: Zen-Sys (Dinesh company) invented Z-Wave • From the initial idea of developing their own home automation solution, the company soon evolved into becoming a chip provider selling a home automation ASIC. • Ecosystem of manufacturers with compatible products.

6 Z-wave history

• The first generation of Zensys hardware was sold in 2003 • 4 generations : 2003, 2005, 2007, 2009 • 2007: The first larger Z-Wave device manufacturer in Europe was the German switch manufacturer Merten (now a part of Schneider Electric). • 2008: Sigma Design (Asian manufacturer) bought Zen-Sys • 2009: Z-Wave gets adopters in Asia.

7 Z-wave alliance today

• 2005: Z-wave alliance • 600 companies* • 2100 products* • All interoperable with each other

8 *: https://z-wavealliance.org/ General Layer model

• Radio layer: The functions of this layer is invisible to the end user • Network layer: This function makes sure, that a message can be exchanged free of error between two wireless nodes. • Application layer: routing functions

9 Z-wave devices

• Z-Wave distinguishes two basic types from devices: • Controllers are Z-Wave devices that can control other Z-Wave devices, • Slaves are Z-Wave devices that are controlled by other Z-Wave devices.

10 Z-wave devices

• Each Z-Wave module can act as a repeater and commands can route through a maximum of four devices. This gives the system a maximum range of ~ 120 m • Routing is managed automatically

11 Z-wave identifications

• The Z-Wave protocol defines two identifications for the organisation of the network: • The Home ID is the common identification of all nodes belonging to one logical Z-Wave network. It has a length of 4 bytes = 32 bits and is less of interest for the final user. • The Node ID is the address of the single node in the network. The Node ID has a length of 1 byte = 8 bits.

12 Z-wave : Before inclusion

13 Z-wave : After inclusion

14 Z-wave network (without routing)

15 Z-wave network (with routing)

16 Z-wave network (with routing)

• Every node is able to determine which nodes are in its direct wireless range. These nodes are called neighbours. • During inclusion and later on request, the node is able to inform the controller about its list of neighbours. • Using this information, the controller is able to build a table that has all information about possible communication routes in a network

17 Z-wave network (with routing)

18 Z-wave network (with routing)

• Every Z-Wave device can receive and acknowledge messages • Controllers can send messages to all node in the network, solicited and unsolicited (“The master can talk whenever he wants and to whom he wants”) • Slaves can not send unsolicited messages but only answer to requests (“The slave shall only speak is he is asked”) • Routing Slaves can answer requests and they are allowed to send unsolicited messages to certain nodes the controller has predefined (“The sensor slave is still a slave but - on permission – he may speak up”)

19 Battery operated devices

20 “Z-Wave Technical Basics” document

• 125 pages document • Introduction : p 6 – p 16 • Comparison of proprietary protocols • History and Characteristics of Z-Wave • Network Layer: p 26 – p 63

21 Plan

• Z-Wave • Python OpenZWave

22 Reminder …

23 OpenZWave

• OpenZWave is an open-source, cross-platform library designed to enable anyone to add support for Z-Wave devices to their applications, without requiring any in depth knowledge of the Z-Wave protocol.

24 python-openzwave

25 Virtual representation

•Network

•Controller •Nodes

•Values

26 Network class

• home_id_str • is_ready : (type: Boolean): indicates if the network is ready or not. As soon as the network is ready, a SIGNAL_NETWORK_READY event is generated by python-openzwave. • nodes_count : (including the controller) • controller : (type:Controller) • nodes : a dictionary of "node" objects representing the nodes connected to the network (including the controller). • start () : This method generates the representation of the Z-Wave network managed by the controller. • stop () : this method deletes the software representation 27 Controller class

• name: controller's name. • device: path of the device’s driver (e.g. /dev/USB0 ) • begin_command_add_device() (return type: Boolean): gets the controller in inclusion mode. The method returns "True" if the command is accepted and started. • begin_command_remove_device() (return type: Boolean): gets the controller in exclusion mode. The method returns "True" if the command is accepted and started. • cancel_command() (return type:none): gets the controller out of the inclusion or exclusion mode.

28 Node class

• node_id (type: integer): identifying the node in the network (note: the node with the id "1" is always the controller). • product_name (type:string): name of the product. (Sensor's product name is "Multisensor 6" and dimmer's product name is "ZE27") • name (type:string): name of the node. • location (type:string) : location of the node. • isReady (type: Boolean): Indicates whether the node is ready or not (this method is not in the documentation) -à deprecated (is_ready) • getNodeQueryStage (type:String): Indicates the State of the Node object (Once the Query Stage is at "Complete", this Node object is ready to be used). • neighbors (type: set()) : a set of the neighbouring nodes. Neighbouring nodes are nodes that can be reached by the current node • values (type:dict()): This is a dictionary containing pairs of (ID, value_object). A “value” object represents a measure or a configuration parameter of this Node.

29 Value class

• label (type:string): the label of the value (eg. "Temperature" in the case of temperature value recovered by the sensor node or "Level" in case of brightness level). • data (type:depends on the type of the value) : value of the measurement. • units (type:string) : unit of the value

30 python-openzwave

31 python-openzwave

dispatcher.connect(…)

dispatcher.send(….)

32 •33 Events and signals

• Event-driven paradigm: • The Z-Wave Network controller waits for externals events (e.g. node_added, …) and send a signal to openzwave library • Backend program must be waiting for this signal and know how to handle it (i.e. it must be “armed”) • Think of it as interrupts & interruption routines •34 The full list of signals

• It can be found in : /home/pi/IoTLab/python- openzwave/src-api/openzwave/network.py • We will essentially use: • SIGNAL_NETWORK_STARTED • SIGNAL_NETWORK_READY • SIGNAL_NODE_ADDED • SIGNAL_NODE_REMOVED • SIGNAL_VALUE •35 Arming signals – Example (1)

• Example: arm the SIGNAL_NETWORK_STARTED signal with the callback function _network_started() • Dispatcher associates a function to a signal:

dispatcher.connect(self._network_started, ZWaveNetwork.SIGNAL_NETWORK_STARTED)

• The callback will print info and arm 2 other signals:

def _network_started(self, network): print("network started - %d nodes were found." % network.nodes_count) dispatcher.connect(self._node_added, ZWaveNetwork.SIGNAL_NODE_ADDED) dispatcher.connect(self._node_removed, ZWaveNetwork.SIGNAL_NODE_REMOVED) •37 Signal chronology

• Chronology may be partially deduced by observing the prints in : •

1) SIGNAL_NETWORK_STARTED 2) SIGNAL_NODE_ADDED 3) SIGNAL_NETWORK_READY 4) SIGNAL_VALUE 5) … •38 Z-Wave nodes configuration

• Wakeup interval • Frequency at which the sensor wakes up to listen to controller commands • Group interval • Frequency at which a given sensor sends data to the controller • Group report • Subset of measurements sent by the sensor Group report configuration (1)

• 3 group reports are possible : group report 1, 2 and 3 • Config must be sent via HTTP POST to the server with the following parameters: • Node_id= • Parameter_index=101, 102 or 103 (group reports 1, 2 & 3) • Value=241 (represents measurements to ”collect”. see next slide) • Size=4 (See next slide) • Example, with node_id=2: requests.post('http://192.168.1.2:5000/nod es/set_parameter',headers={'Content-Type': 'application/json'}, data=json.dumps({'node_id': ‘2','value':'241', 'parameter_index': '101', 'size': '4’}) •41 Group report configuration (2)

• Configuration value table (available in MultiSensor- Documentation.pdf):

• Value coded on 4 bytes • Reserved bits or bytes must be set to zero • Default value = 241 -> why? • Because -> 24110 = 111100012 •42 Group interval configuration (1)

• Parameter index=111 • Description=“The interval time of sending reports in Report group 1” • Example, with node_id=4, and group interval = 10 seconds :

requests.post( 'http://192.168.1.2:5000/nodes/set_parameter',hea ders= {'Content-Type’: 'application/json’}, data=json.dumps({'node_id': '4’, 'value’:’10’, 'parameter_index': '111’, 'size': '4’} ) •43 Alternate method (without using parameter_index)

• Configure group interval & group report & wakeup interval in 1 HTTP POST query: • requests.post('http://192.168.1.2:5000/n etwork/set_sensor_nodes_basic_configurat ion',headers={'Content-Type': 'application/json'}, data=json.dumps({ 'Group_Interval': '240’, 'Group_Reports':'240’, 'Wake-up_Interval': '480’ }))