IMA5 2020/2021 P2 : Différence entre versions
(→Test des différents capteurs) |
(→Documents rendus) |
||
(112 révisions intermédiaires par 2 utilisateurs non affichées) | |||
Ligne 5 : | Ligne 5 : | ||
==Description== | ==Description== | ||
− | Aujourd’hui la qualité de l’air et plus globalement la pollution atmosphérique est un enjeu environnemental majeur, notamment dans le cadre du travail. Ce danger fait l’objet de préoccupations depuis plusieurs années et apparaît aujourd’hui comme un problème majeur de santé publique. Notre projet | + | Aujourd’hui la qualité de l’air et plus globalement la pollution atmosphérique est un enjeu environnemental majeur, notamment dans le cadre du travail. Ce danger fait l’objet de préoccupations depuis plusieurs années et apparaît aujourd’hui comme un problème majeur de santé publique. Notre projet a pour objectif de répondre à cette problématique en proposant une analyse en temps réel de la qualité de l’air des locaux de Polytech. En effet, l’amélioration de la qualité de l’air passe en premier lieu par l’étude de celle-ci, il est primordial de connaître notre environnement avec précision. |
==Objectifs== | ==Objectifs== | ||
+ | Nos objectifs se séparent en 3 parties : | ||
+ | *Le développement de stations émettrices. | ||
+ | Nous devons développer le firmware des stations émettrices pour que ces dernières puissent intégrer les capteurs que nous avons à dispositions (température, humidité, pression, CO2, H2S, …) et envoyer ces données par ondes radio via nos modules Lora, ce code devra être le plus générique possible en vue de l’intégration de futurs capteurs. Nous devons également mettre en place un shield pour que la modularité de ces stations soit accrue et que l’ajout de capteur soit facilement faisable. Notre microcontrôleur, notre module antenne Lora ainsi que nos capteurs seront placés dans une boîte ce qui constituera notre station. Cette boîte permettra de rendre notre station plus compacte et plus esthétique tout en garantissant un accès facile aux composants internes de cette dernière. | ||
+ | *La mise en place d’un réseau LoRaWaN. | ||
+ | La mise en place de notre réseau LoRaWAN passe par plusieurs éléments. Tout d’abord ce qu’on appelle des end-points ou nœuds terminaux (nos stations émettrices). Ces stations envoient leurs informations par ondes radios, qui sont reçues par nos passerelles Kerlink. Le but de ces passerelles est de faire le lien entre nos stations et notre network serveur. Notre tâche est donc de configurer ces passerelles mais également notre network serveur qui réceptionne toutes les informations de nos stations. Finalement notre dernière tâche est de mettre en place un serveur applicatif qui stockera l’ensemble des données pour pouvoir par la suite les présenter à l’utilisateur. Bien entendu notre chaîne de transmission devra être sécurisée avec un système de chiffrement (clé publique/privée). | ||
+ | *La récupération et l'affichage des données. | ||
+ | Notre dernier objectif représente notre partie applicative. Une fois les données enregistrées et stockées dans notre base de données, nous devons mettre en place un application qui sera mise à disposition des utilisateurs pour consulter les données sur la qualité de l’air. Certaines de ces données ne seront pas totalement traitées, il faudra donc pouvoir les repérer et leur appliquer un dernier traitement avant de les présenter. Pour ce qui est de la présentation, un système de graphique sur une donnée spécifique et des indices sur la qualité sur la qualité de l’air représente la manière la plus simple (pour l’utilisateur) de visualiser les informations importantes. | ||
+ | |||
+ | =Travail effectué= | ||
==Prise en main du matériel== | ==Prise en main du matériel== | ||
Ligne 13 : | Ligne 22 : | ||
===Transmission entre 2 cartes=== | ===Transmission entre 2 cartes=== | ||
− | Choix de l'IDE : Nous avons testé différentes IDE (Semtec, uVision, Mbed Studio). De | + | Choix de l'IDE : Nous avons testé différentes IDE (Semtec, uVision, Mbed Studio, STM32). |
+ | De par sa simplicité d'utilisation ainsi que de par la possibilité d'utiliser une version online nous avons privilégier l'utilisation de l'IDE Mbed pour effectuer nos tests. | ||
+ | Cette IDE a d'ailleurs été utilisée dans d'anciens projets Polytech utilisant des émetteurs Lora et des cartes Nucléo. | ||
− | Afin d'avoir une première manipulation de ces cartes et de l'IDE nous avons | + | Afin d'avoir une première manipulation de ces cartes et de l'IDE nous avons utilisé des programmes de démonstration du type "Ping/Pong". |
L'émission et la réception des données sont fonctionnelles entre 2 cartes Nucléo possédant des Antennes Lora. | L'émission et la réception des données sont fonctionnelles entre 2 cartes Nucléo possédant des Antennes Lora. | ||
+ | |||
+ | Par la suite et sur demande de nos enseignants référents nous avons arrêté d'utiliser l'IDE Mbed pour partir sur l'IDE STM32. | ||
+ | Cette IDE à l'avantage d'être plus bas niveau dans la configuration des pins mais elle dispose également de fonctions HAL (Hardware Abstraction Layer). | ||
+ | Ce sont des fonctions qui ont été préalablement programmées par STMicroelectronics et qui nous permettent, par exemple, d'effectuer diverses opérations de lectures et d'écriture dans notre mémoire. | ||
===Test des différents capteurs=== | ===Test des différents capteurs=== | ||
Ligne 22 : | Ligne 37 : | ||
Nous disposons de plusieurs capteurs afin d'affiner nos données sur la qualité de l'air : | Nous disposons de plusieurs capteurs afin d'affiner nos données sur la qualité de l'air : | ||
− | + | SEN0248 de chez DFROBOT, capteur de température, humidité, pression et gaz. L'envoie et la réception de données s'effectue via un bus I2C, il est donc nécessaire de fournir une clock à ce capteur. | |
+ | https://wiki.dfrobot.com/Gravity__I2C_BME680_Environmental_Sensor__VOC,_Temperature,_Humidity,_Barometer__SKU__SEN0248 | ||
+ | |||
+ | DFR0066 de chez DFROBOT, capteur de température et d'humidité. L'envoie et la réception de données se fait via une pin Data et SCK, nous devons également fournir une clock à ce capteur. | ||
Datasheet : https://wiki.dfrobot.com/SHT1x_Humidity_and_Temperature_Sensor__SKU__DFR0066_ | Datasheet : https://wiki.dfrobot.com/SHT1x_Humidity_and_Temperature_Sensor__SKU__DFR0066_ | ||
− | |||
− | |||
− | |||
− | |||
− | |||
ULPSM-H2S de chez SPEC SENSOR, capteur de sulfure d'hydrogène | ULPSM-H2S de chez SPEC SENSOR, capteur de sulfure d'hydrogène | ||
Ligne 34 : | Ligne 47 : | ||
T6713 de chez TELAIRE, capteur de C02 | T6713 de chez TELAIRE, capteur de C02 | ||
− | https:// | + | https://14core.com/wp-content/uploads/2017/11/T6700_Series_CO2_sensor_Module_Datasheet.pdf |
EC4-2000-SO2 de chez SGX SensorTech, capteur de dioxyde de souffre | EC4-2000-SO2 de chez SGX SensorTech, capteur de dioxyde de souffre | ||
https://www.sgxsensortech.com/content/uploads/2014/07/DS-0243-EC4-2000-SO2-Datasheet-V2.pdf | https://www.sgxsensortech.com/content/uploads/2014/07/DS-0243-EC4-2000-SO2-Datasheet-V2.pdf | ||
− | == | + | ==Réseau LoRaWan== |
− | === | + | ===Network Server=== |
− | + | Une machine virtuelle est déployée afin d'héberger le Network Server : | |
+ | * Nom : lorawan.plil.info | ||
+ | * Mdp : glopglop | ||
− | + | Cette machine est connectée à internet via l'interface eth0 et est relié au Vlan 501 (Lorawan) via l'interface eth1. Le Vlan501 comprend donc notre VM, la passerelle Kerlink Outdoor (sur le toit de l'école) et la passerelle Kerlink Indor. | |
− | + | ====Serveur DHCP==== | |
− | + | Les passerelles Kerlink doivent être connues sur notre réseau, elles doivent donc posséder leur propre adresse IP. Cette adresse IP leur est fournie par un serveur DHCP présent sur la carte réseau "eth1" de la VM lorawan. | |
Pour ce faire nous créons un sous-réseau IPV4 192.168.42.0/24. Nous attribuons l'adresse 192.168.42.10 à la carte "eth1" et nous configurons le serveur DHCP de manière à attribuer dynamiquement des adresses IPV4 aux nouveaux appareils repérés sur le réseau. | Pour ce faire nous créons un sous-réseau IPV4 192.168.42.0/24. Nous attribuons l'adresse 192.168.42.10 à la carte "eth1" et nous configurons le serveur DHCP de manière à attribuer dynamiquement des adresses IPV4 aux nouveaux appareils repérés sur le réseau. | ||
+ | '''''Dans le fichier dhcpd.conf :''''' | ||
subnet 192.168.42.0 netmask 255.255.255.0 { | subnet 192.168.42.0 netmask 255.255.255.0 { | ||
range 192.168.42.1 192.168.42.9 | range 192.168.42.1 192.168.42.9 | ||
Ligne 57 : | Ligne 73 : | ||
Ce sous réseau permet d'attribuer des adresses IPV4 allant de 192.168.42.1 à 192.168.42.9. | Ce sous réseau permet d'attribuer des adresses IPV4 allant de 192.168.42.1 à 192.168.42.9. | ||
− | Nous pouvons ainsi accéder à l'interface de configuration | + | Nous pouvons ainsi accéder à l'interface de configuration des passerelles Kerlink en ssh via l'adresse IP attribuée (Sur lorawan.plil.info) : |
+ | * '''Passerelle Outdoor :''' ssh 192.168.42.1, mdp: pdmk-062E7A) | ||
+ | * '''Passerelle Indoor :''' ssh 192.168.42.2, mdp: pdmk-030970) | ||
Cette interface de configuration nous sera très utile lors de la configuration de notre Network Server. | Cette interface de configuration nous sera très utile lors de la configuration de notre Network Server. | ||
− | + | ====Installation et configuration du ChirpStack Network Server==== | |
+ | ChirpStack Network Server est une implémentation open-source de LoRaWAN® Network Server. La responsabilité du composant Network Server est la déduplication des trames LoRaWAN reçues par les passerelles LoRa® et de gérer : | ||
+ | |||
+ | - L'authentification | ||
+ | |||
+ | - La couche mac LoRaWAN (et commandes mac) | ||
+ | |||
+ | - La communication avec le serveur d'applications ChirpStack | ||
+ | |||
+ | - La planification des trames de liaison descendante | ||
+ | |||
+ | * '''Installation :''' | ||
+ | La mise en place de ce serveur sur la VM lorawan nécessite d'installer trois entités : un '''gateway-bridge''', un '''network-server''' et un '''application-server | ||
+ | |||
+ | Pour se faire nous avons suivi les instructions du site officiel : | ||
+ | https://www.chirpstack.io/network-server/ | ||
+ | |||
+ | * '''Configuration :''' | ||
+ | Différents fichiers de configuration sont alors disponibles : | ||
+ | |||
+ | - /etc/chirpstack-gateway-bridge/chirpstack-gateway-bridge.toml | ||
+ | |||
+ | - /etc/chirpstack-network-server/chirpstack-network-server.toml | ||
+ | |||
+ | - /etc/chirpstack-application-server/chirpstack-application-server.toml | ||
+ | |||
+ | Paramétrages notables : | ||
+ | - Les trois serveurs démarrent automatiquement lors de l'allumage de la VM | ||
+ | - NetworkID : 000000 | ||
+ | |||
+ | Nous avons alors un accès a une interface graphique de configuration sur le port 8080 pour notre LoRaWan_Network (accès 172.26.189.22:8080 '''(désactiver le proxy pour cette adresse)'''). Nous instancions alors notre network serveur sous le nom de localhost (localhost:8000). | ||
+ | |||
+ | * '''Configuration des passerelles Kerlink :''' | ||
+ | |||
+ | En connection ssh sur les gateways, nous mettons à jour le firmware des deux passerelles (Indoor : Wirnet iFemToCell et Outdoor Wirnet iBTS). Une fois l'environnement correctement installé, nous nous sommes appuyés sur le https://wikikerlink.fr/ pour activer les '''gateways''' ainsi que leurs '''packet_fowarder''' (https://wikikerlink.fr/wirnet-productline/doku.php?id=wiki:lora:keros_4.3.3:cpf_configuration). Nous instancions notamment notre LoraNetworkServer au sein de nos gateways via la ligne ''gwmp.node = "192.168.42.10"'' dans le fichier ''/etc/lorafwd.toml'' | ||
+ | |||
+ | * '''Instanciation des passerelles sur le LNS (LoraNetworkServer) :''' | ||
+ | |||
+ | Sur la VM lorawan, les logs nous montre bien l'émission de message en provenance de nos deux passerelles. Sur l'interface graphique de paramétrage, nous créons alors deux nouvelles instances de gateways en fournissant leur ID respective. Les gateways sont alors visible pour notre LNS et nous remarquons une émission de trame LoRaWan de façon régulière. | ||
+ | |||
+ | A ce point, nous avons un LNS installé, configuré, capable de détecter et communiquer en LoRaWan avec les passerelles au sein de son réseau. La dernière étape consiste donc à tester la transmission complète d'une trame, d'un terminal LoRa à l'application_server. | ||
+ | |||
+ | * '''Test du LNS :''' | ||
+ | |||
+ | Une nouvelle application GPS_Test est créée sur l'interface graphique du LNS, des "application" et "network" keys sont alors générées et transmises manuellement à notre terminal LoRa en le connectant à un ordinateur (la configuration de ce module est possible grâce à l’application : ). Une fois les clefs correctement transmises, nous sommes capables de recevoir les trames et données issues du GPS. Ces données ont donc correctement transité au sein de nos passerelles Kerlink pour être finalement reçues par notre network serveur. | ||
+ | Ceci conclut donc la mise en place du LoraNetworkServer, la prochaine étape consiste donc à connecter nos propres terminaux LoRa. | ||
+ | |||
+ | ==Stations== | ||
+ | |||
+ | ===Implémentation du firmware=== | ||
+ | |||
+ | Suite à plusieurs tests et expérimentations et comme expliqué dans notre partie sur le choix de l'IDE, il a été décidé d'utiliser l'IDE STM32 Cube pour implémenter le firmware. Cette IDE permet en effet l'utilisation de bibliothèques de plus bas niveau que mbed et ainsi d'obtenir un meilleur contrôle de notre carte. Ce meilleur contrôle nous sera par ailleurs utile lors de l'implémentation des bus I2C pour la lecture de certains capteurs mais également lors de la mise en commun de nos différents bibliothèques relatives à nos capteurs. | ||
+ | |||
+ | ====Architecture du firmware==== | ||
+ | |||
+ | Dans un souci de modularité et de simplicité d'implémentation, notre firmware se découpera en deux parties. La première partie permettra la lecture de chaque capteur connecté à la station tandis que la seconde se chargera de transmettre toute ces données en LoRaWan. Afin de faciliter l'ajout ou le retrait de capteur sur une station établie l'architecture ci-dessous : | ||
+ | |||
+ | [[Fichier:Firmware_archi.png|center|500px]] | ||
+ | |||
+ | Il convient ainsi de créer, pour chaque capteur sur la station : | ||
+ | *Une fonction d'initialisation du capteur (startup séquence etc...), appelée au démarrage de la station. | ||
+ | *Une fonction de lecture spécifique à chaque capteur, appelée dans la boucle principale. Cette fonction de lecture se déroule en deux temps : | ||
+ | **1 - Lecture du capteur (réception et prétraitement des données si besoin) | ||
+ | **2 - Remplissage de la trame avec les données récupérées (en accord avec le format ci-contre) | ||
+ | |||
+ | |||
+ | [[Fichier:FormatTrame.png|center|700px]] | ||
+ | |||
+ | |||
+ | Une fois la trame remplie, celle-ci est transmise à la fonction d'envoi, chargée de transmettre ces données par ondes radio. | ||
+ | |||
+ | Il est capital pour notre projet, avant toute lecture de capteur, d'être capable de transmettre des données vers notre LNS. Nous devons donc disposer d'une bibliothèque permettant de communiquer en respectant les normes d'un réseau LoRa. Cette bibliothèque existe et est disponible à l'adresse suivante : https://www.st.com/content/st_com/en/products/embedded-software/mcu-mpu-embedded-software/stm32-embedded-software/stm32cube-expansion-packages/i-cube-lrwan.html | ||
+ | |||
+ | '''Problèmes rencontrés :''' | ||
+ | |||
+ | La bibliothèque propose des programmes de communications LoRaWan uniquement pour des carte STM32L, non compatible avec notre STM32F411. Après avoir tenté durant plusieurs jours d'adapter le code de la bibliothèque et face à la complexité de la tâche, décision est prise d'utiliser des cartes compatibles avec notre librairie. Nos stations seront donc bâties sur des cartes STM32L152_RE. | ||
+ | |||
+ | '''Communication en LoRa''' | ||
+ | |||
+ | Sur l'interface du LNS : | ||
+ | *Nous créons donc une application "PFE_TheoLolo_2020" | ||
+ | *Nous y instancions un nouveau Device | ||
+ | *L'EUI Device doit correspondre à celui de notre carte, que l'on récupère via les logs de notre serveur. | ||
+ | *Generation d'une Application_key (MAIS PAS de Gen_Application_key qui doit être laissé vide) | ||
+ | |||
+ | Sur notre firmware : | ||
+ | *Ouverture du projet EndNode présent dans la librairie | ||
+ | *Modification du commisionning.h : MAJ de la LORAWAN_APP_KEY et de la LORAWAN_NTW_KEY (Ces deux clefs doivent être IDENTIQUES) | ||
+ | |||
+ | Une fois ces quelques paramètres ajustés, nous sommes capables de visualiser les données issues de notre carte sur notre LNS. La chaîne de communication est maintenant entièrement fonctionnelle. On peut donc pleinement se concentrés sur la lecture des capteurs et la mise en forme des données en amont ainsi que sur la récupération et l'affichage de ces données en aval. | ||
+ | |||
+ | '''Lecture des capteurs''' | ||
+ | Nous disposons, pour notre projet, de nombreux capteurs différents, avec chacun un protocole de lecture définit (en principe) dans leur datasheet. Dans un souci | ||
+ | |||
+ | ==Application== | ||
+ | |||
+ | Les données arrivant sur notre LNS doivent être transmises et traitées afin d'être présentées aux utilisateurs de l'application. La partie applicative de notre projet s'effectuera sur une VM nommée Lorap, afin de bien cloisonner la gestion du réseau LoRaWan (sur la VM lorawan) de la gestion applicative (traitement et affichage des données). | ||
+ | |||
+ | ===Réception et Gestion des données=== | ||
+ | |||
+ | Afin de recevoir les données en provenance de notre LNS (Lora Network Serveur), nous utilisons un bus MQTT. | ||
+ | Mais avant tout qu'est que MQTT ? MQTT (Message Queuing Telemetry Transport) est un protocole de messagerie qui fonctionne sur le principe de souscription/publication qui a été développé à la base pour simplifier la communication entre les machines, pour fonctionner ce protocole de transport nécessite l'utilisation d'un Broker (un serveur) dans notre cas nous avons utilisé le broker Mosquitto. | ||
+ | |||
+ | Ce broker est notamment proposé dans les fichiers de configuration du LNS pour récupérer les données émises par nos stations. La configuration de cette file de message s'effectue dans le fichier '''/etc/chirpstack-application-server/chirpstack-application-server.toml''' de la VM lorawan. Par défaut, le MQTT serveur est disponible sur '''tcp://localhost(VMlorawan):1883.'''. | ||
+ | Nous installons le broker Mosquitto sur la VM lorap puis nous implémentons un script python chargé de récupérer et stocker les données à chaque nouveau message dans des bases de données. | ||
+ | |||
+ | Explication de mosquitto.py : | ||
+ | |||
+ | *Tout d'abord nous souscrivons à un topic de la file de message MQTT 172.26.189.22:1883 (utilisée par notre LNS en tant que publisher) | ||
+ | *Une fonction d'écoute attend l'arrivée de message UP (arrivée de données sous format Json) | ||
+ | *Nous extrayons l'EUI de la station émettrice ainsi que la trame de données des capteurs (en base64) | ||
+ | *Une fonction de traitement se charge d'extraire les informations utiles de cette trame (température, pression, etc...) | ||
+ | *Ces données sont par la suite stockées au sein d'une base de données PostgreSQL et ce grâce à l'utilisation d'un second script en python : postgres.py | ||
+ | |||
+ | Pour toucher quelques mots par rapport à ce dernier script, ce dernier se veut très modulaire et propose des opérations génériques de création de table, d'insertion et de mise à jour de données et bien entendu de suppression. | ||
+ | |||
+ | Ces différents scripts sont exécutés dans un containeur Docker afin d'être totalement indépendant et lancés au démarrage de la machine lorap. | ||
+ | |||
+ | Pour lancer ce containeur nous avons tout d'abord installer Docker sur notre machine, puis créé une image Docker. Cette dernière est très simple, elle se charge de vérifier que python est installé et mis à jour et que les paquets utilisés par le script sont installés. | ||
+ | |||
+ | ===Serveur HTTP=== | ||
+ | |||
+ | Afin de fournir une interface utilisateur web, nous avons installé le serveur HTTP Apache2. Un serveur HTTP permet à un site web de communiquer avec un navigateur en utilisant le protocole HTTP(S) et ses extensions (WebDAV, etc.). | ||
+ | |||
+ | Installation : | ||
+ | apt install apache2 | ||
+ | |||
+ | Une configuration précise n’a pas été nécessaire pour qu’apache fonctionne, la seule configuration a été faite au niveau de notre machine tricholome sur le serveur capbreton, l’explication est faite dans une des parties suivantes. | ||
+ | |||
+ | Le but de notre interface Web est de permettre aux utilisateurs de consulter les informations et les données envoyées par nos stations. Pour ce faire, cette dernière devra disposer d’une page de monitoring (ou utilisation d’une API telle que Grafana, voir partie suivante) permettant de connaître en temps réel la qualité de l’air d’une pièce. Une section devra aussi être développée pour configurer nos balises et changer leur mode (active, inactive ou supprimée), comme nos scripts au niveau de la réception de données sont modulaires, il n’est pas nécessaire de renseigner quelles données sont attendues à la réception. Elle devra également lister l’ensemble des stations connues de la base de données ainsi que leur état. Enfin, une section sera également mise à disposition pour l’affichage de notre monitoring de test. | ||
+ | |||
+ | L’ensemble de nos fichiers html et php se situent dans le dossier /var/www/html. Pour pouvoir utiliser du php sur notre serveur web nous devons installer une extension via la commande suivante : | ||
+ | apt install libapache2-mod-php | ||
+ | |||
+ | Pour pouvoir utiliser et manipuler notre base de données dans nos pages php (à travers des PDO, PHP Data Object) nous avons également installer le package php-pgssql, via la commande : | ||
+ | apt install php-pgsql | ||
+ | Puis il faut décommenter la ligne extension=php_pdo_pgsql dans le fichier php.ini qui se situe dans /etc/php/7.3/apache2/. Dans ce fichier, il peut d'ailleurs être intéressant de modifier les lignes error_reporting et ajouter l'option E_ALL ainsi que la ligne display_errors et ajouter l'option On. Cette modification permet à php de renvoyer des erreurs lors des chargements de nos pages lorsque celles-ci comportent des erreurs. | ||
+ | |||
+ | De plus, pour mettre en place cette interface Web, nous avons utilisé Bootstrap, qui est un Framework, une collection d’outils, utiles à la création du design (graphisme, animation et interactions avec la page dans le navigateur, etc.) pour des sites et des applications Web (code HTML et CSS pour faire des formulaires, boutons, barre de navigation, de recherche, …). | ||
+ | |||
+ | ===Base de données=== | ||
+ | |||
+ | Pour stocker nos données nous nous sommes dans un premier temps orientés vers InfluxDB, qui est un système de gestion de base de données orienté séries temporelles hautes performances. Ce choix vient du fait que ce système de gestion de données est très largement utilisé dans les applications IoT notamment grâce à ces hautes exigences en termes de disponibilité et de performances en temps réel. Après avoir discuté avec nos tuteurs nous nous sommes réorientés vers PostgreSQL, système de gestion de données que nous avions déjà utilisé en 3e année. Comme nous venons de l'expliquer, la réelle force d'InfluxDB est son aspect temps réels, qui offre beaucoup de précision au niveau des relevés, dans notre cas une telle précision n’était pas réellement justifiée et il valait mieux se concentrer sur une technologie que nous connaissions afin d’aboutir le plus rapidement possible sur un projet fonctionnel. | ||
+ | |||
+ | Installation : | ||
+ | apt install postgresql | ||
+ | |||
+ | Après avoir installé ce serveur, nous avons commencé par créer un nouvel utilisateur (Par défaut seul l’utilisateur postgres peut se connecter aux bases de données, c’est utilisateur créé automatiquement à la suite de l’installation de PostgreSQL) cette opération s’effectue avec la commande suivante : | ||
+ | createuser -d -P user_pfe (mot de passe glopglop) | ||
+ | A la suite de la création de cet utilisateur, nous créons notre base de données : | ||
+ | createdb -O user_pfe db_pfe | ||
+ | Pour se connecter à notre base de données tout juste créée nous utilisons la commande suivante : | ||
+ | psql db_pfe | ||
+ | |||
+ | |||
+ | Notre base de données contient 3 tables : | ||
+ | |||
+ | *La première table, list_stations contient l’ID unique d’une station (ce qui constitue la clé primaire de la table), la trame type que cette dernière envoie (cette trame est présente dans le fichier tram.yaml), le mode de fonctionne de la station ainsi que son statut. | ||
+ | |||
+ | *Notre deuxième table, history_stations contient et stocke l’ensemble des valeurs transmises par notre station. Cette table se compose d’un indice unique d’entrée (qui constitue la clé primaire de la table), de l’ID de la station qui a transmis cette entrée (ce qui est notre clé étrangère, liée à l’ID de la table list_stations), d’une colonne temps qui nous permet d’indexer chaque entrée (ce qui nous sera également utile pour tracer nos graphiques par la suite), d’un type de données (température, taux d’humidité, pression, …) et bien évidemment de la valeur en elle-même. | ||
+ | |||
+ | *Notre dernière table, qui se nomme history_stations_test est comme son nom l’indique une table similaire à history_stations mais utilisée pour nos tests. En effet, comme nous avions pris du retard sur notre projet au niveau développement des firmwares nous avons tout de même avancé sur cette partie en nous basant sur des données fictives, générées grâce à un script en python. | ||
+ | |||
+ | Ces 3 tables sont créées grâce aux commandes suivantes : | ||
+ | CREATE TABLE IF NOT EXISTS list_stations(DevEUI_station VARCHAR (50) NOT NULL, Trame VARCHAR(200) NOT NULL, Mode INT NOT NULL, Status INT NOT NULL, PRIMARY KEY(DevEUI_station)) | ||
+ | |||
+ | CREATE TABLE IF NOT EXISTS history_stations(Indice SERIAL, DevEUI_station VARCHAR (100) NOT NULL, Time TIMESTAMP WITH TIME ZONE NOT NULL, Type VARCHAR (50) NOT NULL, Value DOUBLE PRECISION NOT NULL, PRIMARY KEY(Indice), CONSTRAINT fk_list_stations FOREIGN KEY(DevEUI_station) REFERENCES list_stations(DevEUI_station)) | ||
+ | |||
+ | Nous avons également, dans un second temps, lors de l’utilisation de containers Docker, modifié le fichier de configuration de PostgreSQL. En effet, avant cette modification, la base de données autorise seulement des connexions en provenance de localhost. Pour pallier à ce problème, dans le fichier pg_hba.conf (qui se situe dans /etc/postgresql/11/main/), nous avons changé l’adresse IPv4 de provenance des connexions par 0.0.0.0/0 (ce qui autorise des connexions de n’importe quel hôte) | ||
+ | |||
+ | ===Interface utilisateur=== | ||
+ | |||
+ | Afin de prodiguer une interface de monitoring à nos utilisateurs, nous nous servons de l'API Grafana. | ||
+ | Grafana est un logiciel libre sous licence Apache 2.0 qui permet la visualisation de données sous formes de graphique, de tableaux de bord ou simplement d’indicateur depuis plusieurs sources de données tel que PostgreSQL. | ||
+ | |||
+ | La prise en main et l’utilisation de cette API est simple et intuitive. Elle se base sur un système de Dashboard dans lequel il est possible de créer différents panels pour y afficher différentes informations de diverses manières. Dans notre cas nous avons créé 2 Dashboards (un pour notre table history_stations et history_stations_test). Pour créer un graphique qui affiche sur une échelle temporelle les relevés de températures issus de nos stations la requête est la suivante : | ||
+ | SELECT time AS "time", value AS "Température" FROM history_station WHERE type = 'TMP_1 ORDER BY 1 | ||
+ | |||
+ | Grafana propose également de partager ces panels, malheureusement de manière statique car ces panels sont transmis sous forme d’image. Une solution est de partager le Dashboard en entier, c’est d’ailleurs la solution qui a été retenue. | ||
+ | Pour que ces Dashboard soient visibles depuis n’importe quelle source et pour tous les utilisateurs (même ceux non connectés) il faut modifier le fichier grafana.ini qui se situe dans /etc/grafana/. | ||
+ | |||
+ | Plusieurs lignes sont décommentés : | ||
+ | *Dans la section Anonymous : | ||
+ | enabled = true | ||
+ | |||
+ | *Dans la section Embedded : | ||
+ | allow_embedding = true | ||
+ | org_name = Main Org. | ||
+ | org_role = Viewer | ||
+ | |||
+ | ===Accessibilité de notre application=== | ||
+ | |||
+ | Pour rendre notre application web accessible depuis n’importe quel navigateur et sans être connecté au réseau de l’école nous avons réutiliser notre machine virtuelle de PRA qui dispose d’une adresse IP routée ainsi que d’un serveur DNS (qui est d’ailleurs sécurisé par DNSSEC). Dans cette partie nous ne parlerons pas du DNS car la configuration de ce dernier a été fait en PRA. Cette machine virtuelle dispose, comme dit précédemment, d’une adresse ip public : 193.48.57.185. Nous avons rajouté la ligne suivante à la configuration de notre service DNS Bind9 (fichier db.tricholome.site qui se situe dans /etc/bind/) : | ||
+ | pfe IN CNAME www | ||
+ | |||
+ | Grâce à cette ligne, lorsque nous tapons « pfe.tricholome.site » dans notre barre de recherche, le DNS nous retransmet correctement l’adresse de notre site. | ||
+ | De plus, il faut maintenant rediriger l’utilisateur vers le bon site lorsque ce dernier saisi pfe.tricholome.site. Pour cela nous mettons en place un reverse proxy (mandataire inversé). Un reverse proxy permet à un utilisateur d’Internet d’accéder à des serveurs internes. De cette manière, lorsqu'un utilisateur demande la page pfe.tricholome.site, ce dernier arrive sur notre machine tricholome de PRA qui redirige la requête sur notre machine lorap. | ||
+ | |||
+ | La configuration à fournir au fichier pfe.conf (à créer au niveau de /etc/apache2/sites-available) est la suivante : | ||
+ | <VirtualHost * :80> | ||
+ | ServerName pfe.tricholome.site | ||
+ | ServerAdmin Theoic | ||
+ | ProxyPass / http://172.26.189.24:80/ | ||
+ | ProxyPassReverse / http://172.26.189.24:80/ | ||
+ | </VirtualHost> | ||
+ | |||
+ | Pour autant pour que cela soit totalement fonctionnel il faut que notre machine tricholome de PRA et notre machine lorap puissent communiquer entre elles, en effet le routeur de l’école bloque les échanges entre le vlan 50 et le vlan48. Une solution est de fournir à notre machine tricholome une adresse IP dans le vlan 48 et de fournir une route statique afin de contacter la machine lorap : | ||
+ | up ip address add dev eth1 172.26.145.239/24 | ||
+ | up ip route add 172.26.188.0/22 via 172.26.145.254 | ||
+ | down ip address del dev eth1 172.26.145.239/24 | ||
+ | down ip route del 172.26.188.0/22 via 172.26.145.254 | ||
+ | |||
+ | ===Sécurisation de notre site - HTTPS=== | ||
+ | |||
+ | La sécurisation de notre interface web a également été vivement conseillée par nos tuteurs. | ||
+ | Pour passer un site de HTTP vers HTTPS plusieurs étapes sont nécessaires : la génération des clés publiques et privées, la modification de notre hôte virtuel Apache (qui avait été précédemment modifié pour y inclure notre reverse proxy) mais aussi la signature numérique de notre certificat TLS/SSL par une autorité de certification, ici Let’s encrypt (une autorité de certification qui a pour but de proposer à tous, des certificats SSL gratuitement). | ||
+ | |||
+ | Pour cela nous avons tout d’abord télécharger snapd, qui est un système de déploiement de logiciel pour les systèmes d’exploitation linux. Grâce à snapd nous avons installé Certbot. Certbot est un logiciel client qui automatise la plupart des étapes énoncés précédemment de plus il est facile et intuitif à prendre en main. | ||
+ | |||
+ | La première commande après l’installation et la préparation de Certbot permet d’obtenir nos certificats (il est possible de laisser Certbot les installer mais nous avons préféré le faire nous-même) | ||
+ | certbot certonly –apache | ||
+ | |||
+ | Pour notre PFE nous n’avons pas décidé de mettre en place un système de renouvellement automatique pour nos certificats mais il est tout à fait possible de mettre en place un système de ce genre pour une application amenée à durer dans le temps. | ||
+ | A la suite de cette commande 4 certificats sont obtenus (dans le dossier /etc/letsencrypt/live/pfe.tricholome.site.tld) | ||
+ | *Une clé privée : privkey.pem à impérativement garder confidentielle | ||
+ | *Un certificat serveur : cert.pem | ||
+ | *Des certificats intermédiaires : chain.pem | ||
+ | *L’ensemble des certificats : fullchain.prem | ||
+ | |||
+ | Une fois ces certificats obtenus, il faut intégrer nos certificats à Apache dans notre hôte virtuel : | ||
+ | Une fois de plus nous modifions le fichier pfe.conf (/etc/apache2/sites-available) de la manière suivante : | ||
+ | <VirtualHost *:80> | ||
+ | ServerName pfe.tricholome.site | ||
+ | ServerAdmin Theioc | ||
+ | Redirect permanent / https://pfe.tricholome.site/ | ||
+ | </VirtualHost> | ||
+ | |||
+ | <VirtualHost *:443> | ||
+ | ServerName pfe.tricholome.site | ||
+ | ServerAlias pfe.tricholome.site | ||
+ | ServerAdmin Theioc | ||
+ | ProxyPass / http://172.26.189.24:80/ | ||
+ | ProxyPassReverse / http://172.26.189.24:80/ | ||
+ | SSLEngine on | ||
+ | SSLCertificateFile /etc/letsencrypt/live/pfe.tricholome.site/cert.pem | ||
+ | SSLCertificateKeyFile /etc/letsencrypt/live/pfe.tricholome.site/privkey.pem | ||
+ | SSLCertificateChainFile /etc/letsencrypt/live/pfe.tricholome.site/chain.pem | ||
+ | SSLProtocol all -SSLv2 -SSLv3 | ||
+ | SSLHonorCipherOrder on | ||
+ | SSLCompression off | ||
+ | SSLOptions +StrictRequire | ||
+ | SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256 | ||
+ | </VirtualHost> | ||
+ | |||
+ | Finalement nous pouvons tester notre nouvelle configuration d’Apache avec la commande : | ||
+ | apachectl configtest | ||
+ | Puis relancer notre serveur Apache pour que les modifications apportées soient prises en compte : | ||
+ | service apache2 restart | ||
+ | |||
+ | ====Vérification de la sécurité==== | ||
+ | |||
+ | Grâce au site : https://www.ssllabs.com/ssltest/ nous pouvons vérifier la sécurité de notre serveur web | ||
+ | |||
+ | [[Fichier:Securite_tricholome.PNG|center|700px]] | ||
+ | |||
+ | Nous obtenons les mêmes résultats pour notre site graf.tricholome.site, les tests sont concluants, nos sites sont sécurisés. | ||
+ | |||
+ | ==Documents rendus== | ||
+ | |||
+ | Rapport (compressé) : [[:File:Rapport_Final_PFE_Thoic.pdf|Rapport_Final_PFE_Thoic.pdf]] | ||
+ | |||
+ | Diapo soutenance : [[:File:Diapo_soutenance_finale_Thoic.pdf|Diapo_soutenance_finale_Thoic.pdf]] | ||
− | + | Git du projet : https://archives.plil.fr/tevrard/PFE_Thoic |
Version actuelle datée du 19 mai 2021 à 17:19
Sommaire
Présentation générale
Description
Aujourd’hui la qualité de l’air et plus globalement la pollution atmosphérique est un enjeu environnemental majeur, notamment dans le cadre du travail. Ce danger fait l’objet de préoccupations depuis plusieurs années et apparaît aujourd’hui comme un problème majeur de santé publique. Notre projet a pour objectif de répondre à cette problématique en proposant une analyse en temps réel de la qualité de l’air des locaux de Polytech. En effet, l’amélioration de la qualité de l’air passe en premier lieu par l’étude de celle-ci, il est primordial de connaître notre environnement avec précision.
Objectifs
Nos objectifs se séparent en 3 parties :
- Le développement de stations émettrices.
Nous devons développer le firmware des stations émettrices pour que ces dernières puissent intégrer les capteurs que nous avons à dispositions (température, humidité, pression, CO2, H2S, …) et envoyer ces données par ondes radio via nos modules Lora, ce code devra être le plus générique possible en vue de l’intégration de futurs capteurs. Nous devons également mettre en place un shield pour que la modularité de ces stations soit accrue et que l’ajout de capteur soit facilement faisable. Notre microcontrôleur, notre module antenne Lora ainsi que nos capteurs seront placés dans une boîte ce qui constituera notre station. Cette boîte permettra de rendre notre station plus compacte et plus esthétique tout en garantissant un accès facile aux composants internes de cette dernière.
- La mise en place d’un réseau LoRaWaN.
La mise en place de notre réseau LoRaWAN passe par plusieurs éléments. Tout d’abord ce qu’on appelle des end-points ou nœuds terminaux (nos stations émettrices). Ces stations envoient leurs informations par ondes radios, qui sont reçues par nos passerelles Kerlink. Le but de ces passerelles est de faire le lien entre nos stations et notre network serveur. Notre tâche est donc de configurer ces passerelles mais également notre network serveur qui réceptionne toutes les informations de nos stations. Finalement notre dernière tâche est de mettre en place un serveur applicatif qui stockera l’ensemble des données pour pouvoir par la suite les présenter à l’utilisateur. Bien entendu notre chaîne de transmission devra être sécurisée avec un système de chiffrement (clé publique/privée).
- La récupération et l'affichage des données.
Notre dernier objectif représente notre partie applicative. Une fois les données enregistrées et stockées dans notre base de données, nous devons mettre en place un application qui sera mise à disposition des utilisateurs pour consulter les données sur la qualité de l’air. Certaines de ces données ne seront pas totalement traitées, il faudra donc pouvoir les repérer et leur appliquer un dernier traitement avant de les présenter. Pour ce qui est de la présentation, un système de graphique sur une donnée spécifique et des indices sur la qualité sur la qualité de l’air représente la manière la plus simple (pour l’utilisateur) de visualiser les informations importantes.
Travail effectué
Prise en main du matériel
Transmission entre 2 cartes
Choix de l'IDE : Nous avons testé différentes IDE (Semtec, uVision, Mbed Studio, STM32). De par sa simplicité d'utilisation ainsi que de par la possibilité d'utiliser une version online nous avons privilégier l'utilisation de l'IDE Mbed pour effectuer nos tests. Cette IDE a d'ailleurs été utilisée dans d'anciens projets Polytech utilisant des émetteurs Lora et des cartes Nucléo.
Afin d'avoir une première manipulation de ces cartes et de l'IDE nous avons utilisé des programmes de démonstration du type "Ping/Pong". L'émission et la réception des données sont fonctionnelles entre 2 cartes Nucléo possédant des Antennes Lora.
Par la suite et sur demande de nos enseignants référents nous avons arrêté d'utiliser l'IDE Mbed pour partir sur l'IDE STM32. Cette IDE à l'avantage d'être plus bas niveau dans la configuration des pins mais elle dispose également de fonctions HAL (Hardware Abstraction Layer). Ce sont des fonctions qui ont été préalablement programmées par STMicroelectronics et qui nous permettent, par exemple, d'effectuer diverses opérations de lectures et d'écriture dans notre mémoire.
Test des différents capteurs
Nous disposons de plusieurs capteurs afin d'affiner nos données sur la qualité de l'air :
SEN0248 de chez DFROBOT, capteur de température, humidité, pression et gaz. L'envoie et la réception de données s'effectue via un bus I2C, il est donc nécessaire de fournir une clock à ce capteur. https://wiki.dfrobot.com/Gravity__I2C_BME680_Environmental_Sensor__VOC,_Temperature,_Humidity,_Barometer__SKU__SEN0248
DFR0066 de chez DFROBOT, capteur de température et d'humidité. L'envoie et la réception de données se fait via une pin Data et SCK, nous devons également fournir une clock à ce capteur. Datasheet : https://wiki.dfrobot.com/SHT1x_Humidity_and_Temperature_Sensor__SKU__DFR0066_
ULPSM-H2S de chez SPEC SENSOR, capteur de sulfure d'hydrogène https://www.spec-sensors.com/wp-content/uploads/2016/10/ULPSM-H2S-968-003.pdf
T6713 de chez TELAIRE, capteur de C02 https://14core.com/wp-content/uploads/2017/11/T6700_Series_CO2_sensor_Module_Datasheet.pdf
EC4-2000-SO2 de chez SGX SensorTech, capteur de dioxyde de souffre https://www.sgxsensortech.com/content/uploads/2014/07/DS-0243-EC4-2000-SO2-Datasheet-V2.pdf
Réseau LoRaWan
Network Server
Une machine virtuelle est déployée afin d'héberger le Network Server :
- Nom : lorawan.plil.info
- Mdp : glopglop
Cette machine est connectée à internet via l'interface eth0 et est relié au Vlan 501 (Lorawan) via l'interface eth1. Le Vlan501 comprend donc notre VM, la passerelle Kerlink Outdoor (sur le toit de l'école) et la passerelle Kerlink Indor.
Serveur DHCP
Les passerelles Kerlink doivent être connues sur notre réseau, elles doivent donc posséder leur propre adresse IP. Cette adresse IP leur est fournie par un serveur DHCP présent sur la carte réseau "eth1" de la VM lorawan. Pour ce faire nous créons un sous-réseau IPV4 192.168.42.0/24. Nous attribuons l'adresse 192.168.42.10 à la carte "eth1" et nous configurons le serveur DHCP de manière à attribuer dynamiquement des adresses IPV4 aux nouveaux appareils repérés sur le réseau.
Dans le fichier dhcpd.conf : subnet 192.168.42.0 netmask 255.255.255.0 { range 192.168.42.1 192.168.42.9 }
Ce sous réseau permet d'attribuer des adresses IPV4 allant de 192.168.42.1 à 192.168.42.9.
Nous pouvons ainsi accéder à l'interface de configuration des passerelles Kerlink en ssh via l'adresse IP attribuée (Sur lorawan.plil.info) :
- Passerelle Outdoor : ssh 192.168.42.1, mdp: pdmk-062E7A)
- Passerelle Indoor : ssh 192.168.42.2, mdp: pdmk-030970)
Cette interface de configuration nous sera très utile lors de la configuration de notre Network Server.
Installation et configuration du ChirpStack Network Server
ChirpStack Network Server est une implémentation open-source de LoRaWAN® Network Server. La responsabilité du composant Network Server est la déduplication des trames LoRaWAN reçues par les passerelles LoRa® et de gérer :
- L'authentification
- La couche mac LoRaWAN (et commandes mac)
- La communication avec le serveur d'applications ChirpStack
- La planification des trames de liaison descendante
- Installation :
La mise en place de ce serveur sur la VM lorawan nécessite d'installer trois entités : un gateway-bridge, un network-server et un application-server
Pour se faire nous avons suivi les instructions du site officiel : https://www.chirpstack.io/network-server/
- Configuration :
Différents fichiers de configuration sont alors disponibles :
- /etc/chirpstack-gateway-bridge/chirpstack-gateway-bridge.toml
- /etc/chirpstack-network-server/chirpstack-network-server.toml
- /etc/chirpstack-application-server/chirpstack-application-server.toml
Paramétrages notables : - Les trois serveurs démarrent automatiquement lors de l'allumage de la VM - NetworkID : 000000
Nous avons alors un accès a une interface graphique de configuration sur le port 8080 pour notre LoRaWan_Network (accès 172.26.189.22:8080 (désactiver le proxy pour cette adresse)). Nous instancions alors notre network serveur sous le nom de localhost (localhost:8000).
- Configuration des passerelles Kerlink :
En connection ssh sur les gateways, nous mettons à jour le firmware des deux passerelles (Indoor : Wirnet iFemToCell et Outdoor Wirnet iBTS). Une fois l'environnement correctement installé, nous nous sommes appuyés sur le https://wikikerlink.fr/ pour activer les gateways ainsi que leurs packet_fowarder (https://wikikerlink.fr/wirnet-productline/doku.php?id=wiki:lora:keros_4.3.3:cpf_configuration). Nous instancions notamment notre LoraNetworkServer au sein de nos gateways via la ligne gwmp.node = "192.168.42.10" dans le fichier /etc/lorafwd.toml
- Instanciation des passerelles sur le LNS (LoraNetworkServer) :
Sur la VM lorawan, les logs nous montre bien l'émission de message en provenance de nos deux passerelles. Sur l'interface graphique de paramétrage, nous créons alors deux nouvelles instances de gateways en fournissant leur ID respective. Les gateways sont alors visible pour notre LNS et nous remarquons une émission de trame LoRaWan de façon régulière.
A ce point, nous avons un LNS installé, configuré, capable de détecter et communiquer en LoRaWan avec les passerelles au sein de son réseau. La dernière étape consiste donc à tester la transmission complète d'une trame, d'un terminal LoRa à l'application_server.
- Test du LNS :
Une nouvelle application GPS_Test est créée sur l'interface graphique du LNS, des "application" et "network" keys sont alors générées et transmises manuellement à notre terminal LoRa en le connectant à un ordinateur (la configuration de ce module est possible grâce à l’application : ). Une fois les clefs correctement transmises, nous sommes capables de recevoir les trames et données issues du GPS. Ces données ont donc correctement transité au sein de nos passerelles Kerlink pour être finalement reçues par notre network serveur. Ceci conclut donc la mise en place du LoraNetworkServer, la prochaine étape consiste donc à connecter nos propres terminaux LoRa.
Stations
Implémentation du firmware
Suite à plusieurs tests et expérimentations et comme expliqué dans notre partie sur le choix de l'IDE, il a été décidé d'utiliser l'IDE STM32 Cube pour implémenter le firmware. Cette IDE permet en effet l'utilisation de bibliothèques de plus bas niveau que mbed et ainsi d'obtenir un meilleur contrôle de notre carte. Ce meilleur contrôle nous sera par ailleurs utile lors de l'implémentation des bus I2C pour la lecture de certains capteurs mais également lors de la mise en commun de nos différents bibliothèques relatives à nos capteurs.
Architecture du firmware
Dans un souci de modularité et de simplicité d'implémentation, notre firmware se découpera en deux parties. La première partie permettra la lecture de chaque capteur connecté à la station tandis que la seconde se chargera de transmettre toute ces données en LoRaWan. Afin de faciliter l'ajout ou le retrait de capteur sur une station établie l'architecture ci-dessous :
Il convient ainsi de créer, pour chaque capteur sur la station :
- Une fonction d'initialisation du capteur (startup séquence etc...), appelée au démarrage de la station.
- Une fonction de lecture spécifique à chaque capteur, appelée dans la boucle principale. Cette fonction de lecture se déroule en deux temps :
- 1 - Lecture du capteur (réception et prétraitement des données si besoin)
- 2 - Remplissage de la trame avec les données récupérées (en accord avec le format ci-contre)
Une fois la trame remplie, celle-ci est transmise à la fonction d'envoi, chargée de transmettre ces données par ondes radio.
Il est capital pour notre projet, avant toute lecture de capteur, d'être capable de transmettre des données vers notre LNS. Nous devons donc disposer d'une bibliothèque permettant de communiquer en respectant les normes d'un réseau LoRa. Cette bibliothèque existe et est disponible à l'adresse suivante : https://www.st.com/content/st_com/en/products/embedded-software/mcu-mpu-embedded-software/stm32-embedded-software/stm32cube-expansion-packages/i-cube-lrwan.html
Problèmes rencontrés :
La bibliothèque propose des programmes de communications LoRaWan uniquement pour des carte STM32L, non compatible avec notre STM32F411. Après avoir tenté durant plusieurs jours d'adapter le code de la bibliothèque et face à la complexité de la tâche, décision est prise d'utiliser des cartes compatibles avec notre librairie. Nos stations seront donc bâties sur des cartes STM32L152_RE.
Communication en LoRa
Sur l'interface du LNS :
- Nous créons donc une application "PFE_TheoLolo_2020"
- Nous y instancions un nouveau Device
- L'EUI Device doit correspondre à celui de notre carte, que l'on récupère via les logs de notre serveur.
- Generation d'une Application_key (MAIS PAS de Gen_Application_key qui doit être laissé vide)
Sur notre firmware :
- Ouverture du projet EndNode présent dans la librairie
- Modification du commisionning.h : MAJ de la LORAWAN_APP_KEY et de la LORAWAN_NTW_KEY (Ces deux clefs doivent être IDENTIQUES)
Une fois ces quelques paramètres ajustés, nous sommes capables de visualiser les données issues de notre carte sur notre LNS. La chaîne de communication est maintenant entièrement fonctionnelle. On peut donc pleinement se concentrés sur la lecture des capteurs et la mise en forme des données en amont ainsi que sur la récupération et l'affichage de ces données en aval.
Lecture des capteurs Nous disposons, pour notre projet, de nombreux capteurs différents, avec chacun un protocole de lecture définit (en principe) dans leur datasheet. Dans un souci
Application
Les données arrivant sur notre LNS doivent être transmises et traitées afin d'être présentées aux utilisateurs de l'application. La partie applicative de notre projet s'effectuera sur une VM nommée Lorap, afin de bien cloisonner la gestion du réseau LoRaWan (sur la VM lorawan) de la gestion applicative (traitement et affichage des données).
Réception et Gestion des données
Afin de recevoir les données en provenance de notre LNS (Lora Network Serveur), nous utilisons un bus MQTT. Mais avant tout qu'est que MQTT ? MQTT (Message Queuing Telemetry Transport) est un protocole de messagerie qui fonctionne sur le principe de souscription/publication qui a été développé à la base pour simplifier la communication entre les machines, pour fonctionner ce protocole de transport nécessite l'utilisation d'un Broker (un serveur) dans notre cas nous avons utilisé le broker Mosquitto.
Ce broker est notamment proposé dans les fichiers de configuration du LNS pour récupérer les données émises par nos stations. La configuration de cette file de message s'effectue dans le fichier /etc/chirpstack-application-server/chirpstack-application-server.toml de la VM lorawan. Par défaut, le MQTT serveur est disponible sur tcp://localhost(VMlorawan):1883.. Nous installons le broker Mosquitto sur la VM lorap puis nous implémentons un script python chargé de récupérer et stocker les données à chaque nouveau message dans des bases de données.
Explication de mosquitto.py :
- Tout d'abord nous souscrivons à un topic de la file de message MQTT 172.26.189.22:1883 (utilisée par notre LNS en tant que publisher)
- Une fonction d'écoute attend l'arrivée de message UP (arrivée de données sous format Json)
- Nous extrayons l'EUI de la station émettrice ainsi que la trame de données des capteurs (en base64)
- Une fonction de traitement se charge d'extraire les informations utiles de cette trame (température, pression, etc...)
- Ces données sont par la suite stockées au sein d'une base de données PostgreSQL et ce grâce à l'utilisation d'un second script en python : postgres.py
Pour toucher quelques mots par rapport à ce dernier script, ce dernier se veut très modulaire et propose des opérations génériques de création de table, d'insertion et de mise à jour de données et bien entendu de suppression.
Ces différents scripts sont exécutés dans un containeur Docker afin d'être totalement indépendant et lancés au démarrage de la machine lorap.
Pour lancer ce containeur nous avons tout d'abord installer Docker sur notre machine, puis créé une image Docker. Cette dernière est très simple, elle se charge de vérifier que python est installé et mis à jour et que les paquets utilisés par le script sont installés.
Serveur HTTP
Afin de fournir une interface utilisateur web, nous avons installé le serveur HTTP Apache2. Un serveur HTTP permet à un site web de communiquer avec un navigateur en utilisant le protocole HTTP(S) et ses extensions (WebDAV, etc.).
Installation :
apt install apache2
Une configuration précise n’a pas été nécessaire pour qu’apache fonctionne, la seule configuration a été faite au niveau de notre machine tricholome sur le serveur capbreton, l’explication est faite dans une des parties suivantes.
Le but de notre interface Web est de permettre aux utilisateurs de consulter les informations et les données envoyées par nos stations. Pour ce faire, cette dernière devra disposer d’une page de monitoring (ou utilisation d’une API telle que Grafana, voir partie suivante) permettant de connaître en temps réel la qualité de l’air d’une pièce. Une section devra aussi être développée pour configurer nos balises et changer leur mode (active, inactive ou supprimée), comme nos scripts au niveau de la réception de données sont modulaires, il n’est pas nécessaire de renseigner quelles données sont attendues à la réception. Elle devra également lister l’ensemble des stations connues de la base de données ainsi que leur état. Enfin, une section sera également mise à disposition pour l’affichage de notre monitoring de test.
L’ensemble de nos fichiers html et php se situent dans le dossier /var/www/html. Pour pouvoir utiliser du php sur notre serveur web nous devons installer une extension via la commande suivante :
apt install libapache2-mod-php
Pour pouvoir utiliser et manipuler notre base de données dans nos pages php (à travers des PDO, PHP Data Object) nous avons également installer le package php-pgssql, via la commande :
apt install php-pgsql
Puis il faut décommenter la ligne extension=php_pdo_pgsql dans le fichier php.ini qui se situe dans /etc/php/7.3/apache2/. Dans ce fichier, il peut d'ailleurs être intéressant de modifier les lignes error_reporting et ajouter l'option E_ALL ainsi que la ligne display_errors et ajouter l'option On. Cette modification permet à php de renvoyer des erreurs lors des chargements de nos pages lorsque celles-ci comportent des erreurs.
De plus, pour mettre en place cette interface Web, nous avons utilisé Bootstrap, qui est un Framework, une collection d’outils, utiles à la création du design (graphisme, animation et interactions avec la page dans le navigateur, etc.) pour des sites et des applications Web (code HTML et CSS pour faire des formulaires, boutons, barre de navigation, de recherche, …).
Base de données
Pour stocker nos données nous nous sommes dans un premier temps orientés vers InfluxDB, qui est un système de gestion de base de données orienté séries temporelles hautes performances. Ce choix vient du fait que ce système de gestion de données est très largement utilisé dans les applications IoT notamment grâce à ces hautes exigences en termes de disponibilité et de performances en temps réel. Après avoir discuté avec nos tuteurs nous nous sommes réorientés vers PostgreSQL, système de gestion de données que nous avions déjà utilisé en 3e année. Comme nous venons de l'expliquer, la réelle force d'InfluxDB est son aspect temps réels, qui offre beaucoup de précision au niveau des relevés, dans notre cas une telle précision n’était pas réellement justifiée et il valait mieux se concentrer sur une technologie que nous connaissions afin d’aboutir le plus rapidement possible sur un projet fonctionnel.
Installation :
apt install postgresql
Après avoir installé ce serveur, nous avons commencé par créer un nouvel utilisateur (Par défaut seul l’utilisateur postgres peut se connecter aux bases de données, c’est utilisateur créé automatiquement à la suite de l’installation de PostgreSQL) cette opération s’effectue avec la commande suivante :
createuser -d -P user_pfe (mot de passe glopglop)
A la suite de la création de cet utilisateur, nous créons notre base de données :
createdb -O user_pfe db_pfe
Pour se connecter à notre base de données tout juste créée nous utilisons la commande suivante :
psql db_pfe
Notre base de données contient 3 tables :
- La première table, list_stations contient l’ID unique d’une station (ce qui constitue la clé primaire de la table), la trame type que cette dernière envoie (cette trame est présente dans le fichier tram.yaml), le mode de fonctionne de la station ainsi que son statut.
- Notre deuxième table, history_stations contient et stocke l’ensemble des valeurs transmises par notre station. Cette table se compose d’un indice unique d’entrée (qui constitue la clé primaire de la table), de l’ID de la station qui a transmis cette entrée (ce qui est notre clé étrangère, liée à l’ID de la table list_stations), d’une colonne temps qui nous permet d’indexer chaque entrée (ce qui nous sera également utile pour tracer nos graphiques par la suite), d’un type de données (température, taux d’humidité, pression, …) et bien évidemment de la valeur en elle-même.
- Notre dernière table, qui se nomme history_stations_test est comme son nom l’indique une table similaire à history_stations mais utilisée pour nos tests. En effet, comme nous avions pris du retard sur notre projet au niveau développement des firmwares nous avons tout de même avancé sur cette partie en nous basant sur des données fictives, générées grâce à un script en python.
Ces 3 tables sont créées grâce aux commandes suivantes :
CREATE TABLE IF NOT EXISTS list_stations(DevEUI_station VARCHAR (50) NOT NULL, Trame VARCHAR(200) NOT NULL, Mode INT NOT NULL, Status INT NOT NULL, PRIMARY KEY(DevEUI_station))
CREATE TABLE IF NOT EXISTS history_stations(Indice SERIAL, DevEUI_station VARCHAR (100) NOT NULL, Time TIMESTAMP WITH TIME ZONE NOT NULL, Type VARCHAR (50) NOT NULL, Value DOUBLE PRECISION NOT NULL, PRIMARY KEY(Indice), CONSTRAINT fk_list_stations FOREIGN KEY(DevEUI_station) REFERENCES list_stations(DevEUI_station))
Nous avons également, dans un second temps, lors de l’utilisation de containers Docker, modifié le fichier de configuration de PostgreSQL. En effet, avant cette modification, la base de données autorise seulement des connexions en provenance de localhost. Pour pallier à ce problème, dans le fichier pg_hba.conf (qui se situe dans /etc/postgresql/11/main/), nous avons changé l’adresse IPv4 de provenance des connexions par 0.0.0.0/0 (ce qui autorise des connexions de n’importe quel hôte)
Interface utilisateur
Afin de prodiguer une interface de monitoring à nos utilisateurs, nous nous servons de l'API Grafana. Grafana est un logiciel libre sous licence Apache 2.0 qui permet la visualisation de données sous formes de graphique, de tableaux de bord ou simplement d’indicateur depuis plusieurs sources de données tel que PostgreSQL.
La prise en main et l’utilisation de cette API est simple et intuitive. Elle se base sur un système de Dashboard dans lequel il est possible de créer différents panels pour y afficher différentes informations de diverses manières. Dans notre cas nous avons créé 2 Dashboards (un pour notre table history_stations et history_stations_test). Pour créer un graphique qui affiche sur une échelle temporelle les relevés de températures issus de nos stations la requête est la suivante :
SELECT time AS "time", value AS "Température" FROM history_station WHERE type = 'TMP_1 ORDER BY 1
Grafana propose également de partager ces panels, malheureusement de manière statique car ces panels sont transmis sous forme d’image. Une solution est de partager le Dashboard en entier, c’est d’ailleurs la solution qui a été retenue. Pour que ces Dashboard soient visibles depuis n’importe quelle source et pour tous les utilisateurs (même ceux non connectés) il faut modifier le fichier grafana.ini qui se situe dans /etc/grafana/.
Plusieurs lignes sont décommentés :
- Dans la section Anonymous :
enabled = true
- Dans la section Embedded :
allow_embedding = true org_name = Main Org. org_role = Viewer
Accessibilité de notre application
Pour rendre notre application web accessible depuis n’importe quel navigateur et sans être connecté au réseau de l’école nous avons réutiliser notre machine virtuelle de PRA qui dispose d’une adresse IP routée ainsi que d’un serveur DNS (qui est d’ailleurs sécurisé par DNSSEC). Dans cette partie nous ne parlerons pas du DNS car la configuration de ce dernier a été fait en PRA. Cette machine virtuelle dispose, comme dit précédemment, d’une adresse ip public : 193.48.57.185. Nous avons rajouté la ligne suivante à la configuration de notre service DNS Bind9 (fichier db.tricholome.site qui se situe dans /etc/bind/) :
pfe IN CNAME www
Grâce à cette ligne, lorsque nous tapons « pfe.tricholome.site » dans notre barre de recherche, le DNS nous retransmet correctement l’adresse de notre site. De plus, il faut maintenant rediriger l’utilisateur vers le bon site lorsque ce dernier saisi pfe.tricholome.site. Pour cela nous mettons en place un reverse proxy (mandataire inversé). Un reverse proxy permet à un utilisateur d’Internet d’accéder à des serveurs internes. De cette manière, lorsqu'un utilisateur demande la page pfe.tricholome.site, ce dernier arrive sur notre machine tricholome de PRA qui redirige la requête sur notre machine lorap.
La configuration à fournir au fichier pfe.conf (à créer au niveau de /etc/apache2/sites-available) est la suivante :
<VirtualHost * :80> ServerName pfe.tricholome.site ServerAdmin Theoic ProxyPass / http://172.26.189.24:80/ ProxyPassReverse / http://172.26.189.24:80/ </VirtualHost>
Pour autant pour que cela soit totalement fonctionnel il faut que notre machine tricholome de PRA et notre machine lorap puissent communiquer entre elles, en effet le routeur de l’école bloque les échanges entre le vlan 50 et le vlan48. Une solution est de fournir à notre machine tricholome une adresse IP dans le vlan 48 et de fournir une route statique afin de contacter la machine lorap :
up ip address add dev eth1 172.26.145.239/24 up ip route add 172.26.188.0/22 via 172.26.145.254 down ip address del dev eth1 172.26.145.239/24 down ip route del 172.26.188.0/22 via 172.26.145.254
Sécurisation de notre site - HTTPS
La sécurisation de notre interface web a également été vivement conseillée par nos tuteurs. Pour passer un site de HTTP vers HTTPS plusieurs étapes sont nécessaires : la génération des clés publiques et privées, la modification de notre hôte virtuel Apache (qui avait été précédemment modifié pour y inclure notre reverse proxy) mais aussi la signature numérique de notre certificat TLS/SSL par une autorité de certification, ici Let’s encrypt (une autorité de certification qui a pour but de proposer à tous, des certificats SSL gratuitement).
Pour cela nous avons tout d’abord télécharger snapd, qui est un système de déploiement de logiciel pour les systèmes d’exploitation linux. Grâce à snapd nous avons installé Certbot. Certbot est un logiciel client qui automatise la plupart des étapes énoncés précédemment de plus il est facile et intuitif à prendre en main.
La première commande après l’installation et la préparation de Certbot permet d’obtenir nos certificats (il est possible de laisser Certbot les installer mais nous avons préféré le faire nous-même)
certbot certonly –apache
Pour notre PFE nous n’avons pas décidé de mettre en place un système de renouvellement automatique pour nos certificats mais il est tout à fait possible de mettre en place un système de ce genre pour une application amenée à durer dans le temps. A la suite de cette commande 4 certificats sont obtenus (dans le dossier /etc/letsencrypt/live/pfe.tricholome.site.tld)
- Une clé privée : privkey.pem à impérativement garder confidentielle
- Un certificat serveur : cert.pem
- Des certificats intermédiaires : chain.pem
- L’ensemble des certificats : fullchain.prem
Une fois ces certificats obtenus, il faut intégrer nos certificats à Apache dans notre hôte virtuel : Une fois de plus nous modifions le fichier pfe.conf (/etc/apache2/sites-available) de la manière suivante :
<VirtualHost *:80> ServerName pfe.tricholome.site ServerAdmin Theioc Redirect permanent / https://pfe.tricholome.site/ </VirtualHost> <VirtualHost *:443> ServerName pfe.tricholome.site ServerAlias pfe.tricholome.site ServerAdmin Theioc ProxyPass / http://172.26.189.24:80/ ProxyPassReverse / http://172.26.189.24:80/ SSLEngine on SSLCertificateFile /etc/letsencrypt/live/pfe.tricholome.site/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/pfe.tricholome.site/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/pfe.tricholome.site/chain.pem SSLProtocol all -SSLv2 -SSLv3 SSLHonorCipherOrder on SSLCompression off SSLOptions +StrictRequire SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256 </VirtualHost>
Finalement nous pouvons tester notre nouvelle configuration d’Apache avec la commande :
apachectl configtest
Puis relancer notre serveur Apache pour que les modifications apportées soient prises en compte :
service apache2 restart
Vérification de la sécurité
Grâce au site : https://www.ssllabs.com/ssltest/ nous pouvons vérifier la sécurité de notre serveur web
Nous obtenons les mêmes résultats pour notre site graf.tricholome.site, les tests sont concluants, nos sites sont sécurisés.
Documents rendus
Rapport (compressé) : Rapport_Final_PFE_Thoic.pdf
Diapo soutenance : Diapo_soutenance_finale_Thoic.pdf
Git du projet : https://archives.plil.fr/tevrard/PFE_Thoic