Table des matières

Utilisation de la fonction round()

Nous allons modifier notre script python pour introduire l'utilisation de la fonction Python round() pour arrondir les valeurs numériques (température, humidité, point de rosée, humidex) à une seule décimale.

Avant

Les variables temperature ou humidity pouvaient contenir des valeurs longues comme 23.67893452, ce qui :

Pour avoir un affichage correct, nous utilisons le code suivant : print(f“{temperature:.1f}”)

Celui-ci arrondi bien notre résultat à un chiffre après la virgule, mais il n'arrondi que l'affichage.

Après

Grâce à round(variable, 1), on obtient des valeurs comme 23.7, ce qui :

round() arrondit réellement la valeur stockée, contrairement à l’ancienne méthode. Cela permet donc une meilleure réutilisation des données : les fonctions ou interfaces web utilisent des valeurs déjà simplifiées.

Changement dans le code

print(f"{GREEN}Température :{RESET} {round(temperature, 1)}°C")
print(f"{YELLOW}Humidité :{RESET} {round(humidity, 1)}%")
print(f"{RED}Point de rosée :{RESET} {round(point_de_rosee, 1)}°C")
print(f"{MAGENTA}Indice humidex :{RESET} {round(humidex, 1)}")

Ce changement, bien que minime à première vue, marque une étape importante vers la structuration professionnelle du script et prépare le terrain pour la future séparation des modules (capteur, API, interface web).

Logique métier

Nous allons demander à Python de générer une page web et d'y afficher nos données.

Structure du code

Nous sommes prêt à structurer plus proprement notre application en séparant :

Création d'un fichier capteur.py

Dans une démarche de développement propre, modulaire et réutilisable, on sépare la logique métier (la lecture des données et les calculs) de l’interface utilisateur (site web, affichage).

Le fichier capteur.py ne contient plus de boucle while True ni de traitement direct. Il est composé exclusivement de fonctions, que l’on pourra appeler depuis une autre application, ici app.py (notre serveur Flask).

Ce script agit comme une boîte à outils. Il regroupe :

Le projet final étant hors ligne, nous retirons la partie appel API d'openweather, cette partie du code n'avait qu'un but pédagogique.
#importations
import Adafruit_DHT
import math
from datetime import datetime

#definir le capteur et le port GPIO
DHT_SENSOR = Adafruit_DHT.DHT22
DHT_PIN = 4

def lire_donnees_capteur():
    humidity, temperature = Adafruit_DHT.read_retry(DHT_SENSOR, DHT_PIN)
    #attention, la fonction read_retry() retourne en premier l'humidité puis la temperature.
    if humidity is not None and temperature is not None:
        return round(humidity, 1), round(temperature, 1)
    else:
        return None, None

def calculer_point_de_rosee(temperature, humidity):
    #Formule pour calculer le point de rosée
    alpha = 17.27
    beta = 237.7
    gamma = (alpha * temperature) / (beta + temperature) + math.log(humidity / 100)
    point_de_rosee = (beta * gamma) / (alpha - gamma)
    return round(point_de_rosee, 1)

def calculer_humidex(temperature, point_de_rosee):
    #Formule pour calculer l'indice humidex
    humidex = temperature + (5/9) * (6.11 * math.exp(5417.7530 * ((1/273.16) - (1/273.15 + point_de_rosee))) - 10)
    return round(humidex, 1)

def recuperer_date_heure():
    return datetime.now().strftime("%d-%m-%Y %H:%M:%S")

Interface utilisateur -> fichier app.py

La bibliothèque flask

Flask est un micro-framework web en Python, simple et léger. Il permet de créer rapidement un petit site web ou une API sans dépendances complexes.

Dans notre cas, Flask permet de :

Installation de flask

pip3 install flask

Importation de flask

Importons flask au début de notre code :

from flask import Flask, render_template_string

Importation des données de l'application métier

Dans notre fichier app.py, nous avons besoin d'accéder aux données météo produites par notre capteur (température, humidité, etc.) et aux fonctions de calcul (point de rosée, humidex…).

