En situation opérationnelle, les forces de sécurité et les secours ont de nombreux dispositifs à surveiller. Nous allons construire un boîtier d’alertes lumineuses afin d’alléger la charge des effectifs, le système réalisé devra être assez souple pour s’adapter à différents types de missions.
En tant que direction support, la Direction de l’Innovation, de la Logistique et des Technologies (DILT) de la préfecture de Police fournit aux directions opérationnelles le soutien et les moyens techniques nécessaires à leurs missions. Les outils mis à disposition des opérationnels par la DILT doivent par conséquent pouvoir s’adapter aux évolutions du métier et sont donc conçus au plus près des services, en démarche agile, tout en veillant au respect des règles juridiques. L’expertise des ingénieurs et techniciens de la DILT permet en effet d’évaluer les matériels et les technologies disponibles sur le marché pour mesurer l’opportunité de leur mise en œuvre au sein de systèmes rapidement déployables et adaptables.
1. Présentation du besoin
Le besoin initial était d’allumer un gyrophare lorsque se produit une alerte dans une nouvelle application déployée en salle de commandement. Un premier dispositif a été déployé, il se connectait à l’application et implémentait localement la logique de déclenchement du signal lumineux et son extinction.
Plusieurs problèmes sont apparus :
- les boîtiers d’alerte sont déployés sur le terrain, coder la logique applicative à l’intérieur pose des problèmes en termes de mise à jour de cette logique ;
- gérer localement la logique applicative peut obliger le boîtier à traiter un gros volume de données (pour une solution mobile, ça coûte en forfait 4G et en autonomie sur batterie) ;
- nous ne disposons d’aucune information concernant le bon fonctionnement du boîtier sur le terrain (il est arrivé qu’il soit débranché par accident).
Par ailleurs, en discutant avec différents services, le besoin de fonctionnalités additionnelles est apparu :
- gérer plusieurs alertes (par des LED de couleurs sur un tableau synoptique ou une carte, par exemple) ;
- gérer l’acquittement de ces alertes (unitairement ou globalement).
Nous construirons un boîtier aux capacités multiples :
- une alerte principale matérialisée par une LED (éventuellement doublée d’un relais pour commander un gyrophare ou une lampe flash) avec un bouton d’acquittement ;
- des alertes en nombre variable, chacune pouvant avoir plusieurs états grâce à l’emploi de LED RGB ;
- des boutons-poussoirs dont la gestion est assurée intégralement par le serveur.
Nous allons également implémenter :
- des messages cycliques entre le boîtier et le serveur, pour que les deux parties soient assurées de l’état de la connexion, un voyant sur le boîtier permet de matérialiser cet état ;
- des acquittements à destination du serveur lors de la réception de messages de déclenchement d’alertes ;
- le boîtier efface l’alerte principale localement, même en absence du serveur (ceci afin d’éviter des mouvements d’humeur des utilisateurs en cas de problème avec le serveur), un message est toutefois envoyé au serveur lorsque l’alerte principale est acquittée par un utilisateur, ceci permet d’escalader si une alerte n’est pas acquittée.
Les boîtiers seront déployés « sur le terrain », mais en environnement de confiance, il peut s’agir de bureaux, de salles de commandement, de postes de sécurité ou de lieux d’opérations.
Nous allons prévoir le maximum de type de connexions possibles :
- Ethernet : la PSSI (Politique de Sécurité des Systèmes d’Information) interdit de connecter sur le réseau bureautique autre chose que des postes de travail fournis par le service, ce mode de raccordement sera donc réservé à la connexion sur des « box » internet ou des réseaux de partenaires ;
- Wi-Fi : là encore, son utilisation est réservée à une utilisation extérieure, le seul Wi-Fi disponible officiellement étant basé sur un portail captif ;
- 2G/LTE : pratique, car disponible presque partout et ne nécessite ni câblage ni négociations pour le raccordement.
2. Choix d’implémentation
2.1 Protocoles réseau et applicatif
La communication entre le boîtier et le serveur sera faite via le protocole MQTT, qui a l’avantage d’être léger et d’avoir de nombreuses implémentations côté client.
MQTT est un broker de messages, un message est publié (publish) par un client sur un sujet (topic), le serveur MQTT distribue alors ce message aux éventuels clients qui se seraient abonnés (subscribe) au topic sur lequel le message a été publié.
Nous sécuriserons les échanges grâce au protocole TLS avec authentification mutuelle à l’aide de certificats clients et serveur, pour ceci nous allons gérer notre propre autorité de certification.
La sécurité sera également assurée par des règles d’accès au niveau du serveur (ACL) permettant de limiter les droits sur les topics au strict nécessaire (principe de moindre privilège). Ceci pour éviter qu’en cas de compromission d’un boîtier, les applications utilisant le même serveur MQTT ne soient compromises aussi.
2.2 LED et boutons
Pour l’alerte principale, nous allons utiliser :
- un GPIO pour une LED d’alerte et/ou un relais ;
- un GPIO pour le bouton d’acquittement.
Pour les alertes multiples, on peut estimer avoir besoin de 1 à 32 LED RGB en fonction des missions et des applications (supervision, par exemple), ceci représente un nombre conséquent de GPIO dont aucune carte ne dispose nativement.
Une possibilité est d’utiliser un ruban de LED RGB adressables, un tel ruban ne nécessite qu’un seul GPIO, quel que soit le nombre de LED.
L’organisation en ruban permet de réaliser des tableaux d’alertes, il est possible avec un peu de câblage de réaliser des cartes interactives, par exemple.
Si nous souhaitons acquitter individuellement chacune des alertes, il nous faut autant de boutons que de LED, là encore, il faudrait un nombre de GPIO supérieur au nombre de GPIO disponibles. En conséquence, nous utiliserons un composant permettant d’ajouter des GPIO en utilisant un bus I2C.
2.3 Carte de base
Afin de choisir la carte qui va nous servir de base, nous recensons les ressources dont nous aurons besoin :
- 1 GPIO pour la LED d’alerte principale ;
- 1 GPIO pour le bouton-poussoir d’acquittement de l’alerte principale ;
- 1 GPIO pour le ruban de LED RGB adressables (la LED témoin de bon fonctionnement sera la LED numéro 0 sur le ruban) ;
- 1 bus I2C pour les boutons-poussoirs d’acquittement des alertes (donc 2 GPIO).
Nous allons utiliser une carte à base d’ESP32, ce microcontrôleur gère au minimum un bus I2C, dispose d’un certain nombre de GPIO, de la puissance de calcul nécessaire pour faire du MQTTS, et il est facilement programmable dans l’environnement de développement Arduino.
Pour commencer, nous allons utiliser une carte ESP-32-DevKit, cette carte est une des plus simples utilisant une puce ESP32, c’est aussi une des moins chères, elle va néanmoins nous permettre d’assurer toutes les fonctions du boîtier d’alerte avec une connectivité Wi-Fi.
2.4 Organisation du code pour l’ESP32
La connexion du boîtier au serveur MQTT sera assurée en TLS avec authentification mutuelle, chaque boîtier aura donc sa propre paire clé privée/certificat.
Nous développerons un programme unique pour les différents types de cartes, un fichier header (.h) permet de décrire un boîtier à l’aide de directives #define et #include définissant les différents paramètres propres au boîtier.
2.5 Gestion des alertes avec Node-RED
La gestion des alertes sera effectuée sur le serveur et non sur le boîtier :
- pour ne pas avoir à déployer de code applicatif difficile à mettre à jour sur les boîtiers ;
- pour limiter la consommation de données des boîtiers (coût élevé en 2G/LTE) ;
- pour ne pas donner de droits de consultation des données applicatives à un boîtier qui se trouve dans un environnement non maîtrisé en termes de sécurité physique.
Node-RED est un système conçu pour l’Internet des objets (IoT), c’est à la fois un environnement de développement graphique, et l’environnement d’exécution correspondant. Le traitement des événements extérieurs est organisé en suites (flow) de blocs de codes prédéfinis (nodes).
2.6 Utilisation de Docker
La partie serveur de notre système est basée sur Docker.
On ne présente plus Docker et ses avantages :
- indépendance de l’OS support ;
- les images Docker sont construites automatiquement et contiennent tout le nécessaire à l’exécution de chacun des composants ;
- l’utilisation de docker-compose permet de décrire la partie serveur.
3. Définition des échanges MQTT
Les boîtiers sont raccordés au serveur en utilisant le protocole MQTT, nous allons décrire les topics utilisés pour les échanges entre le boîtier et le système en charge de sa gestion.
Le topic de tous les messages échangés entre le boîtier et le système commence par alert/id_du_boitier/.
La valeur de id_du_boitier sera choisie au moment de la programmation du boîtier, il s’agit de choisir un nom qui permettra de reconnaître facilement à quoi correspond chaque boîtier.
3.1 Heartbeat (ligne de vie)
Le boîtier envoie toutes les 60 secondes un message « ping » vers le serveur, le serveur lui répond avec un message « pong », cette réponse permet au boîtier de s’assurer de l’état de la connexion afin de gérer l’allumage du témoin de bon fonctionnement.
La payload du message « ping » contient le nombre de secondes écoulées depuis que le boîtier a démarré (uptime), un système de supervision côté serveur peut détecter qu’un problème est survenu avec un boîtier grâce à l’absence de message « ping » ou en constatant que uptime est revenu à une valeur faible.
ATTENTION : La fonction millis() est utilisée pour déterminer la valeur de uptime, elle retourne un entier sur 32 bits qui donne le nombre de millisecondes depuis l’initialisation du système, ce nombre boucle au bout de 2^31/1000 secondes, c’est-à-dire un peu moins de 50 jours, il faut en tenir compte si on veut superviser la valeur de l’uptime.
3.2 Gestion de l’alerte principale
Pour déclencher l’alerte principale, le serveur publie un message « push » sur le topic surveillé par le boîtier, le boîtier acquitte l’alerte en publiant un message « acq » sur le topic correspondant du serveur.
Lorsque quelqu’un appuie sur le bouton pour effacer l’alerte, celle-ci est effacée directement sur le boîtier, puis un message « button » est envoyé au serveur pour l’en informer. Ce message permet à l’application d’escalader, dans le cas d’une alerte non prise en compte.
Le serveur déclenche une alerte en publiant un 1, dans le cas où l’alerte n’aurait pas été déjà effacée par un appui sur le bouton correspondant, le serveur a la possibilité de l’annuler en publiant un 0.
3.3 Gestion des alertes multiples
Une alerte peut être matérialisée par la combinaison :
- de l’allumage fixe ou clignotant de la LED ;
- par un niveau à 0 ou 1 pour chacune des trois couleurs RGB, soit un total de 7 combinaisons (la combinaison 0,0,0 représentant l’extinction de la LED).
Nous ajoutons la possibilité de faire clignoter chacune des trois couleurs afin d’attirer l’œil et d’augmenter le choix en termes de couleurs.
L’application pourra choisir pour chacune des trois couleurs RGB :
- « A » : allumée ;
- « E » : éteinte ;
- « C » : clignotante.
Les couleurs disponibles sont les suivantes :
Les LED et les boutons correspondants sont numérotés à partir de 0.
3.4 Gestion des boutons
Un bouton est utilisé pour effacer l’alerte principale.
Il est possible de rajouter jusqu’à 32 boutons, ces boutons ne sont pas gérés localement par le boîtier, l’appui d’un bouton est transmis au serveur, puis un flow Node-RED devra en assurer la gestion. Ceci permet de donner à ces boutons un autre rôle que le simple acquittement des alertes.
4. MQTT
Nous allons commencer par MQTT, car c’est la pierre angulaire de notre système, comme tout notre système, il sera lancé via un container Docker.
Nous allons créer une infrastructure de gestion de clés « technique » avec sa propre autorité de certification pour gérer les certificats, qui seront utilisés dans notre système.
MQTT et sa sécurisation ont été traités dans le numéro 26 de Hackable [1] de septembre-octobre 2018, vous pourrez vous y reporter pour avoir plus d’informations.
4.1 Création de l’autorité de certification
Nous allons utiliser le logiciel TinyCA2 pour créer notre infrastructure de gestion de clés (IGC, ou PKI en anglais).
Nous installons TinyCA2 et nous effectuons un premier lancement :
Lors du premier lancement, l’écran de création d’autorité de certification (AC) s’affiche :
L’écran des options pour l’AC s’affiche ensuite, une fois cet écran validé, notre autorité de certification est créée.
Nous devons modifier une option de l’AC afin que TinyCA nous demande quels sont les sujets alternatifs que l’on souhaite ajouter au certificat. Ceci est utile dans le cas du serveur afin d’ajouter l’adresse IP du serveur au certificat.
Menu Préférences → OpenSSL configuration → Onglet Server Certificate :
- dans « default_days », mettre « 1825 » (5 ans) ;
- dans « Subject alternative name », remplir « Ask User », si possible, cliquez sur « DNS Name » (suite à un bug dans la version 0.7.5, il est possible qu’il vous faille valider l’écran, puis y revenir pour pouvoir sélectionner « DNS Name »).
4.2 Création du certificat pour le serveur
Les échanges avec le serveur MQTT seront protégés par TLS avec une authentification mutuelle, nous commençons par créer le certificat qui sera utilisé par le serveur, sans lui il est impossible de lancer le serveur.
Dans TinyCA : onglet Certificates → Icône New → Create Key and Certificate (Server).
Dans « Common name », tapez le nom DNS du serveur (ce n’est pas grave si vous n’avez pas de nom DNS pour le serveur, puisque son adresse IP sera également ajoutée au certificat). Choisissez un mot de passe pour la clé correspondant au certificat, choisissez une longueur de clé de 2048, SHA-256 et RSA.
Sur l’écran suivant, tapez le mot de passe de l’AC, une validité de 1825 jours (5 ans), dans « Subject alternative name (DNS Name) », tapez « ab-mqtt » suivi de la ou des adresses IP du serveur (avec la virgule comme séparateur).
Note : ab-mqtt est le nom du container Docker du serveur MQTT, c’est le nom qu’utilisent les autres containers pour se connecter au serveur MQTT.
Il faut désormais exporter le certificat du serveur et la clé correspondante. Notre certificat apparaît dans l’onglet « Certificates », cliquez droit dessus, puis sélectionnez « Export Certificate » :
Choisissez un emplacement où sauvegarder le fichier et appelez-le « server.crt », choisissez le format « PEM » et de ne pas inclure ni la clé privée ni l’empreinte de la clé :
On exporte ensuite la clé privée, dans l’onglet « Keys », cliquez droit sur la clé et choisissez « Export Key » :
Sauvegarder le fichier dans le même répertoire que le précédent et appelez le « server.key », choisissez le format « PEM », sauvegardez sans mot de passe (without passphrase) et ne pas inclure le certificat :
Le mot de passe utilisé lors de la génération de la clé privée vous sera demandé afin d’exporter la clé sans mot de passe :
Nous aurons également besoin du certificat de notre autorité de certification, il sera utilisé par le serveur MQTT pour vérifier les certificats présentés par les clients.
Dans TinyCA, cliquez sur l’icône « Export CA », nommez le fichier ca.crt, puis choisissez le format PEM.
4.3 Récupération des sources
Un exemple démarqué des sources du programme du boîtier d’alerte et l’environnement nécessaire à son fonctionnement sont disponibles sur GitHub :
Le repo contient les fichiers suivants :
4.4 Application Docker
Nous allons utiliser docker-compose pour construire notre environnement, pour le moment nous allons lancer deux containers :
- un container ab-mqtt avec notre serveur MQTT (Eclipse Mosquitto) ;
- un container ab-logger, il permet de conserver l’historique des messages échangés sur notre topic alert/#.
Nous avons récupéré le code depuis GitHub, notre environnement Docker se trouve dans le fichier 01_mqtt_docker-compose.yml que nous recopions en docker-compose.yml :
Le container ab-logger nécessite une image « maison », le fichier ablogger-docker/Dockerfile contient la définition de cette image. Son fonctionnement est une combinaison de mosquitto_sub pour récupérer les messages émis sur nos topics d’intérêt, de ts pour ajouter un timestamp au début de chaque ligne, suivi de rotatelogs pour générer un fichier log tous les jours (86400 secondes) :
Le fichier docker-compose.yml décrit notre infrastructure, pour le container ab-logger il pointe vers ablogger-docker/Dockerfile qui décrit comment construire l’image nécessaire. La commande build permet de construire les images nécessaires :
La commande docker-compose pull permet de télécharger les images nécessaires. Notez que l’utilisation des commandes build et pull est facultative, elles sont lancées automatiquement si nécessaire lorsque l’on monte notre application.
Avant de lancer notre application, nous devons créer les volumes nécessaires, qui permettront de conserver les données même en cas de redémarrage des containers :
4.5 Premier lancement
Avant d’effectuer le premier lancement, il est nécessaire de copier dans le répertoire mqtt/ les clés et certificats générés précédemment (ca.crt, server.crt et server.key).
Des fichiers sont déjà présents dans le répertoire, vous pouvez les utiliser si vous n’en avez pas généré.
Nous pouvons désormais lancer notre application :
Nous publions un message et nous vérifions qu’il a bien été enregistré dans les logs, notez au passage que l’heure enregistrée est en UTC, car nous n’avons pas défini de fuseau horaire à l’intérieur du container id-logger :
5. Matériel
Nous allons utiliser des cartes à base de ESP32 que nous programmerons dans l’environnement Arduino. Différents modèles de cartes existent, mais les différences sont globalement très faibles, si ce n’est les ports auxquels sont assignés les périphériques, qu’il s’agisse de périphériques que nous pourrions utiliser (Ethernet, modem 2G/LTE), ou de périphériques que nous n’utiliserons pas tels que caméra, carte SD…
Il faudra choisir nos GPIO en fonction du modèle de carte, ceci aura une incidence sur la programmation (utilisation de fichiers include contenant des directives #define adaptées).
Nous commencerons avec la carte ESP32-DevKitC qui est la carte de base pour faire du Wi-FI.
5.1 Ruban de LED adressables
Les WS2812B sont un assemblage de 3 LED (rouge, verte, bleue) et d’un circuit de contrôle dans un composant CMS rectangulaire, elles sont parfois appelées WS2812B 5050 (où 5050 désigne un composant CMS de 5 mm*5 mm).
Elles sont alimentées de 3,5 à 5 V, comportent 4 connexions, 2 pour l’alimentation, 1 entrée de contrôle et 1 sortie de contrôle branchée en cascade avec l’entrée de la LED suivante.
En utilisant le protocole de contrôle, il est possible de choisir le niveau des 3 couleurs pour chacune des LED d’un ruban de LED connectées les unes aux autres. Chacune des LED remet le signal de contrôle en forme pour la LED suivante et il est possible de créer un ruban d’une longueur quelconque.
Une bibliothèque Arduino existe pour contrôler ce genre de ruban de LED, sans qu’il soit nécessaire d’implémenter soi-même le protocole.
5.2 Extension d’entrées sorties en I2C
Afin d’augmenter le nombre de GPIO pour disposer d’un maximum de boutons, nous allons utiliser des PCF8574, ils permettent sur un bus I2C d’obtenir l’équivalent de 8 GPIO.
Le composant PCF8574 comporte 3 broches permettant de choisir l’adresse du composant sur le bus I2C, il est donc possible sur un bus I2C d’avoir 8*PCF8574 et de disposer de 64 GPIO supplémentaires en n’utilisant que les deux GPIO qui constituent le bus I2C. Nous nous limiterons à 32 GPIO (et donc 4*PCF8574).
5.3 Câblage
Nous alimenterons le module ESP32 DevKit par l’entrée EXT_5V (broche 19), un régulateur intégré fournit les 3,3 V nécessaire à l’ESP32.
Attention : lors de la programmation du module en USB, veillez à ne pas l’alimenter en 5 V sous peine de risquer d’endommager les ports USB de votre ordinateur.
Le ruban de LED sera alimenté en 5 V, car le régulateur 3,3 V du module n’est pas dimensionné pour alimenter un ruban de LED. Bien que les LED WS2812B soient alimentées en 5 V, leur entrée est compatible avec un microcontrôleur en 3,3 V (notez que seule la première LED est concernée, puisqu’elle génère le signal d’entrée de la seconde).
6. Programmation du boîtier
Nous nous concentrerons dans un premier temps sur la programmation du boîtier, comme il est entièrement piloté par le serveur MQTT, nous pourrons tester notre boîtier en publiant des messages MQTT, comme nous l’avons vu au §4.4.
Nous développerons ultérieurement la logique applicative avec Node-RED.
6.1 Connectivité Wi-Fi et MQTT
Nous utilisons la bibliothèque wifiMultiple qui permet de spécifier une liste de SSID Wi-Fi, ceci permet éventuellement de déplacer le boîtier entre plusieurs lieux :
Attention, cette bibliothèque ne permet pas d’utiliser des points d’accès qui ne diffusent pas leur SSID (Wi-Fi cachés).
Parfois, la bibliothèque n’arrive pas à se connecter à un point d’accès, il faut alors redémarrer le microcontrôleur si on n’a pas réussi à se connecter au bout de 20 tentatives :
6.2 Gestion du bandeau de LED
Nous utilisons la bibliothèque FastLED, elle permet d’utiliser de nombreux modèles de LED adressables, il est nécessaire de spécifier le nombre de LED du ruban, car la bibliothèque ne peut pas le déterminer. Ce nombre n’a pas besoin d’être exact, il faut qu’il soit supérieur ou égal au nombre réel de LED, au pire on perd un peu de mémoire et de performance.
Le ruban de LED est matérialisé par un tableau de structures CRGB, il est possible de positionner le niveau de chacune des composantes RGB, nous mettons 0 pour la lettre code E (éteinte) ou 255 pour A (allumée).
Pour le clignotement, nous mettons 1 ou 254, l’écart de luminosité est faible par rapport à 0 ou 255 et ceci nous permet de repérer les couleurs à faire clignoter. La variable blinkMillis indique quand le dernier clignotement a été effectué, blinkCourant quel est le niveau courant. La formule 255 – clignotement_courant permet de passer d’un niveau à l’autre.
6.3 Gestion des boutons
Le bouton permettant d’acquitter l’alerte principale est connecté directement à un GPIO dans le mode INPUT_PULLUP.
Lors de la réalisation d’un boîtier raccordé en 2G/LTE, nous avons constaté que parfois l’alarme s’acquittait toute seule de façon aléatoire. Ceci est dû au fil utilisé pour connecter le bouton au GPIO, en raison de sa longueur et de sa proximité avec l’antenne GSM, il génère des signaux parasites que la valeur trop élevée de la résistance de pull-up interne de l’ESP32 n’arrive pas à neutraliser.
Nous aurions pu ajouter une résistance de pull-up, mais ceci aurait complexifié la réalisation, nous avons fait le choix de traiter ces signaux parasites de façon logicielle en vérifiant que le GPIO reste au niveau bas pendant 280 ms minimum.
En plus de ce bouton, nous pouvons gérer jusqu’à 32 boutons, nous construisons un entier de 32 bits représentant l’état de chacun des boutons par scrutation de 4 composants PCF8574. Il n’est pas obligatoire de disposer des 4, il est même possible de n’en mettre aucun si on n’a pas besoin de la fonctionnalité.
Les entrées des PCF sont de type PULL_UP, le bouton poussoir les place donc à la masse, dans le cas d’un composant absent, on place 0xFF pour les boutons correspondants, il faut penser à inverser les bits au final pour refléter l’état (appuyé ou non) des boutons :
6.4 Création de certificats pour les boîtiers
Nous utilisons notre autorité de certification pour générer les certificats qui seront utilisés par les boîtiers d’alerte.
Dans TinyCA : onglet Certificates → Icône New → Create Key and Certificate (Client).
Le « Common name » (CN) sera le nom du boîtier, pour cet article, ce sera PP_DILT_SDT_SIO_LFO, choisissez un mot de passe pour la clé correspondant au certificat, choisissez une longueur de clé de 2048, SHA-256 et RSA.
Sur l’écran suivant, tapez le mot de passe du CA, une validité de 1825 jours (5 ans).
Attention : le CN doit correspondre au nom du boîtier, sinon les Access Control List sur le serveur MQTT vont empêcher le boîtier de fonctionner.
Il faut désormais exporter le certificat du serveur et la clé correspondante. Notre certificat apparaît dans l’onglet « Certificates », cliquez droit dessus, puis sélectionnez « Export Certificate ».
Choisissez l’emplacement où sauvegarder le fichier et appelez le PP_DILT_SDT_SIO_LFO.crt, choisissez le format « PEM » et de n’inclure ni la clé ni l’empreinte de la clé.
Exportez ensuite la clé, dans l’onglet « Keys », cliquez droit sur la clé et choisissez « Export Key ».
Choisissez l’emplacement où sauvegarder le fichier et appelez le PP_DILT_SDT_SIO_LFO.key, choisissez le format « PEM », sauvegardez sans mot de passe (without passphrase) et ne pas inclure le certificat.
Le mot de passe utilisé lors de la génération du certificat vous sera demandé afin d’exporter la clé sans mot de passe.
Répétez l’opération pour les utilisateurs suivants :
- nodered.alert.u03.fr
- administrateur.alert.u03.fr
6.5 Création du fichier certificates.h
La bibliothèque BearSSL, qui gère la partie TLS, utilise un format spécial pour la chaîne de certification, l’outil pycert_bearssl permet de générer le fichier include nécessaire pour que notre application puisse contrôler le certificat présenté par le serveur.
Nous exécuterons l’outil dans un container Docker, car il a besoin de dépendances Python. On commence par construire l’image Docker :
Il est ensuite possible d’exécuter l’outil pour convertir le certificat de notre CA (ca.crt) au format utilisable pour l’Arduino, nous nommerons le fichier certificates.h :
Le script a été modifié par rapport à l’original pour écrire tous ses messages sur stderr afin que la redirection de stdout n’inclue pas les messages du script.
6.6 Le fichier card_esp_wroom_32.h
Le fichier card_esp_wroom_32.h permet de décrire la carte et le câblage qui ont été réalisés :
6.7 Création du fichier networks.h
Le fichier networks.h permet de spécifier les paramètres réseau :
- adresse IP et port du serveur MQTT ;
- pour les cartes raccordées en Wi-Fi, les SSID et clés des réseaux susceptibles d’être utilisés ;
- les caractéristiques de l’APN dans le cas des cartes 2G ou LTE :
6.8 Création du fichier box_PP_DILT_SDT_SIO_LFO.h
Le fichier box_PP_DILT_SDT_SIO_LFO.h décrit le boîtier et fait la liaison avec les fichiers précédents.
Il donne l’identifiant du boîtier qui sera utilisé pour déterminer les topics utilisés, il décrit le ruban de LED utilisé.
Nous ajoutons à ce fichier le certificat client que nous avons généré ainsi que la clé correspondante, au final le fichier doit ressembler à ceci :
6.9 Fichier alertbox.ino
En tête du fichier, vous devez inclure le fichier box_PP_DILT_SDT_SIO_LFO.h, qui décrit notre boîtier :
6.10 Programmation du boîtier
Nous utilisons l’environnement Arduino pour programmer notre boîtier.
Vous devez ajouter les ESP32 dans le gestionnaire de carte, dans le menu Fichier → Préférences → URL de gestionnaire de cartes supplémentaires ajouter https://dl.espressif.com/dl/package_esp32_index.json, sélectionner ensuite le type qui correspond à votre carte dans le menu Outils → Type de carte.
Nous utilisons les bibliothèques suivantes qui doivent être installées par menu Outils → Gérer les bibliothèques :
- FastLED (v3.5.0 par Daniel Garcia) ;
- PCF8574 (v0.3.3 par Rob Tillaart) ;
- PubSubClient (v2.8.0 par Nick O’Leary) ;
- SSLClient (v1.6.11 par OPEnS Lab) ;
- StreamDebugger (v1.0.1 par Volodymyr Shymanskyy) ;
- TinyGSM (v0.11.5 par Volodymyr Shymanskyy).
Conclusion
Nous sommes d'ores et déjà en présence d’un boîtier fonctionnel, capable de gérer LED et boutons, et de se connecter de façon sécurisée à un serveur MQTT.
Nous avons choisi de ne pas coder de logique applicative dans le boîtier et de le piloter à travers un serveur MQTT. Il existe des librairies permettant d’interagir avec un serveur MQTT dans tous les langages modernes, aussi nous pourrions coder dans le langage de notre choix.
Afin d’assurer le maximum de flexibilité, nous optons plutôt pour du « low-code » avec Node-RED, ceci nous permettra de nous adapter rapidement aux différents scénarios d’utilisation du boîtier.
Dans la suite de cet article, à paraître avec le prochain numéro de Hackable, nous verrons le déploiement de Node-RED, la sécurisation du serveur MQTT et les différents types de cartes utilisables pour construire nos boîtiers.
Référence
[1] Hackable n°26 - https://connect.ed-diamond.com/Hackable/hk-026