Tutoriel ZigBee

Atelier Open the Box

Table des matières

1      Introduction
2      Concepts ZigBee
2.1         Concepts de base
2.2         Intégration à la plate-forme Open the Box
3      Mise en œuvre
3.1         Application hackathon.tutorial.zigbee
3.2         Étape 1 : intégration d’’un équipement ZigBee dans l’’application
3.3         Étape 2 : récupération de la valeur des attributs en mode polling
3.4         Étape 3 : récupération de la valeur d’’un attribut en mode reporting
4      Annexes
4.1         Requêtes gérées par la servlet ZigBeeTutorialServlet
4.2         Architecture IHM
4.3         Console d’’administration
4.4         Équipements compatibles
5      Références

1         Introduction

Le présent tutoriel montre comment intégrer des équipements ZigBee dans une application Open the Box.

Il est décomposé en deux parties. La première présente les concepts liés à la technologie ZigBee (architecture, équipements). La seconde partie mettra en œuvre ces concepts avec une prise communicante ZPlug de Cleode.

2         Concepts ZigBee

2.1       Concepts de base

En ZigBee, un équipement est/offre un ou plusieurs endpoints représentant un équipement logique fournissant une application. Chaque endpoint fournit des clusters qui sont des objets applicatifs. Chacun de ces clusters fournit des commandes et des attributs spécifiques.

La spécification ZigBee Cluster Library définit chacun des clusters disponibles avec leurs commandes et attributs.

Par exemple, la prise communicante ZPlug de Cleode fournit un seul endpoint (id : 1) contenant les clusters Basic (0x00), Identify (0x03), Groups (0x04), Scene (0x05), OnOff (0x06) et Metering (0x702).Le cluster OnOff contient 3 commandes (On, Off, Toggle) et un attribut (On/Off), cf. figure ci-dessous.

2.2       Intégration à la plate-forme Open the Box

La plate-forme Open the Box intègre un base driver ZigBee qui, via le dongle TI CC2531, réifie l’’ensemble des équipements ZigBee du réseau (resp. leurs endpoints) par des services de type org.osgi.service.zigbee.ZigBeeNode (resp. org.osgi.service.zigbee.ZigBeeEndpoint). Chaque fois qu’’un équipement arrive ou quitte le réseau ZigBee, les services (ZigBeeNode et son/ses ZigBeeEndpoint) sont respectivement enregistrés ou désenregistrés du registre de services OSGi.

Par exemple, pour la prise communicante ZPlug de Cleode, le base driver ZigBee va créer :

  • un service de type org.osgi.service.zigbee.ZigBeeNode représentant l’’équipement physique ;
  • un service de type org.osgi.service.zigbee.ZigBeeEndPoint représentant l’’endpoint 1 de l’’équipement (équipement logique).

2.2.1       ZigBeeNode

Un ZigBeeNode sert à récupérer des informations relatives à l’’équipement ZigBee dans le réseau, comme le panId ou l’’adresse IEEE. ZigBeeNode permet aussi de faire sortir l’’équipement ZigBee correspondant de son réseau actuel.

En pratique, on utilisera peu ce type d’’objet.

2.2.2       ZigBeeEndpoint

Un ZigBeeEndpoint permet de récupérer les clusters (de type org.osgi.service.zigbee.ZigBeeCluster), qu’’ils soient de type client ou de type serveur.

Chaque cluster défini par la spécification ZigBee Cluster Library a généralement un profil « serveur » et un profil « client ». Le profil « client » sert à requêter le profil « serveur » correspondant. La plupart des équipements (c’’est le cas de la ZPlug) implémente des clusters de type « serveur ». Le profil « client » est automatiquement implémenté par le base driver ZigBee.

Par exemple, pour la ZPlug, le service org.osgi.service.zigbee.ZigBeeEndpoint représentant l’’endpoint 1 fournit les clusters de type « serveur » suivants :

  • ZigBeeCluster pour le cluster Basic (id : 0x00).
  • ZigBeeCluster pour le cluster Identify (id : 0x03).
  • ZigBeeCluster pour le cluster Groups (id : 0x04).
  • ZigBeeCluster pour le cluster Scene (id : 0x05).
  • ZigBeeCluster pour le cluster OnOff (id : 0x06).
  • ZigBeeCluster pour le cluster Metering (id : 0x702).

2.2.3       ZigBeeCluster

Chaque ZigBeeCluster fournit les commandes (org.osgi.service.zigbee.ZigBeeCommand) et attributs (org.osgi.service.zigbee.ZigBeeAttribute) associés et définis par la spécification ZigBee Cluster Library.

