Projet Raspberry Pi
Réaliser un server Python pour consulter les courbes de température


Mis à jour le : 13/09/2018


Nous avons vu dans le tutoriel sur la sonde DS18B20 comment mesurer la température à l'aide d'un Raspberry. Le projet que je vous présente aujourd'hui explique comment on peut, à partir de ces données, céer une courbe de température consultable à l'aide d'un navigateur, simplement en utilisant Python et la librairie flask.
Voici un aperçu de ce que l'on va faire :

Capture d'écran objectif projet Capture d'écran objectif projet

I. Prérequis

Pour ce projet, il faut le même matériel que dans le tutoriel sur la mesure de température, rien de plus. Ce qui donne dans le détail :

Une fois tout le matériel réunis, on peut passer au branchement.

II. Branchement de la sonde

Ici encore, rien de nouveau, on garde le même branchement que dans le tuto, soit :


Shéma de branchement d'une DS18B20 sur Raspberry Pi 3
Shéma de branchement d'une DS18B20 sur Raspberry Pi B rev 2

Maintenant que la sonde est branchée, on essaie de mesurer la température via le terminal pour tester la liaison. (Voir le III. du tuto sur la sonde)

III. Installation de Flask et premiers pas

Important ! Tout au long du projet, il faudra executer le fichier app.py avec la commande suivante :

sudo python3 app.py
Si l'on n'indique pas la version de Python 3, le script ne s'executera pas.

Pour commencer, il va falloir installer la librairie flask qui va nous permettre de faire de notre Raspberry Pi un server Web. Entrez simplement la commande suivante dans le terminal :

sudo apt-get install python3-flask

Maintenant que la librairie est installée, voyons les notions de base de flask. Voici le code le plus simple que l'on peut faire avec Flask :

En executant ce code, on devrait voir s'écrire dans le terminal ceci :

* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger pin code: xxx-xxx-xxx

Cela signifie que le server est démaré, et que on peut y accéder en entrant l'IP du Raspberrry, suivi de :5000, qui est le numéro du port. Si on accède à cette page, on verra s'afficher Hello World.
Pour tester, entrer ceci dans le champ URL d'un navigateur : xxx.xxx.x.xxx:5000, où xxx.xxx.x.xxx est l'adresse IP du Raspberry Pi.
Si vous ne connaissez pas l'adresse IP de votre Raspberry Pi, entrez dans une console ceci :

hostname -I

Capture d'écran premier script Flask

Plutôt que de renvoyer un simple texte, Flask peut retourner une page HTML. Pour se faire, il suffit de changer le return 'Hello world' de la fonction appelée en celui-ci : return render_template('index.html').
La page index.html sera donc affichée sur le navigateur lorsque la fonction est appelée.
Pour transférer des variables entre le script Python et la page HTML, on ajoute simplement l'élément à transférer comme ceci : return render_template('index.html', valeur="2").
Pour récupérer la donnée transférée, il suffit d'écrire {{ valeur }} entre des balises HTML.

Prenons un exemple :
Créez les fichiers et répertoires comme ceci sur votre Raspberry Pi :

├──ProjetGraphTemp
    └── app.py
├── templates └── index.html
├── static (optionnel) └── style.css
Aide

Pour tout créer d'un coup, entrez ces commandes dans le terminal :

cd ~
mkdir ProjetGraphTemp
cd ProjetGraphTemp
touch app.py
mkdir templates
touch templates/index.html
mkdir static
touch static/style.css

Insérez le code suivant dans le fichier app.py :

Et celui-ci dans le fichier index.html :

Enfin, changez le style d'écriture ou tout autre élément graphique dans le fichier css si vous le souhaitez. Pour faire le lien entre les document HTML & CSS avec Flask, ajouter cette ligne dans la balise <head> du code HTML :

<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}" />

En exécutant le code Python et en se rendant à l'adresse IPRaspberry:5000, on obtient ceci :

Capture d'écran script avec redirection HTML Flask

On a donc les bases pour commencer par afficher la température sur une page Web.

IV. Afficher la température

Avec ce que l'on vient de voir et ce que l'on a déjà vu dans tutoriel sur la sonde DS18B20, il n'est pas compliqué d'afficher la température sur une page HTML, il suffit de modifier un tout petit peu le code précédent.

Information