Ces fonctions ne sont pas écrites directement dans app.py, mais dans un autre fichier appelé capteur.py. Ce fichier est ce qu'on appelle notre application métier : il contient toute la logique de calcul et de lecture.

from capteur import (
    lire_donnees_capteur,
    calculer_point_de_rosee,
    calculer_humidex,
    recuperer_date_heure
)

C’est un peu comme si on disait :

« Va chercher dans la boîte capteur.py ces outils bien précis, et rends-les disponibles ici. »

Création de l’application Flask

# Création de l'application Flask
app = Flask(__name__)

Cette ligne est essentielle. Elle signifie :

Autrement dit :

👉 « Je démarre une application web avec ce fichier comme point d’entrée. »

Définir une route dans Flask (la page d’accueil)

@app.route('/')
def index():

@app.route('/') : Indique que la fonction juste en dessous va être exécutée quand un utilisateur accède à l’adresse « / », c’est-à-dire la racine du site, la page d’accueil.

def index(): C’est une fonction Python classique, appelée ici index. Elle contiendra le code qui définit ce que l'on affiche ou retourne quand on visite cette page.

Récupération des données

humidity, temperature = lire_donnees_capteur()
if humidity is not None and temperature is not None:
    point_de_rosee = calculer_point_de_rosee(temperature, humidity)
    humidex = calculer_humidex(temperature, point_de_rosee)
    date_heure = recuperer_date_heure()

nous mettons en œuvre la logique métier définie dans notre fichier capteur.py :

Génération simple d’une page HTML avec une f-string

    html = f"""
    <h1>Données météo locales</h1>
    <ul>
      <li>Date et heure : {date_heure}</li>
      <li>Température : {temperature} °C</li>
      <li>Humidité : {humidity} %</li>
      <li>Point de rosée : {point_de_rosee} °C</li>
      <li>Humidex : {humidex}</li>
    </ul>
    """
else:
    html = "<p>Erreur de lecture du capteur.</p>"

Nous créons une chaîne de caractères contenant du HTML, dans laquelle nous insérons directement les valeurs des variables Python (température, humidité, etc.).

La balise h1 sert à afficher titre de niveau 1.

La balise ul sert à afficher une liste à puce, les balises li correspondent aux éléments de la liste.

La balise p sert à afficher un paragraphe.

Pourquoi le f devant la chaîne ?

Le f signifie que c’est une f-string (ou formatted string literal en anglais).

Cela permet d’écrire des variables à l’intérieur de la chaîne entre des accolades {}.

C’est une méthode claire et moderne pour mélanger texte et variables dans une même ligne.

Et si la lecture échoue ?

else:
    html = "<p>Erreur de lecture du capteur.</p>"

Ce code gère le cas où le capteur ne renvoie pas de valeurs valides. Dans ce cas, on prépare un message simple à afficher sur la page web.

Démarrage de l'application et affichage de la page web

return render_template_string(html)

Ce code indique à Flask d'afficher le HTML généré comme contenu de la page web.

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

Ce code permet de lancer l'application :

Page app.py :

#importations
from flask import Flask, render_template_string
from capteur import (
    lire_donnees_capteur,
    calculer_point_de_rosee,
    calculer_humidex,
    recuperer_date_heure
)

# Définition de l'application Flask
app = Flask(__name__)

@app.route('/')
def index():
    humidity, temperature = lire_donnees_capteur()
    if humidity is not None and temperature is not None:
        point_de_rosee = calculer_point_de_rosee(temperature, humidity)
        humidex = calculer_humidex(temperature, point_de_rosee)
        date_heure = recuperer_date_heure()

        html = f"""
        <h1>Données météo locales</h1>
        <ul>
            <li>Date et heure : {date_heure}</li>
            <li>Température : {temperature} °C</li>
            <li>Humidité : {humidity} %</li>
            <li>Point de rosée : {point_de_rosee} °C</li>
            <li>Humidex : {humidex}</li>
        </ul>
        """
    else:
        html = "<p>Erreur de lecture du capteur.</p>"

    return render_template_string(html)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)