Par exemple, pour la ZPlug, l’’instance ZigBeeCluster OnOff (id : 0x06) fournit :

  • Les commandes
    • ZigBeeCommand pour la commande Off (id : 0x00).
    • ZigBeeCommand pour la commande On (id : 0x01).
    • ZigBeeCommand pour la commande Toggle (id : 0x02).
  • Les attributs
    • ZigBeeAttribute pour l’’attribut OnOff (id : 0x00).

2.2.4       ZigBeeCommand

Une instance ZigBeeCommand permet d’’envoyer la commande à l’’équipement correspondant. L’’envoi de cette commande, via la méthode invoke(byte[], ZigBeeCommandHandler), est asynchrone. Il convient de fournir une instance de type org.osgi.service.zigbee.ZigBeeCommandHandler qui recevra la réponse (positive ou négative) de l’’invocation.

2.2.5       ZigBeeAttribute

Une instance de ZigBeeAttribute permet de récupérer la valeur de l’’attribut correspondant.

Il existe deux modes permettant de récupérer la valeur de l’’attribut.

Le premier, appelé « polling », interroge directement l’’équipement afin d’’obtenir la valeur de l’’attribut, via la méthode getValue(ZigBeeAttributeHandler) de l’’instance ZigBeeAttribute.

Le second mode met en œuvre le mécanisme ZigBee appelé « reporting », qui configure l’’équipement afin qu’’il émette une notification à périodicité régulière ou lorsque l’’attribut en question change de valeur.

3         Mise en œuvre

Cette section précise comment mettre en pratique les différents concepts présentés dans la section précédente.

La première partie décrira l’’architecture de l’’application à trous servant tout au long de cette section.

La seconde partie de cette section décrira comment intégrer dans une application Open the Box une prise communicante ZPlug de Cleode. Cette partie abordera notamment la question des dépendances Maven liées au base driver ZigBee, la gestion des services ZigBeeEndpoint et l’’utilisation des instances ZigBeeCommand.

La troisième partie décrira comment récupérer la valeur des attributs en mode « polling ».

Enfin, la quatrième partie mettra en œuvre la récupération des valeurs d’’attributs en mode « reporting ».

3.1       Application hackathon.tutorial.zigbee

L’’application hackathon.tutorial.zigbee est utilisée dans ce tutoriel afin de montrer comment utiliser une prise communicante ZPlug de Cleode dans une application Open the Box.

Cette application est intégrée dans Eclipse fourni avec la machine virtuelle Ubuntu (voir ici). Elle est visible dans le workspace Eclipse sous cette forme :

projet_hackathon.tutorial.zigbee

Le dossier src/main/java contient l’’ensemble des classes java organisées par package :

  • com.orange.openthebox.hackathon.tutorial.zigbee : contenant le point d’’entrée de l’’application (ZigBeeTutorialApp) et la partie IHM (ZigBeeTutorialServlet)
  • com.orange.openthebox.hackathon.tutorial.zigbee.exception : l’’ensemble des exceptions créées et gérées par cette application
  • com.orange.openthebox.hackathon.tutorial.zigbee.response : gestion des invocations (attributs & commandes) via la servlet.

Le dossier src/main/resources contient :

  • OSGI-INF : ressources liées à l’’intégration dans la plate-forme Open the Box (component-devices.xml et otb.properties)
  • WEB-INF : ressources liées à la partie IHM web (fichier HTML, javascript, images, fonts et css).

Le dossier lib contient les librairies ZigBee nécessaires à ce tutoriel.

Le fichier pom.xml permet la configuration et la construction du projet via Maven 3.

Cette application possède une interface web qui sera utilisée pour tester les développements réalisés durant ce tutoriel. Elle est accessible à l’’adresse http://@IP-target:8081/ZigBeeTutorial/index.html

3.2       Étape 1 : intégration d’’un équipement ZigBee dans l’’application

L’’intégration de la prise communicante ZPlug de Cleode à une application Open the Box nécessite les actions suivantes :

  • L’’ajout de la librairie ZigBee au projet de l’’application.
  • L’’ajout d’’une dépendance de service dans le fichier Declarative Services component-devices.xml.
  • La modification de la classe principale de l’’application afin de récupérer le service org.osgi.service.zigbee.ZigBeeEndPoint associé à la ZPlug.
  • L’’ajout du code applicatif permettant l’’envoi de commandes ZigBee à la prise communicante.

3.2.1       Ajout de la librairie ZigBee

Afin de pouvoir utiliser les APIs ZigBee, l’’application doit intégrer la librairie org.osgi.service.zigbee.jar.

Cette librairie n’’étant pas encore disponible sur les répertoires Maven en ligne, elle a été intégrée dans le répertoire lib de l’’application du tutoriel.

Il convient cependant de la rajouter dans le système de construction Maven3. Pour cela, il faut éditer le fichier pom.xml et de vérifier que les lignes suivantes sont bien présentes dans la section dependencies :

<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>