Comment récupérer le numéro de la sonde ?

Il suffit d'entrer les commandes suivantes dans le terminal :

sudo modprobe w1-gpio
sudo modprobe w1-therm
ls /sys/bus/w1/devices/

Une ligne de ce type devrait s'afficher :

28-0317229e0bff  w1_bus_master1

La partie verte correspond au numéro de la sonde.
Si rien ne s'affiche, lire cette section du tutoriel sur la DS18B20.

En exécutant le code Python et en se rendant à l'adresse IPRaspberry:5000/getTemp, on obtient ceci :

Capture d'écran script avec affichage température HTML Flask

Pour améliorer un peu l'esthétique, je vous propose ce CSS, qu'il faut ajouter dans le fichier static/style.css :

Rappel : Il faut ajouter cette ligne dans la balise <head> du code HTML :

<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}" />

En executant le code avec ce CSS, on obtient ceci :

Capture d'écran script avec redirection HTML Flask et CSS

V. Enregistrer les températures

Pour construire un graphique de température, on va avoir besoin de données, il va falloir enregistrer les températures à intervalle de temps régulier. On va pour se faire créer une fonction supplémentaire à notre code, que l'on va nommer enregistrement(temperature). Cette fonction va être appelée lorsque l'on fait un getTemp. Elle va enregistrer la température donnée en paramètre dans un fichier texte ayant pour nom la date du jour. Le fichier contiendra sur chaque ligne l'heure et la température associée.
Les fichiers contenant les données de température seront de cette forme :

00:00 18.625
00:15 18.437
00:30 18.312
00:45 18.125
01:00 18.0
01:15 17.812
01:30 17.5
01:45 17.375
02:00 17.312
Information J'ai déjà pensé à utiliser une base de donnée pour enregistrer les températures, mais le temps de chargement du graphique était beaucoup plus long que lorsque l'on vient lire le contenu des fichiers.

Voici la fonction enregistrement(temp), que j'explique juste après.

Cette fonction prend la température en paramètre. Tout d'abord, elle ouvre le fichier dans lequel la température va être enregistrée. Si le fichier n'existe pas déjà, on ouvre en mode w (write) : On crée le fichier et on écrit la première température dedans. Sinon, si le fichier existe déjà, (donc des températures on déjà été enregistrées ce jour), en ouvre le fichier en mode a (add). Une fois le fichier ouvert ou créé, on écrit l'heure suivi de la température sur une nouvelle ligne

Pourquoi ouvrir en add plutot qu'en write ?
Si on ouvre le fichier en write, tout le contenu qui existait déjà serait écrasé. Il faut donc d'abord vérifier l'existence du fichier pour savoir si l'on utilise le mode add ou write.
De plus, on ne peut pas être en mode add si le fichier n'existe pas déjà.

Personnellement, j'enregistre la température toutes les 15 minutes. Modifions un peu la fonction getTemp en lui ajoutant un argument ordonnant ou non l'enregistrement de la température.

Pourquoi ne pas enregistrer la température à chaque getTemp ?
Car plus tard, on va calculer la moyenne de température de la journée et on va la comparer. Il faut donc avoir le même nombre de température chaque jour, donc il faut qu'elle soit enregistrée seulement toutes les 15 minutes : Lorsque l'on va consulter la courbe, la température sera affichée mais pas enregistrée.

Voici donc le nouveau code après modifications :

Il faut maintenant demander au Raspberry Pi de charger la page IPRasp:5000/getTemp?sauvegarde=True à intervalle régulier, je choisis 15 minutes mais vous pouvez choisir une autre fréquence évidemment. Pour se faire, on va modifier le fichier crontab.
Entrez donc la commande suivante dans le terminal :

sudo crontab -e
Information

Le fichier devrait ressembler à ceci :

# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (/tmp/crontab.L71rF1/crontab installed on Tue May 29 20:57:03 2018)
# (Cron version -- $Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $)
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command

