Station météo
Réalisation d’un station météo au sein d’un lycée - Documentation
Ce billet de blog est en cours de rédaction et d'amélioration.
Cela est donc normal si des informations s'ajoutent au fil des jours :)
Bonjour ! Un projet de station météorologique à été lancée dans mon lycée et voici donc un petit billet de blog ayant l’objectif d’expliquer au mieux l’ensemble de l’installation, principalement logicielle, d’une station météo à base de Raspberry Pi et d’un capteur BME280, qui permet de mesurer la pression, la température et l’humidité directement ensemble et avec une précision vraiment intéressante.
Si vous ne souhaitez que visionnez directement les données receuillies par la station du projet « Senghor Météo » , je vous invite à cliquer sur le lien suivant : https://io.adafruit.com/meteosenghor/dashboards/meteo-senghor
Sinon, passons maintenant à la réalisation de ce projet !
Matériels :
- 1 ou 2 Raspberry Pi 3
- Une carte SD Classe 10 de 16 Go
- Un disque dur
- Un capteur BME280
- Quelques fils
- Une breadboard (optionnel)
Installation :
Installation du Raspberry Pi 3 :
Téléchargement de l’image du système d’exploitation pour le Raspberry Pi sur le site de la fondation Rapsberry pi : https://www.raspberrypi.com/software/operating-systems/
On choisira la version Raspberry Pi OS Lite dans le cadre de ce projet afin de restreindre la quantité de mémoire utilisée en installant uniquement les logiciels et bibliothèques utiles.
A l’aide du logiciel Rufus, on installe l’image disque sur une carte SD.
Configuration du réseau wifi et du proxy réseau :
Afin de pouvoir se connecter à distance sur le Raspberry Pi, on crée à la racine de la carte SD un fichier appelé ssh
.
Attention à ne pas mettre une extension de nom de fichier !
Pour connecter le Raspberry Pi à Internet, 2 options :
- brancher un câble Ethernet
- se connecter au Wifi
Dans notre cas, on utilise le wifi, on doit donc créér un fichier à la racine de la carte SD qui sera appelé wpa_supplicant.conf
.
A l’aide d’un éditeur de texte, on le complète des lignes suivantes :
country=fr
update_config=1
ctrl\_interface=/var/run/wpa\_supplicant
network={
scan_ssid=1
ssid="MaBoxInternet"
psk="ClefSecurite"
}
Ne pas oublier de remplacer le ssid par celui de sa box et le mot de passe par celui qui correspond !
Source : https://raspberry-pi.fr/raspberry-pi-sans-ecran-sans-clavier/
Si votre réseau utilise un serveur proxy, n’hésitez pas à regarder le lien suivant pour le configurez sur le Raspberry Pi, cela est notamment nécessaire pour le mettre à jour ou installer les bibliothèques : https://artheodoc.wordpress.com/2019/06/04/configuration-du-proxy-ou-serveur-mandataire-raspberry-pi-sous-raspbian/
Installation des bibliothèques python pour la lecture des données du capteur BME280 :
Pour l’installation du capteur BME280 et ses bibliothèques, le lien suivant vous sera d’une très grande utilité : https://www.raspberryme.com/utilisation-du-capteur-de-temperature-et-de-pression-bme280-i2c-en-python/
Afin d’utiliser la platerforme Adafruit IO, il vous faudra vous créer un compte. Vous devrez ensuite vous rendre dans la partie « feeds » et créer les flux suivants :
- temperature
- pression
- humidite
N’oubliez pas de récupérer au passage votre identifiant et votre token de connexion, cela vous sera utile pour le suite !
Il sera nécessaire d’installer la librairie d’Adafruit IO :
pip3 install adafruit-io
Code de récupération et envoi des données sur Adafruit IO :
import time
from bme280 import * # Gestion capteur BME280
from Adafruit_IO import Client # Gestion envoie donnée
# Connexion à Adafruit IO
aio = Client('Identifiant', 'Token')
# Initialisation des flux
temperature_feed = aio.feeds("temperature")
pression_feed = aio.feeds("pression")
humidite_feed = aio.feeds("humidite")
# Affichage information identification capteur
(chip_id, chip_version) = readBME280ID()
print("Chip ID :", chip_id)
print("Version :", chip_version)
while True:
# Récupération des données du capteur
temperature, pression, humidite = readBME280All()
# Affichage des données
print("[LOGS] Données : ",temperature, "°C |",round(pression,2), "hPa |",round(humidite,2), "%")
# Envoie des données sur Adafruit IO
aio.send_data(temperature_feed.key, temperature)
aio.send_data(pression_feed.key, pression)
aio.send_data(humidite_feed.key, humidite)
# Attente de 10 secondes avant la mesure suivante
time.sleep(10)
On va maintenant installer PM2 qui est un utilitaire permettant de lancer automatiquement et simplement un programme au démarrage du Raspberry Pi.
Installation de nodejs et npm pour installer pm2
sudo apt install nodejs npm
sudo npm cache clean -f
sudo npm install -g n
sudo n stable
Installation de PM2 pour gérer le lancement automatique
sudo npm install pm2@latest -g
Pour activer le lancement automatique de PM2, tapez la commande suivante et suivez les instructions :
pm2 startup
On lance maintenant notre script python de collecte de données :
pm2 start meteo.py
pm2 save
et pour vérifier le bon foncionnement de notre processus automatisé on utilisera la commande ci-dessous :
pm2 list
Second Raspberry Pi (en intérieur):
Source : https://simonhearne.com/2020/pi-influx-grafana/
Installation de InfluxDB :
On ajoute le dépot de InfluxDB à apt :
wget -qO- https://repos.influxdata.com/influxdb.key | sudo apt-key add -
source /etc/os-release
echo "deb https://repos.influxdata.com/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/influxdb.list
On mets à jour ensuite apt avec les nouveaux dépots et on installe InfluxDB:
sudo apt update && sudo apt install -y influxdb
On lance ensuite le service influxdb
et on le configure pour qu’il se lance automatiquement au démarrage :
sudo systemctl unmask influxdb.service
sudo systemctl start influxdb
sudo systemctl enable influxdb.service
Nous sommes maintenant en capacité de lancer le client Influx avec la commande influx
et nous allons créer un nouvel utilisateur administrateur, ici nommé grafana
, que nous utiliserons plus tard et on vérifie que l’utilisateur est bien créé :
create database meteo
use meteo
create user grafana with password '<VotreMotDePasseIci>' with all privileges
grant all privileges on meteo to grafana
show users
L’affichage retourner devrait être celui-ci :
user admin
---- -----
grafana true
Si l’affichage est bon, c’est fini ! Vous pouvez maintenant quitter la console en tapant exit
.
Installation de Grafana :
Nous devons également ajouter le package de Grafana à apt :
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
On mets à jour les dépots et on installe Grafana :
sudo apt update && sudo apt install -y grafana
On active le service et on le configure pour un démarrage automatique au lancement du Raspberry Pi :
sudo systemctl unmask grafana-server.service
sudo systemctl start grafana-server
sudo systemctl enable grafana-server.service
On peut maintenant vérifier le bon fonctionnement de Grafana en allant, à travers notre navigateur, sur : http://<ipaddress>:3000
.
Si cela marche correctement, vous pouvez vous connecter avec l’identifiant et le mot de passe par défaut :admin
.
Vous devrez configurer un nouveau mot de passe administrateur par la suite.
Ajouter Influx comme source dans Grafana :
Maintenant que Influx et Grafana fonctionne correctemenr, nous devons les connecter ensemble. Connecter vous sur Grafana et allez dans la partie « Data Sources ». Selectionnez « Add data source » puis InfluxDB dans la catégorie « Time series databases ».
Puisque les deux services tournent sur le même Raspberry Pi, configurez l’URL sur localhost (127.0.0.1) et utilisez le port par défaut d’influx 8086
:
Nous devons maintenant créer une nouvelle base de donnée et rentrant les informations que nous avons précisez plus tôt:
Appuyez sur le bouton « Save & test » pour vérifier et enregistrer les informations et créer la connexion entre Grafana et notre base de donnée Influx :
Récupérer les données météo :
Maintenant que nous avons configurée notre base de donnée, il nous faut collecter les données de notre capteur BME280.
On installe la librairie pour InfluxDB :
sudo pip install influxdb
On utilise maintenant le code suivant, qui sera exécuté sur le Raspberry Pi avec le capteur BME280, pour collecter les mesures toutes les 10 secondes :
import datetime
from influxdb import InfluxDBClient
import time
from bme280 import * # Gestion capteur BME280
# Configuration d'Influx - Editez ici
ifuser = "grafana"
ifpass = "<VotreMotDePasseIci>"
ifdb = "meteo"
ifhost = "<VotreIP>" #127.0.0.1 si la base de données est sur le même Raspberry PI
ifport = 8086
measurement_name = "mesure_meteo"
# Connexion à Influx
ifclient = InfluxDBClient(ifhost,ifport,ifuser,ifpass,ifdb)
# Affichage information identification capteur
(chip_id, chip_version) = readBME280ID()
print("Chip ID :", chip_id)
print("Version :", chip_version)
while True:
# Récupération de l'horodatage de la mesure
horodatage = datetime.datetime.utcnow()
# Récupération des données du capteur
temperature, pression, humidite = readBME280All()
# Affichage des données
print("[LOGS] Horodatage:",horodatage,"| Données : ",temperature, "°C |",round(pression,2), "hPa |",round(humidite,2), "%")
# Formatage des données comme une seule mesure pour influx
body = [
{
"measurement": measurement_name,
"time": horodatage,
"fields": {
"pression": pression,
"temperature": temperature,
"humidite": humidite
}
}
]
# Enregistrement de la mesure
ifclient.write_points(body)
# Attente de 10 secondes avant la mesure suivante
time.sleep(10)
A vous de créer un magnifique dashboard et de jouer avec les options pour afficher vos données toutes neuves !
Connexion à distance et accès aux données sur le web
Afin de pouvoir récupérer les données à distance, la solution la plus simple est d’utiliser la platerforme Adafruit IO pour accéder aux données, mais une autre solution est de mettre en place une redirection de ports, ou d’utiliser un service comme LocalTunnel permettant l’accès à un service sans modifier la configuration réseau, pour accéder à la page de Grafana.
Capacité autonome de la station
Dans le cadre de ce projet, et la difficulté de tirer une rallonge électrique en extérieur dans ce contexte n’aidant pas, nous avons décider d’alimenter notre station météo grâce à une carte d’extension PiJuice HAT associé à un panneau solaire de 40W et une batterie de 12 000 mAh. Le Raspberry Pi est configuré pour s’allumer toutes les 10 minutes, effectuer la collecte des données, se connecter simultanément à un second Raspberry Pi, servant de serveur pour la base de données, et à Adafruit IO pour pouvoir accéder facilement aux données depuis n’importe où, puis s’éteinds jusqu’au prochain cycle.
Code final de la station météo
Voici donc le code final de la station, tournant actuellement en permanence au lycée, et gérant l’envoi des données sur Grafana et Adafruit IO, les cycles d’allumages et la batterie.
import datetime
from influxdb import InfluxDBClient
import time
from bme280 import * # Gestion capteur BME280
from Adafruit_IO import Client
from pijuice import PiJuice
from subprocess import call
# Connect to pijuice hat
pijuice = PiJuice(1,0x14)
# Connect to Adafruit IO
aio = Client("<Identifiant>", "<Token>")
print("Connexion réussie !")
# Initialisation flux adafruit io
temperature_feed = aio.feeds("temperature")
pression_feed = aio.feeds("pression")
humidite_feed = aio.feeds("humidite")
batterie_feed = aio.feeds("charge-batterie")
print("initialitation flux réussis !")
# influx configuration - edit these
ifuser = "grafana"
ifpass = "<MDP>"
ifdb = "meteo"
ifhost = "<IP_INFUX>"
ifport = 8086
measurement_name = "mesure_meteo"
# connect to influx
ifclient = InfluxDBClient(ifhost,ifport,ifuser,ifpass,ifdb)
# Affichage information identification capteur
(chip_id, chip_version) = readBME280ID()
print("Chip ID :", chip_id)
print("Version :", chip_version)
def capture():
# take a timestamp for this measurement
temps = datetime.datetime.utcnow()
# Get battery charge level
data_charge = pijuice.status.GetChargeLevel()
charge_level = data_charge["data"]
# Récupération des données du capteur
temperature, pression, humidite = readBME280All()
# Affichage des données
print("[LOGS] Date:",temps,"| Batterie : ",charge_level,"% | Données : ",temperature, "°C |",round(pression,2), "hPa |",round(humidite,2), "%")
# Envoie des données sur Adafruit IO
aio.send_data(temperature_feed.key, temperature)
aio.send_data(pression_feed.key, pression)
aio.send_data(humidite_feed.key, humidite)
aio.send_data(batterie_feed.key, charge_level)
# format the data as a single measurement for influx
body = [
{
"measurement": measurement_name,
"time": temps,
"fields": {
"pression": pression,
"temperature": temperature,
"humidite": humidite,
"niveau_batterie": charge_level
}
}
]
# write the measurement
ifclient.write_points(body)
### MAIN ###
capture()
print("fin mesure, au revoir !")
pijuice.rtcAlarm.SetWakeupEnabled(True)
call("sudo shutdown -h now", shell=True)
En espérant que ce projet vous aura intéressé et surtout n’hésitez pas à envoyez un mail en cas de question !
Si vous avez une question concernant le projet, n’hésitez pas à envoyer un mail à l’adresse e-mail du projet : senghormeteo[@]protonmail.com
Si vous souhaitez me contacter directement, moi, l’ours geek écrivant ces lignes, envoyez un mail à postmaster[@]ursusnocte.fr