Initial release 1.2.2

This commit is contained in:
2026-05-24 13:05:18 +02:00
parent 87d33b41c7
commit b075d04706
28 changed files with 2022 additions and 124 deletions
+181 -25
View File
@@ -19,9 +19,9 @@ Firmware ESP32 pour une station d'acquisition de températures avec interface we
DS18B20 (×3 en parallèle)
VCC → 3.3V
GND → GND
DATA → GPIO 4
DATA → GPIO27 / D6
Résistance 4.7 kΩ entre 3.3V et GPIO 4 (pull-up)
Résistance 4.7 kΩ entre 3.3V et GPIO27 / D6 (pull-up)
```
> **Important :** Sans la résistance pull-up, les sondes retournent systématiquement 127°C.
@@ -55,17 +55,30 @@ Dans `include/config.h` :
#define MQTT_PORT 1883
```
### 3. Compiler et flasher
### 3. Compiler et téléverser par USB
```bash
# Flash du firmware
pio run -t upload
# Compiler le firmware sans téléverser
pio run -e esp32dev
# Flash de l'interface web (LittleFS)
pio run -t uploadfs
# Compiler l'image filesystem LittleFS sans téléverser
pio run -e esp32dev -t buildfs
# Moniteur série (débogage)
pio device monitor
# Téléverser le firmware par USB
pio run -e esp32dev -t upload --upload-port /dev/ttyUSB0
# Téléverser l'interface web LittleFS par USB
pio run -e esp32dev -t uploadfs --upload-port /dev/ttyUSB0
# Ouvrir le moniteur série
pio device monitor --port /dev/ttyUSB0 --baud 115200
```
Si PlatformIO détecte automatiquement le port USB, `--upload-port /dev/ttyUSB0` peut être omis :
```bash
pio run -e esp32dev -t upload
pio run -e esp32dev -t uploadfs
```
### 4. Vérifier le boot
@@ -78,7 +91,7 @@ pio device monitor
[OTA] Prêt
[FS] LittleFS monté
[HTTP] Serveur web démarré sur port 80
[SONDES] 3 capteur(s) DS18B20 détecté(s) sur GPIO 4
[SONDES] 3 capteur(s) DS18B20 détecté(s) sur GPIO 27
```
---
@@ -111,12 +124,23 @@ L'ESP tente de se reconnecter au WiFi STA toutes les 60 secondes.
## API REST
Les anciens endpoints `/api/...` restent disponibles pour compatibilité avec l'interface web. Les nouveaux endpoints recommandés pour un agent IA sont versionnés sous `/api/v1/...`.
| Méthode | Endpoint | Description |
|---|---|---|
| GET | `/api/status` | État système (WiFi, MQTT, RAM, uptime) |
| GET | `/api/temperatures` | Températures instantanées |
| GET | `/api/history` | Historique 24h (288 points) |
| GET | `/api/history` | Historique glissant 24h, moyennes 5 min |
| POST | `/api/config` | Mise à jour configuration |
| POST | `/api/restart` | Redémarrage logiciel de l'ESP |
| GET | `/api/v1/info` | Identité, version, capacités |
| GET | `/api/v1/status` | État système complet |
| GET | `/api/v1/readings/latest` | Dernière valeur instantanée connue |
| GET | `/api/v1/sensors` | Alias de la dernière lecture, avec noms de sondes |
| GET | `/api/v1/history` | Historique glissant 24h en moyennes 5 min |
| GET | `/api/v1/mqtt` | Broker actif et topics utilisés |
| POST | `/api/v1/config/mqtt` | Met à jour broker/port et reconnecte MQTT |
| GET | `/api/v1/agent` | Résumé compact pour agent IA |
**Exemple `/api/temperatures` :**
```json
@@ -131,32 +155,165 @@ curl -X POST http://esp_jardin.local/api/config \
-d '{"intervalleMs": 5000, "mqttBroker": "10.0.0.3", "mqttPort": 1883}'
```
Les paramètres MQTT sont sauvegardés dans `/config.json` sur LittleFS. Après sauvegarde depuis l'interface web, la connexion MQTT est coupée puis relancée avec le broker et le port enregistrés, sans attendre un redémarrage complet.
**Exemple `/api/v1/readings/latest` :**
```json
{
"device": "esp_jardin",
"unit": "C",
"aggregation": {
"history_window_s": 300,
"samples_per_average": 30
},
"readings": [
{ "index": 0, "name": "T°C Ext", "error": false, "temperature": 19.3 }
]
}
```
**Exemple `/api/v1/history` :**
```json
{
"device": "esp_jardin",
"unit": "C",
"range_s": 86400,
"resolution_s": 300,
"points_max": 288,
"sequence": 42,
"points": [
{
"ts": 12600,
"age_s": 120,
"window_s": 300,
"t": [19.3, 22.1, null],
"samples": [30, 30, 0]
}
]
}
```
L'historique est glissant sur 24h : `24 × 12 = 288` points. Chaque point est une moyenne de 5 minutes, soit `5 min × 60 s / 10 s = 30` mesures par sonde. Les valeurs sont exposées avec 1 chiffre après la virgule.
L'historique est gardé en RAM pour servir rapidement l'API. Il est sauvegardé dans `/history.bin` sur LittleFS une fois par heure, après 12 nouveaux points moyens. Le fichier est compact : environ 3.8 Ko pour 24h complètes (`288` points × `3` sondes), très inférieur à la partition LittleFS de 128 Ko.
Le buffer RAM est circulaire : les nouveaux points remplacent automatiquement les points de plus de 24h. La sauvegarde horaire écrit l'état compact des dernières 24h ; en cas de coupure électrique, on perd au maximum environ 1h d'historique non encore persisté.
---
## MQTT
Topics publiés (retain=true) :
Topics publiés pour les températures :
| Sonde | Topic | Deadband |
| Sonde | Topic | Cadence |
|---|---|---|
| T°C Extérieur | `maison/jardin/ext/temperature` | 0.2°C |
| T°C Serre | `maison/jardin/serre/temperature` | 0.1°C |
| T°C Sol | `maison/jardin/sol/temperature` | 0.1°C |
| T°C Extérieur | `maison/jardin/ext/temperature` | moyenne 5 min |
| T°C Serre | `maison/jardin/serre/temperature` | moyenne 5 min |
| T°C Sol | `maison/jardin/sol/temperature` | moyenne 5 min |
Payload : valeur numérique en string, ex : `"19.3"`. Les erreurs ne sont jamais publiées.
Le topic d'état publie toujours un payload simple, compatible availability :
```text
maison/jardin/status online
```
Ce topic est publié en `retain=true`. Le Last Will MQTT publie `offline` sur le même topic si la carte plante, perd le WiFi, ou disparaît brutalement. Le broker peut mettre quelques secondes à détecter la perte selon le keepalive MQTT.
Les topics température publient uniquement la moyenne 5 minutes validée, en JSON **non retained**. Les mesures brutes toutes les 10 secondes restent utilisées pour le live web, mais ne sont pas publiées en MQTT :
```json
{
"device": "esp_jardin",
"index": 0,
"sensor": "T°C Ext",
"temperature": 19.3,
"unit": "C",
"kind": "avg",
"window_s": 300,
"samples": 30,
"ts": 12600,
"error": false,
"uptime_s": 123,
"rssi": -63
}
```
Les topics erreur publient un JSON `retain=true`, car ils représentent l'état courant d'une sonde :
```json
{
"device": "esp_jardin",
"index": 0,
"sensor": "T°C Ext",
"error": true,
"uptime_s": 123,
"rssi": -63
}
```
Pour visualiser les interruptions dans les courbes, utiliser `maison/jardin/status` comme disponibilité de l'appareil. Quand le status passe à `offline`, la période doit être affichée comme indisponible plutôt que prolonger la dernière température.
---
## Mise à jour OTA (après déploiement)
## Mise à jour OTA
L'OTA est disponible uniquement quand l'ESP est connecté en WiFi STA. Le mode AP de secours reste accessible pour l'interface web, mais les uploads OTA passent par le réseau WiFi principal. L'OTA n'utilise pas de mot de passe.
Les fichiers générés par PlatformIO sont :
| Type | Fichier |
|---|---|
| Firmware | `.pio/build/esp32dev/firmware.bin` |
| Filesystem LittleFS | `.pio/build/esp32dev/littlefs.bin` |
Ordre conseillé :
1. Mettre à jour le firmware.
2. Attendre le redémarrage de l'ESP.
3. Mettre à jour le filesystem LittleFS.
4. Recharger la page web et vérifier le footer `FW ... / UI ...`.
### OTA via PlatformIO
```bash
# Remplacer 192.168.1.42 par l'IP réelle de la carte
pio run -t upload --upload-port 192.168.1.42
# Compiler le firmware OTA sans téléverser
pio run -e esp32dev_ota
# Mot de passe OTA : Jardin2026
# Compiler l'image filesystem LittleFS OTA sans téléverser
pio run -e esp32dev_ota -t buildfs
# Firmware OTA via mDNS
pio run -e esp32dev_ota -t upload
# Firmware OTA via IP directe
pio run -e esp32dev_ota -t upload --upload-port 192.168.1.42
# Filesystem LittleFS OTA via mDNS
pio run -e esp32dev_ota -t uploadfs
# Filesystem LittleFS OTA via IP directe
pio run -e esp32dev_ota -t uploadfs --upload-port 192.168.1.42
```
Le mot de passe OTA peut être changé dans `include/config.h` (`OTA_PASS`) et `platformio.ini` (`upload_flags = --auth=...`).
### OTA via interface web
Depuis l'interface web :
1. Ouvrir `http://esp_jardin.local`.
2. Cliquer sur l'icône engrenage.
3. Dans `Mise à jour OTA firmware`, sélectionner `.pio/build/esp32dev/firmware.bin`.
4. Envoyer le firmware et attendre le redémarrage.
5. Revenir sur `http://esp_jardin.local`.
6. Dans `Mise à jour OTA filesystem`, sélectionner `.pio/build/esp32dev/littlefs.bin`.
7. Envoyer le filesystem et attendre le redémarrage.
Sécurités appliquées par l'ESP avant écriture flash :
- le champ firmware accepte uniquement un fichier nommé `firmware.bin`,
- le champ filesystem accepte uniquement un fichier nommé `littlefs.bin`,
- le firmware doit commencer par l'en-tête binaire ESP32 attendu,
- la taille du fichier doit tenir dans la partition cible,
- en cas d'erreur, l'ESP renvoie un message JSON et ne redémarre pas volontairement.
---
@@ -168,7 +325,6 @@ Le mot de passe OTA peut être changé dans `include/config.h` (`OTA_PASS`) et `
| 32 / 33 | Capteur humidité sol | ADC1 (compatible WiFi) |
| 25 / 26 | Relais / électrovanne | Digital out |
| 14 | Pluviomètre à augets | Interruption |
| 27 | Bouton reset / forçage AP | Interruption |
> **Ne jamais utiliser ADC2** (GPIO 3439) quand le WiFi est actif — conflit hardware ESP32.
@@ -178,8 +334,8 @@ Le mot de passe OTA peut être changé dans `include/config.h` (`OTA_PASS`) et `
| Symptôme | Cause probable | Solution |
|---|---|---|
| Sonde affiche 127°C | Résistance pull-up absente ou câble défectueux | Vérifier la résistance 4.7 kΩ sur GPIO 4 |
| Sonde affiche 127°C | Résistance pull-up absente ou câble défectueux | Vérifier la résistance 4.7 kΩ sur GPIO27 / D6 |
| Sonde affiche 85.0°C | Sonde en court-circuit ou alimentation insuffisante | Vérifier l'alimentation 3.3V |
| Interface web inaccessible | LittleFS non flashé | `pio run -t uploadfs` |
| `esp_jardin.local` ne répond pas | mDNS non supporté sur certains réseaux | Utiliser l'IP directe |
| OTA échoue | Mauvais mot de passe | Vérifier `OTA_PASS` dans `config.h` |
| OTA échoue | ESP non connecté au WiFi STA ou fichier `.bin` incorrect | Vérifier l'IP, la connexion WiFi et choisir `firmware.bin` ou `littlefs.bin` selon le champ utilisé |