6.8 KiB
Plan de corrections — esp_jardin
Toutes les améliorations identifiées lors de la revue de code, classées par priorité.
✅ Déjà corrigé dans cette session
| Correction | Fichier | Description |
|---|---|---|
| Race condition historique | sensors.cpp |
Utilise tempLues[i] au lieu de sondesEtat[i] dans le buffer historique |
| MQTT timeout bloquant | mqtt_manager.cpp |
_wifiClient.setTimeout(2000) — limite le blocage à 2s max |
| LWT (Last Will Testament) | mqtt_manager.cpp |
Le broker publie offline automatiquement si l'ESP disparaît |
| Heartbeat MQTT | mqtt_manager.cpp |
Publication online toutes les 60s sur maison/jardin/status |
| Erreurs sonde MQTT | mqtt_manager.cpp |
Publication 1/0 sur maison/jardin/ext/erreur au changement d'état |
Corrections restantes
Tâche 1 — DS18B20 : lecture par adresse ROM (priorité haute)
Problème : getTempCByIndex(i) retourne les capteurs dans l'ordre d'énumération OneWire, qui peut changer si une sonde est débranchée ou remplacée. Cela peut inverser T°C Ext ↔ T°C Sol sans avertissement.
Fichiers : include/config.h, include/sensors.h, src/sensors.cpp
Changements :
include/sensors.h — ajouter la déclaration :
extern DeviceAddress sondesAddr[NB_SONDES];
src/sensors.cpp — dans sensors_init(), scanner et mémoriser les adresses :
DeviceAddress sondesAddr[NB_SONDES] = {};
void sensors_init() {
_sensors.begin();
_sensors.setWaitForConversion(false);
uint8_t nb = _sensors.getDeviceCount();
Serial.printf("[SONDES] %u capteur(s) détecté(s) sur GPIO %d\n", nb, ONE_WIRE_BUS);
for (uint8_t i = 0; i < NB_SONDES; i++) {
if (_sensors.getAddress(sondesAddr[i], i)) {
Serial.printf("[SONDE %u] Adresse: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
i, sondesAddr[i][0], sondesAddr[i][1], sondesAddr[i][2], sondesAddr[i][3],
sondesAddr[i][4], sondesAddr[i][5], sondesAddr[i][6], sondesAddr[i][7]);
} else {
Serial.printf("[SONDE %u] Adresse introuvable\n", i);
}
}
}
Dans la boucle de lecture, remplacer :
// Avant
float t = _sensors.getTempCByIndex(i);
// Après
float t = _sensors.getTempC(sondesAddr[i]);
Note : Les adresses ROM doivent être fixées au premier branchement. Si tu changes l'ordre physique des sondes, il faut reprogrammer la correspondance dans
main.cppou les sauvegarder en NVS.
Tâche 2 — DS18B20 : résolution 11-bit (priorité faible)
Problème : La résolution par défaut est 12 bits (précision 0,0625°C, conversion 750ms). Pour une station jardin, 11 bits suffisent largement (précision 0,125°C, conversion 375ms).
Fichiers : include/config.h, src/sensors.cpp
config.h — modifier la constante :
// Avant
static const uint32_t CONVERSION_MS = 750;
// Après (déplacer dans config.h)
#define CONVERSION_MS 375 // 11-bit : 375ms au lieu de 750ms
sensors.cpp — ajouter dans sensors_init() après _sensors.begin() :
_sensors.setResolution(11); // 0.125°C, 375ms — suffisant pour jardin
Tâche 3 — WiFi : RSSI lu trop souvent (priorité faible)
Problème : WiFi.RSSI() est appelé à chaque itération de loop() (plusieurs milliers de fois par seconde), alors que la valeur change sur une échelle de secondes.
Fichier : src/network.cpp
Remplacer dans network_update() :
// Avant
} else {
netStatus.rssi = WiFi.RSSI();
}
// Après
} else {
static uint32_t _dernierRssiMs = 0;
if (millis() - _dernierRssiMs >= 10000) {
netStatus.rssi = WiFi.RSSI();
_dernierRssiMs = millis();
}
}
Tâche 4 — WiFi : persistent(false) (priorité faible)
Problème : Sans WiFi.persistent(false), le SDK ESP32 sauvegarde aussi les credentials en NVS automatiquement, en doublon de notre propre gestion NVS.
Fichier : src/network.cpp
Ajouter dans _demarrerSTA() avant WiFi.begin() :
WiFi.persistent(false); // on gère la persistance nous-mêmes via Preferences
WiFi.begin(_ssidActif, _passActif);
Tâche 5 — Web server : delay() dans callback async (priorité faible)
Problème : delay(500) dans le handler /api/wifi/connect bloque la tâche AsyncTCP (Core 0) pendant 500ms avant le redémarrage.
Fichiers : include/web_server.h, src/web_server.cpp, src/main.cpp
web_server.h — ajouter la déclaration :
void web_server_update(); // à appeler dans loop()
web_server.cpp — remplacer le delay par un flag :
static bool _redemarrerDemande = false;
// Dans le handler POST /api/wifi/connect, remplacer :
// delay(500);
// ESP.restart();
// Par :
req->send(200, "application/json", "{\"ok\":true}");
_redemarrerDemande = true;
// Ajouter la fonction :
void web_server_update() {
if (_redemarrerDemande) {
delay(300); // dans loop() : delay() est toléré
ESP.restart();
}
}
main.cpp — ajouter dans loop() :
void loop() {
network_update();
web_server_update(); // ajouter
bool nouvelleMesure = sensors_update();
...
}
Tâche 6 — Historique : timestamps absolus via NTP (priorité optionnelle)
Problème : Les timestamps sont basés sur millis() (ms depuis le démarrage). Après un reboot, ils repartent à 0. L'interface web ne peut pas afficher des heures réelles (ex: "23h15").
Fichier : src/sensors.cpp, src/network.cpp
network.cpp — synchroniser l'heure NTP après connexion WiFi :
#include <time.h>
// Dans _configurerMDNS() ou après la connexion WiFi :
configTime(3600, 3600, "pool.ntp.org"); // UTC+1, +1h été (à adapter)
Serial.println("[NTP] Synchronisation heure...");
sensors.cpp — utiliser time(nullptr) comme timestamp :
// Avant
historique[histIdx].timestamp = maintenant; // millis()
// Après
historique[histIdx].timestamp = (uint32_t)time(nullptr); // Unix timestamp
config.h — adapter le type si nécessaire (uint32_t Unix timestamp est valide jusqu'en 2106).
Note : Les graphiques de l'interface web devront adapter l'axe X pour des Unix timestamps plutôt que des ms depuis le boot.
Ordre d'exécution recommandé
| Priorité | Tâche | Risque si ignoré |
|---|---|---|
| 🔴 Haute | Tâche 1 — DS18B20 adresses ROM | Fausses lectures MQTT si sonde déconnectée |
| 🟡 Moyenne | Tâche 2 — Résolution 11-bit | Aucun, juste optimisation |
| 🟡 Moyenne | Tâche 3 — RSSI throttle | Aucun, CPU légèrement gaspillé |
| 🟢 Faible | Tâche 4 — WiFi persistent(false) | Doublon NVS, usure Flash négligeable |
| 🟢 Faible | Tâche 5 — delay() async | 500ms de blocage une seule fois (reboot) |
| ⚪ Optionnel | Tâche 6 — NTP timestamps | Graphiques sans heure réelle |