Station météo IoT

Un projet local-first né d'un besoin très concret (et de quelques huîtres) : un ESP32 mesure, envoie en Wi-Fi, un serveur Flask stocke en SQLite/CSV, et un dashboard affiche l'historique.

IoTESP32DIYDomotiqueFlaskSQLiteMakerStation météo

Dashboard principal sur desktop (capteurs int/ext, batterie, RSSI) Dashboard desktop : températures, humidité, batterie, RSSI, statut capteurs.

Une station météo IoT, des huîtres… et une excellente excuse pour bricoler

Il y a des projets qui naissent d’une réflexion stratégique longuement mûrie.
Et puis il y a ceux qui commencent par une question beaucoup plus pragmatique :

« Est-ce que je suis en train de flinguer des huîtres sans m’en rendre compte… et vais-je rendre mes amis très, très malades pour le Nouvel An ? »

Nous étions fin décembre. J’avais apporté des huîtres. Elles devaient rester deux jours dehors.
La météo annonçait du froid, mais ça, mon téléphone savait déjà me le dire.

Ce que mon téléphone ne savait pas me dire, en revanche, c’était la température réelle là où je les avais stockées.
Le garage, par exemple, est presque à la température extérieure… mais un peu plus chaud. « Un peu » étant un mot scientifiquement insuffisant quand il s’agit de fruits de mer.

Et c’est là que la pensée dangereuse est apparue : je pourrais mettre un capteur.


Du besoin réel au prétexte parfait

Soyons honnêtes :

  • oui, j’avais un besoin concret,
  • oui, je voulais éviter une catastrophe digestive collective,
  • mais surtout… c’était une excellente excuse pour lancer un projet IoT.

Et quitte à mettre un capteur dans le garage, autant ne pas faire les choses à moitié.

Pourquoi se contenter de « est-ce qu’il fait trop froid ? »
quand on peut avoir :

  • température et humidité,
  • intérieur et extérieur,
  • un serveur local,
  • une base de données,
  • un dashboard,
  • et — tant qu’à faire — un projet propre, extensible, documentable.

C’est ainsi qu’une simple question ostréicole s’est transformée en station météo IoT locale complète.


Une philosophie simple (et assumée)

Ce projet repose sur quelques principes :

  • Local-first : tout fonctionne sur le réseau local
  • Compréhensible : chaque brique a un rôle lisible
  • DIY assumé : soudure, tests, itérations, jurons modérés
  • Évolutif : on commence simple, on verra plus tard

L’objectif n’est pas de battre un produit commercial, mais de comprendre ce que l’on fabrique — et surtout pourquoi.


Vue d’ensemble : comment tout s’articule

Schéma de fonctionnement global (capteurs > ESP32 > Wi-Fi > serveur > dashboard) Flux : capteurs → ESP32 → Wi-Fi → serveur Flask → dashboard local.

À haut niveau, le système fonctionne ainsi :

  1. Un capteur mesure température et humidité
  2. Un ESP32 envoie les données en Wi-Fi
  3. Un serveur local reçoit et stocke
  4. Un tableau de bord affiche et historise

Dit comme ça, ça semble simple. Dans la réalité… ça l’est presque, une fois que tout marche.


Le nœud de mesure : ESP32, capteurs et écran

Composants ESP32 + capteur + écran OLED ESP32 + BME280 + OLED avant montage dans le boîtier.

Au cœur du dispositif, on trouve un ESP32.
Enfin… plusieurs ESP32, en réalité.

J’en ai testé différents modèles avant de tomber sur celui qui convenait vraiment. Certains ne voulaient rien savoir. D’autres coopéraient… partiellement. L’électronique, c’est aussi apprendre à reconnaître quand un composant vous dit poliment non.

À l’ESP32 sont connectés :

  • un capteur de température et d’humidité,
  • un petit écran OLED.

L’écran affiche les valeurs en direct. Ce détail est plus important qu’il n’y paraît : voir des chiffres s’afficher est souvent le premier moment où l’on se dit « ok, quelque chose fonctionne ». Même si tout le reste ne fonctionne pas encore.

Le capteur en fonctionnement (OLED visible, relevés en direct) Lecture en direct sur l’OLED, avant envoi Wi-Fi.


De la mesure à la donnée : Wi-Fi, HTTP et patience

Une fois les mesures prises, l’ESP32 envoie les données au serveur via le Wi-Fi local.
Sur le papier, c’est simple.

