Files
kc868-a2_solar/consigne.md
T
gilles a8f0d6ccba Initial commit — KC868-A2 contrôleur solaire ESP32
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>
2026-05-09 19:25:01 +02:00

13 KiB

consigne.md

Projet : Contrôleur solaire autonome KC868-A2 + Epever 4210N


Rôle de l'assistant

Tu es un expert en développement d'objets IoT ESP32 avec PlatformIO. Tu emploieras le français pour la discussion. Les commentaires de code seront en français.


1. Objectif du projet

Développer un système autonome basé sur une carte Kincony KC868-A2 (ESP32) permettant :

  • Lecture des données d'un régulateur solaire Epever 4210N via RS485 Modbus
  • Pilotage de 2 relais
  • Gestion de 2 boutons via contacts secs DI1 / DI2
  • Hébergement d'une interface web responsive adaptée smartphone
  • Fonctionnement autonome via point d'accès WiFi ESP32
  • Mise à jour firmware OTA via interface web
  • Moteur de règles programmable depuis l'interface web
  • Gestion d'un mode économie d'énergie / sleep
  • Système robuste tolérant aux erreurs RS485

Le système doit fonctionner sans internet.


2. Hardware utilisé

Carte principale

  • Kincony KC868-A2
  • ESP32-WROOM-32E intégré
  • 2 relais
  • RS485 intégré (MAX13487 — direction automatique, pas de pin DE/RE à gérer)
  • Entrées contacts secs DI1 / DI2
  • Alimentation 12V

Régulateur solaire

  • Epever Tracer 4210N
  • Communication Modbus RS485 via RJ45

3. GPIO KC868-A2

Extraits du schéma bloc officiel de la carte :

Fonction GPIO Notes
Relay 1 GPIO15 Actif haut
Relay 2 GPIO2 ⚠️ Pin de boot — doit être HIGH au démarrage
RS485 TXD GPIO32 Vers MAX13487
RS485 RXD GPIO35 Depuis MAX13487 (input only)
DI1 GPIO36 Input only, pull-up interne
DI2 GPIO39 Input only, pull-up interne
SDA (I2C) GPIO4 Disponible si besoin
SCL (I2C) GPIO5 Disponible si besoin
1-Wire / DTH1 GPIO27 Disponible si besoin
DTH2 / LED GPIO26 Disponible si besoin

⚠️ GPIO2 : relais 2 est sur ce pin de boot. Le relais ne doit pas forcer GPIO2 à LOW au démarrage sous peine de bloquer l'ESP32 en mode flash.

⚠️ GPIO35 et GPIO36 / GPIO39 : ces pins sont en entrée uniquement (input-only) sur l'ESP32 — pas de sortie possible.

Tous les GPIO sont en logique 3,3V.


4. Développement logiciel

Environnement

  • Visual Studio Code
  • PlatformIO
  • Framework Arduino ESP32

Langages

  • C++
  • HTML / CSS / JavaScript

5. Configuration PlatformIO

platformio.ini

[env:kc868_a2]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
board_build.filesystem = littlefs

lib_deps =
    bblanchon/ArduinoJson
    emelianov/modbus-esp8266
    me-no-dev/ESPAsyncWebServer
    me-no-dev/AsyncTCP
    ayushsharma82/AsyncElegantOTA

Commandes utiles

pio run                        # Compiler
pio run --target upload        # Compiler et flasher
pio run --target monitor       # Moniteur série
pio run --target uploadfs      # Uploader le filesystem LittleFS (/data)
pio run --target clean         # Nettoyer le build

6. Architecture générale

Epever 4210N
    │
    └── RS485 (Modbus RTU) ──► ESP32 KC868-A2
                                    │
                        ┌───────────┼───────────┐
                        ▼           ▼           ▼
                   Moteur règles  Relais 1/2  Boutons DI1/DI2
                        │
                        ▼
                   Interface Web (WiFi AP 192.168.4.1)
                        │
                        ▼
                   Smartphone utilisateur

7. Ordre de développement validé

Étape 1 — WiFi + Interface Web + OTA

  • Point d'accès WiFi actif
  • Serveur web async avec pages statiques depuis LittleFS
  • OTA via /update

Étape 2 — Pilotage relais

  • API REST ON/OFF relais 1 et 2
  • Retour état relais dans le dashboard

Étape 3 — Gestion boutons DI1 / DI2

  • Lecture non-bloquante avec anti-rebond
  • DI1 : bascule mode auto / manuel
  • DI2 : commande manuelle relais

Étape 4 — Lecture RS485 Epever

  • Initialisation Serial2 (GPIO32 TX, GPIO35 RX)
  • Lecture périodique non-bloquante des registres Epever
  • Mise à jour du SystemState global