On ouvre ensuite un terminal et on se place dans le dossier /home/otb/workspace/hackathon.tutorial.zigbee. On met à jour la configuration Eclipse en exécutant la commande dans ce terminal :

mvn eclipse:eclipse

On retourne ensuite dans Eclipse, on sélectionne le projet hackathon.tutorial.zigbee et on appuie sur la touche F5 qui permet de rafraîchir le projet dans Eclipse. On devrait alors voir apparaître la librairie org.osgi.service.zigbee.jar dans la liste des librairies associées au projet :

3.2.2       Mise à jour du fichier Declarative Services

Comme vu dans le Guide de développement, les applications Open the Box possèdent un fichier Declarative Services (component-devices.xml) permettant de spécifier les dépendances de services liées aux applications. Il sert aussi à spécifier les droits d’’accès à ces équipements.

Le fichier component-devices.xml se trouve dans le dossier src/main/resources/OSGI-INF.

Ce fichier XML définit le composant Hackathon.ZigBee.Tutorial ayant les caractéristiques suivantes :

  • sa classe d’implémentation (balise implementation) est com.orange.openthebox.hackathon.tutorial.zigbee.ZigBeeTutorialApp ;
  • ses propriétés (balise properties) sont localisées dans le fichier OSGI-INF/otb.properties ;
  • il utilise deux services OSGi (balise reference) :
    • un service de log de type org.osgi.service.log.LogService
    • un service Http de type org.osgi.service.http.HttpService (pour la partie IHM web)

Afin d’’intégrer la prise communicante ZPlug à cette application, il convient de créer une nouvelle reference vers un service de type org.osgi.service.zigbee.ZigBeeEndpoint avec les propriétés suivantes :

  • name = « zplug ». Cet attribut permet de spécifier un nom à la dépendance de service.
  • interface = « org.osgi.service.zigbee.ZigBeeEndpoint ». L’’interface définit le type de service OSGi (i.e. l’’interface Java de programmation) que l’’application requiert.
  • cardinality = « 0..1 ». La cardinalité permet de définir le nombre d’’instances de service org.osgi.service.zigbee.ZigBeeEndpoint qui seront utilisées par l’’application. Il en existe 4 différentes :
    • 0..1 : l’’application fonctionnera sans équipement ZigBee présent et utilisera au plus un équipement ZigBee ;
    • 0..n : l’’application fonctionnera sans équipement ZigBee présent et utilisera tous les équipements ZigBee disponibles ;
    • 1..1 : l’’application ne fonctionnera que si au moins 1 équipement ZigBee est présent et elle n’en n’utilisera qu’un seul ;
    • 1..n : l’’application ne fonctionnera que si au moins 1 équipement ZigBee est présent et elle les utilisera tous.
  • bind = « bindZPlug ». Définit la méthode de la classe d’’implémentation du composant (com.orange.openthebox.hackathon.tutorial.zigbee.ZigBeeTutorialApp) qui est appelée par Declarative Services lorsqu’’un service de type org.osgi.service.zigbee.ZigBeeEndpoint sera disponible. Cette méthode permet de récupérer l’’instance de service org.osgi.service.zigbee.ZigBeeEndpoint associé à la prise communicante.
  • unbind = « unbindZPlug ». Définit la méthode de classe d’’implémentation du composant (com.orange.openthebox.hackathon.tutorial.zigbee.ZigBeeTutorialApp)  qui est appelée par Declarative Services lorsque le service org.osgi.service.zigbee.ZigBeeEndpoint représentant la prise communicante n’’est plus disponible (soit parce que la prise communicante a quitté le réseau, soit lorsque l’’on arrête l’’application).
  • target = « (DEVICE_FRIENDLY_NAME=Mains Power Outlet*) ». Définit un filtre permettant de spécifier précisément quel service OSGi org.osgi.service.zigbee.ZigBeeEndpoint utiliser. Il pourrait en effet y en avoir plusieurs s’’il y a plusieurs équipements ZigBee disponibles.

Au final, le fichier component-devices.xml :

3.2.3       Modification de la classe principale de l’’application

La classe principale de l’’application est la classe d’’implémentation du component Declarative Services com.orange.openthebox.hackathon.tutorial.zigbee.ZigBeeTutorialApp. Elle se trouve dans le dossier src/main/java.

Afin de récupérer l’’instance de service org.osgi.service.zigbee.ZigBeeEndpoint correspondant à la prise ZPlug, nous devons implémenter les méthodes bindZPlug(ZigBeeEndpoint) et unbindZPlug(ZigBeeEndpoint) qui ont été définies dans la section précédente.

La méthode bindZPlug(ZigBeeEndpoint) est appelée par Declarative Services lorsqu’’une prise communicante est disponible sur le réseau ZigBee.  L’’implémentation de cette méthode consiste simplement à :

  • stocker le ZigBeeEndpoint fourni en paramètre dans la variable membre zplug de la classe afin de la réutiliser plus tard ;
  • tracer l’’appel via le service de log pour faciliter la phase de mise au point de l’’application.

