Inovia Blog

L’actualité des technologies innovantes

Pratique du réseau LoRa|WAN avec Objenious, PlatformIO et Node-RED

Par Kadda SAHNINE

Publié le | 18 septembre 2016 | Pas de commentaire

Lora - PlatformIO - Node-RED

La société Objenious, filiale de Bouygues Telecom dédiée à l’Internet des Objets (IoT), a eu la courtoisie de me faire parvenir un kit de développement très complet et permettant d’expérimenter le réseau bas débit LoRa actuellement en cours de déploiement.

Cet article a pour objet de vous familiariser au réseau LoRa à travers le développement d’une boîte aux lettres connectée, notifiant en temps réel dès la réception du courrier.

Ce sera également l’occasion de se familiariser avec PlatformIO, un environnement de plus en plus populaire chez les développeurs de systèmes embarqués, ainsi que Node-RED, un fantastique outil permettant d’élaborer des scénarios d’intégration complexes et dont j’ai déjà vanté les mérites dans un précédent billet.

Présentation du kit

Remarquablement packagé, le kit de développement d’Objenious contient :

  • un microcontrôleur The Airboard, très compact et modulaire, de type Arduino avec un facteur de forme XBee et muni d’une batterie LiPo de 3,7 V rechargeable (capacité de 155 mAh)
  • le module LoRaBee, un transceiver LoRa avec un facteur de forme XBee conçu par la société ATIM
  • une antenne 868 MHz avec connecteur SMA
  • un programmateur FTDI muni d’un câble USB
  • un jeu de capteurs et d’actionneurs :
    • un bouton poussoir
    • un thermistor
    • un détecteur filaire d’ouverture de porte
  • un jeu de résistances et de câbles

Objenious kit

Un peu de terminologie

A l’instar de SIGFOX (dont j’ai déjà parlé dans cet article), les réseaux LoRa/LoRaWAN font partis de la famille des réseaux de type LPWAN (Low-Power Wide-Area Network), des réseaux de communication radio à longue portée, bas débit et à faible consommation, très adaptés au déploiement d’un réseau d’objets connectés.
Conçu à l’origine par une start-up française (Cycleo) rachetée par le constructeur de semi-conducteurs Semtech, LoRa est en fait le nom donné à la technologie de modulation (la couche physique dans le modèle OSI) opérant sur la bande de fréquences 868 MHz (en Europe) et 975 Mhz (reste du monde) et permettant un débit théorique compris entre 0,3 et 50 kb/s.

LoRaWAN désigne le protocole mettant en oeuvre un réseau étendu à longue portée (correspond à la couche MAC du modèle OSI) utilisant une typologie en étoile où les noeuds (objets connectés) communiquent avec les applications (backends) via une passerelle LoRa.

L’Alliance LoRa est un consortium de plus de 300 constructeurs, intégrateurs et opérateurs visant à standardiser au niveau mondial les réseaux LPWAN autour du protocole LoRaWAN.

Par rapport à SIGFOX, un réseau LoRaWAN présente plusieurs avantages comparatifs :

  • un standard et une technologie ouverte. Il est ainsi tout à fait possible de déployer ses propres passerelles LoRa.
  • un débit plus important ouvrant la voie à des mises à jour OTA (Over The Air)
  • une technologie indépendante de l’opérateur garantissant un principe de réversibilité

Eléments d’architecture

L’architecture type que nous allons expérimenter est décrite dans le schéma suivant :

Architecture LoRa - Objenious


Le dépôt du courrier dans la boîte aux lettres connectée met en oeuvre la chaîne de liaison suivante :

  • envoi d’un message via le réseau LoRa de l’opérateur (Bouygues Telecom)
  • routage du message par la plateforme d’Objenious vers une instance Node-Red (appel d’un service REST/JSON)
  • traitement du message par Node-RED et envoi d’une notification Pushbullet
  • réception de la notification Pushbullet sur un smartphone

Environnement de développement

Etant plutôt adepte de la ligne de commande, j’ai abandonné l’EDI Arduino au profit de PlatformIO, un environnement de développement ouvert (vous avez le choix de l’éditeur de code), supportant un très large éventail de micro-contrôleurs et s’intégrant parfaitement à une chaîne d’intégration continue.
J’ai une préférence pour la variante PlatformIO CLI (command line interface) utilisée dans cet article.