Étape 5 — Moteur de règles

  • Chargement règles depuis LittleFS (rules.json)
  • Évaluation périodique des conditions
  • Application des actions sur les relais

Étape 6 — Gestion sleep / économie d'énergie

  • Détection mode JOUR / NUIT via état Epever
  • Deep sleep la nuit, réveil périodique

8. Câblage

8.1 RS485

EPEVER RS485 A (D+)  ───── KC868-A2 A1 / RXI
EPEVER RS485 B (D-)  ───── KC868-A2 B1 / TXO
EPEVER GND           ───── KC868-A2 GND (recommandé)

⚠️ Ne jamais connecter une alimentation provenant du RJ45 Epever.

8.2 Boutons (contacts secs)

DI1 ----[Bouton]---- GND
DI2 ----[Bouton]---- GND
  • DI1 : mode auto / manuel
  • DI2 : commande manuelle relais

8.3 Relais

  • Relay 1 (GPIO15) → charge 1
  • Relay 2 (GPIO2) → charge 2

9. WiFi

Mode point d'accès (AP)

SSID : KC868_SOLAR
IP   : 192.168.4.1

Le smartphone se connecte directement à la carte, sans routeur ni internet.


10. Interface Web

Objectifs

  • Responsive smartphone (mobile-first)
  • Interface légère — pas de framework lourd (pas de React, Vue, etc.)
  • Mise à jour dynamique par fetch JSON sans rechargement de page
  • Vanilla JS + CSS simple

Sections

[ Dashboard ]
  - Tension batterie (V)
  - Tension PV (V)
  - Courant PV (A)
  - Etat jour / nuit
  - Etat relais 1 et 2
  - Etat RS485 (OK / erreur)

[ Commandes ]
  - ON/OFF relais 1 et 2
  - Bascule mode auto / manuel

[ Programmation ]
  - Liste des règles actives
  - Ajout / suppression règle

[ Configuration ]
  - Activation sleep
  - Seuils batterie
  - Intervalle de lecture RS485
  - Temporisations règles

[ Firmware ]
  - OTA update (upload .bin)

[ Debug ]
  - Logs série
  - Erreurs RS485
  - Etats DI1 / DI2

11. OTA (mise à jour firmware)

http://192.168.4.1/update
  • Upload fichier .bin depuis l'interface web
  • Redémarrage automatique après mise à jour
  • Protection par mot de passe

12. Communication Modbus Epever

Paramètres

  • Baudrate : 9600
  • Adresse esclave : 1
  • Modbus RTU (half-duplex)
  • Serial2 : TX=GPIO32, RX=GPIO35

Registres utiles

Donnée Registre Unité Facteur
Tension PV 0x3100 V ÷100
Courant PV 0x3101 A ÷100
Puissance PV 0x3102 W ÷100
Tension batterie 0x3104 V ÷100
Courant de charge 0x3106 A ÷100
Etat jour/nuit 0x200C bit 0 = nuit
Etat charge batterie 0x3201 bits

Timing de lecture

  • Intervalle recommandé : toutes les 5 secondes
  • Timeout réponse : 200 ms maximum
  • Retry : 2 tentatives maximum

13. Gestion des erreurs RS485

Règle critique

Une erreur RS485 ne doit jamais bloquer :

  • le serveur web
  • le pilotage relais
  • les boutons
  • le moteur de règles

Interdit

// JAMAIS de boucle bloquante
while (!response) { }
delay(x);

Comportement attendu

  • Lecture périodique pilotée par millis()
  • Timeout court (200 ms)
  • Maximum 2 retries
  • En cas d'échec : conserver la dernière valeur valide, passer rs485_ok = false
  • L'interface web affiche l'état RS485

14. Etat système global

struct SystemState {
    // Données Epever
    float battery;        // Tension batterie (V)
    float pv;             // Tension PV (V)
    float pvCurrent;      // Courant PV (A)
    bool sun;             // true = jour

    // Relais
    bool relay1;
    bool relay2;

    // Boutons
    bool di1;
    bool di2;

    // Santé RS485
    bool rs485_ok;
    unsigned long last_update;  // millis() de la dernière lecture OK
};

15. Pilotage relais

  • ON/OFF manuel depuis l'interface web
  • Pilotage automatique via moteur de règles
  • Pilotage manuel via boutons DI1/DI2
  • État affiché en temps réel dans le dashboard

16. Boutons DI1 / DI2

  • Anti-rebond logiciel (50 ms)
  • DI1 : bascule mode auto ↔ manuel
  • DI2 : en mode manuel, toggle relais 1
  • En mode auto : les règles reprennent le contrôle