La méthode unbindZPlug(ZigBeeEndpoint) est appelée par Declarative Services lorsque la ZPlug n’’est plus disponible (i.e lorsque la prise quitte le réseau ou lorsque l’’application s’’arrête). L’’implémentation de cette méthode consiste à :

  • mettre à null la variable membre zplug afin de ne plus utiliser le service ZigBeeEndpoint qui n’’est plus disponible ;
  • tracer l’’appel via le service de log pour faciliter la phase de mise au point de l’’application.

3.2.4       Ajout de code applicatif permettant d’’envoyer des commandes à la prise

Une fois que l’’instance ZigBeeEndpoint a été récupérée via la méthode bindZPlug(ZigBeeEndpoint) définie dans la section précédente, il est très facile de récupérer les clusters et commandes associés afin d’’envoyer des ordres à la prise communicante.

La ZPlug répond à trois commandes, toutes les trois fournies par le cluster de type serveur OnOff (id : 0x06) :

  • Off : éteint la prise
  • On : allume la prise
  • Toggle : fait changer d’état la prise (i.e On à Off ou Off à On)

L’’envoi de commande ZigBee se fait via les instances de type org.osgi.service.zigbee.ZigBeeCommand. Ces instances ZigBeeCommand sont stockées dans les clusters (org.osgi.service.ZigBeeCluster).

Chaque ZigBeeCommand possède une méthode invoke qui permet d’’envoyer la commande à l’’équipement. Cette méthode prend comme paramètre :

  • un tableau de bytes permettant de spécifier des arguments si la commande en nécessite. Ce n’’est pas le cas pour les commandes on, off et toggle ;
  • une instance de ZigBeeCommandHandler. Ce handler est appelé lorsque l’’invocation a été réalisée, et permet de savoir si l’’invocation a été un succès (appel de ZigBeeCommandHandler.onSuccess(byte[])) ou un échec (appel de ZigBeeCommandHandler.onFailure(ZigBeeException)).

La classe d’’implémentation com.orange.openthebox.hackathon.tutorial.zigbee.ZigBeeTutorialApp implémente l’’interface ZPlugManager qui spécifie les méthodes on(ZigBeeCommandHandler), off(ZigBeeCommandHandler) et toggle(ZigBeeCommandHandler). Ces trois méthodes sont utilisées par la servlet ZigBeeTutorialServlet pour envoyer respectivement les commandes on, off et toggle.

On complètera donc l’’implémentation des méthodes on(ZigBeeCommandHandler), off(ZigBeeCommandHandler) et toggle(ZigBeeCommandHandler), présentes dans la classe ZigBeeTutorialApp, de la façon suivante :

  • On vérifie que l’’instance ZigBeeEndpoint zplug n’’est pas nulle. Si elle l’’est, on renvoie l’’exception UnavailableZPlugException.
  • On récupère le cluster serveur OnOff (id : 0x06) du ZigBeeEndpoint zplug via la méthode ZigBeeEndpoint.getServer(clusterId).
  • On récupère l’’instance de ZigBeeCommand correspondant à la commande on (id : 0x01), off (id : 0x00) ou toggle (id : 0x02) via la méthode ZigBeeCluster.getCommand(commandId).
  • Enfin, on lance l’’invocation de la commande via la méthode ZigBeeCommand.invoke(byte[], ZigBeeCommandHandler). Le tableau de byte[] est vide car il n’’y a pas d’’argument à fournir pour les commandes on, off ou toggle. On passera l’’instance ZigBeeCommandHandler reçue en paramètre via la servlet comme second argument.

L’’implémentation des méthodes off(ZigBeeCommandHandler) et toggle(ZigBeeCommandHandler) est identique. Seul l’’identifiant de commande change !

À titre d’’information, on pourra aller voir l’’implémentation de la classe CommandHandlerForServlet (package com.orange.openthebox.hackathon.tutorial.zigbee.response) qui implémente l’’interface ZigBeeCommandHandler. Lors de l’’invocation des commandes on, off et toggle depuis l’’ihm web, la servlet crée des instances de CommandHandlerForServlet et les passe en argument des méthodes ZigBeeTutorialApp.on(ZigBeeCommandHandler), ZigBeeTutorialApp.off(ZigBeeCommandHandler) et ZigBeeTutorialApp.toggle(ZigBeeCommandHandler).

En cas de succès de l’’invocation des commandes on, off ou toggle, la méthode CommandHandlerForServlet.onSuccess(byte[]) est appelée. Dans notre cas, les commandes on, off et toggle ne renvoient aucune information. Le tableau de bytes fourni est donc vide.