Installation

PlatformIO CLI est écrit en Python (v 2.7 recommandée) et est installable via pip :

pip install -U platformio

Créer la structure du projet

Note : les impatients peuvent récupérer l’ensemble du projet prêt à l’emploi via les commandes suivantes :

git clone https://github.com/ksahnine/mailbox-lora.git
cd mailbox-lora/objeniouskit/lora-notifier

Les commandes suivantes permettent d’initialiser un projet vide.

mkdir lora-notifier
cd lora-notifier
pio -f init -d . -b fio

Le paramètre -d indique le répertoire racine du projet. Le micro-contrôleur étant pré-chargé avec le bootloader de l’Arduino Fio, on passera l’option -b fio pour définir le type de plateforme cible.

Note : la commande pio est un alias de la commande platformio.

A ce stade, le répertoire projet ne contient que:

  • le fichier de configuration du projet platformio.ini
  • 2 sous-répertoires src et lib

PlatformIO gère un registre de librairies tierces installables en ligne de commande et offre une gestion simple des mises à jour des dépendances.
Nous utiliserons les librairies suivantes :

  • ArmAPI : l’API utilisée pour piloter le transceiver LoRa (ou tout transceiver ATIM de la gamme ARM - Advanced Radio Modem)
  • IsTime, une librairie Arduino implémentant un timer (utilisé pour n’envoyer qu’une seule notification pendant une période donnée)

La commande pio lib search permet de rechercher une librairie dans le registre à partir d’un mot clé :

$ pio lib search lora
[ ID  ] Name             Compatibility         "Authors": Description
---------------------------------------------------------------------------------------------------
[ 374 ] armapi           arduino, atmelavr, atmelsam, espressif, intel_arc32, microchippic32 [...]

$ pio lib search timer
[ ID  ] Name             Compatibility         "Authors": Description
---------------------------------------------------------------------------------------------------
[1006 ] istime           arduino, atmelavr, atmelsam, espressif8266, intel_arc32, microchippic32 [...]

Procédons à l’installation des 2 librairies via la commande pio lib install suivie des identifiants des librairies :

pio lib install 374 1006
Note : la mise à jour des dépendances s’effectue via la commande pio lib update.
La commande pio lib list affiche la liste des librairies installées.

Déposer dans le répertoire ./src le code source du programme disponible sur mon dépôt Github.
Le code ne présente aucune difficulté. Noter que :

  • la fonction setup()
    • configure le module LoRa (via l’API d’ATIM) et a
    • attache la routine d’interruption tiltStateChange() à chaque changement d’état de l’entrée D3 du micro-contrôleur
  • la routine d’interruption tiltStateChange() ignore les changements d’état superflus (par plage de 30 secondes) et envoie un message LoRa
  • l’intervalle minimum entre 2 notification est de 30 secondes par défaut (variable interval)
Note : Objenious met à disposition publie sur son compte Github quelques exemples de code prêt à l’emploi.

Téléverser le programme via une liaison série

Raccordez le micro-contrôleur au programmateur FTDI fourni comme suit :

Airboard FTDI

Mettez sous tension le micro-contrôleur puis lancer la commande ci-dessous pour compiler et téléverser le programme :

pio run -t upload

Raccordement du capteur

Le prototype utilise un capteur d’inclinaison ou de vibration bon marché fixé sur le volet de la boite aux lettre. On pourrait également utiliser un interrupteur REED (à lame souple) et un aimant.

Raccordement capteur

Routage vers un serveur d’application

Côté Objenious

L’interface d’administration d’Objenious permet de définir des scénarios de traitement des données issues des objets connectés : envoi de mail ou routage vers un serveur tiers.
C’est précisément le dernier type de scénario que nous allons mettre en oeuvre afin de rerouter le message vers votre propre serveur d’application (backend Node-RED dans notre cas).
Naturellement, le backend peut être auto-hébergé sur un serveur Raspberry Pi par exemple. Voir à ce sujet mon article Pratique du réseau M2M SIGFOX avec Sens’it et Docker.