Dans la pratique, il a fallu :

  • comprendre que mon PC devait être en Ethernet et non en Wi-Fi,
  • réaliser que mon extender Wi-Fi était un acteur à part entière du problème,
  • configurer pare-feu et antivirus pour autoriser des scripts Python à vivre leur vie.

Windows faisait très bien son travail de sécurité. Moi, un peu moins bien mon travail de compréhension au début.

Paramètres firewall / autorisations réseau Windows pour Flask Règles Windows nécessaires pour autoriser Flask et le trafic local.

Les données envoyées sont structurées en JSON. Un exemple ressemble à ceci (format simplifié) :

{
  "sensor_id": "indoor",
  "temp_c": 21.5,
  "hum_pct": 55,
  "rssi_dbm": -62
}

Le serveur local : là où tout se joue

Le serveur est une application Flask, hébergée localement. Son rôle :

  • recevoir les données,
  • les comprendre (ce qui n’est pas toujours gagné),
  • les horodater,
  • les stocker proprement.

Console des logs serveur Flask (réceptions MQTT/HTTP) Logs Flask : réception, parsing et stockage des mesures.

À un moment, en voulant « améliorer » le serveur, j’ai laissé une IA me générer une nouvelle version… qui ne comprenait plus les requêtes envoyées par l’ESP32.

Résultat : des données envoyées, aucune donnée comprise, et une excellente leçon : l’IA n’est pas magique du premier coup. On apprend aussi en revenant en arrière.


Stockage : SQLite et CSV, le duo tranquille

Organisation des données (SQLite + CSV, export Excel) SQLite pour l’historique, CSV pour l’analyse rapide.

Les mesures sont stockées de deux façons :

  • SQLite pour l’historique structuré,
  • CSV pour la portabilité et l’analyse rapide (Excel, scripts, etc.).

Ce choix volontairement sobre permet de relire les données partout et de garder la main sur ce qui est enregistré.


Le tableau de bord : enfin, quelque chose à regarder

Dashboard mobile (intérieur/extérieur, batterie, RSSI) Vue mobile : mêmes métriques, lisibles en déplacement.

Le dashboard est accessible depuis un navigateur sur le réseau local.
Il permet :

  • de voir les capteurs en ligne / hors ligne,
  • de consulter les valeurs instantanées,
  • d’explorer l’historique,
  • de comparer intérieur et extérieur.

C’est aussi là que l’on passe beaucoup de temps à ajuster les détails : tailles de police, espacements, défilements, « juste un petit truc » qui prend deux heures. Mais quand tout s’aligne, c’est extrêmement satisfaisant.


Boîtiers et bricolage : quand le millimètre compte

Boîtier imprimé/découpe laser (montage sur mât) Boîtier (impression 3D + découpe laser) fixé sur le mât.

Parce que j’aime compliquer les choses « juste ce qu’il faut », j’ai aussi réalisé des boîtiers :

  • un en impression 3D,
  • un en découpe laser.

Et là, on entre dans la phase rocambolesque où 0,5 mm peut transformer une belle idée en puzzle, surtout quand une soudure décide de lâcher précisément au moment où l’on veut prendre de jolies photos pour l’article.


L’IA comme coéquipier (pas comme gadget)

Ce projet a été réalisé avec l’IA du début à la fin : structuration du repo, aide au câblage et à la logique, génération de code via Codex (dans VS Code), débogage, itérations, amélioration du dashboard.

Pas comme une baguette magique, mais comme :

  • un assistant,
  • un accélérateur,
  • un coéquipier silencieux.

On peut se sentir un peu comme Iron Man avec Jarvis… avec la différence notable que Jarvis ne ressoude pas à votre place quand la soudure lâche.


Ce que ce projet m’a appris

Avec :

  • quelques capteurs à quelques euros,
  • un ESP32,
  • un PC,
  • du Wi-Fi,
  • et de l’IA,

on peut construire bien plus qu’on ne l’imagine.


Ce projet n’est pas une fin : c’est une base

Un point de départ pour d’autres capteurs, d’autres usages, d’autres idées.

Prochaines étapes

  • Ajouter une girouette et un pluviomètre (mêmes chemins de données).
  • Publier un dashboard public (lecture seule) avec alertes température/batterie.
  • Scripts de recalibrage auto (offset T/H) et vérification nocturne d’autonomie.
  • Passage des visuels en WebP/AVIF pour alléger le chargement.

Ressources

  • ESP32 + BME280 : mesures T/H/P, bus I2C.
  • Flask + SQLite/CSV : stockage et API locale.
  • MQTT/HTTP local : envoi périodique, JSON compact.
  • LightBurn / découpe laser : fabrication du boîtier (option).