Dans le cas contraire (i.e échec de la commande), c’’est la méthode CommandHandlerForServlet.onFailure(ZigBeeException) qui est appelée. Le paramètre ZigBeeException permet de connaitre la cause de l’’échec.

3.2.5       Construction de l’’application

Dans le terminal ouvert précédemment, on exécute la commande mvn clean install

Maven va alors créer le jar hackathon.tutorial.zigbee-1.0.3-SNAPSHOT.jar dans le dossier target :

3.2.6       Installation du base driver ZigBee

L’’installation du base driver ZigBee se fait automatiquement en branchant le dongle ZigBee fourni dans l’’un des ports USB du Raspberry Pi.

3.2.7       Déploiement de l’’application

Comme décrit dans la section Cycle de vie du guide du développeur, on ouvre un navigateur web à la page d’’administration HABAM http://@IP-target:8081/habam/index.html. On utilise la commande « Upload Application (jar)» pour installer cette nouvelle application.

Après l’’installation, un numéro d’’application devrait apparaître dans le paramètre Return. On gardera précieusement ce numéro d’’application pour des déploiements futurs (on peut le retrouver en cliquant sur le lien « Installed Applications »).

3.2.8       Test

On ouvre un nouvel onglet dans le navigateur sur la page http://@IP-target:8081/ZigBeeTutorial/index.html (lien qu’’on peut retrouver en appelant « Configure Application » de la page HABAM). On devrait alors avoir :

On fera quelques tests des commandes on, off et toggle via cette page web de test.

En cliquant sur le bouton du tableau attribut, on voit apparaître un message « Not implemented ». C’’est l’’objet de l’’étape suivante !

3.3       Étape 2 : récupération de la valeur des attributs en mode polling

Les attributs ZigBee sont représentés par des instances ZigBeeAttribute. Ces instances sont stockées au niveau des clusters (ZigBeeCluster).

La prise communicante ZPlug propose 3 attributs intéressants :

  • l’’attribut onOff (id : 0x00) du cluster OnOff (id : 0x06) qui informe du fait que la prise est allumée (valeur : true) ou éteinte (valeur : false) ;
  • l’’attribut currentSummationDelivered (id : 0x00) du cluster Metering (id : 0x702) qui donne la consommation cumulative de la prise communicante (en Wh) ;
  • l’’attribut instantaneousDemand (id : 0x400) du cluster Metering (id : 0x702) qui donne la consommation instantanée de la prise (en Wh).

Comme évoqué dans le paragraphe ZigBeeAttribute, il existe deux modes pour récupérer la valeur d’’un attribut : le mode polling et le mode reporting. Cette section traite de la récupération de la valeur via le mode polling c’’est-à-dire que c’’est l’’application qui demande la valeur en émettant une requête ZigBee.

La récupération de la valeur se fait via la méthode ZigBeeAttribute.getValue(ZigBeeAttributeHandler), qui est asynchrone. L’’instance ZigBeeAttributeHandler recevra la valeur de l’’attribut (ZigBeeAttributeHandler.onSuccess(Map)) ou un message d’’erreur (ZigBeeAttributeHandler.onFailure(ZigBeeException)).

3.3.1       Implémentation dans la classe ZigBeeTutorialApp

Comme pour l’’envoi de commande, la classe ZigBeeTutorialApp fournit les méthodes getOnOffAttributeValue(ZigBeeAttributeHandler), getCurrentSummationDeliveredValue(ZigBeeAttributeHandler) et getInstantaneousDemandValue(ZigBeeAttributeHandler) qui permettent de récupérer respectivement la valeur des attributs OnOff, CurrentSummationDelivered et InstantaneousDemand en mode polling. Ces trois méthodes sont appelées par la servlet ZigBeeTutorialServlet.

L’’implémentation de ces trois méthodes consiste à :

  • Vérifier si l’’instance ZigBeeEndpoint zplug est nulle. Dans l’’affirmative, on renvoie l’’exception UnavailableZPlugException notifiant de l’’absence de la prise communicante.
  • Récupérer via la méthode ZigBeeEndpoint.getServerCluster(clusterId) l’’instance ZigBeeCluster OnOff (id : 0x06) ou le cluster Metering (id : 0x702) suivant l’’attribut.
  • Ensuite, on récupère l’’instance ZigBeeAttribute pour les différents attributs via la méthode ZigBeeCluster.getAttribute(attributeId). Pour rappel, l’’identifiant de l’’attribut OnOff est 0x00, celui de l’’attribut instantaneousDemand est 0x400 et celui de l’’attribut currentSummationDelivered est 0x00.
  • Une fois l’’instance ZigBeeAttribute récupérée, on invoque la méthode ZigBeeAttribute.getValue(ZigBeeAttributeHandler) avec l’’instance ZigBeeAttributeHandler fournie.

 Ci-dessous l’’implémentation complète de la méthode ZigBeeTutorialApp.getOnOffAttributeValue(ZigBeeAttributeHandler) :