17. Moteur de règles

Structure logique

SI (conditions)
ALORS (action)
AVEC (délai optionnel en secondes)

Conditions possibles

  • Soleil (jour/nuit)
  • Batterie > seuil
  • Batterie < seuil
  • Etat relais
  • Etat DI

Actions possibles

  • Activer relais 1 ou 2
  • Désactiver relais 1 ou 2

Exemple règle

SI soleil ET batterie > 13V → ALORS relais1 ON
SI soleil ET batterie > 13V → ATTENDRE 3600s → ALORS relais2 ON

Format JSON (stocké dans LittleFS rules.json)

[
  {
    "id": 1,
    "enabled": true,
    "sun": true,
    "battery_min": 13.0,
    "battery_max": 0,
    "relay": 1,
    "state": true,
    "delay": 0
  }
]
Champ Type Description
id int Identifiant unique
enabled bool Règle active ou non
sun bool Condition soleil (true=jour, false=nuit)
battery_min float Seuil min batterie en V (0 = ignoré)
battery_max float Seuil max batterie en V (0 = ignoré)
relay int Numéro relais (1 ou 2)
state bool true = ON, false = OFF
delay int Délai avant action (secondes)

Timing des règles

// Évaluation pilotée par millis(), jamais par delay()
if (millis() - lastRuleEval > RULE_INTERVAL_MS) {
    evaluerRegles();
    lastRuleEval = millis();
}

18. Gestion de l'énergie

Mode JOUR

WiFi ON
Serveur web ON
Lecture Epever active (toutes les 5s)
Règles actives

Mode NUIT

WiFi OFF
Serveur web OFF
Deep sleep
Réveil périodique (configurable, ex: 10 min)
Lecture Epever au réveil
Si toujours nuit → retour deep sleep

Paramètres configurables

  • Activation / désactivation du sleep
  • Intervalle de réveil (secondes)
  • Seuil de détection soleil (valeur registre 0x200C)
  • Mode : deep sleep ou light sleep

Contraintes deep sleep

  • Deep sleep = reboot complet de l'ESP32
  • UART indisponible pendant le sleep
  • Les relais conservent leur état (verrouillage mécanique)
  • Variables RAM perdues au réveil → sauvegarder en RTC memory si besoin

19. Consommation estimée

Mode Consommation
Normal 1.8 à 4 W
Sleep 0.1 à 0.6 W

20. Structure projet PlatformIO

/src
  main.cpp          ← boucle principale, init, dispatcher
  wifi.cpp          ← AP WiFi
  webserver.cpp     ← serveur HTTP async, endpoints REST
  ota.cpp           ← mise à jour OTA
  modbus.cpp        ← lecture RS485 Epever non-bloquante
  relais.cpp        ← contrôle GPIO relais
  rules.cpp         ← évaluation moteur de règles
  sleep.cpp         ← gestion deep sleep
  buttons.cpp       ← lecture DI1/DI2 avec anti-rebond

/include
  config.h          ← constantes GPIO, SSID, intervalles
  state.h           ← déclaration SystemState

/data
  index.html        ← interface web principale
  style.css
  app.js            ← fetch JSON, mise à jour dynamique
  rules.json        ← règles persistées (LittleFS)

21. Contraintes de conception

Non-bloquant partout

Toute la logique doit utiliser millis() et des machines à états. Jamais de delay() ni de boucle d'attente.

RS485 half-duplex

  • Le MAX13487 gère automatiquement la direction (pas de pin DE)
  • Ne pas lire trop fréquemment : respecter l'intervalle de 5 secondes
  • Bien gérer le timeout de 200 ms par requête Modbus

GPIO2 (Relay 2)

  • GPIO2 est un pin de strapping de boot sur ESP32
  • S'assurer que le relais ne tire pas GPIO2 à LOW au démarrage

LittleFS

  • Le filesystem doit être uploadé séparément : pio run --target uploadfs
  • La partition LittleFS doit être configurée dans platformio.ini

22. Evolutions possibles

  • MQTT / Home Assistant
  • Historique graphique (Chart.js)
  • Mode STA (connexion au routeur existant)
  • Accès distant VPN
  • Conditions avancées ET / OU dans les règles
  • Gestion des priorités entre règles
  • Notifications push

23. Objectif final

Le système final doit être :

  • autonome — fonctionne sans internet ni serveur externe
  • robuste — tolérant aux erreurs RS485 et aux redémarrages
  • configurable — réglable depuis un smartphone
  • optimisé énergie — mode sleep la nuit
  • extensible — architecture modulaire facilitant les ajouts
  • maintenable — code commenté en français, structure claire