Depuis ce lien de l’interface d’administration, créer un scénario de type Routage, sélectionner le type de capteurs à utiliser et saisir l’URL du point de terminaison du serveur Node-RED.

Interface d'aministration Objenious

Le message est publié par la plateforme d’Objenious vers le serveur d’application tiers sous la forme d’un appel HTTP (méthode POST) avec un contenu au format JSON structuré comme suit :

Outre les données purement applicative (propriété data), on trouvera les informations suivantes :

  • device_id : identifiant de l’objet connecté
  • timestamp : horodatage d’émission du message
  • deveui : identifiant unique sur 64 bits (DevEUI) défini par le protocole LoRaWAN et attribué par le fabricant du transceiver LoRa. Il est utilisé pour identifier l’objet connecté sur le réseau.
  • appeui : identifiant unique sur 64 bits (AppEUI) défini par le protocole LoRaWAN, utilisé pour identifier l’application destinatrice du message (le backend d’Objenious j’imagine)
  • lat et lng : les coordonnées de l’objet connecté, relevées au moment de la publication du message. La précision est approximative.

Côté backend Node-RED

Voici le flux de traitement Node-RED permettant de traiter les messages reroutés par le serveur d’Objenious :

Node-RED flow


Il est constitué de l’enchaînement des noeuds suivants :

  • noeud Objenious in : listener HTTP/POST interceptant les messages publiés par la platefome d’Objenious :

    Node-RED listener
  • noeud Ack : fonction d’acquittement du message publié par Objenious (retourne ACK).
  • noeud Objenious out : retourne la réponse HTTP contenant l’acquittement au serveur d’Objenious
  • noeud Message à envoyer : fonction construisant le message à envoyer dans la notification Pushbullet
  • noeud Notification téléphone : envoi d’une notification Pushbullet à un périphérique (smartphone, ordinateur, …)

Le code source du flux de traitement Node-Red est disponible sur mon dépôt Github (à déposer dans le répertoire .node-red de votre instance, puis à personnaliser)

Quelques ressources pour approfondir :

La détection de présence avec un Raspberry Pi 3 et Node-RED

Par Kadda SAHNINE

Publié le | 17 avril 2016 | 1 Commentaire

Node-RED


Comme de nombreux fans, je suis un heureux possesseur d’un Raspberry Pi 3, le dernier né de la fondation Raspberry Pi, intégrant en standard les technologies sans fil WiFi 802.11 b/g/n et Bluetooth Low Energy 4.1.
Ce concentré de technologies constitue une plateforme idéale pour une centrale domotique bon marché et un objet d’étude fort intéressant pour quiconque s’intéresse au monde de l’Internet des Objets (IoT).

Depuis longtemps déjà, j’avais le projet de réécrire le code de ma solution domotique “maison” avec Node-RED, un fantastique outil permettant d’élaborer des scénarios d’intégration complexes combinant des objets physiques (capteurs, micro-contrôleurs, transceivers, etc.) et des services en ligne.

Dans cet article, j’exposerai une solution de détection de présence (et d’absence) via Bluetooth fonctionnant aussi bien avec un smartphone ou un tracker Bluetooth bon marché glissé dans un cartable par exemple.
Les cas d’utilisation sont très nombreux. Citons par exemple :

  • la réception d’un itinéraire conseillé en transports en commun en sortant de chez soi
  • l’envoi d’une notification lorsque ses enfants sont bien rentrés à la maison
  • le verrouillage/déverrouillage d’une alarme
  • le pilotage d’une prise radio-commandée

Node-RED a vu le jour sous les hospices d’IBM Emerging Technologies Group à des fins de prototypage rapide de solutions IoT. Le code source a été publié en licence libre fin 2013.
Il offre un modèle de développement normalisé, orienté message, et une interface graphique permettant de décrire un flux de traitements.

Il existe une extension Node-RED fournissant un support Bluetooth (basée sur le module nodeJS noble) mais je n’ai pas trouvé le résultat satisfaisant, l’extension étant beaucoup trop expérimentale.