L’’implémentation des méthodes ZigBeeTutorialApp.getInstantaneousDemandValue(ZigBeeAttributeHandler) et ZigBeeTutorialApp.getCurrentSummationDeliveredValue(ZigBeeAttributeHandler) est pratiquement identique. Seul les identifiants de cluster (Metering : 0x702) et les identifiants d’’attributs (currentSummationDelivered : 0x00, instantaneousDemand : 0x400) changent.

À titre d’’information, on peut regarder la classe AttributeHandlerForServlet du package com.orange.openthebox.hackathon.tutorial.zigbee.response qui implémente ZigBeeAttributeHandler. Une instance de cette classe est passée aux trois méthodes implémentées précédemment par la servlet.

La méthode AttributeHandlerForServlet.onSuccess(Map), appelée en cas de succès de la lecture de la valeur de l’’attribut,  est implémentée de la façon suivante :

On récupère la valeur de l’’attribut dans la Map nommée response. La clé pour récupérer la valeur est l’’identifiant de l’’attribut sous la forme d’’un objet de type Integer. Pour l’’attribut onOff et currentSummationDelivered, la clé est 0x00. Pour l’’attribut instantaneousDemand, la clé est 0x400.

3.3.2       Construction de l’’application et mise à jour sur la HAB

Dans le terminal, on ré-exécute la commande Maven permettant de construire le jar de l’’application : mvn clean install.

Depuis le navigateur web pointant sur la page http://@IP-target:8081/habam/index.html, on utilise la commande « Update Application (jar) » en saisissant l’’id d’’application obtenue lors de la première installation et en sélectionnant le jar mis à jour dans le dossier target.

3.3.3       Tests

Depuis le navigateur web pointant sur la page http://@IP-target:8081/ZigBeeTutorial/index.html, on rafraîchit la page, on devrait alors avoir :

En cliquant sur les boutons , on peut voir l’’état de la prise (attribut onOff), la consommation instantanée et la consommation cumulative.

3.4       Étape 3 : récupération de la valeur d’’un attribut en mode reporting

Le mode reporting permet de configurer la prise communicante ZPlug afin qu’’elle émette, à périodicité régulière ou sur changement de valeur, un message contenant la valeur des attributs. L’’intérêt de cette méthode est bien évidemment d’’être informé de manière instantanée lorsque la prise est allumée ou éteinte manuellement par l’’utilisateur.

Le mode reporting introduit une nouvelle entité appelée ZigBeeEventListener. Un ZigBeeEventListener est un listener qui est enregistré en tant que service OSGi et qui reçoit des notifications (ZigBeeEvent) à chaque fois que l’’attribut associé change de valeur ou en fonction d’’une périodicité.

Les notifications sont reçues via la méthode ZigBeeEventListener.notifyEvent(ZigBeeEvent). L’’objet ZigBeeEvent passé en argument possède la méthode ZigBeeEvent.getValue() qui permet de récupérer la nouvelle valeur de l’’attribut.

L’’application contient la classe CustomZigBeeEventListener qui implémente l’’interface ZigBeeEventListener. Afin de rendre opérationnel la notification via le mécanisme de reporting, il faut :

  • Enregistrer l’instance CustomZigBeeEventListener en tant que service OSGi avec les propriétés nécessaires.
  • Créer les instances de CustomZigBeeEventListener pour chaque attribut dont on veut recevoir les notifications.

3.4.1       Enregistrement des CustomZigBeeEventListener

Un ZigBeeEventListener doit être enregistré comme service OSGi avec les propriétés suivantes :

Nom propriété Valeur
zigbee.node.ieee.address Adresse IEEE de l’équipement. Par exemple : “00124b0002202697”
La valeur de ce paramètre est inscrite sur l’’étiquette collée derrière la prise communicante.
zigbee.endpoint.id Identifiant du endpoint. Par exemple, “1”
zigbee.cluster.id Identifiant du cluster. Par exemple, “6”
zigbee.attribute.id Identifiant de l’attribut. Par exemple, “0”
zigbee.attribute.min.report.interval Intervalle minimum entre deux notifications. La valeur doit être un String représentant un entier en hexadécimal sur 4 chiffres. Par exemple "0x0000".
zigbee.attribute.max.report.interval Intervalle maximum entre deux notifications. La valeur doit être un String représentant un entier en hexadécimal sur 4 chiffres. Par exemple "0x001e".
Attention, max doit être supérieur à min.
zigbee.attribute.reportable.change Valeur minimum déclenchant une notification.
Ce paramètre n’’est applicable que pour les attributs dont la valeur est dite « discrète ». C’’est le cas des attributs instantaneousDemand et currentSummationDelivered.