Une fois le fichier ouvert en édition, ajoutez les lignes suivantes à la fin puis enregistrez et quittez. (la première ligne permet d'executer le programme dès le démarage du Raspberry Pi)

@reboot cd /home/pi/ProjetGraphTemp; sudo python3 app.py
*/15 * * * * curl localhost:5000/getTemp?sauvegarde=True

Grace à ces lignes, le Raspberry Pi executera le script app.py à chaque démarage et enregistrera la température toutes les 15 minutes.

VI. Mise en place de la courbe et des statistiques

Maintenant que la température est enregistrée à intervalle de temps régulier dans un fichier, il suffit de récupérer ses données et de les insérer dans un graphique. Pour cette dernière partie, nous allons utiliser un outil développé par Google : Google Charts.
Google Charts permet de réaliser assez facilement un tas de graphique de tous types : Circulaires, histogrammes, cartes, courbes... Pour notre projet, nous allons utiliser le module de coubres : Line Chart
Pour commencer, on va créer une fonction fichierVersListe(cheminFich) qui va transformer les lignes contenues dans le fichier de température en deux listes qui vont nous servir plus tard pour la courbe et les statistiques.

Fonction fichierVersListe(cheminFich)

Exemple d'éxecution de la fonction :

00:00 18.625
00:15 18.437
00:30 18.312
00:45 18.125
01:00 18.0

fichierVersListe(cetExemple)

[
    [['00', '00', '18.625'], ['00', '15', '18.437'], ['00', '30', '18.312'], ['00', '45', '18.125'], ['01', '00', '18.']],
    [18.625, 18.437, 18.312, 18.125, 18.0]
]

fichierVersListe(cetExemple)[0]
Cette liste est la liste des points que l'on va dessiner sur le graphe.

[['00', '00', '18.625'], ['00', '15', '18.437'], ['00', '30', '18.312'], ['00', '45', '18.125'], ['01', '00', '18.']]

fichierVersListe(cetExemple)[1]
Cette liste permet de trouver très facilement la température max, min et moyenne.

[18.625, 18.437, 18.312, 18.125, 18.0]

On va maintenant se servir de tout ça en créant la fonction graphTemp(date) qui renverra sur la page HTML qui s'occupera de dessiner le graph. La fonction est la fin du code final, tout est commenté et expliqué :


Enfin, voici le code HTML qui permet de transformer toutes les données transférées en un beau graphique, grace à Google charts.

Enregistrez les images de flèche permettant la navigation entre les dates en entrant les deux lignes de commande suivantes dans le terminal :

wget -P ~/ProjetGraphTemp/static http://espace-raspberry-francais.fr/Projets/Courbe-temp%C3%A9rature-accessible-avec-un-server-Web-Python/Images/nextDay.png
wget -P ~/ProjetGraphTemp/static http://espace-raspberry-francais.fr/Projets/Courbe-temp%C3%A9rature-accessible-avec-un-server-Web-Python/Images/prevDay.png

En laissant tourner le programme, la journée, on obtient des courbes comme ceci (avec un Raspberry à l'exterieur) :

Capture d'écran objectif projet Capture d'écran objectif projet

PS : J'ai ajouté uen statistique année précédente dans mon priogramme car j'enregistre les températures avec mon Raspberry Pi depuis plusieurs années déjà ! :)


Voilà, ce projet est maintenant terminé, n'hésitez pas à laisser un commentaire pour dire si tout a bien marché, ou si vous avez quelques soucis. C'est le premier projet que j'explique entièrement, j'ai hate de lire vos retours ! Ce projet peut évidemment être amélioré, avec des statistiques plus poussées etc... La seule limite sera votre imagination !


Commentaires

Commenter
Votre adresse mail ne sera pas visible sur le site.

Seuls les commentaires jugés corrects seront mis en ligne.



Composants Bien débuter sur le Raspberry PI Configurer le Raspberry Pi
Ecran LCD 16x02 Accessoires indispensables sur Raspberry Pi Connexion sans login ni mot de passe au Raspberry
Capteur de température DS18B20 Première installation et démarage Changer le Hostname du Raspberry Pi
Afficheurs 7 segments Création et execution d'un programme Python Connexion Ethernet Raspberry/ordinateur
Capteur distance HC-SR04 Connexion au bureau depuis Windows
Bouton
Servo Moteur
Capteur de présence HC-SR501
Module RFID-RC522
Caméra sur Raspberry Pi

EspaceRaspberryFrançais | Contact | Facebook



En tant que Partenaire Amazon, je réalise un bénéfice sur les achats remplissant les conditions requises.

Espace-raspberry-francais.fr est hebergé par SARL LWS.