Mon objectif était de pouvoir suivre et consulter la température des différentes pièces de l’appartement en temps quasi-réel à la fois sur une tablette fixée au mur et depuis un smartphone en dehors de l’appartement.
Ma solution repose sur plusieurs sondes disposées dans chaque pièce qui captent périodiquement la température et le taux d’humidité puis transmettent ces données à un serveur distant. Ce dernier conserve les données et héberge une application web permettant de les consulter via un smartphone ou un ordinateur. Au travers de webservices il met également ces données à disposition d’une tablette qui les affiche en continu.
Sommaire
Les sondes de température et d’humidité
Matériel
Pour le choix du matériel des sondes 3 critères étaient importants :
- La capacité à définir la période de capture de la température et des taux d’humidité (toutes les 10 minutes) ;
- Pas d’émission radio (car elles sont actives toute la journée dans les chambres des enfants) ;
- Le coût.
Je me suis ainsi orienté vers le matériel suivant pour chacune des sondes :
- Un Raspberry Pi Zero pour l’unité centrale (il dispose d’une connectique bien plus limitée que le Pi 3 mais il est également nettement moins cher (environ 5€ contre 35€) ;
- Une sonde DHT22 qui permet de capter la température et le taux d’humidité. Cette sonde présente l’avantage d’être numérique et semblait la plus fiable dans cette gamme de prix (~3€) ;
- Une résistance de 4,7KΩ (<1€) ;
- Une carte réseau Ethernet en USB (car le Pi Zero ne dispose pas de connectique réseau) (~2,5€) ;
- Un convertisseur micro-USB -> USB (~1€) ;
- Le nécessaire pour le Pi Zero (carte SD, adaptateur secteur) ;
- Un boitier pour le Pi Zero (non indispensable mais c’est plus propre) ;
- Un adaptateur CPL car mes pièces ne disposent pas de prises ethernet et je ne souhaitais pas de Wi-Fi.
L’adaptateur CPL est de loin l’élément le plus coûteux, sans celui-ci l’ensemble tourne autour de 25€ par sonde.
Montage
Le montage est relativement simple, il consiste à souder la sonde sur le Raspberry. Il faut prévoir une longueur de fil suffisante en fonction de l’emplacement de la sonde. Pour ma part, je pose le Raspberry au sol près de la prise électrique et je place la sonde à environ 1m du sol et non exposée aux courants d’air pour obtenir des valeurs de températures et de taux d’humidité les plus fiables possibles.
Voici le montage à réaliser :
Les branchements à effectuer sont :
- La broche 1 de la sonde vers une broche de 3,3v du Pi Zero ;
- La broche 2 de la sonde vers une broche d’entrée du Pi Zero (j’ai choisi la broche 4) ;
- La broche 3 de la sonde n’est pas utilisée ;
- La broche 4 de la sonde vers une broche terre du Pi Zero.
Logiciel
Il existe plusieurs distributions pour Raspberry, j’ai choisi l’officielle Raspbian basée sur Debian qui suffit largement à mes besoins.
Pour récupérer périodiquement la température et le taux d’humidité, j’ai choisi d’écrire une application en python reposant sur la bibliothèque d’Adafruit.
Première étape l’installation des pré-requis :
sudo apt-get update sudo apt-get install build-essential python-dev python-openssl
Puis récupération de la bibliothèque :
git clone https://github.com/adafruit/Adafruit_Python_DHT.git cd Adafruit_Python_DHT
Avant d’aller plus loin un hack est nécessaire :
A l’exécution la bibliothèque d’Adafruit détermine la version du Raspberry (Pi 1/Pi Zero ou Pi 2) sur la base de la version du processeur. Or il existe sur le marché plusieurs versions du Pi Zero (avec différentes versions du processeur). (Pour ma part j’ai deux versions différentes parmi mes 6 Pi Zero). Il est ainsi nécessaire de patcher la bibliothèque pour que le test fonctionne avec sa version du Pi Zero.
Il faut tout d’abord déterminer la version du processeur de son Pi Zero :
cat /proc/cpuinfo
Et chercher la ligne Hardware.
Sur l’un des miens, j’obtiens BCM2835.
pi@pi1:~ $ cat /proc/cpuinfo processor : 0 model name : ARMv6-compatible processor rev 7 (v6l) BogoMIPS : 997.08 Features : half thumb fastmult vfp edsp java tls CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x0 CPU part : 0xb76 CPU revision : 7 Hardware : BCM2835 Revision : 900093 Serial : 000000004fc34801
Il faut ensuite éditer le fichier Adafruit_DHT/platform_detect.py pour indiquer cette version à la ligne 97 (if match.group(1) == ‘BCM2835’:) :
def pi_version(): """Detect the version of the Raspberry Pi. Returns either 1, 2 or None depending on if it's a Raspberry Pi 1 (model A, B, A+, B+), Raspberry Pi 2 (model B+), or not a Raspberry Pi. """ # Check /proc/cpuinfo for the Hardware field value. # 2708 is pi 1 # 2709 is pi 2 # Anything else is not a pi. with open('/proc/cpuinfo', 'r') as infile: cpuinfo = infile.read() # Match a line like 'Hardware : BCM2709' match = re.search('^Hardware\s+:\s+(\w+)
On peut maintenant compiler la bibliothèque :
sudo python setup.py install
Il reste ensuite a écrire un programme lancé périodiquement par un cron (pour ma part toutes les 10 minutes) qui interroge la sonde puis envoie les données au serveur. Afin de ne pas perdre de valeurs en cas de coupure réseau, si le programme ne parvient pas à envoyer les données au serveur, il les stocke temporairement dans un fichier pour les réémettre dès que la connexion fonctionne à nouveau.
#!/usr/bin/python import sys import os from time import localtime, strftime import Adafruit_DHT import requests # Reference de la sonde (DHT22), a ne pas modifier SENSOR = 22 # Numero de la broche sur laquelle la sonde est soudee PIN = 4 # Identifiant de la piece dont les donnees sont capturees ROOM = '' # Racine de l'url du webservice du serveur destinataires des donnees capturees BASE_URL = 'http://XXXXXXXX/' # Fichier utilise pour stocker les donnees n'ayant pu etre transmise au serveur DATAS_NOT_SENT_FILE = '/home/pi/error_sonde' # Nombre de tentative maximum de capture NUMBER_OF_TRIES = 4 current_date = strftime("%Y-%m-%d %H:%M:%S", localtime()) formatted_humidity = '' formatted_temperature = '' # Interroge la sonde pour obtenir la temperature et le taux d'humidite courante # Si necessaire, reessaye 15 fois en attendant 2 secondes entre chaque tentatives humidity, temperature = Adafruit_DHT.read_retry(SENSOR, PIN) # La capture des donnees peut ne pas fonctionner (cas rare), au besoin tente 'nbTries' fois i = 1 while (humidity is None or temperature is None) and i < NUMBER_OF_TRIES: humidity, temperature = Adafruit_DHT.read_retry(SENSOR, PIN) i = i + 1 # Si les donnees ont pu etre capturees if humidity is not None and temperature is not None: # Formattage des donnees pour transmission au serveur formatted_humidity = '{0:0.0f}'.format(humidity) formatted_temperature = '{0:0.0f}'.format(temperature*100) url = BASE_URL + 'Releve/' + ROOM + '/' + formatted_temperature + '/' + formatted_humidity print(current_date + ';' + ROOM + ';' + formatted_temperature + ';' + formatted_humidity + ';' + str(temperature) + ';' + str(humidity) + ';' + url) try: # Envoi des donnees collectees au serveur requests.get(url) # Si l'envoi a fonctionne, on envoie egalement les donnees qui n'avaient pu etre transmises lors de precedentes captures if os.path.exists(DATAS_NOT_SENT_FILE): if os.path.getsize(DATAS_NOT_SENT_FILE) > 0 : datas = [('file', ('file', open(DATAS_NOT_SENT_FILE, 'rb'),'text'))] requests.post(BASE_URL + 'ReleveBulk', files=datas) # Vidage du contenu du fichier d'erreur f = open(DATAS_NOT_SENT_FILE, 'w') f.close() except: print("erreur lors de l'envoi des releves") # En cas d'erreur lors de l'envoi des donnees, celles-ci sont conservees dans le fichier des erreurs afin d'etre transmises des que la connexion est a nouveau fonctionnelle f = open(DATAS_NOT_SENT_FILE, 'a') f.write(current_date + ';' + ROOM + ';' + formatted_temperature + ';' + formatted_humidity + '\n') f.close()
Pour la maintenance logicielle des Raspberry, j’utilise ansible qui permet d’effectuer des opérations groupées via SSH sur l’ensemble des 6 Raspberry. Je l’utilise essentiellement pour la mise à jour du système et le déploiement d’une nouvelle version du programme python.
Le serveur
Le serveur doit réceptionner les données brutes transmises par les sondes (température, humidité) pour :
- Stocker ces données ;
- Notifier la tablette que de nouvelles valeurs sont disponibles ;
- Mettre à disposition de la tablette la dernière valeur de température et de taux d’humidité pour chacune des pièces ;
- Héberger l’application web pour smartphone.
Les flux ressemblent à cela :
Ces webservices reposent sur la bibliothèque python flask pour réceptionner les valeurs brutes transmises par les sondes et pour répondre aux requêtes de la tablette 10′′. La couche de stockage repose sur une base de données relationnelle MySQL. Un webservice est dédié au superviseur nagios me permettant d’être notifié si une sonde ne transmet plus ses données. Cela m’évite de superviser directement les sondes (qui générerait du trafic réseau pour chaque sonde), seule la disponibilité de l’information depuis le serveur m’intéresse.
Les interfaces utilisateurs
Tablette 10′′
Je souhaitais disposer d’un écran fixé au mur affichant en permanence les températures dans les différentes pièces. J’ai choisi un Raspberry PI 3 avec un écran 10′’ tactile. Un affichage plus petit de type LCD aurait pu convenir mais je souhaitais profiter de cet écran pour afficher d’autres informations. Aujourd’hui il me permet également d’apporter d’autres services :
- Afficher un tableau blanc (éditable depuis une appli iPhone) ;
- Afficher les listes de courses et permettre d’ajouter des articles parmi les plus ajoutés ;
- Ajouter un minuteur de cuisson qui notifie par SMS ;
- Afficher la météo du jour et de la semaine ;
- Afficher les temps de cuisson du cuit-vapeur ;
- Permettre de réactiver le wifi quand il est coupé par la programmation horaire ;
- Afficher le matin en semaine les prochains passages du bus pour la crèche ;
- etc.
Tout comme les sondes, le Raspberry Pi 3 derrière cette tablette tourne sur Raspbian. Ce dernier est configuré pour lancer au démarrage un programme (toujours en python) apportant les différents services listés ci-dessus. Pour l’IHM je n’ai pas trouvé de bibliothèque python suffisamment souple pour le rendu que j’avais en tête. J’ai donc utilisé la bibliothèque « bas niveau » Tkinter sur laquelle repose ma version « maison » de widget et de widget manager.
Je me suis posé la question de la consommation électrique induite par cette tablette qui reste allumée. La consommation du Raspberry est très limitée et reste raisonnable. N’ayant pas l’information concernant l’écran, j’ai configuré le X window manager pour que l’écran se mette en veille au bout de 10 minutes d’inactivité et se rallume au toucher. Via une tâche cron cette veille est désactivée (l’écran reste allumé) le matin du réveil au départ et le soir du retour au coucher.
Application mobile
Je souhaitais pouvoir également consulter les températures en dehors de l’appartement. Plutôt que de développer une application native j’ai choisi de le faire au travers d’une application web ce qui me permet d’y accéder simplement depuis n’importe quel navigateur et même au travers d’une application iPhone en l’installant sous forme de web app.
Un minimum d’HTML et de CSS permet d’afficher les températures et taux d’humidité courants de chaque pièce.
Je souhaitais pouvoir également suivre l’évolution des données, j’ai utilisé pour cela la bibliothèque Highstock suffisamment paramétrable pour obtenir le rendu que je souhaitais.
Références des Sources utilisées
https://www.highcharts.com/products/highstock/
Je suis preneur de vos retours, suggestions ou questions via le formulaire de commentaire. Et n’hésitez pas à partager si vous avez également réalisé un système de suivi de température.
Hello,
Super projet, je suis fan et esthétique en plus.
quels retours ou améliorations faites depuis 2 ans ?
Perso je vais me lancer pour monitorer l’hygrométrie de mes pièces avant changement de fenêtres.
Merci pour le retour, j’ai effectué des améliorations (principalement cosmétiques). J’ai mis à jour les captures de l’article.
N’hésitez pas à faire un retour à votre tour quand vous aurez démarré le monitorage de l’hygrométrie de vos pièces.
Bonjour,
Merci pour ce tutoriel. Je trouve votre application mobile très jolie. Est-elle téléchargeable quelque part ?
Cordialement,
Pierre-Jean V.
Bonjour Pierre-Jean,
Merci pour ce retour. L’application mobile n’est pas téléchargeable publiquement car je n’ai pas industrialisé le système pour qu’il puisse être déployé dans un autre contexte.
Salut,
Super projet. Je me lance (bien que novice) pour répliquer tout ça.
J’ai cherché des RPI0 mais c’est impossible d’en trouver. Je me suis donc rabattu sur des Zero-W mais on est à 20€ la bête..
Petite question : est-il possible de plugger plusieurs DHTT22 sur un RPI0 ? (en mettant évidemment un câblage plus long pour qu’ils soit dans une autre pièce 🙂 ).
Merci en tous cas d’avoir partagé ce pj inspirant !
Christophe
Merci Christophe pour le commentaire !
J’ai pris les PI0 sur Pimoroni, on ne peut en prendre qu’un à la fois (avec ainsi les frais de port à chaque fois) mais rien n’empêche de commander plusieurs fois.
Concernant le branchement de plusieurs DHT22 je m’étais posé la question. Je ne l’ai pas réalisé mais je pense qu’on peut en brancher plusieurs en utilisant d’autres broches que la n°4 du GPIO. Attention à la longueur des fils reliant la sonde au PI0, j’ai lu que d’après des tests empiriques celle-ci est limitée. A tester donc avant sur breadboard…
Voila je suis en sonde DHT22 sur un raspberry depuis plusieurs mois deja. Par contre je constate que je ne recupere pas tout le temps les valeurs de la sonde.
d’abord merci beaucoup pour vos soutiens, ça m’aide vraiment au niveau de mon projet de fin d’étude
SVP pouvez-vous de m’envoyer les tableaux de la base de données ??
Merci d’avance
Bonjour,
En premier lieu merci pour cet article qui résume bien ce que je veux réaliser.
Je dispose de 3 caves à vin sur 3 sites différents Je recherchais de sondes thermomètre fonctionnant en WiFi genre Xiaomi mais du coup il me faudrait un Hub pour chaque capteur 🙁 et le coût s’envole…
Du coup si je peux disposer sur chaque site d’un RPI0 avec 2 sondes (une à l’intérieur et l’autre a l’extérieur du frigo cave) en reprenant votre design j’obtiendrais l’historique des valeurs… et éventuellement en cas de dysfonctionnement (montée de la Temp ou Hydro en dehors de valeurs prédéterminées) envoi d’un mail pour me prévenir.
Par contre je suis une quiche en développement RPI… alors j’ai besoin d’aide sur la partie serveur et App mobile. Je me doute du travail que représente ce projet, alors je suis preneur de tout renseignement ou tout partage.
Merci d’avance
Bonjour Jean-Louis,
Le fonctionnement que vous décrivez semble tout à fait réalisable. J’ai indiqué ici un exemple de ce qui peut être fait en python.