La classe CustomZigBeeEventListener possède la méthode registerAsAService(BundleContext) qu’’il convient de compléter afin d’’enregistrer l’’instance en tant que ZigBeeEventListener. On se sert de l’’objet BundleContext pour cela. L’’ensemble des valeurs des différentes propriétés est présent sous forme de variables de classe. Une implémentation possible :

3.4.2       Création des instances CustomZigBeeEventListener dans la classe ZigBeeTutorialApp

Depuis la classe ZigBeeTutorialApp, il faut créer un CustomZigBeeEventListener pour chacun des attributs onOff, currentSummationDelivered et instantaneousDemand.

La méthode ZigBeeTutorialApp.registerZigBeeEventListener() a pour but de créer une instance de CustomZigBeeEventListener pour chacun des trois attributs. Pour ces trois attributs, il existe une variable membre (onOffCustomZigBeeEventListener, instantaneousDemandCustomZigBeeEventListener et currentSummationDeliveredCustomZigBeeEventListener) qu’’il convient d’’initialiser.

Le constructeur de la classe CustomZigBeeEventListener prend en arguments :

  • l’’adresse IEEE de la prise communicante ;
  • l’’identifiant du endpoint ;
  • l’’identifiant du cluster ;
  • l’’identifiant de l’’attribut ;
  • la valeur de l’’intervalle minimum ;
  • la valeur de l’’intervalle maximum ;
  • la valeur de seuil de déclenchement (uniquement pour les attributs instantaneousDemand et currentSummationDelivered).

Par exemple :

Une fois la méthode ZigBeeTutorialApp.registerZigBeeEventListeners() implémentée, il convient de l’’appeler depuis la méthode activate() :

La méthode ZigBeeTutorialApp.activate() sera appelée lors du démarrage de l’’application par Declarative Services.

3.4.3       Liaison avec la servlet

La servlet ZigBeeTutorialServlet va utiliser les instances de type CustomZigBeeEventListener via les méthodes ZigBeeTutorialApp.getOnOffAttributeValueUsingNotification(timeout), ZigBeeTutorialApp.getCurrentSummationDeliveredAttributeValueUsingNotification(timeout) et ZigBeeTutorialApp.getInstantaneousDemandAttributeValueUsingNotification(timeout).

La servlet utilise le mécanisme de « long-polling » qui consiste à retarder l’’envoi de la réponse d’’une requête afin de limiter les interactions client-serveur. Ce mécanisme est mis en œuvre afin de renvoyer une valeur d’’attribut nouvellement reçue ou d’’attendre timeout millisecondes pour renvoyer la dernière valeur connue de l’’attribut.

Le navigateur web va donc appeler la servlet, attendre la réponse (soit une nouvelle valeur, soit la dernière reçue) et rappeler la même servlet.…

3.4.4       Construction de l’’application et mise à jour sur la HAB

Dans le terminal, on ré-exécute la commande Maven permettant de construire le jar de l’’application : mvn clean install

On met aussi à jour l’’application sur la target (« Update Application (jar) » depuis la page HABAM).

3.4.5       Tests

Depuis le navigateur web pointant sur la page http://@IP-target:8081/ZigBeeTutorial/index.html, on rafraîchit la page, on devrait alors avoir :

On active le mécanisme de long-polling :

  1. En cochant la case « Reporting »
  2. Et en activant le bouton « Auto Refresh »

Le champ Delay permet de configurer le paramètre timeout.

En appuyant sur le bouton On/Off situé sur la prise, l’’attribut OnOff doit varier automatiquement sur l’’interface web.

4         Annexes

4.1       Requêtes gérées par la servlet ZigBeeTutorialServlet

4.1.1       Commandes

URL Méthode HTTP Action
http://@_ip_hab:8081/ZigBeeTutorial/api/command/on POST Allume la prise communicante
http://@_ip_hab:8081/ZigBeeTutorial/api/command/off POST Éteint la prise communicante
http://@_ip_hab:8081/ZigBeeTutorial/api/command/toggle POST Change d’’état la prise communicante (on à off, off à on)

Les requêtes précédentes sont gérées par la méthode ZigBeeTutorialServlet.doPost(request, response).

4.1.2       Attributs