J’ai opté pour le développement en Python d’un service de découverte de périphériques Bluetooth, publiant vers Node-RED les évènements d’absence ou de présence dans un socket TCP (Node-RED propose en standard un module d’écoute TCP). Cette solution fonctionne très bien.
Le code source est disponible sur mon dépôt Github.

Mise en oeuvre

Node-RED est disponible par défaut sur les dernières versions de Raspbian Jessie ou installable via le gestionnaire de paquets APT :

sudo apt-get update
sudo apt-get install nodered

Procéder ensuite aux étapes suivantes :

  • installer les dépendances :
    sudo apt-get install bluetooth python-yaml python-bluetooth
    
  • recopier la configuration et les flux Node-RED mis en oeuvre dans le cadre de l’article :
    wget -P ~/.node-red https://github.com/ksahnine/rpi-home-automation/blob/master/.node-red/settings.js
    wget -P ~/.node-red https://github.com/ksahnine/rpi-home-automation/blob/master/.node-red/flows.json
    
    Attention : les 2 commandes ci-dessus remplacent votre configuration et vos flux Node-RED ! Faites l’opération manuellement si vous partez d’une configuration existante.
  • installer l’application de détection de périphériques :
    git clone https://github.com/ksahnine/rpi-home-automation.git
    
  • configurer le fichier rpi-home-automation/ble2tcp/devices.yml
  • démarrer Node-RED puis le programme de détection de périphériques Bluetooth :
    node-red
    python rpi-home-automation/ble2tcp/ble2node-red.py -c rpi-home-automation/ble2tcp/devices.yml
    

