Vous êtes sur la page 1sur 24

Bienvenue sur la base documentaire des Éditions Diamond !

(/)

HACKABLE 470 article(s)


L'embarqué à sa source

Accueil (/)  Hackable (/hackable)  HK-045 (/hackable/hk-045)  AlertBox : un boîtier d’alerte multifonctions (suite)



+ +
(/hackable/hk-
  

045/personnalisez-
 (/readlist/get/m
(/alert/a
automatiquement-
(/hackable/hk-

vos- 045/accelerez-

installations-
vos-

de- simulations-

raspberry-
vhdl-

pi- avec-

os) verilator)

AlertBox : un boîtier d’alerte multifonctions (suite)


Hackable n° 45 (/hackable/hk-045) novembre 2022 Par Foucher Laurent (/auteur/foucher-laurent)

Spécialité(s) :
Domotique (/search/node?domains%5B0%5D=72455) Électronique (/search/node?domains%5B0%5D=72452)

Tag(s) :
Node-RED (/search/node?tags%5B0%5D=74724) MQTT (/search/node?tags%5B0%5D=73833)

ESP32 (/search/node?tags%5B0%5D=73827) Docker (/search/node?tags%5B0%5D=72796)

Dans la première partie de cet article, nous avons construit un boîtier d’alerte, nous
l’avons conçu suffisamment souple pour s’adapter aux différents cas d’utilisation par les
services opérationnels. Nous allons voir comment le piloter en mode « low code » à l’aide
de Node-RED.

Par certains aspects, Node-RED ressemble très fortement au langage « Scratch » utilisé pour l’apprentissage de la
programmation aux enfants. Il s’agit néanmoins d’un outil professionnel qui s’avère particulièrement agréable à mettre
en œuvre et à utiliser.

Malgré son aspect « graphique », Node-RED est un outil puissant grâce à la possibilité d’intégrer du code JavaScript
pour implémenter les fonctionnalités qui ne seraient pas disponibles dans les composants standard.

1. Node-RED

1.1 Présentation
Node-RED est un outil spécialisé dans les applications de l’Internet des Objets (IdO/IoT). Il est basé sur la gestion
d’évènements : des blocs de code (nodes) sont connectés ensemble pour créer des flux (flows) afin de traiter des
évènements entrants dans le système et produire des actions en conséquence.

Des nodes de base sont livrés avec le système, d’autres sont disponibles dans une bibliothèque (library). Les flux créés
peuvent être exportés au format JSON en vue de leur déploiement ou de leur partage.

Node-RED peut être décomposé en deux parties :

un environnement de développement permettant de créer les flows de façon graphique (développement faible code
- low code) ;
un environnement assurant l’exécution des flows créés.
Node-RED permet également de développer des tableaux de bord (dashboard) permettant de visualiser l’état de notre
système IoT et d’interagir avec.

Node-RED est développé en Node.js ; cette plateforme logicielle libre est particulièrement adaptée au traitement
d’évènements asynchrones. Tous les éléments, que nous manipulerons dans nos développements, seront constitués
d’un mélange de code JavaScript et de données au format JSON.

Les données en entrée et en sortie ne sont pas typées, mais les messages échangés à l’intérieur des flows sont des
dictionnaires JavaScript.

Node-RED dispose de multiples protocoles en entrée et en sortie, cependant les messages échangés à l’intérieur du
flow sont par défaut composés de payload (charge utile) et de topic (sujet), qui sont des concepts MQTT.

1.2 Docker et Node-RED


Créez le volume pour stocker les données rémanentes du serveur Node-RED :

u03@takeshiba:~$ docker volume create ab-nodered


ab-nodered

Arrêtez l’environnement précédemment lancé, recopiez le fichier 02_nodered_docker-compose.yml en docker-


compose.yml et relancez l’environnement grâce à la commande docker-compose up -d :

$ docker-compose down
docker-compose down
Stopping ab-mqtt ... done
Stopping ab-logger ... done
Removing ab-mqtt ... done
Removing ab-logger ... done
Removing network u03
$ cp 02_nodered_docker-compose.yml docker-compose.yml
$ docker-compose up -d
Creating ab-nodered ... done
Creating ab-logger ... done
Creating ab-mqtt ... done

1.3 Environnement graphique de développement


À l’aide de votre navigateur, allez à http://adresse_ip_de_votre_serveur:1880/ : vous arrivez dans l’environnement de
développement graphique. L’écran est très classique avec une palette de composants (nodes) à gauche, une zone de
travail au milieu pour dessiner vos flows et une palette de propriétés à droite :

(/sites/default/files/magazines/hackable/hk-045/nodered_01_bienvenue.png)

Notez que l’environnement graphique ne sert pas qu’au développement des flows :

il sert également d’interface avec l’environnement d’exécution en permettant leur déploiement (deploy) ;
certains nodes peuvent également afficher des informations d’état dans l’interface graphique ;
il est possible de produire des évènements en cliquant sur certains nodes ;
un node spécifique permet de produire des messages facilitant le débogage.
Les nodes sont regroupés en catégories dans la palette, il existe une bibliothèque « Node-RED library » dans laquelle on
peut trouver de nouveaux nodes, flows ou collections.

1.4 Création de flows de pilotage du boîtier

1.4.1 Allumage/extinction de l’alerte principale


Nous allons écrire un flow permettant d’allumer ou d’éteindre l’alerte principale du boîtier en cliquant sur un node
inject qui permet d’injecter un message.

Pour rappel, le serveur doit publier les messages suivants pour allumer, puis éteindre l’alerte principale du boîtier :

serveur >>>> boitier: alert/PP_DILT_SDT_SIO_LFO/push 1


serveur >>>> boitier: alert/PP_DILT_SDT_SIO_LFO/push 0

Nous glissons/déplaçons deux nodes inject de la palette de composants vers la partie gauche du flow, de la même
façon, nous positionnons un node debug sur la partie droite :
(/sites/default/files/magazines/hackable/hk-

045/flux_pilotage_01.png)

Un point gris à droite d’un node est une connexion de sortie, un point gris à gauche d’un node est une entrée.

Le point bleu au-dessus de l’icône d’un node signifie que des modifications sur ce node n’ont pas encore été déployées
dans l’environnement d’exécution.

En double-cliquant sur le node inject du haut, vous pouvez modifier ses propriétés :

(/sites/default/files/magazines/hackable/hk-045/flux_pilotage_02.png)

On voit que le message comporte une propriété msg.payload et une propriété msg.topic :

comme valeur de la propriété Name du node, mettre ALLUMER ;


en face de msg.payload, cliquez sur le triangle à gauche de timestamp, puis sélectionnez le type de données string,
donnez-lui la valeur 1 ;
comme valeur de msg.topic, mettez alert/PP_DILT_SDT_SIO_LFO/push.

Pour le node inject du bas :

comme valeur de la propriété Name du node, mettez ETEINDRE ;


comme valeur de msg.payload, sélectionnez le type de données string, donnez-lui la valeur 0 ;
comme valeur de msg.topic, mettez alert/PP_DILT_SDT_SIO_LFO/push.

Pour le node debug :

comme valeur de la propriété Output du node, mettez Complete msg object.

Reliez les nodes inject et le node debug en cliquant sur la connexion de sortie d’un node inject, en laissant le
bouton de la souris appuyé et en reliant la connexion d’entrée du node debug :

(/sites/default/files/magazines/hackable/hk-

045/flux_pilotage_03.png)
Cliquez sur le bouton Deploy en haut à droite de l’écran afin de déployer notre flow afin qu’il s’exécute, notez que les
ronds bleus sur les icônes des nodes ont disparu, puisqu’il n’y a pas eu de modifications depuis le dernier déploiement.

Cliquez sur l’insecte (bug) au-dessus de la zone d’informations sur la droite de l’écran pour afficher l’onglet de
débogage.

Cliquez sur la case carrée à gauche du node ALLUMER pour injecter le message correspondant, vous devez le voir
s’afficher à droite dans l’onglet debug quand le message atteint le node debug. Faites pareil avec le node ETEINDRE.

(/sites/default/files/magazines/hackable/hk-045/flux_pilotage_04.png)

Le carré à droite du node debug permet d’activer ou de désactiver ce nœud de débogage.

Vous pouvez maintenant placer un node mqtt-out en dessous du node debug, notez le triangle rouge au-dessus de
l’icône du node, il indique qu’il manque des paramètres nécessaires au bon fonctionnement du node.

Paramétrez le node mqtt-out :

laissez Topic à blanc (car le topic est présent dans le message) ;


mettez QoS à 0 et Retain à false ;
mettez AB-MQTT dans Name ;
cliquez sur le crayon à droite de Add new mqtt-broker afin de créer la connexion vers le serveur MQTT ;
mettez ab-mqtt dans Server, et 8883 dans Port, sélectionnez Use TLS, cliquez sur le crayon à droite de Add new tls-
config ;
mettez ab-mqtt-tls dans Name, uploadez les fichiers certificat, clé privée et CA Certificate, cliquez sur Add pour
ajouter la configuration TLS ;
cliquez sur Add pour ajouter le node MQTT ;
choisissez ab-mqtt:8883 dans Server, cliquez sur Done (notez que le triangle rouge au-dessus de l’icône du node
mqtt-out a dû disparaître).

Reliez maintenant les nodes ALLUMER et ETEINDRE à AB-MQTT :

(/sites/default/files/magazines/hackable/hk-

045/flux_pilotage_05.png)

Cliquez sur Deploy. En dessous du node AB-MQTT vous devez voir une petite icône d’état apparaître marquée
« connected ». Cliquez sur le carré à gauche d’ALLUMER, puis celui à gauche d'ETEINDRE, vous devez voir la LED de
votre ESP32 s’allumer et s’éteindre.

$ docker logs -f ab-mqtt --since 15m


2022-04-13 19:01:24: New connection from 192.168.0.174:50274 on port 8883.
2022-04-13 19:01:26: New client connected from 192.168.0.174:50274 as PP_DILT_SDT_SIO_LFO (p2, c1,
k240, u'PP_DILT_SDT_SIO_LFO').
2022-04-13 19:03:12: New connection from 172.99.0.203:33476 on port 8883.
2022-04-13 19:03:12: New client connected from 172.99.0.203:33476 as nodered_245a53f07f7a1dfc (p2, c1,
k60, u'nodered.alert.u03.fr').
$ docker exec -ti ab-logger tail -n 10 alertbox.`date +%Y%m%d`.log
2022/04/13 19:04:40 alert/PP_DILT_SDT_SIO_LFO/push 1
2022/04/13 19:04:40 alert/PP_DILT_SDT_SIO_LFO/acq 1
2022/04/13 19:04:41 alert/PP_DILT_SDT_SIO_LFO/push 0
2022/04/13 19:05:00 alert/PP_DILT_SDT_SIO_LFO/acq 0

Vous pouvez désormais supprimer les liens, qui pointent vers le node debug, puis supprimer le node debug.

1.4.2 Génération du ping/pong


Les boîtiers d’alerte publient un message ping toutes les minutes, le serveur doit répondre en publiant un message
pong.

Nous avons vu qu’il est possible de publier des messages en utilisant le node mqtt-out. Il est possible de souscrire à
des topics en utilisant le node mqtt-in, chaque message publié sur le serveur MQTT sur les topics en question sera
transformé en message dans notre flow.

Nous allons ajouter un nouveau flow en cliquant sur le menu à droite du bouton Deploy, Flows-->Add. Il est ensuite
possible de le renommer en utilisant le menu Flows-->Rename.

Placez un node mqtt-in sur la gauche :

Server : sélectionnez le serveur existant qui doit s’appeler ab-mqtt:8883 ;


Action : Subscribe to single topic ;
Topic : alert/+/ping (le signe + remplace une valeur quelconque pour un seul niveau d’arborescence) ;
QoS : 0 ;
Output : a String ;
Name : Détection PING.

Ajoutez un node debug de la même manière que dans le chapitre précédent, reliez la sortie du node mqtt-in à l’entrée
du node debug.

Nous voyons arriver les messages ping de notre boîtier, preuve que la connexion et la souscription fonctionnent
correctement :

(/sites/default/files/magazines/hackable/hk-045/ping_pong_01.png)

Vous pouvez si nécessaire simuler un message ping à l’aide de la commande suivante lancée sur le serveur Docker :

$ docker exec -ti ab-mqtt mosquitto_pub -t alert/PP_DILT_SDT_SIO_LFO/ping -m `awk -F. '{print $1}'
/proc/uptime`

Nous allons maintenant voir comment traiter ces messages pour générer la réponse pong.

Commencez par ajouter un node function :

Name : Prepare Pong ;


dans l’onglet On message, placez le code suivant :
var pong = {
topic: msg.topic.replace(/\\/ping$/, '/pong'),
payload: 'PONG'
};
return pong;

Ce code construit un message en remplaçant /ping par /pong dans le topic, avec PONG comme payload.

Placez un node mqtt-out identique à celui du chapitre précédent avec Envoi Pong comme Name, ainsi qu’un
deuxième node debug, câblez l’ensemble comme ceci :

(/sites/default/files/magazines/hackable/hk-

045/ping_pong_02.png)

Une fois le flow déployé, il est possible de voir les messages ping reçus et les messages pong envoyés :

$ docker exec -ti ab-logger tail -F -n 10 alertbox.`date +%Y%m%d`.log


2022/03/05 12:06:21 alert/PP_DILT_SDT_SIO_LFO/ping 398
2022/03/05 12:06:21 alert/PP_DILT_SDT_SIO_LFO/pong PONG
2022/03/05 12:07:21 alert/PP_DILT_SDT_SIO_LFO/ping 458
2022/03/05 12:07:21 alert/PP_DILT_SDT_SIO_LFO/pong PONG

Nous avons utilisé un node function pour montrer comment il est possible d’écrire un programme en Node.js pour
manipuler les messages dans un flow, il est aussi possible d’utiliser un node change en le paramétrant comme ceci :

(/sites/default/files/magazines/hackable/hk-045/ping_pong_03.png)

1.4.3 Génération d’une alerte de température


Note : en langage « Police », l’indicatif « TC » désigne un camion (et « TV » une voiture). Comme son nom l’indique, le TC
SOUTIEN est utilisé en soutien logistique lors d’opérations. Pour les besoins de cet article, prenons l’exemple fictif de
réfrigérateurs dans le TC SOUTIEN. Ces réfrigérateurs sont destinés à stocker et garder fraîche la limonade des forces de
l’ordre pour le 14 juillet. Nous ne pouvons tout de même pas vous révéler tous les secrets de la PP.

Une sonde connectée à notre serveur MQTT publie la température sur le topic
sondes/temperature/TC_SOUTIEN_FRIGO_01. Nous allons écrire un flow qui envoie une alerte sur la LED 0 du
boîtier PP_DILT_SDT_SIO_LFO en fonction de la température.

Le tableau suivant donne les alertes en fonction de la température et la payload à publier sur le topic
alert/PP_DILT_SDT_SIO_LFO/push/0 :
(/sites/default/files/magazines/hackable/hk-045/temperature_01.png)

Placez un node mqtt-in et un node mqtt-out, remplissez leurs propriétés topic et server comme dans le chapitre
précédent. Pour le node mqtt-out, placez QoS à 1 et Retain à true.

Ces valeurs de QoS et Retain permettent au boîtier de recevoir la dernière valeur envoyée sur le topic lorsqu’il se
connecte après sa mise sous tension.

Le découpage en 5 plages de températures va être réalisé grâce à un node Switch. Son fonctionnement est similaire à
l’instruction switch/case, qui existe dans différents langages de programmation. Les conditions sont évaluées dans
leur ordre d’apparition, chaque condition va créer un nouveau point de sortie sur le node, il est possible d’arrêter à la
première condition satisfaite (et donc le message entrant va sortir sur au plus une des sorties, ce qui va être notre cas),
soit on peut évaluer toutes les conditions et donc le message entrant va être aiguillé sur zéro, une ou plusieurs sorties.

Placer un node Switch et paramétrez-le comme ceci :

(/sites/default/files/magazines/hackable/hk-045/temperature_02.png)

Notez bien que le message sortant est identique au message entrant : il n’est pas modifié par le node Switch.

Nous allons utiliser 3 nodes Change (ROUGE, JAUNE, VERT) qui vont nous permettre de modifier la payload du message
afin d’obtenir la couleur voulue. Le choix de la couleur se fera en reliant chacune des sorties du node Switch vers la
couleur correspondante, puis la sortie de chaque couleur vers le node mqtt-out.

Commencez par placer 3 nodes Change, puis paramétrez-les, l’exemple ci-dessous correspond à la couleur rouge (les
payloads pour les autres couleurs sont listées dans le tableau précédent) :

(/sites/default/files/magazines/hackable/hk-045/temperature_03.png)

Une fois les 3 nodes créés, raccordez l’ensemble, ajoutez un node Debug et connectez-le à la sortie 3 du node Switch
(qui correspond à la couleur verte), ceci vous permettra de constater que le node Switch ne modifie pas le message
entrant :
(/sites/default/files/magazines/hackable/hk-045/temperature_04.png)

Vous pouvez simuler la réception d’une mesure de température avec la commande suivante (ici, 14 degrés) :

$ docker exec -ti ab-mqtt mosquitto_pub -t sondes/temperature/TC_SOUTIEN_FRIGO_01 -m 14

Vous pouvez contrôler le bon fonctionnement du système en simulant des températures dans chacune des plages :

$ docker exec -ti ab-logger tail -F -n 10 alertbox.`date +%Y%m%d`.log


2022/03/06 16:38:18 sondes/temperature/TC_SOUTIEN_FRIGO_01 14
2022/03/06 16:38:18 alert/PP_DILT_SDT_SIO_LFO/push/0 CEE
2022/03/06 16:38:26 sondes/temperature/TC_SOUTIEN_FRIGO_01 11
2022/03/06 16:38:26 alert/PP_DILT_SDT_SIO_LFO/push/0 AAE
2022/03/06 16:38:29 sondes/temperature/TC_SOUTIEN_FRIGO_01 9
2022/03/06 16:38:29 alert/PP_DILT_SDT_SIO_LFO/push/0 EAE
2022/03/06 16:38:34 sondes/temperature/TC_SOUTIEN_FRIGO_01 7
2022/03/06 16:38:34 alert/PP_DILT_SDT_SIO_LFO/push/0 AAE
2022/03/06 16:38:38 sondes/temperature/TC_SOUTIEN_FRIGO_01 2
2022/03/06 16:38:38 alert/PP_DILT_SDT_SIO_LFO/push/0 CEE

Nous avons utilisé un node Switch et des nodes Change ainsi que quelques câbles… Il aurait été possible d’utiliser un
node Function et d’écrire le code JavaScript nécessaire pour arriver au même résultat, mais la solution proposée est
bien plus conforme à la philosophie « low code » de Node-RED.

1.4.4 Utilisation de subflow


En fait, nous avons 4 réfrigérateurs dans notre TC SOUTIEN, sans compter ceux situés sur nos différents sites. Bien que
l’environnement de développement de Node-RED nous permette de réaliser du copier-coller, nous allons nous
retrouver avec une multitude de nodes et de câbles.

Node-RED nous permet de regrouper un ensemble de nodes et de câbles dans un subflow. Les subflows ont une seule
entrée, mais peuvent avoir plusieurs sorties.

Nous allons réaliser un subflow qui va prendre en entrée un message d’une sonde de température et envoyer en sortie
la payload pour la couleur correspondante.

Pour ceci, nous allons regrouper les sorties des 3 couleurs grâce à un node Change que l’on appellera « FAKE WIRE » et
qui n’effectue aucun changement :

(/sites/default/files/magazines/hackable/hk-045/subflows_01.png)

Nous avons désormais un flow qui ressemble à ceci :


(/sites/default/files/magazines/hackable/hk-045/subflows_02.png)

À l’aide de la souris, sélectionnez les nodes Switch et Change en faisant un rectangle de sélection les englobant tous,
puis dans le menu en haut à droite du bouton Deploy, sélectionnez Sublows-->Selection to subflow :

(/sites/default/files/magazines/hackable/hk-

045/subflows_03.png)

À noter, tous les nodes que nous avons sélectionnés ont disparu, remplacés par un node Subflow 1. Dans la palette de
composants à gauche, une nouvelle catégorie subflows est apparue, comprenant notre node qui s’appelle subflow 1.

Il est possible de renommer le subflow dans la palette :

passez le pointeur de la souris dans la palette de composants ;


une infobulle apparaît : cliquez sur l’icône en forme de crayon ;
la feuille avec le contenu du subflow s’affiche : cliquez sur edit properties en haut à gauche de la feuille pour
renommer le subflow en Couleur Frigo.
Le node change alors de nom dans notre flow de supervision du réfrigérateur.

Recopiez les éléments du flow pour superviser les réfrigérateurs 01 à 04 en affichant leur état sur les LED 0 à 3 du
boîtier d’alerte PP_DILT_SDT_SIO_LFO.

(/sites/default/files/magazines/hackable/hk-

045/subflows_04.png)

Vérifier le bon fonctionnement :

$ docker exec -ti ab-mqtt mosquitto_pub -t sondes/temperature/TC_SOUTIEN_FRIGO_01 -m 9


$ docker exec -ti ab-mqtt mosquitto_pub -t sondes/temperature/TC_SOUTIEN_FRIGO_02 -m 7
$ docker exec -ti ab-mqtt mosquitto_pub -t sondes/temperature/TC_SOUTIEN_FRIGO_03 -m 14.9
$ docker exec -ti ab-mqtt mosquitto_pub -t sondes/temperature/TC_SOUTIEN_FRIGO_04 -m 4.5
$ docker exec -ti ab-logger tail -F -n 10 alertbox.`date +%Y%m%d`.log
2022/03/06 20:43:45 sondes/temperature/TC_SOUTIEN_FRIGO_01 9
2022/03/06 20:43:45 alert/PP_DILT_SDT_SIO_LFO/push/0 EAE
2022/03/06 20:43:52 sondes/temperature/TC_SOUTIEN_FRIGO_02 7
2022/03/06 20:43:52 alert/PP_DILT_SDT_SIO_LFO/push/1 AAE
2022/03/06 20:44:02 sondes/temperature/TC_SOUTIEN_FRIGO_03 14,9
2022/03/06 20:44:02 alert/PP_DILT_SDT_SIO_LFO/push/2 CEE
2022/03/06 20:44:12 sondes/temperature/TC_SOUTIEN_FRIGO_04 4,5
2022/03/06 20:44:12 alert/PP_DILT_SDT_SIO_LFO/push/3 CEE

1.4.5 Supervision des boîtiers (uptime)


Bien qu’un témoin de bon fonctionnement soit présent sur les boîtiers, il peut être nécessaire de les superviser depuis
un centre de supervision afin de s’assurer qu’ils sont connectés au serveur. Pour ceci, nous nous basons sur les
messages ping émis par le boîtier, ces messages contiennent le nombre de secondes depuis lesquelles le boîtier est
actif (uptime).

Nous allons distinguer les 3 cas suivants :

pas de message ping depuis plus de 65 secondes (rouge clignotant - payload CEE) ;
l’uptime dans le message ping reçu est inférieur à 600 secondes, ce qui dénote un reboot du boîtier (jaune fixe -
payload AAE) ;
l’uptime dans le message ping reçu est supérieur ou égal à 600 secondes (vert fixe - payload EAE).

Il peut être normal qu’un boîtier ne soit pas joignable : par exemple, l’équipe qui l’utilise n’est pas en opération. Dans
ce cas, le centre de supervision appuie sur le bouton correspondant au boîtier incriminé, le rouge clignotant est alors
éteint pour ne pas encombrer la supervision.

Le flow correspondant est le suivant :

(/sites/default/files/magazines/hackable/hk-045/supervision_ping_01.png)

Le node Switch Vérifier uptime permet d’aiguiller les messages ping reçus en fonction de la valeur de l’uptime ; il
dispose de deux sorties :

sortie du haut uptime inférieur à 600 secondes ;


sortie du bas uptime supérieur ou égal à 600 secondes.
Le node Change Reboot récent ne fait que positionner msg.payload à AAE, notez qu’il n’est connecté qu’à la sortie du
haut (uptime inférieur à 600 secondes).

Le node Trigger Absence PING n’envoie aucun message au lancement du flow, il attend 65 secondes avant
d’envoyer msg.payload à CEE, ce délai est réinitialisé à chaque message reçu. Notez qu’il est connecté aux deux
sorties pour recevoir tous les ping (à la fois les ping uptime inférieurs et supérieurs à 600 secondes).

Le node Change Présence ping ne fait que positionner msg.payload à EAE, notez qu’il n’est connecté qu’à la sortie
du bas (uptime supérieur ou égal à 600 secondes).

(/sites/default/files/magazines/hackable/hk-045/supervision_ping_02.png)

Le node Filter permet de ne pas renvoyer plusieurs fois de suite le même message (sinon, chaque minute un
nouveau message avec la payload EAE serait envoyé pour chaque boîtier supervisé).

Cette solution est low-code, mais tous les 50 jours une alerte de reboot récent va être déclenchée lorsque la valeur de
millis() repasse à 0.
En utilisant un node Function et un contexte pour mémoriser si l’uptime est en train de repasser à 0 (ce que nous
nommerons « cycler »), il est possible de ne pas générer d’alerte :

// Indicateur si l'uptime est en train de cycler:


// 0: N'est pas en train de cycler
// > 1: Cyclage en cours, il ne faut pas générer d'alerte
var uptimeCycleEnCours = context.get("uptimeCycleEnCours") || 0;

// Uptime du message en cours


var uptimeCourant = parseInt(msg.payload);

// Alerte Jaune "AAE" si uptime < 600 alors qu'on n’est pas en train de cycler
if (uptimeCourant <= 600 && uptimeCycleEnCours == 0) {
msg.payload = "AAE";
}

// Alerte Jaune "AAE" si on était en train de cycler, mais que l'uptime a diminué
// Et du coup on est plus en train de cycler
else if (uptimeCourant < uptimeCycleEnCours && uptimeCycleEnCours < 4294900) {
msg.payload = "AAE";
uptimeCycleEnCours = 0
}
// Alerte Verte "EAE"
else {
msg.payload = "EAE";
}

// L'uptime est en train de cycler:


// - S'il est supérieur à 4294900
// - S'il est déjà en train de cycler et que l’uptime est < 600
// Une fois qu'il a passé 600 on est plus en train de cycler
if (uptimeCourant >= 4294900 || uptimeCourant <= 600 && uptimeCycleEnCours > 0) {
context.set("uptimeCycleEnCours", uptimeCourant)
} else {
context.set("uptimeCycleEnCours", 0)
}

return msg;

Un node mqtt-in est utilisé pour détecter l’appui sur le bouton 4 du boîtier PP_DILT_SDT_SIO_LFO, le node change
place alors EEE comme payload pour effacer le voyant rouge clignotant. Lorsque le boîtier émettra son prochain
message PING, le système reviendra dans le fonctionnement normal.

Importez le fichier 7_4_5a_supervision_boitier.json et cliquez sur Deploy.

Vous pouvez simuler le message PING du boîtier PP_DOPC_SIC en utilisant la commande suivante (en remplaçant 123
par la valeur d’uptime souhaitée) :

$ docker exec -ti ab-mqtt mosquitto_pub -t alert/PP_DOPC_SIC/ping -m 123

Si vous n’avez pas les boutons, vous pouvez simuler l’appui sur le bouton 4 avec la commande suivante :

$ docker exec -ti ab-mqtt mosquitto_pub -t alert/PP_DILT_SDT_SIO_LFO/button/4 -m BUTTON

Le flow 7_4_5b_supervision_boitier est le même flow écrit d’une autre façon.

1.4.6 Utilisation des boutons


Le boîtier ne comporte aucune logique applicative, il est géré entièrement par le serveur, de fait les boutons sont
indépendants des LED. Les boutons peuvent même être utilisés pour piloter des voyants d’alerte sur un autre boîtier,
voire sur des systèmes externes, il existe par exemple des prises électriques qui peuvent être commandées en MQTT ou
en HTTP.

Nous allons utiliser 3 boutons pour réaliser un système type « voyant de présence » d’hôpital :

le bouton 0 est le bouton « appel soignant » utilisé par le patient, il provoque le clignotement en rouge du voyant
au-dessus de la porte dans le couloir (matérialisé par la LED 0) ;
le bouton 1 est le bouton « présence soignant », il provoque l’allumage en vert fixe du voyant ;
le bouton 2 est le bouton « départ soignant », il provoque l’extinction du voyant.

(/sites/default/files/magazines/hackable/hk-045/bouton_presence_hopital.png)

1.5 Sécurisation de l’interface de Node-RED


Jusqu’ici, nous avons utilisé l’interface web sans avoir à nous authentifier, ce qui est particulièrement gênant puisque
notre système est accessible depuis différents réseaux.

Les mots de passe sont chiffrés dans le fichier de configuration de Node-RED, le container inclut un utilitaire permettant
d’obtenir le mot de passe chiffré.

Nous allons récupérer deux mots de passe chiffrés, un pour un administrateur et un pour un utilisateur en consultation
seulement :

$ docker exec -ti ab-nodered sh -c "echo MaitreDuMonde | node-red admin hash-pw"


Password:
$2b$08$R8.1b1YafovpJpg5mU2jZe.hHXcYQP1ErbleI.ndnaUX1jANiQgeu
$ docker exec -ti ab-nodered sh -c "echo Consultation | node-red admin hash-pw"
Password:
$2b$08$NmbgNT17h5cQL4PP0kGkUO46gkoUX2BAMrVfHRKQtmvHZ6786bpu6

Nous éditions le fichier de configuration de Node-RED :

$ docker exec -ti ab-nodered vi /data/settings.js

Le fichier de configuration contient déjà une section en commentaire, nous la remplacerons par :

adminAuth: {
type: "credentials",
users: [
{
username: "admin",
password: "$2b$08$R8.1b1YafovpJpg5mU2jZe.hHXcYQP1ErbleI.ndnaUX1jANiQgeu",
permissions: "*"
},
{
username: "readonly",
password: "$2b$08$NmbgNT17h5cQL4PP0kGkUO46gkoUX2BAMrVfHRKQtmvHZ6786bpu6",
permissions: "read"
}
]
},
Ensuite, nous relançons le container Node-RED :

$ docker-compose restart ab-nodered


Restarting ab-nodered ... done

Il est également souhaitable d’activer HTTPS, vous pouvez le faire directement dans Node-RED en vous reportant à
http://nodered.org/docs/security.html (http://nodered.org/docs/security.html) pour plus d’informations.

Personnellement, je préfère placer un mandataire inverse (reverse proxy) tel qu’un container NGINX, en lui adjoignant
un container CertBot, il est possible d’obtenir et de renouveler automatiquement un certificat via le service Let's
Encrypt.

1.6 Utilisation des API pour le déploiement


Nous avons vu qu’il est possible d’utiliser l’interface web de Node-RED pour développer des flows, les gérer et les
déboguer. Il est également possible d’utiliser les API de Node-RED si vous ne souhaitez pas utiliser l’interface web pour
des raisons de sécurité ou des raisons d’exploitabilité.

Node-RED dispose d’une API RESTful, qui est décrite à l’adresse https://nodered.org/docs/api/admin/methods/
(https://nodered.org/docs/api/admin/methods/).

Nous allons voir l’utilisation de l’API en ligne de commande grâce à la commande curl.

Commençons par appeler l’API du service d’authentification avec un couple user/password pour obtenir un token
permettant de nous authentifier auprès des autres API.

La réponse de l’API /auth/token est un dictionnaire JSON, qui contient le token lui-même ainsi que sa durée de vie :

{
"access_token": "aMkqdi…...8ndfdfvhtyjtujkiN0lrM0uU=",
"expires_in": 604800,
"token_type": "Bearer"
}

Nous exportons le couple user/password dans les variables RED_ADMIN_USER et RED_ADMIN_PASSWORD, nous
appelons l’API /auth/token pour obtenir un token que nous exportons dans la variable RED_ADMIN_TOKEN.

export RED_ADMIN_USER=admin
export RED_ADMIN_PASSWORD=MaitreDuMonde

export RED_ADMIN_TOKEN=`curl http://localhost:1880/auth/token \


--silent \
--data "client_id=node-red-
admin&grant_type=password&scope=*&username=$RED_ADMIN_USER&password=$RED_ADMIN_PASSWORD" \
| jq --raw-output '.["access_token"]'`
echo $RED_ADMIN_TOKEN
aMkqdi…...8ndfdfvhtyjtujkiN0lrM0uU=

Il est possible de sauvegarder l’ensemble des flows sous forme d’un fichier JSON avec une requête GET sur l’API
/flows :

curl http://127.0.0.1:1880/flows \
--silent \
--request GET \
--header "Authorization: Bearer $RED_ADMIN_TOKEN" \
--output flows.json

Puis de recharger l’ensemble en supprimant tous les flows existants grâce à une requête POST sur l’API /flows :
curl http://127.0.0.1:1880/flows \
--verbose \
--request POST \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $RED_ADMIN_TOKEN" \
--header "Node-RED-Deployment-Type: full" \
--data @flows.json

Il est possible d’afficher l’ID d’un flow (tab) à partir de son nom (label) :

curl http://127.0.0.1:1880/flows \
--silent \
--request GET \
--header "Authorization: Bearer $RED_ADMIN_TOKEN" \
| jq '.[] | select(.type == "tab" and .label == "7_6_deploy_api") | .label, .id'
"7_6_deploy_api"
"b02a088a8cf71847"

Nous pouvons ensuite extraire le flow concerné à partir de son ID :

curl http://127.0.0.1:1880/flow/b02a088a8cf71847 \
--silent \
--request GET \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $RED_ADMIN_TOKEN" \
--output 7_6_deploy_api.json

Sur la machine cible après avoir obtenu un token, vous pouvez charger le flow précédemment exporté (requête POST) :

curl http://127.0.0.1:1880/flow \
--verbose \
--request POST \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $RED_ADMIN_TOKEN" \
--data @7_6_deploy_api.json

Note : le flow change d’ID lorsqu’il est rechargé en utilisant POST. Le flow est déployé immédiatement après son
chargement.

Il est aussi possible de mettre à jour un flow sur la machine cible grâce à la requête PUT (il faut au préalable obtenir son
ID en utilisant la requête précédente) :

curl http://127.0.0.1:1880/flow/7ee982982c04c05c \
--verbose \
--request PUT \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $RED_ADMIN_TOKEN" \
--data @7_6_deploy_api.json

1.7 Sécurisation du serveur MQTT


Le fichier mosquitto.conf contient les paramètres de base du serveur MQTT. Ils définissent 3 listeners qui traitent les
connexions des clients, chaque listener dispose de ses propres paramètres (per_listener_settings true) :

user mosquitto

log_timestamp true
log_timestamp_format %Y-%m-%d %H:%M:%S
connection_messages true

persistence true
retain_available true

per_listener_settings true

listener 8883
socket_domain ipv4
protocol mqtt
persistence true
allow_anonymous false
require_certificate true
cafile /mosquitto/config/ca.crt
certfile /mosquitto/config/server.crt
keyfile /mosquitto/config/server.key
use_identity_as_username true
acl_file /mosquitto/config/mosquitto.acl

listener 1883
bind_interface eth0
socket_domain ipv4
protocol mqtt
persistence true
allow_anonymous false
password_file /mosquitto/config/mosquitto.passwd
acl_file /mosquitto/config/mosquitto.acl

listener 1883
bind_interface lo
socket_domain ipv4
protocol mqtt
persistence false
allow_anonymous true
sur le port 8883, nous activons le TLS, et exigeons un certificat client ; le CN du certificat sert alors de username
(donc pas de connexion avec un couple username/password). Le fichier mosquitto.acl contient les Access Control
List qui autorisent (ou non) l’accès des utilisateurs aux différents topics ;
sur le port 1883 de l’interface eth0, nous nous connectons avec un couple username/password. Le fichier
mosquitto.acl contient les ACL, et le fichier mosquitto.passwd contient la définition du couple
username/password ;
sur le port 1883 de l’interface lo (loopback), nous n’exigeons pas de mot de passe et il n’y a aucune ACL pour
restreindre les accès aux différents topics. Ce listener est utilisé lorsque la commande mosquitto_pub est exécutée
à l’intérieur du container Docker ab-mqtt.

Le fichier mosquitto.acl contient les différentes ACL :

pattern write alert/%u/ping


pattern read alert/%u/pong
pattern write alert/%u/acq/#
pattern read alert/%u/push/#
pattern write alert/%u/button/#
pattern write alert/%u/err

user nodered.alert.u03.fr
topic read alert/+/ping
topic write alert/+/pong
topic read alert/+/acq/#
topic write alert/+/push/#
topic read alert/+/button/#
topic read sondes/#

user administrateur.alert.u03.fr
topic readwrite #

user ab_logger.alert.u03.fr
topic read #

Les lignes pattern permettent aux boîtiers d’accéder aux topics nécessaires à leur fonctionnement, la chaîne de
caractères « %u » est remplacée par le nom d’utilisateur, c’est pour cette raison que le nom du boîtier (ID_BOITIER
dans card.h) doit correspondre au certificat utilisé par le boîtier.

Si vous créez un certificat au nom de administrateur.alert.u03.fr il aura tous les droits sur les topics alert/#,
vous pourrez l’utiliser avec MQTT Explorer, par exemple.

L’utilisateur ab_logger.alert.u03.fr a été créé pour vous, son mot de passe est AB_LOGGER, il est utilisé par le
container ab-logger.

Vous pouvez augmenter le niveau de sécurité en :

n’activant que MQTT avec TLS avec certification et en désactivant MQTT avec username/password ;
créant un certificat pour ab-logger.

2. Autres cartes et connectivités


La carte ESP32 Devkit offre la connectivité Wi-Fi de base, il existe d’autres cartes offrant d’autres connectivités :

WT32-ETH01 : carte ESP32 avec un port Ethernet ;


LILYGO TTGO T-CALL : connectivité GSM 2G ;
LILYGO TTGO T-SIM7000G : connectivité 2G, Cat-M, Cat-NB (NB-IoT) ;
LILYGO Carte TTGO T-Internet-COM : connectivité Ethernet et port Mini PCIe pour installer une carte 3G ou 4G, il est
possible de choisir sa carte en fonction de la connectivité requise.
Attention, les cartes 2G sont moins chères que les autres cartes, leur débit est suffisant, mais la technologie 2G est en fin
de vie, Orange envisage une fin de service en 2025.

2.1 Ethernet avec WT32-ETH01


Cette carte offre une connectivité Ethernet, elle a toutefois certaines limitations :

elle n’offre pas nativement de PoE. Le PoE aurait pu permettre de simplifier le déploiement en n’utilisant qu’un seul
câble. Il est toutefois possible d’utiliser un splitter PoE ;
la carte ne dispose pas de port USB avec une interface série, pour la programmation et le débogage, il faut utiliser
un convertisseur USB série en 3,3 V.

2.2 LTE et 2G
LILYGO produit plusieurs cartes offrant les connectivités suivantes, GPRS, LTE Cat-M ou NB-IoT :

la carte LilyGO T-Call offre une connectivité GPRS (2G) ;


les cartes LilyGO TTGO T-SIM7000G offrent la connectivité GPRS, LTE Cat-M, et NB-IoT. Ces cartes disposent
également du positionnement GNSS (support GPS, Beidou, Glonass), il serait donc possible d’ajouter les
coordonnées GPS au message PING pour localiser le boîtier d’alerte en utilisation mobile.
3. Réalisation du boîtier
Notre boîtier prendra la forme d’un tableau blanc dans lequel nous percerons des trous pour les boutons en face des
LED. Nous utiliserons un ruban de LED IP65/IP67, le modèle dont les LED sont recouvertes d’un isolant en plastique
souple (et non le modèle où le ruban LED est glissé dans une gaine souple).

(/sites/default/files/magazines/hackable/hk-
045/boitier_alerte_portable.jpg)

Réalisation Major Stéphane T.

Les rubans existent en 30, 60, 100 ou 144 LED par mètre. Nous utiliserons 30/m si les libellés sur le tableau sont destinés
à être réécrits à la main à l’aide d’un feutre effaçable, nous utiliserons 60/m si les libellés sont imprimés.

(/sites/default/files/magazines/hackable/hk-
045/boitier_alerte_portable_interieur.jpg)

Réalisation Major Stéphane T.


Veillez à prendre des LED WS2812B, ou du moins des LED qui supportent la commande en 3,3 V en étant alimentées en
5 V.

(/sites/default/files/magazines/hackable/hk-
045/tableau_alerte_simple.jpg)

Réalisation GPX David W.

Attention au diamètre des boutons-poussoirs qui doit être choisi en fonction de la densité des LED.

(/sites/default/files/magazines/hackable/hk-045/tableau_alerte_bouton.jpg)

Réalisation Major Stéphane T.

4. Évolutions
Si plusieurs boîtiers doivent partager les mêmes alertes, il faut publier les alertes sur le topic de chaque boîtier. Une
évolution serait de paramétrer les boîtiers avec deux topic de base :

un pour échanger les messages ping / pong / acq / button ;


un pour recevoir les messages push (ce topic sera alors un topic générique en fonction de l’application).

Lors du codage de nos flows, nous avons publié directement sur le topic des boîtiers. Cette solution n’est clairement
pas industrialisable, car chaque ajout ou modification de boîtier oblige à modifier les flows de base. Le mieux est de
publier les résultats de supervision vers un topic intermédiaire, par exemple
/supervision/temperature/TC_SOUTIEN_FRIGO_02, ensuite sur un flow propre à chaque boîtier avec aiguillage
vers les différents points de supervision souhaités vers leur LED cible.

Conclusion
En exécutant la logique applicative sur le serveur avec un outil tel que Node-RED, nous avons réduit drastiquement le
codage nécessaire. Nous avons utilisé le protocole MQTT pour la communication entre les boîtiers et le serveur. Les
systèmes externes peuvent être supervisés à l’aide des protocoles HTTP, WebSocket, TCP et UDP, en mode client et en
mode serveur. Nous avons vu que Node-RED gère TLS nativement, y compris avec authentification mutuelle. Le site
https://cookbook.nodered.org/ (https://cookbook.nodered.org/) donne des exemples de différents cas d’usage.

Nous aurions pu utiliser un écran en lieu et place d’un ruban de LED adressables, mais les écrans sont plus fragiles, plus
lourds, plus consommateurs et sont difficilement visibles en plein soleil.

Un boîtier d’alerte basé sur une carte LILYGO TTGO T-CALL avec 8 LED consomme environ 80 mA, il peut tenir environ 5
jours sur une powerbank de 10 000 mAh.

La construction sur une base de tableau blanc nous permet d’utiliser soit un feutre effaçable, si les libellés des LED sont
variables en fonction de la mission, soit une étiqueteuse à ruban dans le cas contraire.

Article rédigé par

Foucher Laurent (/auteur/foucher-laurent)

FL 4 articles

(/auteur/foucher-
laurent)

Par le(s) même(s) auteur(s)

AlertBox : un boîtier d’alerte multifonctions (/hackable/hk-044/alertbox-un-boitier-d-alerte-multifonctions)

Hackable n° 44 (/hackable/hk-044) septembre 2022

Par Foucher Laurent (/auteur/foucher-laurent)

Domotique (/search/node?domains%5B0%5D=72455) Électronique (/search/node?domains%5B0%5D=72452)

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. ...
OpenWrt : un firmware et des applications (/hackable/hk-041/openwrt-un-firmware-et-des-applications)

Hackable n° 41 (/hackable/hk-041) mars 2022

Par Foucher Laurent (/auteur/foucher-laurent)

Embarqué (/search/node?domains%5B0%5D=72457)

Pour certaines applications légères, OpenWrt tournant sur un équipement réseau low cost est une alternative solide
face à un OS classique sur une Raspberry Pi. Nous allons voir comment intégrer une application dans un firmware
destiné à un petit routeur Wi-Fi coûtant moins de 30 euros.
...

 PLUS D'ARTICLE DE CET AUTEUR (/SEARCH/NODE?AUTHORS%5B0%5D=74609)

 Les derniers articles Premiums

(/contenu-premium/de-la-scytale-au-bit-quantique-l- (/contenu-premium/exposez-vos-donnees-avec-
avenir-de-la-cryptographie) sqlpage)

De la scytale au bit quantique : l’avenir de la Exposez vos données avec SQLPage (/contenu-
cryptographie (/contenu-premium/de-la-scytale- premium/exposez-vos-donnees-avec-sqlpage)
au-bit-quantique-l-avenir-de-la-cryptographie)
Par Auverlot Olivier (/auteur/auverlot-olivier)
Par Samhi Jordan (/auteur/samhi-jordan)
Code (/search/node?domains%5B0%5D=72464)
Crypto (/search/node?domains%5B0%5D=74479)
Web (/search/node?domains%5B0%5D=72468)

Imaginez un monde où nos données seraient aussi


Malgré l’évolution des technologies, concevoir une
insaisissables que le célèbre chat de Schrödinger : à la
application web reste un travail complexe qui nécessite
fois sécurisées et non sécurisées jusqu'à ce qu'un
de nombreuses connaissances dans de multiples
cryptographe quantique décide d’y jeter un œil. Cet
article nous emmène dans les méandres de la
cryptographie quantique, où la physique quantique
n'est pas seulement une affaire de laboratoires, mais la domaines. Heureusement, de nouvelles approches
clé d'un futur numérique très sécurisé. Entre principes émergent actuellement et c’est justement le cas avec
quantiques mystérieux, défis techniques, et applications SQLPage.
pratiques, nous allons découvrir comment cette
technologie s'apprête à encoder nos données dans une
dimension où même les meilleurs cryptographes n’y
pourraient rien faire.

(/contenu-premium/les-nouvelles-menaces-liees-a-l- (/contenu-premium/migration-d-une-collection-
intelligence-artificielle) ansible-a-l-aide-de-fqcnmigration)

Les nouvelles menaces liées à l’intelligence Migration d’une collection Ansible à l’aide de
artificielle (/contenu-premium/les-nouvelles- fqcn_migration (/contenu-premium/migration-d-
menaces-liees-a-l-intelligence-artificielle) une-collection-ansible-a-l-aide-de-fqcnmigration)

Par Samhi Jordan (/auteur/samhi-jordan) Par Pelisse Romain (/auteur/pelisse-romain)

IA (/search/node?domains%5B0%5D=72466) Système (/search/node?domains%5B0%5D=72451)

Sécurité système (/search/node?


Distribuer du contenu Ansible réutilisable (rôle,
domains%5B0%5D=74489)
playbooks) par l’intermédiaire d’une collection est
Malware (/search/node?domains%5B0%5D=74477) devenu le standard dans l’écosystème de l’outil
d’automatisation. Pour éviter tout conflit de noms, ces
collections sont caractérisées par un nom unique, formé
Sommes-nous proches de la singularité technologique ?
d’une espace de nom, qui peut-être employé par
Peu probable. Même si l’intelligence artificielle a fait un
plusieurs collections (tel qu'ansible ou community) et
bond ces dernières années (elle est étudiée depuis des
d’un nom plus spécifique à la fonction de la collection
dizaines d’années), nous sommes loin d’en perdre le
en elle-même. Cependant, il arrive parfois qu’il faille
contrôle. Et pourtant, une partie de l’utilisation de
migrer une collection d’un espace de noms à un autre,
l’intelligence artificielle échappe aux analystes. Eh oui !
par exemple une collection personnelle ou
Comme tout système, elle est utilisée par des acteurs
communautaire qui passe à un espace de noms plus
malveillants essayant d’en tirer profit pécuniairement.
connus ou certifiés. De même, le nom même de la
Cet article met en exergue quelques-unes des
collection peut être amené à changer, si elle dépasse son
applications de l’intelligence artificielle par des acteurs
périmètre d’origine ou que le produit qu’elle concerne
malveillants et décrit succinctement comment parer à
est lui-même renommé.
leurs attaques.

 VOIR LES 36 ARTICLES PREMIUM (/CONTENUS-PREMIUM)


Les listes de lecture

Communications satellites (/liste-de-lecture/communications-satellites-0)

7 article(s) - ajoutée le 01/07/2020

Radio et wireless (/search/node?domains=72465)

La SDR permet désormais de toucher du doigt un domaine qui était jusqu'alors inaccessible : la réception et l'interprétation de
signaux venus de l'espace. Découvrez ici différentes techniques utilisables, de la plus simple à la plus avancée...

Rétrocomputing : résurrection de matériel (/liste-de-lecture/retrocomputing-resurrection-de-materiel-0)

8 article(s) - ajoutée le 01/07/2020

Rétro (/search/node?domains=72471)

Au-delà de l'aspect nostalgique, le rétrocomputing est l'opportunité unique de renouer avec les concepts de base dans leur plus
simple expression. Vous trouverez ici quelques-unes des technologies qui ont fait de l'informatique ce qu'elle est aujourd'hui.

Outils et matériel pour la SDR (/liste-de-lecture/outils-et-materiel-pour-la-sdr-0)

9 article(s) - ajoutée le 01/07/2020

Radio et wireless (/search/node?domains=72465)

S'initier à la SDR est une activité financièrement très accessible, mais devant l'offre matérielle il est parfois difficile de faire ses
premiers pas. Découvrez ici les options à votre disposition et les bases pour aborder cette thématique sereinement.

 VOIR LES 31 LISTES DE LECTURE (/RECHERCHE/LISTES-DE-LECTURE?DOMAINS%5B74527%5D=74527)

DOMAINES 

NOS PUBLICATIONS 

AIDE & CONTACT 

ABONNEMENTS 

À PROPOS 
TÉL. : 0 3 . 6 7 . 1 0 . 0 0 . 2 0 ( T E L : 0 3 6 7 1 0 0 0 2 0 )

Vous aimerez peut-être aussi