a8f0d6ccba
Fonctionnalités : - Lecture RS485 Modbus Epever Tracer 4210N (115200 bps, FC03/FC04/FC16) - Moteur de règles JSON (LittleFS) — commande automatique des relais - Interface web mobile-first (dashboard, règles, config, historique, EPEVER, debug) - WiFi AP+STA simultanés avec reconnexion automatique et portail captif - mDNS configurable (pv.local par défaut) - Configuration registres EPEVER depuis l'UI (18 registres holding) - Historique basse/haute résolution avec graphes canvas - VPN WireGuard optionnel (désactivé par défaut, config via UI) - OTA firmware + filesystem via ElegantOTA - Deep sleep / économie d'énergie Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
127 lines
4.1 KiB
Markdown
127 lines
4.1 KiB
Markdown
# Émulateur QEMU ESP32 — KC868-A2
|
||
|
||
Émulation du firmware sur QEMU ESP32 (fork Espressif, GPL).
|
||
Interface de débogage 3 volets : GPIO / terminal série / webserver ESP32.
|
||
|
||
## Architecture
|
||
|
||
```
|
||
Docker
|
||
├── qemu-system-xtensa (ESP32 firmware + WiFi + réseau)
|
||
│ UART0 → stdout (logs Serial.print → terminal)
|
||
│ UART2 → TCP:1235 (Modbus RTU ← stub Python)
|
||
│ NIC → slirp (hostfwd port 10080 → ESP32:80)
|
||
│
|
||
├── modbus_stub.py (émulateur Modbus RTU slave Epever)
|
||
│ Se connecte à TCP:1235, répond aux FC04 avec données simulées
|
||
│
|
||
└── server.py (interface web débogage, port 8888)
|
||
/ → UI 3 volets
|
||
/serial → SSE flux UART0
|
||
/api/* → proxy vers webserver ESP32 (port 10080)
|
||
```
|
||
|
||
## Prérequis
|
||
|
||
- Docker + Docker Compose
|
||
- Firmware compilé avec PlatformIO : `pio run`
|
||
|
||
## Lancement
|
||
|
||
### Option 1 — Serveur de simulation (recommandé)
|
||
|
||
Sert les vrais fichiers `data/` + simule tous les `/api/*` en mémoire.
|
||
L'état des relais, règles et config sleep sont modifiables via l'interface.
|
||
L'historique s'alimente toutes les 5 secondes (= 5 min en temps réel).
|
||
|
||
```bash
|
||
# Sans Docker (Python 3 requis) :
|
||
cd emulator && python3 sim.py
|
||
|
||
# Avec Docker :
|
||
cd emulator && docker compose up sim
|
||
```
|
||
|
||
Accès : **http://localhost:8087**
|
||
|
||
---
|
||
|
||
### Option 2 — Émulateur QEMU (boot séquence + terminal série)
|
||
|
||
Exécute le vrai binaire compilé. Montre le boot ESP32 et les logs Serial.
|
||
Le firmware crashe au démarrage de WiFi (hardware non émulé) — normal.
|
||
|
||
```bash
|
||
# 1. Compiler le firmware
|
||
pio run && pio run -t buildfs
|
||
|
||
# 2. Copier les binaires
|
||
cp .pio/build/kc868_a2/*.bin emulator/firmware/
|
||
|
||
# 3. Démarrer
|
||
cd emulator && docker compose up --build emulator
|
||
```
|
||
|
||
Accès :
|
||
- **Interface de débogage** : http://localhost:8888
|
||
- **WebServer ESP32** : http://localhost:10080 (si WiFi démarre)
|
||
|
||
## Mise à jour de la version QEMU
|
||
|
||
Si le téléchargement échoue, vérifier la dernière version disponible sur :
|
||
https://github.com/espressif/qemu/releases
|
||
|
||
Modifier `QEMU_TAG` et `QEMU_ARCHIVE` dans le `Dockerfile`.
|
||
|
||
## Correctif registres WiFi (LoadStorePIFAddrError)
|
||
|
||
Le QEMU Espressif standard n'émule pas les registres matériels WiFi modem
|
||
(`0x60033C00`). Sans correctif, le firmware crash en boucle avec
|
||
`LoadStorePIFAddrError` dès l'initialisation WiFi.
|
||
|
||
**Solution** : le `Dockerfile` utilise un build multi-étapes :
|
||
1. **`rom-extractor`** — télécharge le binaire pré-compilé, extrait les ROM blobs ESP32 (fichiers binaires propriétaires)
|
||
2. **`qemu-builder`** — clone le source Espressif QEMU, applique `wifi_stub_patch.py`, compile uniquement la cible xtensa
|
||
3. **Image finale** — ROM blobs de l'étape 1 + binaire patché de l'étape 2
|
||
|
||
`wifi_stub_patch.py` injecte un appel `create_unimplemented_device()` dans
|
||
`hw/xtensa/esp32.c` qui mappe silencieusement la plage `0x60033C00–0x60043BFF`
|
||
(64 Ko, WiFi MAC + baseband) : toutes les lectures retournent 0, les écritures
|
||
sont ignorées, plus de fault CPU.
|
||
|
||
> **Note** : le build initial prend 15–30 min (compilation QEMU). Docker met
|
||
> les layers en cache — les rebuilds suivants sont instantanés.
|
||
|
||
## Limites connues
|
||
|
||
| Fonctionnalité | État |
|
||
|---|---|
|
||
| WiFi AP mode (softAP) | Registres stubés (pas de WiFi réel) — le firmware démarre |
|
||
| Webserver ESP32 (port 80) | Accessible via hostfwd → port 10080 si WiFi s'initialise |
|
||
| Modbus RS485 | Émulé par `modbus_stub.py` (données sinusoïdales) |
|
||
| GPIO physiques (DI1/DI2) | Non émulés — toujours à 0 |
|
||
| Deep sleep | Non supporté dans QEMU |
|
||
| OTA | Non testé |
|
||
|
||
## Modbus simulé
|
||
|
||
Le stub `modbus_stub.py` répond aux lectures FC04 des registres Epever Tracer 4210N :
|
||
|
||
| Registre | Valeur simulée |
|
||
|---|---|
|
||
| 0x3100 PV tension | ~18.72 V (variation sinusoïdale) |
|
||
| 0x3101 PV courant | ~4.20 A |
|
||
| 0x3104 Batterie | ~13.45 V |
|
||
| 0x310E Load | 26.80 W |
|
||
| 0x311A SOC | 75 % |
|
||
| 0x3200 Statut | Float charge |
|
||
| 0x200C Jour/Nuit | Jour |
|
||
|
||
## Arrêt
|
||
|
||
```bash
|
||
docker compose down
|
||
```
|
||
|
||
Pour quitter la console QEMU (dans le terminal) : `Ctrl+A` puis `X`.
|