L’interface Node-RED est accessible par défaut sur le port 1880 du Raspberry Pi (ex: http://rumah.local:1880/)

Comment ça marche

Les périphériques à surveiller sont définis dans un fichiers de configuration (devices.yml) au format YAML :

Un scan est effectué périodiquement toutes les 4 secondes.

Note : l’adresse Bluetooth d’un périphérique peut être récupérée via la commande hcitool scan sous Debian après avoir installé le paquet bluetooth (sudo apt-get install bluetooth).

Lorsque l’état d’un périphérique change (présence ou absence), un évènement est publié au format JSON dans un socket TCP :

L’évènement est ensuite lu en entrée du flux de traitement Node-RED :

Node-RED flow


Il est constitué de l’enchaînement de noeuds suivants :

  • noeud BLE to Node TCP scanner : implémente un listener TCP écoutant les évènements de présence ou d’absence des périphériques surveillés.
    Node-RED TCP

  • noeud json : transforme l’évènement en objet JSON
  • noeud Présence ? : switch orientant le traitement en fonction de la présence ou de l’absence d’un périphérique
    Node-RED switch

  • noeud Arrivé : traite l’évènement émis lorsqu’un périphérique est proche du foyer
    Node-RED debug node

  • noeud Sorti : traite l’évènement émis lorsqu’un périphérique quitte le foyer

React ou l’art de la composition

Par Kadda SAHNINE

Publié le | 28 janvier 2016 | Pas de commentaire

Logo React


Eric Clemmons a publié sur Medium un billet d’humeur remarqué, intitulé JavaScript Fatigue, une lourde charge contre React et l’écosystème JavaScript.
Eric y déplore à juste titre la pénibilité d’initialiser un projet React, l’usage frénétique de boilerplates ou de générateurs de codes, la pléthore d’outils et d’API JavaScript en compétition les uns avec les autres, etc.

Tout cela est vrai. L’honnête développeur ou l’évangéliste JavaScript ne peuvent qu’acquiescer mais le réquisitoire contre React me paraît très injuste.
Pour appuyer cette conviction, je vous propose de découvrir les qualités de React à travers le développement d’un widget affichant les prochains passages du métro parisien dans une station donnée :

Widget RATP

Le rendu du widget est issu du code JSX ci-dessous :

On notera que le composant expose les propriétés suivantes :

  • type : le type de réseau (métro, rer, etc.)
  • line : le numéro de ligne
  • station : l’identifiant de la station
  • direction : l’identifiant de la direction

Le code source du widget est disponible sur mon dépôt GitHub.
Les données du trafic proviennent de l’excellente API REST de Pierre Grimaud

Mise en oeuvre pour les impatients

Si vous souhaitez tester localement ce projet, installez préalablement npm / node puis suivez le mode opératoire suivant :

git clone https://github.com/ksahnine/ratp-widget-react.git
cd ratp-widget-react
npm install
npm run dev
open http://localhost:8080
Note : je vous conseille d’utiliser npm/node à travers le gestionnaire de version nvm.

La structure du projet est la suivante :

├── app
│   ├── components
│   │   ├── RatpHeader.jsx
│   │   ├── RatpStatusBar.jsx
│   │   ├── RatpWidget.jsx
│   │   └── css
│   │       └── ratp-widget.css
│   └── main.js
├── build
│   └── index.html
├── package.json
└── webpack.config.js

React : en bref

React est une librairie JavaScript orientée composant développée par Facebook, permettant de construire des interfaces utilisateur modulaires et très performantes.
Elle jouit depuis plus d’un an d’une popularité grandissante, à telle enseigne que certains développeurs Angular envisagent sérieusement une conversion.
React encourage le développement d’interfaces utilisateur par composition, c’est-à-dire par assemblage de composants graphiques réutilisables pouvant eux mêmes être issus d’une composition. Ce modèle de conception est en train d’émerger dans le monde du développement des interfaces web et constitue une avancée majeure dans l’effort d’une plus grande standardisation des développements.

React présente au moins 3 avantages comparatifs :

  • la performance grâce au concept de DOM virtuel
  • l’approche composants
  • la possibilité de construire des applications universelles

Le DOM virtuel

Manipuler un arbre DOM directement via son API est compliqué. Suivre ses changements d’état est encore plus difficile et nécessite de développer des stratégies qui sont loin d’être neutres vis-à-vis des performances.
Angular 1 par exemple utilise la technique du dirty checking. Tous les objets du modèles sont surveillés en permanence, y compris ceux ne changeant jamais d’état.

Angular DOM

C’est une des raisons pour lesquelles Angular 1 pose des problèmes de performances, bien perceptibles sur des supports mobiles comme les tablettes.

React quant à lui implémente le concept de DOM virtuel, une structure de données JavaScript représentant l’arbre DOM dans un état donné. Lorsque le modèle de données évolue, React génère un nouveau DOM virtuel dans son intégralité, reflétant le nouvel état du modèle.

React DOM virtuel

React calcule ensuite le différentiel entre les 2 DOM virtuels et applique les modifications minimales à l’arbre DOM. Cette phase très performante est appelée réconciliation.

Orienté composant

Le principe de séparation des concepts (separation of concerns) appliqué au développement web consiste traditionnellement à séparer le code HTML, CSS et JavaScript. C’est un principe de division technologique.

Mais ce n’est pas la seule façon d’interpréter ce principe. L’approche de React est radicalement différente car elle consiste à développer des composants unitaires où template et logique de présentation sont encapsulés dans une même unité de développement en JavaScript.
Examinons cet exemple de composant React implémentant une fiche :

Ce qui peut décontenancer de prime abord, c’est l’impression de mélanger JavaScript, HTML et même CSS. Or ce n’est qu’une vue de l’esprit car tout est écrit en JavaScript, le code JSX n’étant que du sucre syntaxique pour rendre le code plus lisible.
Dans cette approche, le principe de séparation des responsabilités est plutôt fonctionnel, chaque composant remplissant une fonction élémentaire et exposant une interface bien définie (propriétés).

Applications universelles (ou isomorphiques)

Angular a popularisé le développement d’applications SPA (Single Page Application). Néanmoins, en plus de poser des problèmes de performance (l’ancien client web de Twitter en est un exemple fameux), cette architecture présente également l’inconvénient de rendre les sites non indexables par les moteurs de recherche.
React fonctionne aussi bien sur un navigateur (SPA) que sur un serveur (node.JS) ouvrant ainsi la voie au développement d’applications dites universelles (ou isomorphiques), c’est-à-dire pouvant s’exécuter de manière concomitante du côté client ou du côté serveur.

Pourquoi je crois en React

Au delà des qualités propres à React, je crois en la viabilité de cette librairie du seul fait de la pérennité du language JavaScript, quasiment la seule compétence requise pour développer avec React, alors que le développement d’une vue avec Angular ou tout autre framework MVC nécessite l’assimilation de nombreuses spécificités syntaxiques, par ailleurs changeantes au fil des versions (ex. ng-repeat Angular 1 devient ngFor sous Angular 2).
En outre, alors qu’Angular est plutôt centré sur HTML, React est totalement centré sur JavaScript (ES2015/ES6), incomparablement plus puissant que HTML.

Même si React est un projet encore jeune et que son écosystème fait penser à de la lave en fusion, je ne saurais trop vous conseiller de prendre ce projet au sérieux, ne serait-ce que pour pratiquer ECMAScript 6 et adopter un angle de développement tout à fait nouveau dans le monde des interfaces web.

Initialisation d’un projet : le trio React - Babel - webpack

C’est incontestablement la tâche la plus pénible. Elle a de quoi irriter beaucoup de développeurs tant elle peut être complexe, obscure et chronophage.
Nous utiliserons le gestionnaire de paquets npm pour installer les nombreux modules constituant la chaîne de développement et dont voici le descripteur package.json :

Essayons de démystifier tout cela. Les principaux composants utilisés dans la chaîne de développement sont :

React

Le projet utilise React 0.14.6, la version la plus récente publiée à ce jour.
Depuis la version 0.14, React a été découpé en deux paquets npm :

  • react : le coeur de la librairie React
  • react-dom : ce module est utilisé pour générer/synchroniser l’arbre DOM lors du rendu des composants React. L’opération peut se faire côté client (ReactDOM.render()) ou côté serveur (ReactDOMServer.renderToString()), ouvrant ainsi la voie au développement d’applications isomorphiques

L’idée de ce redécoupage est de mutualiser le code de React, ayant vocation à être multiplateforme (web ou mobile via React Native).

Babel

Même s’il est techniquement possible de développer un projet React en ECMAScript 5 (la version de JavaScript supportée par tous les navigateurs actuels), on tirera un énorme profit d’ECMAScript 6 tant les innovations de cette version simplifieront le développement.
On utilisera Babel 6.0, un transcompilateur JavaScript (ou compilateur source à source) transformant le code source ES6 en ES5.
Dans sa 6ème version, le code de Babel a été profondément réorganisé en plugins indépendants afin d’en faire une plateforme modulaire et ouverte vers d’autres outils ou langages.
Dans notre cas, nous utiliserons les modules :

  • babel-core : l’API node.JS de Babel
  • babel-loader : ce module est utilisé par webpack pour automatiser la transcompilation du code via Babel
  • babel-preset-es2015 : ensemble de plugins Babel (d’où le préfixe preset) pour le support ECMAScript 6.
  • babel-preset-react : ensemble de plugins Babel pour le support de React (la syntaxe JSX essentiellement).
  • babel-runtime : helpers et polyfills Babel

L’activation des presets babel-preset-es2015 et babel-preset-react nécessite de définir le fichier de configuration .babelrc à la racine du projet et avec le contenu suivant :

{
  "presets": ["es2015", "react"]
}

Webpack

Webpack est à la fois un gestionnaire de tâche et un assembleur de modules. Grâce à webpack, le code du projet peut être organisé en modules autonomes sans se soucier des problématiques de dépendances ou de packaging. On utilisera les packages npm webpack et webpack-dev-server.
Dans notre cas d’utilisation, webpack coordonne :

  • la transformation du code JSX en JavaScript
  • la transcompilation du code source ES6 en ES5
  • l’assemblage du projet et de ses dépendances en une seule unité de déploiement (dans notre cas, le fichier JavaScript bundle.js)

Webpack

Le module webpack-dev-server implémente un serveur HTTP local avec rechargement à chaud en cas de modification du code source.

Enfin, on utilisera également les 2 plugins webpack suivants :

  • css-loader :ce plugin permet “d’importer” une feuille de style CSS depuis un composant React
  • style-loader : ce plugin insère dynamiquement le code CSS d’une feuille de style importée dans une balise HTML style
Note : On aurait pu se passer de ces 2 plugins dans le cadre de notre projet.

Les règles d’assemblage du projet sont définies dans le fichier de configuration webpack.config.js situé à la racine du projet :

  • entry définit le point d’entrée de l’application (fichier app/main.js).
  • output définit le fichier résultant de l’assemblage des composants et de leurs dépendances (fichier build/bundle.js).
  • resolve.extensions contient un tableau des extensions identifiant les modules à assembler.
  • module.loaders contient 2 chargeurs, l’un traitant des imports CSS et l’autre du code JSX ainsi que de la transformation ES6/ES5 des fichiers contenus dans le répertoire app

L’application SPA est chargée dans le navigateur via le fichier statique build/index.html depuis un serveur web (ou plus exactement webpack-dev-server en mode développement) :

Développement du widget RatpWidget

Décomposition

Le schéma ci-dessous décrit un choix de décomposition du widget (RatpWidget) avec la hiérarchie de composants suivante :

  • RatpHeader : un cartouche affichant le logo de la ligne de métro, la station et la destination
  • RatpStatusBar : un message décrivant l’état du trafic sur la ligne

Décomposition du widget

RatpStatusBar

Le composant RatpStatusBar est très simple. Il affiche l’état du réseau défini par la propriété message du composant :

RatpStatusBar

Il est implémenté sous la forme d’un module ES6 afin de pouvoir être importé :

  • la directive import charge la librairie React.
  • le mot clé ES6 export permet d’exporter le composant au reste de l’application sous la forme d’un module.
  • l’API React.createClass() permet de définir un nouveau composant React.
  • la méthode render() implémente le rendu du composant, décrit par la syntaxe JSX. React invoque cette méthode dès que l’état ou une propriété du composant est modifié.
  • on notera à la ligne 11 que la propriété message du composant est utilisé pour afficher l’état du trafic ({this.props.message}).

RatpHeader

Passons au composant RatpHeader affichant le cartouche dont voici un exemple d’utilisation :

RatpHeader

Sa structure n’est pas très différente de celle du composant RatpStatusBar :

On remarquera à la ligne 7 que l’URL des icônes est dynamique et s’appuie sur de très pratiques template Strings, une fonctionnalité d’ES6.

RatpWidget

Analyson le code du composant (RatpWidget.jsx) :

  • 3 méthodes de l’API React sont utilisées :
    • getInitialState() retourne l’état initial du composant. Dans la terminologie React, un état (this.state) est un objet JavaScript accessible en lecture écriture et modélisant un ensemble de propriétés internes au composant.
    • render() implémente le rendu du composant. On notera l’utilisation des sous composants RatpHeader et RatpStatusBar
    • componentDidMount() est une méthode invoquée à l’initialisation du widget, juste avant l’appel à la méthode render(). Dans le cas d’espèce, on récupère les données du trafic via un appel AJAX.
  • Ligne 18 : la méthode fetchData récupère les données du trafic et met à jour l’état du widget (setState()).
    Note : l’architecture Flux (et en particulier le framework Redux) est un modèle de développement beaucoup plus adaptée à une application web.
  • Ligne 58 : les données sont mise à jour sur le clic du bouton de rafraichissement (onClick={this.fetchData}). Ainsi, l’état du composant est mis à jour et React invoque la méthode render() retournant le nouveau rendu.

Point d’entrée de l’application

Passons à la phase finale. Le point d’entrée de l’application est implémenté dans le fichier app/main.js :

On notera en particulier :

  • ligne 3 : import du composant React RatpWidget
  • ligne 8 : l’API RenderDOM.render() génère le rendu du composant RatpWidget (1er paramètre) dans l’arbre DOM (à l’intérieur du conteneur div passé dans le 2nd paramètre).

L’assemblage et la publication du projet est effectué par webpack via la commande npm run dev :

keep looking »

A propos de l'auteur

Kadda SAHNINE
Architecte technique Java EE
#JavaEE #Linux #vim addict #OpenSoftware #OpenHardware
Voir le profil de Kadda Sahnine sur LinkedIn

Flux RSS

Rechercher

Administration