URL Méthode HTTP Action
http://@_ip_hab:8081/ZigBeeTutorial/api/attribute/onOff GET Renvoie la valeur de l’’attribut OnOff du cluster OnOff en mode polling.
Exemple de réponse : {“value”:”false”}
http://@_ip_hab:8081/ZigBeeTutorial/api/attribute/onOff?reporting=timeout GET Renvoie la valeur de l’’attribut OnOff du cluster OnOff en mode reporting.
Le paramètre reporting permet de configurer la valeur timeout. Valeur en millisecondes.
Exemple de réponse : {“value”:”false”}
http://@_ip_hab:8081/ZigBeeTutorial/api/attribute/currentSummationDelivered GET Renvoie la valeur de l’’attribut CurrentSummationDelivered du cluster Metering en mode polling.
Exemple de réponse : {“value”:”10481″}
http://@_ip_hab:8081/ZigBeeTutorial/api/attribute/currentSummationDelivered?reporting=timeout GET Renvoie la valeur de l’’attribut CurrentSummationDelivered du cluster Metering en mode reporting.
Le paramètre reporting permet de configurer la valeur timeout. Valeur en millisecondes.
Exemple de réponse : {“value”:”10481″}
http://@_ip_hab:8081/ZigBeeTutorial/api/attribute/instantaneousDemand GET Renvoie la valeur de l’’attribut InstantaneousDemand du cluster Metering en mode polling.
Exemple de réponse : {“value”:”0″}
http://@_ip_hab:8081/ZigBeeTutorial/api/attribute/instantaneousDemand?reporting=timeout GET Renvoie la valeur de l’’attribut InstantaneousDemand du cluster Metering en mode reporting.
Le paramètre reporting permet de configurer la valeur timeout. Valeur en millisecondes.
Exemple de réponse : {“value”:”0″}

Les requêtes précédentes sont gérées par la méthode ZigBeeTutorialServlet.doGet(request, response).

4.2       Architecture IHM

Les pages web de l’’application sont disponibles dans le dossier src/main/resources/WEB-INF :

L’’ihm est construite à l’’aide du framework CSS bootstrap et du framework Javascript jQuery. Le choix de ces deux frameworks n’’est en aucun cas obligatoire. Tout framework de même nature pourrait être utilisé dans une application Open the Box.

L’’architecture est simple : une page HTML statique (index.html) montrant les commandes et attributs de la prise communicante ; l’’utilisation de requêtes AJAX (avec le framework JQuery) permettant de requêter les informations dynamiques (id du plug) et d’’envoyer des commandes ou d’’obtenir la valeur des attributs ; des fichiers de style permettant la mise en forme de la page web.

  1. La page index.html est la page principale de l’’application. Elle charge l’’ensemble des scripts (bootstrap.js, bootstrap-min.js, jquery-1.11.2.min.js, data.js).
  2. Le dossier js contient les fichiers javascript des framework bootstrap et jQuery. Il contient aussi le fichier data.js qui contient des fonctions pour requêter la servlet ZigBeeTutorialServlet.
  3. Le dossier img contient les images de l’’application.
  4. Le dossier fonts contient les glyphicons bootstrap.
  5. Le dossier css contient les fichiers css fournis par le framework bootstrap ainsi que le fichier index.css utilisé par la page HTML index.html.

4.3       Console d’’administration

Le base driver ZigBee inclut une IHM web qui permet de lister les équipements ZigBee actuellement disponibles sur le réseau. Elle permet aussi d’’ouvrir le réseau ZigBee permettant l’’appairage de nouveaux équipements.

Cette IHM est accessible via l’’url http://@IP-target:8081/configurator

Utiliser le compte admin dont le mot de passe est orange.

4.3.1       Appairage

Un équipement ZigBee doit être appairé pour rejoindre le réseau ZigBee géré par le coordinateur.

Depuis la console web, aller dans l’onglet « add equipment » et cliquer sur le bouton Add :

Le réseau va rester ouvert 60 s environ et se refermer automatiquement.

4.3.2       Liste des équipements

Depuis la console, aller dans l’’onglet « current equipment » :

L’’ensemble des équipements actuellement connectés sur le réseau est listé. Pour chaque équipement, on peut retrouver ses endpoints, ses clusters, ses attributs. Il est aussi possible d’’invoquer certaines commandes (notamment celles ne nécessitant pas d’’arguments).

4.4       Équipements compatibles

Le tableau suivant liste les équipements qui ont été testés :

Type Marque Modèle Version Commentaires
Détecteur ouverture de porte CLEODE ZDOOR Rev 2.2 Nécessite de temps en temps d’’être réappairé ou alors de redémarrer le framework.
NETVOX Z601A 3.0
Plug CLEODE ZPLUG 5.11 et 5.14
Vanne de gaz NETVOX ZA10 1.4
Plug DEVELCO Reporting à mettre sur le cluster Metering
Détecteur de mouvement CLEODE ZMOVE Rev 2.4 Année 2014 Activer le reporting sur le paramètre Occupancy (0x00) du cluster OccupancySensing (0x406)
Bouton CLEODE ZRC Rev 5.1 Année 2011 Nécessite de temps en temps d’’être réappairé ou alors de redémarrer le framework.

5         Références

ZigBee Cluster Library – http://zigbee.org/?wpdmdl=2177