Table of contents
1 Introduction
2 ZigBee concepts
2.1 ZigBee architecture
2.2 Open The Box integration
3 How to
3.1 hackathon.tutorial.zigbee application
3.2 First step – How to use a ZigBee device from an Open The Box application
3.3 Second step – How to get ZigBee attribute value (polling mode)
3.4 Third step – ZigBee notifications (reporting mode)
4 Annex
4.1 Requests handled by the ZigBeeTutorialServlet servlet
4.2 Web page architecture
4.3 Management console
4.4 Compliant devices
5 References
1 Introduction
This tutorial shows how to use ZigBee devices from an Open The Box application.
The first part describes ZigBee wireless protocol and its underlying entities. The second part focuses on a simple zigbee application to be completed in order to be use a smart plug from Cleode.
2 ZigBee concepts
2.1 ZigBee architecture
A ZigBee device offers one or more endpoints which are logical device providing applications (i.e features). Every single endpoint provides clusters which are applicative objects. Every single cluster provides commands and attributes.
The ZigBee Cluster Library specification defines clusters and their associated commands and attributes.
For instance, the ZPlug smart plug from Cleode provides only one endpoint (id: 1) offering the Basic cluster (0x00), the Identify cluster (0x03), the Groups cluster (0x04), the Scene cluster (0x05), the OnOff cluster (0x06) and the Metering cluster (0x702). The OnOff cluster provides 3 commands (On, Off and Toggle) and one single attribute (On/Off). The next schema shows a partial representation of the endpoint, clusters, commands and attributes of a ZPlug smart plug from Cleode:
2.2 Open The Box integration
The Open The Box framework provides a ZigBee base driver. This base driver, through the CC 2531 Texas Instrument dongle, reifies all ZigBee devices (and their endpoints) as OSGi services. org.osgi.service.zigbee.ZigBeeNode OSGi services represent ZigBee physical devices whereas org.osgi.service.zigbee.ZigBeeEndpoint OSGi services represent ZigBee endpoint.
When a device joins or leaves its network, the OSGi services (ZigBeeNode and its ZigBeeEndpoint) are respectively registered and unregistered from the OSGi registry.
For instance, the ZigBee base driver will register the following OSGi services when it detects the ZPlug smart plug from Cleode on the ZigBee network:
- a single org.osgi.service.zigbee.ZigBeeNode service representing the smart plug physical device.
- a single org.osgi.service.zigbee.ZigBeeEndPoint service for the single endpoint of the device (id: 1)
2.2.1 ZigBeeNode
A ZigBeeNode OSGi service offers technical data about the device and its belonging network. For instance, the ZigBeeNode service offers the panId of the ZigBee network and the IEEE adress of the device. A ZigBeeNode service can also be used to exclude the related physical device from the network.
Usually, this kind of service is a little bit used.
2.2.2 ZigBeeEndpoint
A ZigBeeEndpoint provides clusters objects (org.osgi.service.zigbee.ZigBeeCluster) whatever their facets: client or server.
Every single cluster, defined by the ZigBee Cluster Library specification, has a server and a client facet. A client facet is used to request (i.e sends commands or retrieves attribute value) the related server facet. Most of the ZigBee device implement server-facet clusters (that is the case for the ZPlug smart plug from Cleode). The ZigBee base driver transparently implements the client facet of the clusters.
For instance, the org.osgi.service.zigbee.ZigBeeEndpoint service representing the endpoint 1 of a ZPlug smart plug from Cleode provides the following server-facet clusters:
- ZigBeeCluster for the Basic cluster(id : 0x00).
- ZigBeeCluster for the Identify cluster(id : 0x03).
- ZigBeeCluster for the Groups cluster(id : 0x04).
- ZigBeeCluster for the Scene cluster(id : 0x05).
- ZigBeeCluster for the OnOff cluster(id : 0x06).
- ZigBeeCluster for the Metering cluster(id : 0x702).
2.2.3 ZigBeeCluster
A ZigBeeCluster provides commands (org.osgi.service.zigbee.ZigBeeCommand) and attributes (org.osgi.service.zigbee.ZigBeeAttribute) according to the ZigBee Cluster Library specification.
For instance, the OnOff ZigBeeCluster of a ZPlug smart plug from Cleode offers:
- the commands
- ZigBeeCommand for the Off command (id: 0x00).
- ZigBeeCommand for the On command (id: 0x01).
- ZigBeeCommand for the Toggle command (id: 0x02).
- the attributes
- ZigBeeAttribute for the OnOff attribute (id: 0x00).
2.2.4 ZigBeeCommand
A ZigBeeCommand object is used to send a command to the related device. The command is sent through a call to ZigBeeCommand.invoke(byte[], ZigBeeCommandHandler)
asynchronous method. The byte array argument contains the input argument of the command (if needed, else the array is empty). The second argument org.osgi.service.zigbee.ZigBeeCommandHandler is a callback to be called by the ZigBee base driver to notify about the result (success: ZigBeeCommandHandler.onSuccess or failure ZigBeeCommandHandler.onFailure) of the command.
2.2.5 ZigBeeAttribute
A ZigBeeAttribute object is used to retrieve the value of a ZigBee attribute.
ZigBee protocol offers two differents modes to get value of an attribute. The first one, called “polling”, sends a request to the equipment in order to retrieve the attribute value. This mode is used through a call to ZigBeeAttribute.getValue(ZigBeeAttributeHandler)
method.
The second mode is based on the reporting feature provided the ZigBee protocol. In such case, the device is requested to send the value of the attribute at specific period of time or when the value changes exceeds a threshold.
3 How to
This section shows how to send command and how to retrieve attribute value from an Open The Box application.
The first part describes briefly the architecture of the sample application to be completed during this tutorial.
The second part shows how to send command (On, Off, Toggle) to the ZPlug smart plug from Cleode. This part describes the Maven dependency to be added to your Open The Box application and how to retrieve the ZigBeeEndpoint OSGi service.
The third presents how to retrieve the value of the ZPlug smart plug attributes in polling mode.
Finally, the fourth part describes how to enable to reporting mode for retrieving attribute value.
3.1 hackathon.tutorial.zigbee application
This tutorial is based on the hackathon.tutorial.zigbee application which will to be completed in the next part of this section. This application shows how to send command and how to retrive attribute from a Cleode ZPlug smart plug.
This application is fully integrated in your Eclipse environment provided with the Ubuntu virtual machine (Please see here for more details). You should see:
The src/main/java folder contains all the Java classes of the application. These classes are organized by package:
- com.orange.openthebox.hackathon.tutorial.zigbee : contains the entrpy point of application (ZigBeeTutorialApp) et the web page servlet (ZigBeeTutorialServlet)
- com.orange.openthebox.hackathon.tutorial.zigbee.exception : exceptions handled by the application
- com.orange.openthebox.hackathon.tutorial.zigbee.response : attribute and command invocation callback to be used by the servlet.
The src/main/resources contains:
- OSGI-INF : all resources needed by the Open The Box framework such as the component-devices.xml file and the otb.properties file
- WEB-INF : the web page files such as HTML files, javascript files, pictures, fonts and css files..
The lib folder contains the ZigBee libraries to be added to your Eclipse project.
The pom.xml file is a Maven3 file used to configure and build the application bundle (to be deployed on the Open The Box framework).
This application provides some web pages which are used to test your application. The entry point url is http://@IP-target:8081/ZigBeeTutorial/index.html
.
You have to launch the Open The Box framework. The quick start guide can help you to do so. Before launching the Open The Box framework, please plug in the ZigBee dongle.
3.2 First step – How to use a ZigBee device from an Open The Box application
The hackathon.tutorial.zigbee application must be updated in order to use ZPlug smart plug from Cleode. The following actions must be done:
- Adding a Maven dependency to the ZigBee artifact library into the pom.xml file
- Adding a new service dependency into the Declarative Services component-devices.xml file).
- Modifying the entry point class of the application in order to retrieve the org.osgi.service.zigbee.ZigBeeEndPoint service related to the ZPlug endpoint.
- Implementing the business logic which send ZigBee command.
3.2.1 Adding the ZigBee Library
The hackathon.zigbee.tutorial application must be linked with the ZigBee APIs. These APIs are included in the org.osgi.service.zigbee.jar library.
This library is not published on public Maven repositories. As a consequence, it is included into the application Eclipse project (lib folder).
This library must be added into the pom.xml file of the application as a dependency artifact in order to add it into the Maven build process. So, edit the pom.xml file and check if the following lines are well located into the dependencies section:
<dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.service.zigbee</artifactId> <version>1.0</version> <scope>system</scope> <systemPath>${basedir}/lib/org.osgi.service.zigbee.jar</systemPath> </dependency>
Next, open a linux terminal et locate it in the /home/otb/workspace/hackathon.tutorial.zigbee. Then, update the Eclipse project settings by executing the next command:
mvn eclipse:eclipse
After that, go back to Eclipse, select the hackathon.zigbee.tutorial project and refresh it (F5). The org.osgi.service.zigbee.jar should appear into the Referenced Library folder.
3.2.2 Updating Declarative Services component of the application
As described in the Developer Guide page, the Open The Box applications owns a Declarative Services file (component-devices.xml) specifying a component requiring some OSGi services. This file also specifies the device access right (through their service dependencies).
The component-devices.xml file is located into the src/main/resources/OSGI-INF folder. It defines a component called Hackathon.ZigBee.Tutorial with the following characteristics:
- its implementation class (implementation tag) is com.orange.openthebox.hackathon.tutorial.zigbee.ZigBeeTutorialApp ;
- its properties (properties tag) are located into the OSGI-INF/otb.properties ;
- it requires two OSGi services (reference tag) :
- the standard OSGi log service: org.osgi.service.log.LogService
- the standard OSGi Http service Http: org.osgi.service.http.HttpService (REST api and web interface)
A new reference tag must be created in order to require the org.osgi.service.zigbee.ZigBeeEndpoint OSGi service related to the ZPlug smart plug:
- name = « zplug ». This attribute specifies the name of the service dependency.
- interface = « org.osgi.service.zigbee.ZigBeeEndpoint ». The interface attribute defines the type of OSGi service to be required.
- cardinality = « 0..1 ». The cardinality defines the number of ZigBeeEndpoint instance to be bound. It exists four differents cardinalities:
- 0..1 : the application will be activated even if no ZigBeeEndpoint service is available and at most, it will use only one ZigBeeEndpoint;
- 0..n : the application will be activated even if no ZigBeeEndpoint service is available and will use all available ZigBeeEndpoint;
- 1..1 : the application will be activated only if at least one ZigBeeEndpoint service is available. The application will use only one of them;
- 1..n : the application will be activated only if at least one ZigBeeEndpoint service is available. The application will use all of them.
- bind = « bindZPlug ». Defines the method name (to be implemented into the implementation class of the component: com.orange.openthebox.hackathon.tutorial.zigbee.ZigBeeTutorialApp). Declarative Services makes a call to this method when a org.osgi.service.zigbee.ZigBeeEndpoint service is available in the OSGi registry. This method is used to retrieve the org.osgi.service.zigbee.ZigBeeEndpoint service related to the ZPlug smart plug.
- unbind = « unbindZPlug ». Defines the method name (to be implemented into the implementation class of the component: com.orange.openthebox.hackathon.tutorial.zigbee.ZigBeeTutorialApp). Declarative Services calls this method when the org.osgi.service.zigbee.ZigBeeEndpoint service (the one related to the Zplug smart plug) is unregistered from the OSGi registry (i. e the ZPlug smart plug leaves the ZigBee network or the application is going to be stopped).
- target = « (DEVICE_FRIENDLY_NAME=Mains Power Outlet*) ». Defines a filter used to select the service objects to be bound (in our case, the org.osgi.service.zigbee.ZigBeeEndpoint service with a property DEVICE_FRIENDLY_NAME matching the “Mains Power Outlet*” chain.
At the end, your component-devices.xml file should looks like:
3.2.3 Modifying the entry point implementation class of the application
The entry point class of the application the implementation class of the Declarative Services component: com.orange.openthebox.hackathon.tutorial.zigbee.ZigBeeTutorialApp. It is located into the src/main/resources.
As seen in the previous part, the bindZPlug(ZigBeeEndpoint) method and the unbindZPlug(ZigBeeEndpoint) method have to be implemented into the entry point class.
Declarative Services calls ZigBeeTutorialApp.bindZPlug(ZigBeeEndpoint) when the ZPlug smart plug endpoint object is registered or when the application starts. The implementation of this method should:
- store the ZigBeeEndpoint object (related to the ZPlug smart plug). We can use store the value into the “zplug” member variable.
- create a log DEBUG trace through the LogService in order to make easier the debugging of the application.
At the end, your ZigBeeTutorialApp.bindZPlug(ZigBeeEndpoint) method should looks like:
Declarative Services calls the ZigBeeTutorialApp.unbindZPlug(ZigBeeEndpoint) method when the application is going to stop and or when the ZPlug smart plug. The implementation of the method should set null the “zplug” member variable in order to release the leaving ZigBeeEndpoint object.
3.2.4 Implementing the business logic which send ZigBee command
From the ZigBeeEndpoint bound through the bindZPlug(ZigBeeEndpoint) method, it is quite easily to get clusters and their associated ZigBee commands.
A ZPlug smart plug provides three commands, all of them are located into the OnOff server cluster (id : 0x06):
- Off: switch off the smart plug
- On: switch on the smart plug
- Toggle: change the plug state (On->Off or Off->On).
A command are executed through the org.osgi.service.zigbee.ZigBeeCommand objects which are located into clusters (org.osgi.service.ZigBeeCluster).
A ZigBeeCommand object own the invoke method which is used to send the command to the ZigBee device. This method has two input parameters:
- a byte array specifying the input parameters of the ZigBee command. This parameter may be an empty array if the underlying ZigBeeCommand do not need input arguments; this is typically the case for the on, off and toggle commands. Other ZigBeeCommand (provided by other types of devices) may need input parameters. The ZigBee Cluster Library specification describes the input parameters for the commands.
- a ZigBeeCommandHandler object. This handler is a callback to be called by the ZigBee Base Driver to inform about the success (ZigBeeCommandHandler.onSuccess(byte[])) or the failure (ZigBeeCommandHandler.onFailure(ZigBeeException)) of the command.
The com.orange.openthebox.hackathon.tutorial.zigbee.ZigBeeTutorialApp class implements ZPlugManager interface. This interface specifies the on(ZigBeeCommandHandler), off(ZigBeeCommandHandler) and toggle(ZigBeeCommandHandler) methods. The ZigBeeTutorialServlet servlet uses these three methods to send on, off and toggle commands.
You have to complete the on(ZigBeeCommandHandler) method, the off(ZigBeeCommandHandler) method and the toggle(ZigBeeCommandHandler) method into the ZigBeeTutorialApp class:
- check if the “zplug” member variable is not null (i.e the ZPlug smart meter is available). If null, throw an UnavailableZPlugException exception.
- Get the OnOff server ZigBeeCluster (id : 0x06) object through a call to the zplug.getServer(clusterId) method.
- Get the on (and the two others) ZigBeeCommand object related to the on command (id : 0x01). ZigBeeCommand objects are retrieved through a call to ZigBeeCluster.getCommand(commandId). method. The id for the toggle command is (id : 0x02) and the id for the off command (id : 0x00).
- finally, call the ZigBeeCommand.invoke(byte[], ZigBeeCommandHandler) method. As on, off and toggle command do not have any input argument, the first argument is an empty byte array. The second one is the ZigBeeCommandHandler object given as input argument of the method.
The on method implementation looks like:
The implementation of the off(ZigBeeCommandHandler) method and the toggle(ZigBeeCommandHandler) method are quite similar. Only the identifier of ZigBeeCommand changes !
For your information, you can have a look on the CommandHandlerForServlet class (com.orange.openthebox.hackathon.tutorial.zigbee.response package). In particular, pay attention on the implementation of the CommandHandlerForServlet.onSuccess(byte[]) method and CommandHandlerForServlet.onFailure(ZigBeeException). The ZigBee base driver calls one of these two methods to report the success or the failure of the command.
If a on, off or toggle command invocation succeeds, the ZigBee base driver will make a call to the CommandHandlerForServlet.onSuccess(byte[]). The byte array should be empty for these three commands as they do not return any output data.
On the contrary, the ZigBee base driver will call the CommandHandlerForServlet.onFailure(ZigBeeException e). The provided ZigBeeException describes why the command failed.
3.2.5 Application build process
In the opened linux terminal, launch the command mvn clean install -o
.
Maven creates a jar called hackathon.tutorial.zigbee-1.0.3-SNAPSHOT.jar into the target folder:
3.2.6 ZigBee base driver installation
The bundle of the base driver are automatically installed by the Open The Box framework when the TI CC2530 is detected. As you plugged in the dongle at the beginning of this tutorial, the bundles of the base driver were installed at that time.
You can check if ZigBee the base driver is fully installed with the the Android Open The Box Dashboard application.
Open the Dashboard, and have a look on the right part. You will see a ZigBee logo with a number. It represents the number of connected ZigBee devices + 1 for the ZigBee dongle. If the number is above or equals to 1, it means that the ZigBee base driver is functional:
For instance, here we have 3 connected ZigBee devices + 1 for the dongle: the ZigBee base driver is properly installed!
3.2.7 Install the application
The developer guide fully explains how to locally install an application on your Raspberry Pi.
Open web browser on page http://@IP-target:8081/habam/index.html. Then upload the application jar. If the installation is completed, you should see the application identifier in the Return. Please, keep a copy of this application identifier as it is used to update the application afterwards.
3.2.8 Test
Open a new tab in your web browser and go to the page http://@IP-raspberry:8081/ZigBeeTutorial/index.html. The web page looks like:
You can test the implementation of the on, off and toggle command through this page.
Now, if you click on the button located into the attribute table, you will see a “Not Implemented” message. This is the next step 😉 !
3.3 Second step – How to get ZigBee attribute value (polling mode)
The ZigBee attributes are represented by ZigBeeAttribute objects. These objects are located into their related cluster (ZigBeeCluster).
The ZPlug smart plug provides 3 attributes:
- the OnOff attribute (id: 0x00) belonging to the OnOff cluster (id : 0x06). This attribute holds the status (on or off) of the smart plug.
- the currentSummationDelivered attribute (id: 0x00). This attribute is hold by the Metering cluster (id : 0x702). This attribute contains the cumulative value of electrical consumption (unit: kWh).
- the instantaneousDemand attribute (id: 0x400) of the Metering cluster (id : 0x702).This attribute informs about the instantaneous consumption value (unit: kW per hour).
The above ZigBeeAttribute section described two different attribute value retrieving modes: “polling” mode and “reporting” mode. This section only focuses the “polling” mode, that is to say the application asks the value of the attribute through a ZigBee request.
The polling mode attribute value retrieving is executed through a call to ZigBeeAttribute.getValue(ZigBeeAttributeHandler)
method. This is an asynchronous method. The ZigBeeAttributeHandler input argument is a callback to be used by the ZigBee base driver to report about the success or the failure of this operation.
If the operation completes, the base driver will make a call to ZigBeeAttributeHandler.onSuccess(Map)
method. The map argument contains the value of the attribute.
If the operation fails, the base driver will call ZigBeeAttributeHandler.onFailure(ZigBeeException)
. The ZigBeeException argument explains why the operation failed.
The ZPlugManager interface specifies three methods related to the attribute polling mode retrieving value:
- the getOnOffAttributeValue(ZigBeeAttributeHandler) method. It gets the value of the OnOff attribute (id: 0x00) belonging to the OnOff cluster (id: 0x06).
- the getInstantaneousDemandValue(ZigBeeAttributeHandler) method. It is dedicated to the retrieving of the instantaneousDemand value (id: 0x400). This attribute belongs to the Metering cluster (id: 0x702).
- the getCurrentSummationDeliveredValue(ZigBeeAttributeHandler) method. It retrieves the value of the currentSummationDelivered attribute (id: 0x00) of the Metering cluster.
These three methods have to be implemented into the ZigBeeTutorialApp class. The ZigBeeTutorialServlet servlet uses them to get the value of the ZPlug smart plug attributes.
3.3.1 Add polling mode retrieving code into the ZigBeeTutorialApp class
You have to implement the three methods described above. Each one has to perform the next actions:
- Check if the ‘zplug’ ZigBeeEndpoint member variable is not null. If so, throw an UnavailableZPlugException exception
- Retrieve, through a call to ZigBeeEndpoint.getServerCluster(clusterId) method, the OnOff server cluster (id: 0x06) or the Metering server cluster (id: 0x702).
- Then, retrieve the ZigBeeAttribute object related to the requested attribute: make a call to
ZigBeeCluster.getAttribute(attributeId)
method. Use the attribute identifier value 0x00 for both OnOff attribute and currentSummationDelivered attribute. Use the attribute identifier 0x400 for the instantaneousDemand attribute. - Finally, invoke the ZigBeeAttribute.getValue(ZigBeeAttributeHandler) on the ZigBeeAttribute object you get in the previous action. The ZigBeeAttributeHandler object to be used is given as input argument of the method.
For instance, here is a snapshot of the fully implemented ZigBeeTutorialApp.getOnOffAttributeValue(ZigBeeAttributeHandler)
:
The implementation of the two other methods (i.e code>ZigBeeTutorialApp.getInstantaneousDemandValue(ZigBeeAttributeHandler) method and ZigBeeTutorialApp.getCurrentSummationDeliveredValue(ZigBeeAttributeHandler)
method) are similar. Only the cluster identifier (Metering : 0x702) and the attribute identifiers (currentSummationDelivered : 0x00, instantaneousDemand : 0x400) have to be updated.
For your information you can have a look on the AttributeHandlerForServlet class. This class implements the ZigBeeAttributeHandler interface. The ZigBeeTutorialServlet servlet creates instances of this class and gives them to three methods implemented above.
If the reading attribute value succeeds, the base driver will call the AttributeHandlerForServlet.onSuccess(Map)
method. Here is a snapshot of this method:
The map argument contains the value of the attribute. Use the id of the attribute to get the value. This id must be an Integer object. For instance, if the map contains the value of the OnOff attribute or the currentSummationDelivered attribute, the key to use to retrieve the value is 0x00. For the instantaneousDemand attribute, the key is 0x400.
3.3.2 Build the application and update it on the raspberry pi
In the linux terminal, execute again the Maven command used to build the application: mvn clean install -o
.
From the http://@IP-target:8081/habam/index.html, update your application bundle (“Update Application (jar)”) with the application identifier you previously stored.
3.3.3 Tests
Refresh the http://@IP-target:8081/ZigBeeTutorial/index.html page from your web browser.
The web page should look like:
If you click on button, you will see the status (OnOff attribute), the instantaneous and cumulative consumption.
3.4 Third step – ZigBee notifications (reporting mode)
The reporting mode enables a ZigBee device to periocally send the value of its attributes. The periodicity of notification is based on interval of reporting as well as a threshold for the discrete attributes. For instance, this mode is very usefull in case of we want to be immediately informed about a status change of the ZPlug smart plug.
The reporting mode uses a ZigBeeEventListener service. A ZigBeeEventListener is a listener which has to be registered as an OSGi service (white board pattern). The base driver notifies ZigBeeEventListener services when it receives reporting messages about an attribute ( attribute value change or depending on the periodicity).
The base driver calls the ZigBeeEventListener.notifyEvent(ZigBeeEvent)
to notify to the listener the received reporting message. The value of the attribute is retrieved through a call to ZigBeeEvent.getValue()
.
The CustomZigBeeEventListener class implements the ZigBeeEventListener interface. The following actions have to be performed in order to enable the reporting mode for an attribute:
- register a CustomZigBeeEventListener object as an ZigBeeEventListener service.
- create one CustomZigBeeEventListener object per attribute that we want to receive reporting message.
3.4.1 Registering of CustomZigBeeEventListener services
A ZigBeeEventListener must be registered as an OSGi service with the next mandatory properties:
Property name | Value |
---|---|
zigbee.node.ieee.address | IEEE address of the ZigBee device. For instance: “00124b0002202697” The value of this parameter is located behind the ZPlug smart plug. |
zigbee.endpoint.id | Endpoint identifier. For instance, “1” |
zigbee.cluster.id | Cluster identifier. For instance, “6” |
zigbee.attribute.id | Attribute identifier. For example, “0” |
zigbee.attribute.min.report.interval | Minimum interval of time betweeb two notifications. The value must be a String of an 4-digit hexadecimal integer value. For instance, "0x0000" . |
zigbee.attribute.max.report.interval | Maximum interval between two notifications. . The value must be a String of an 4-digit hexadecimal integer value. For instance, "0x001e" .Be careful, max value must be higher than min. |
zigbee.attribute.reportable.change | Threshold value triggering a notification.This parameter is relevant only in case of discrete value attribute. It must not be added if it is not the case. For instance, the instantaneousDemand attribute and the currentSummationDelivered attribute are discrete value attribute |
The CustomZigBeeEventListener class owns the registerAsAService(BundleContext) method. This method has to be completed in order to register the current CustomZigBeeEventListener object as a ZigBeeEventListener service. Use the provided BundleContext object to register the service. Here is a possible implementation:
3.4.2 Create CustomZigBeeEventListener object from the ZigBeeTutorialApp class
We have to create one CustomZigBeeEventListener object per attribute: OnOff attribute, currentSummationDelivered attribute and instantaneousDemand attribute.
The ZigBeeTutorialApp class owns the ZigBeeTutorialApp.registerZigBeeEventListener()
which is dedicated to register the CustomZigBeeEventListener objects. The three member variables (onOffCustomZigBeeEventListener, instantaneousDemandCustomZigBeeEventListener et currentSummationDeliveredCustomZigBeeEventListener) must be used to store the related CustomZigBeeEventListener.
The constructor of the CustomZigBeeEventListener class takes the next arguments:
- the ZPlug smart plug IEEE address;
- the endpoint identifier;
- the cluster identifier;
- the attribute identifier;
- the minimum interval reporting value;
- the maximum interval reporting value;
- the threshold value (only for instantaneousDemand attribute and currentSummationDelivered attribute).
Here is an implementation example:
Once the ZigBeeTutorialApp.registerZigBeeEventListeners()
has been completed, call it from the activate()
:
For your information, Declarative Service calls ZigBeeTutorialApp.activate()
method at the startup of the application.
3.4.3 Servlet
The ZigBeeTutorialServlet servlet uses CustomZigBeeEventListener objects through the ZigBeeTutorialApp.getOnOffAttributeValueUsingNotification(timeout)
method, ZigBeeTutorialApp.getCurrentSummationDeliveredAttributeValueUsingNotification(timeout)
method and ZigBeeTutorialApp.getInstantaneousDemandAttributeValueUsingNotification(timeout) method
.
The servlet takes advantage of the long-polling mecanism. This mecanism delays the answer to a HTTP request until an attribute notification is received or until a timeout is reached. The web browser is in charge of requesting the attribute value through this long-polling mecanism, waits for the response and requests again the same value (and so on…)
3.4.4 Build the application and update it on the raspberry pi
From the linux terminal, execute again the mvn clean install -o
command.
Update the application bundle on the raspberry pi (using the HABAM web page).
3.4.5 Tests
Refresh the http://@IP-target:8081/ZigBeeTutorial/index.html.
Here is a snapshot of the web page:
You enable the long-polling mecanism by:
- checking the “Reporting” checkbox
- and enabling the “Auto Refresh” button.
The “delay” field can be used to set the timeout value for the long-polling mecanism.
If you manually toggle the smart plug from the device, the web interface should automatically update the value of the OnOff attribute.
4 Annex
4.1 Requests handled by the ZigBeeTutorialServlet servlet
4.1.1 Commands
URL | HTTP method | Action |
---|---|---|
http://@_ip_hab:8081/ZigBeeTutorial/api/command/on | POST | Swith on the ZPlug smart plug |
http://@_ip_hab:8081/ZigBeeTutorial/api/command/off | POST | Switch off the ZPlug smart plug |
http://@_ip_hab:8081/ZigBeeTutorial/api/command/toggle | POST | Toggle the state of the plug (Off -> On or On -> Off) |
ZigBeeTutorialServlet.doPost(request, response) handles these requests.
4.1.2 Attributes
URL | HTTP method | Action |
---|---|---|
http://@_ip_hab:8081/ZigBeeTutorial/api/attribute/onOff | GET | Get the value of the OnOff attribute of the OnOff cluster in polling mode. Example of response: {“value”:”false”} |
http://@_ip_hab:8081/ZigBeeTutorial/api/attribute/onOff?reporting=timeout | GET | Get the value of the OnOff attribute of the OnOff cluster in reporting mode. The reporting parameter set the value of timeout. Unit: milliseconds. Example of response: {“value”:”false”} |
http://@_ip_hab:8081/ZigBeeTutorial/api/attribute/currentSummationDelivered | GET | Get the value of the CurrentSummationDelivered attribute of the Metering cluster in polling mode. Example of response : {“value”:”10481″} |
http://@_ip_hab:8081/ZigBeeTutorial/api/attribute/currentSummationDelivered?reporting=timeout | GET | Get the value of the CurrentSummationDelivered attribute of the Metering cluster in reporting mode. The reporting parameter set the value of timeout. Unit: milliseconds. Example of response: {“value”:”10481″} |
http://@_ip_hab:8081/ZigBeeTutorial/api/attribute/instantaneousDemand | GET | Get the value of the InstantaneousDemand attribute of the Metering cluster in polling mode. Example of response : {“value”:”0″} |
http://@_ip_hab:8081/ZigBeeTutorial/api/attribute/instantaneousDemand?reporting=timeout | GET | Get the value of the InstantaneousDemand attribute of the Metering cluster in reporting mode. The reporting parameter set the value of timeout. Unit: milliseconds. Example de response : {“value”:”0″} |
ZigBeeTutorialServlet.doGet(request, response) method handles these requests.
4.2 Web page architecture
All web pages are located into src/main/resources/WEB-INF folder:
The web ui uses the Bootstrap CSS framework and the jQuery library. The developer can used any CSS or javascript framework.
The web ui is composed of a static html file (index.html) displaying the commands and attributes of the ZPlug smart plug. Dynamic data like attribute value are loaded through AJAX requests. This is the same for ZPlug commands.
- the index.html page is the entry point of the web ui. It loads all needed javascript files (bootstrap.js, bootstrap-min.js, jquery-1.11.2.min.js, data.js).
- The js folder is composed of the javascript framework file (such as bootstrap and jQuery). It also contains data.js file. This file implements javascript functions to be used to send AJAX request to the ZigBeeTutorialServlet servlet).
- img folder holds pictures of the application.
- fonts folder contains some bootstrap glyphicons.
- css folder holds all css file.
4.3 Management console
The ZigBee base driver provides a web user interface. This interface can be used to list ZigBee devices. It is also used to open the ZigBee network (allow new ZigBee device to join the network).
The url of this web interface is http://@IP-target:8081/configurator.
Use the credentials:
- login: admin
- password: orange
4.3.1 Pairing
A ZigBee device must be paired in order to join an existing ZigBee network. A ZigBee coordinator handles only one ZigBee network.
From the web interface, go to the “add equipement” tab and click on the “Add” button:
The ZigBee network will be opened for about 60s.
4.3.2 List of devices
Go the “current equipment” tab:
For each device, you can see its endpoints, its clusters and attributes. It is also possible to invoke ZigBee commands (only if they do not need input arguments).
4.4 Compliant devices
The next table lists compliant ZigBee equipement:
td>Siren
Type | Vendor | Modèle | Version | Comments |
---|---|---|---|---|
Door opening detector | CLEODE | ZDOOR | Rev 2.2 | Sometimes, this device needs to join again the network. |
NETVOX | Z601A | 3.0 | ||
Smart Plug | CLEODE | ZPLUG | 5.11 et 5.14 | |
Gaz pump | NETVOX | ZA10 | 1.4 | |
Smart Plug | DEVELCO | Enable the reporting mode on Metering cluster attributes. | ||
Motion sensor | CLEODE | ZMOVE | Rev 2.4 Année 2014 | Enable the reporting mode on the Occupancy attribute (0x00) of the cluster OccupancySensing (0x406) |
Button | CLEODE | ZRC | Rev 5.1 Année 2011 | Sometimes, need to join again the ZigBee network. |
5 References
ZigBee Cluster Library – http://zigbee.org/?wpdmdl=2177