Accueil > ESP32, NodeMCU > Créer une station météo sans capteurs en MicroPython

Créer une station météo sans capteurs en MicroPython

Aujourd’hui, nous allons étudier la possibilité de créer une station météo sans utilisation de capteurs spécifiques.
Notre station devra être capable :
– D’afficher la date et l’heure.
– D’afficher la température, la pression Atmosphérique et le taux d’humidité.
– D’afficher la vitesse du vent et son orientation.
– D’afficher le lever et le coucher de soleil.

Voilà pour le cahier des charges et tout cela en MicroPython; pour les tests nous pourrons utiliser un ESP32 ou un ESP8266.

Afin de pouvoir récupérer toutes ces informations, nous allons nous appuyer sur 2 sites internet qui proposent l’accès via leur API.
Bien souvent les informations renvoyées par ces sites utilisent le format JSON (JavaScript Object Notation). Pour avoir des informations sur ce format, je vous conseille d’aller sur le site https://www.json.org/json-fr.html.

MicroPython fournit en standard une librairie qui permet de traiter ce type de format.

Le programme complet se trouve sur mon Github et est disponible en téléchargement.

Interessons-nous au premier site qui va me permettre de récupérer l’heure ainsi que le décalage (offset) horaire été / Hiver; ce site est http://worldtimeapi.org. Si on veut récupérer les informations au format JSON, il suffit simplement de taper l’adresse http://worldtimeapi.org/api/timezone/Europe/Paris et on obtient les informations suivantes :

{"week_number":"17","utc_offset":"+02:00","unixtime":"1556002004",
"timezone":"Europe/Paris","dst_until":"2019-10-27T01:00:00+00:00",
"dst_from":"2019-03-31T01:00:00+00:00","dst":true,"day_of_year":113,
"day_of_week":2,"datetime":"2019-04-23T08:46:44.759571+02:00",
"abbreviation":"CEST"}

Les 2 champs que je vais traiter est « unixtime » qui est le nombre de secondes écoulées depuis le 1er janvier 1970 et l' »utc_offset » qui va me permettre de compenser l’heure en fonction du lieu où on se situe en prenant en compte l’heure d’été et hiver.

La première étape est de récupérer le temps unix via ces lignes :

import json
import urequests
from machine import RTC
rtc = RTC()  # horloge temps réel interne
compteur = time.ticks_ms() - requete_web_delai  # initialise le compteur
url_worldtimeapi = "http://worldtimeapi.org/api/timezone/Europe/Paris"
reponse = urequests.get(url_worldtimeapi)  # effectue la requête Web
    if reponse.status_code == 200:  # requête ok
        data = json.loads(reponse.text)  # transforme les données JSON en objet Python
        temps_unix = int(data.get("unixtime"))

Rien de bien compliqué, j’ai récupéré le temps Unix; maintenant il va falloir écrire une fonction pour traiter cette valeur et me renvoyer en retour les informations de date et heure dont voici la routine :

def convert_epoch_time(temps):
    # Epoch time Linux démarre le 1 janvier 1970
    # Epoch time ESP32 démarre le 1 janvier 2000
    # donc il faut soustraire le temps de 946,684,800 secondes (30 ans)
    temps -= 946684800
    (u_annee, u_mois, u_jour, u_heure, u_minute, u_seconde, u_jour_semaine, u_jour_annee) = time.localtime(temps)
    return u_annee, u_mois, u_jour, u_heure, u_minute, u_seconde, u_jour_semaine

Le piège est que le temps Unix pour les ESP32 et ESP8266 ne démarre pas le 1er janvier 1970 mais le 1er janvier 2000, c’est pour cela que je suis obligé de soustraire 946684800 secondes (ce qui correspond à 30 ans).

L’appel à cette fonction s’effectue de la manière suivante :

annee, mois, date, heure, minute, seconde, jour = convert_epoch_time(temps_unix)

Donc j’ai récupéré les informations mais l’heure est au format UTC, donc je suis dans l’obligation de traiter le TimeZone (offset) et de mettre à jour l’horloge interne de l’ESP dans la partie suivante :

        heure_offset = data.get("utc_offset")  # on récupére l'offset
        operation_offset = heure_offset[0]  # récupère l'opérateur + ou -
        heure_offset = int(heure_offset[2:3]) # récupère uniquement les heures
        if operation_offset == "+":
            heure += heure_offset
        if operation_offset == "-":
            heure -= heure_offset
        rtc.datetime((annee, mois, date, 0, heure, minute, seconde, 0))  # MAJ horloge interne

