We’re here to help you

Menu

ZWave System

This Dezyne example is Richard Dennemans’s submission for the Dezyne Challenge 2016.

The application

The ZWave protocol is not completely implemented and only 2 functions (messages) are used in this example. Namely the SendData function (function code 0x13) and the ApplicationCommandHandler function (function code 0x04). The first one is to send data from an application to the controller and from controller to a slave. The second one is to receive data as a response of the send data function or to receive data unsolicited from a slave. These 2 functions can be used to send/receive messages with 3 different types of destinations. Namely:

  1. to a single node (single/unicast)

  2. to a selection of nodes (multicast)

  3. or to all nodes (broadcast)

Only when using single/unicast the receiver must acknowledge the message. If no acknowledge is received, the transmitter will retry a few times (mostly 3).

Architecture

An overview of the modelled ZWave system is displayed in the following figure:

image

In the following paragraphs, the displayed system is build up step by step.

ZWave Controller

The ZWaveController can send messages to slave nodes (at request of a user application) and receives messages from slave nodes that will be send to the user application. Communication from controller to slave nodes is performed using an RF signal. And communication from an application to the controller with a RS232 serial port interface.

The ZWaveController component implements 2 types of interfaces:

image

  1. An interface for the serial communication to the application

  2. An interface for the RF communication to the slaves.

ZWaveControllerSw

This is the main implementation of the ZWaveController.

The ZWaveControllerSw uses the following interfaces for the serial communication to/from an application:

  • IZWaveSendDataSerial: To send a message to a ZWave slave node from an application and to receive an acknowledge back from the slave. image

  • IZWaveApplicationCommandHandlerSerial: To receive a message from a slave in the application. This can be an unsolicited message or a response to the IZWaveSendDataSerial.SendDataUnicast function. Only an unsolicited message is used in this example. State diagram of the interface: image

The ZWaveControllerSw uses the following interfaces for the RF communication to/from the slaves:

  • IZWaveSendDataRf: to send data from a ZWave controller to a slave using RF.

    State diagram of the interface:

    image

  • IZWaveApplicationCommandHandlerRf: to receive data from a slave to a ZWave controller using RF.

    State diagram of the interface:

    image

The ZWaveControllerSw uses the following interfaces to helper components:

  • IZWaveTxBuffer: interface to check if the transmit buffer is full. ZWaveTxBuffer is a helper component needed to simulate transmit buffer full/not full with the following interfaces.

  • IZWaveRxState: interface to check if the RF network is busy. ZWaveRxState is a helper component needed to simulate the RF network busy/not busy.

  • ITimer: timer interface to wait for a period of time. Timer is a helper component to simulate a timer. For example, the timer is used to send an ACK message, after a maximal time, from the controller/slave node (if an unicast transmit function is used).

The following is an example sequence of the ZWaveControllerSw component. It is sending a message to a slave and receiving an acknowledge back from a slave. Transmit buffer is not full, RF network not busy and timer does not timeout. Acknowledge received on time.

image

And another example of receiving an unsolicited message from a slave to the application, and sending an acknowledge back to the slave.

image

ZWave Slave

This component is an implementation of a ZWave slave node. The slave receives commands from a controller and sends commands to the controller. The slave uses the same RF interfaces as the ZWave controller but with inverted direction. See the following figure for the overview.

image

The slave node implemented in Dezyne contains a digital input and a digital output. The input can be connected to e.g. a switch and is used to send a message to the application if the switch is activated. The output can be connected to e.g. a LED and an application can send a message to toggle the LED.

The ZWaveSlave component contains the following interfaces:

RF interfaces:

  • IZWaveSendDataRf: to receive data from a ZWave controller using RF. See the ZWaveControllerSw component for the state diagram.

  • IZWaveApplicationCommandHandlerRf: to send data to a ZWave controller using RF. See the ZWaveControllerSw component for the state diagram.

User interfaces:

  • IZWaveSendDataNodeUi: received action from a ZWave controller.

    State diagram of the interface:

    image

  • IZWaveApplicationCommandHandlerUi: send action to a ZWave controller.

    State diagram of the interface:

    image

The following sequence is an example of receiving a single cast data message by the ZWaveSlaveSw component from the RF signal and sending an acknowledge back. The ZWaveSlaveSw component is the main implementation of the ZWaveSlave component.

image

And a sequence example of sending a message from a slave over RF and receiving an acknowledge back.

image

ZWave Controller&Slave

The ZWaveSlave component and ZWaveController component can be connected to each other because they have the same RF interfaces with inverted direction. The ZWaveControllerSlaveSystem view after connecting both components is displayed in the following figure.

image

The Dezyne application doesn’t like this setup, and it gives an error that there is a cyclic binding issue in the design when generating code. Because the send implementation should be completely isolated from the receive implementation this could not be a cyclic binding problem I thought. Otherwise I did something wrong with my implementation. To check if I did something wrong and that I made a mistake in my design by creating a cyclic binding, I did the following decomposition.

I extracted the ZWaveSlave component into 2 new components namely a ZWaveSlaveRx and a ZWaveSlaveTx component with same code, same implementation, same behavior, only separated in 2 components. In the following figure displaying the ZWaveControllerSlaveTxSlaveRxSystem is the new system with the separated ZWaveSlaveRx and ZWaveSlaveTx. You can clearly see that there’s no cyclic binding in the design.

image

Now the Dezyne application is not complaining anymore about a cyclic-binding. Then I thought when using these 2 components in a new ZWaveSlaveTxRx component, it should be fine for Dezyne.

image

I created a new system with this component. The ZWaveControllerSlaveTxRxSystem.

image

But also in this situation, Dezyne complains about a cyclic-binding issue during code generation. So I had to use the ZWaveSlaveRx and ZWaveSlaveTx component as separate components otherwise I get the cyclic binding error. Dezyne gives this error because Dezyne only looks at the outside of a component, and not inside a component to check if there’s a real cyclic-binding. Hope that Dezyne will cope with this in the future, because then you can combine separate features into one new component.

ZWave Switch

This component can act as an input for the slave component.

image

The ZWaveSlave will send an ApplicationCommandHandler message to the controller when the input is activated.

This component uses the following interfaces:

  • IZWaveSwitch: Interface that implements a push button

  • IZWaveApplicationCommandHandlerUi: send action to controller via slave

The following sequence is an example of activating the switch, and sending out a message. In this example the first message did not get an acknowledge, and a timeout occurs. After the second retry, an acknowledge is received.

image

ZWave Led

This component can act as an output for the slave component.

image

The controller can send a SendData message to the slave to toggle the led.

This component uses the following interfaces:

  • IZWaveLed: Interface that implements a LED output

  • IZWaveSendDataNodeUi: received action from slave

In the following example, a message is received to toggle a LED.

image

ZWave Controller&Slave With Switch&Led

In the following system overview displaying the ZWaveControllerSlaveWithIoSystem, a ‘userinterface’ in the form of a Led and Switch is added to the system.

image

Finally all slaves and the controller can be connected to a complete ZWave network. The system overview is already displayed in the first section at the beginning of this document. The system has 3 slave nodes and 1 controller node. In this system the ZWaveControllerNw component described in the following section is added to connect all nodes.

ZWave ControllerNw

This is a helper component used to connect all nodes.

image

This component is also split into a ZWaveControllerNwRx and ZWaveControllerNwTx because of a cyclic-binding issue in Dezyne. So I had the same problem also with this component as I had with the ZWaveSlave component.

I use the INodeSelect interface in this example to select the destination node because I couldn’t do that by a limitation of parameter check during an event in Dezyne. In the next section, I use another method without this interface but using an external variable.

The following is an example of selecting destination node2 and sending data from node 1 to node 2 with an acknowledgement.

image

And an example of selecting node 1 as destination and receiving data from node2, also with an acknowledgement at the end.

image

Using an external variable to select the destination node.

Instead of using the INodeSelect interface as mentioned in the previous section, also another method can be used to select the node namely using parameters.

Dezyne does not support internal variables as parameters at this moment, but you can use external variables for this purpose.

In the following overview the system using this method is displayed. The INodeSelect interface is removed, and a NodeIDChecker component with interface is added.

image

In all the ZWave functions, an external parameter naming nodeID is added. The external parameter is defined in the NodeIDChecker. All interfaces and components needing the nodeID are changed.

Documentation

You can download the example in a zip-file from here.

Note that all of the diagrams included in this document have been produced in and exported from Dezyne. The System View and State Charts are part of the Dezyne editor. The Sequence Trace has been produced using the Dezyne simulation engine.

If you have questions that weren’t by this Guide,
let our support team help you out.

Enjoy this article? Don't forget to share.