Voilà c’est tout pour la récupération de la date et l’heure. Passons maintenant à la récupération de la météo.
Pour cela on va utiliser le site OpenWeatherMap.org; il est nécessaire de s’y inscrire, c’est gratuit pour la météo du jour. Cela va permettre de récupérer un identifiant à garder précieusement. Et il sera nécessaire également de récupérer la latitude et la longitude du lieu qui vous interresse. Pour moi c’est Criel sur mer (lat=50.02 et lon=1.31).

Pour la partie programme donc je déclare mes variables :

adresse_openweathermap = "http://api.openweathermap.org/data/2.5/weather?lat=50.02&lon=1.31&units=metric&APPID="
cle_api_openweathermap = "générer sur le site openweathermap"
url_openweathermap = adresse_openweathermap + cle_api_openweathermap

Quand je tape l’url_openweathermap, le site me renvois les informations suivantes au format JSON :

{« coord »:{« lon »:1.31, »lat »:50.02}, »weather »:[{« id »:800, »main »: »Clear », »description »: »clear sky », »icon »: »01d »}], »base »: »stations », »main »:{« temp »:14.48, »pressure »:997, »humidity »:62, »temp_min »:13.89, »temp_max »:15.56}, »visibility »:10000, »wind »:{« speed »:3.1, »deg »:110}, »clouds »:{« all »:0}, »dt »:1556005495, »sys »:{« type »:1, »id »:6449, »message »:0.0051, »country »: »FR », »sunrise »:1555994788, »sunset »:1556045968}, »id »:3022461, »name »: »Criel-sur-Mer », »cod »:200}

Donc on va traiter ces données :

    reponse = urequests.get(url_openweathermap)  # effectue la requête Web
    if reponse.status_code == 200:  # requête ok
        data = json.loads(reponse.text)  # transforme les données JSON en objet Python
        temperature = data.get("main").get("temp")
        pression = data.get("main").get("pressure")
        humidite = data.get("main").get("humidity")
        annee_s, mois_s, date_s, heure_s, minute_s, seconde_s, jour_s = convert_epoch_time(data.get("sys").get("sunrise"))
        if operation_offset == "+":
            heure_s += heure_offset
        if operation_offset == "-":
            heure_s -= heure_offset
        lever_soleil = "{0:02}:{1:02}:{2:02}".format(heure_s, minute_s, seconde_s)
        annee_s, mois_s, date_s, heure_s, minute_s, seconde_s, jour_s = convert_epoch_time(data.get("sys").get("sunset"))
        if operation_offset == "+":
            heure_s += heure_offset
        if operation_offset == "-":
            heure_s -= heure_offset
        coucher_soleil = "{0:02}:{1:02}:{2:02}".format(heure_s, minute_s, seconde_s)
        vent_vitesse = data.get("wind").get("speed")  # vitesse du vent en m/s
        vent_vitesse *= 3.6  # conversion du vent en Km/h
        vent_orientation = data.get("wind").get("deg")  # origine du vent en ° (0° --> Nord)

Il ne reste plus qu’à afficher les différentes informations toutes les 60 secondes :

if time.ticks_ms() - compteur >= requete_web_delai: # test si 60s sont passées
        traite_date_heure()
        traite_openweathermap()
        time_str = "{:02}:{:02}:{:02}".format(rtc.datetime()[4], rtc.datetime()[5], rtc.datetime()[6])
        print((jour) + " " + str(date) + " " + (mois) + " " + str(annee))
        print(time_str)
        print("Température : " + str(temperature) + "°C, Pression : " + str(pression) + " hPa, Taux d'humidité : " + str(humidite) + "%")    
        print("Lever Soleil : " + (lever_soleil) + ", Coucher Soleil : " + (coucher_soleil))
        print("Vitesse du vent : " + str(vent_vitesse) + " Km/h, Orientation : " + str(vent_orientation) + "°")
        compteur = time.ticks_ms()  # maj du compteur

Bien entendu, ces informations peuvent être affichées sur un écran OLED ou TFT.
Voilà pour l’utilisation de JSON pour traiter des données Météo.

Publicités
Catégories :ESP32, NodeMCU Étiquettes : , , , ,
  1. Aucun commentaire pour l’instant.
  1. No trackbacks yet.

Répondre

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google

Vous commentez à l'aide de votre compte Google. Déconnexion /  Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s

%d blogueurs aiment cette page :