From 7aa8cd2a1c391c6f2ddb66632186ebb2d79f376f Mon Sep 17 00:00:00 2001 From: Gilles Soulier Date: Sat, 23 May 2026 14:58:24 +0200 Subject: [PATCH] init: structure initiale du projet esp_jardin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spec, plan d'implémentation, design system, documentation de déploiement. Co-Authored-By: Claude Sonnet 4.6 --- .gitignore | 6 + CLAUDE.md | 99 ++ Fichier de Consignes - esp_jardin.md | 167 ++ README.md | 185 +++ amelioration.md | 1 + design_system/README.md | 304 ++++ design_system/components/ui-kit.jsx | 656 ++++++++ design_system/consigne_design_system.md | 363 ++++ design_system/examples/exemple-minimal.html | 115 ++ design_system/examples/exemple-tout.html | 1015 ++++++++++++ design_system/tokens/tokens.css | 204 +++ design_system/tokens/tokens.gnome.css | 378 +++++ design_system/tokens/tokens.json | 136 ++ .../plans/2026-05-23-esp-jardin-firmware.md | 1468 +++++++++++++++++ .../2026-05-23-esp-jardin-firmware-design.md | 261 +++ feature.md | 54 + plan.md | 77 + platformio.ini | 14 + 18 files changed, 5503 insertions(+) create mode 100644 .gitignore create mode 100644 CLAUDE.md create mode 100644 Fichier de Consignes - esp_jardin.md create mode 100644 README.md create mode 100644 amelioration.md create mode 100644 design_system/README.md create mode 100644 design_system/components/ui-kit.jsx create mode 100644 design_system/consigne_design_system.md create mode 100644 design_system/examples/exemple-minimal.html create mode 100644 design_system/examples/exemple-tout.html create mode 100644 design_system/tokens/tokens.css create mode 100644 design_system/tokens/tokens.gnome.css create mode 100644 design_system/tokens/tokens.json create mode 100644 docs/superpowers/plans/2026-05-23-esp-jardin-firmware.md create mode 100644 docs/superpowers/specs/2026-05-23-esp-jardin-firmware-design.md create mode 100644 feature.md create mode 100644 plan.md create mode 100644 platformio.ini diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c5ca1ca --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.pio +.superpowers/ +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..2a8d608 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,99 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. tu t'exprimera uniquement en francais, les page web et les commentaire seront en francais +brainstorming + recherche web -> plan.md et feature.md +ecrire un fichier readme.md de deploiement + +## Project + +**esp_jardin** — ESP32 firmware for a garden environmental monitoring station. Acquires temperatures from 3 DS18B20 sensors on OneWire (GPIO 4), stores 24h rolling history in RAM, and exposes a real-time web interface (WebSocket) and a REST API. + +Full specifications: [`Fichier de Consignes - esp_jardin.md`](Fichier\ de\ Consignes\ -\ esp_jardin.md) + +## Build & Development Commands + +```bash +pio run # Compile only +pio run -t upload # Compile + flash via USB +pio device monitor # Open serial monitor (115200 baud) +pio run -t upload && pio device monitor # Flash then monitor +pio run -t clean # Clean build artifacts +``` + +Environment: `esp32dev` (Espressif32, Arduino framework) — defined in [platformio.ini](platformio.ini). + +## Target Architecture + +The project must be **modular** — no logic in `main.cpp` beyond initialisation and the state machine loop. + +``` +include/ + config.h # Constants and structs derived from parametrage.md + network.h # WiFi (STA/AP hybrid), mDNS, OTA, WebSockets + sensors.h # OneWire, DallasTemperature, circular RAM buffer + web_server.h # HTTP routing, REST API declarations + mqtt_manager.h # MQTT client declarations +src/ + main.cpp # setup(), loop() — state machine only, no blocking + network.cpp + sensors.cpp + web_server.cpp + mqtt_manager.cpp +data/ + index.html # Served from SPIFFS/LittleFS +design_system/ # CSS tokens, React UI-kit (read-only reference) +``` + +## Critical Constraints + +**No blocking code** — `delay()` is forbidden. Use `millis()` for all timing. + +**Temperature handling:** +- Format to 1 decimal place (`%.1f`) +- Discard sensor errors: −127.0°C (CRC fail) and 85.0°C (power-on default) +- History: circular buffer of 288 points/sensor (uint32_t timestamp + 2× float = 12 bytes each) + +**WiFi:** Boot in STA mode; fall back to AP (`ESP_CHEF_JARDIN`) after 30s timeout. Reconnect loop must never block the main loop. + +**WebSocket:** Push new readings as JSON to all connected clients immediately after acquisition. No HTTP polling for real-time data. + +**MQTT per-sensor:** Each sensor publishes independently with deadband filtering (skip publish if delta < threshold AND max interval not elapsed). + +**REST endpoints:** +- `GET /api/status` — WiFi RSSI, uptime, free RAM +- `GET /api/temperatures` — current readings as JSON +- `GET /api/history` — full 24h buffer as JSON array + +## GPIO Allocation + +| GPIO | Function | Notes | +|------|----------|-------| +| 4 | OneWire bus (DS18B20) | 4.7kΩ pull-up to 3.3V required | +| 21 | I2C SDA (future) | BH1750 / SHT31 | +| 22 | I2C SCL (future) | | +| 32/33 | ADC1 (future) | Soil moisture — ADC1 only (ADC2 conflicts with WiFi) | +| 25/26 | Digital out (future) | Relays / actuators | +| 14/27 | Interrupts (future) | Rain gauge / push button | + +## Web Interface — Design System + +The web UI must use the **Gruvbox Seventies** design system from [`design_system/`](design_system/). Full rules in [`design_system/consigne_design_system.md`](design_system/consigne_design_system.md). + +**Absolute rules:** +- Always use CSS variables — never hardcode hex colors (`var(--accent)` not `#fe8019`) +- Always declare `data-theme="dark"` (or `"light"`) on `` or a parent wrapper +- Use existing components from `ui-kit.jsx` — check before creating anything new +- Icons: use `` with mapped names — no emoji, no inline SVG +- Fonts: `--font-ui` (Inter) for UI, `--font-mono` (JetBrains Mono) for numeric data, `--font-terminal` (Share Tech Mono) for logs +- Tiles: `border-radius: 10–12px`, use `className="glass"` for styling +- Labels: uppercase + `letter-spacing: 0.08em` + +**For temperature display:** `` for 24h history, `` or `` for live KPIs, `` for sensor faults. + +Chart.js (or equivalent via CDN) initialises from `/api/history` then increments via WebSocket messages. + +## Code Style + +- Comments in French (project convention from specs) +- All configurations and default values sourced from `parametrage.md` → reflected in `config.h` +- OTA upload protected with a password diff --git a/Fichier de Consignes - esp_jardin.md b/Fichier de Consignes - esp_jardin.md new file mode 100644 index 0000000..b49ebe6 --- /dev/null +++ b/Fichier de Consignes - esp_jardin.md @@ -0,0 +1,167 @@ +# **CAHIER DES CHARGES & CONSIGNES DE DÉVELOPPEMENT : ESP\_JARDIN** + +Ce document sert de prompt maître (Master Prompt) et de cahier des charges technique pour guider le développement de l'application embarquée esp\_jardin. + +## **1\. Contexte, Vision & Objectifs** + +L'objectif est de concevoir le firmware d'une station d'acquisition environnementale autonome basée sur un microcontrôleur **ESP32**, nommée **esp\_jardin**. +Cet appareil doit acquérir les températures de trois sondes DS18B20, conserver un historique glissant de 24 heures en RAM, et proposer une double interface d'accès aux données : + +1. Une **interface web locale moderne, responsive et en temps réel** (via WebSockets), accessible depuis les ordinateurs et smartphones. +2. Une **API REST ultra-rapide** pour l'intégration automatique (ex: serveurs MCP, scripts d'automation, Home Assistant). + +Le projet est développé sous **VS Code avec l'extension PlatformIO** en s'appuyant sur le **framework Arduino (C++)**, jugé optimal pour l'écosystème de librairies asynchrones requis. + +tu debutera par une phase de recherche sur internet, suivi d’un brainstorming avec question sur les lib a utiliser ( avantage inconvenient) , les sondes a utiliser, le cablage, les evolution futures du projet). ensuite tu mettre a jours le dossier du projet en respectant l’architecture de plateformio, tu mettra a jours le parametrage de platformio pour la carte utilisée, ensuite tu creera le plan de deploiement. pense bien a faire l’analyse du design\_system. verifier la coherence de ce fichier de consigne avec les bonnes pratiques et mettre ajours si besoin. + +## **2\. Phase 1 : Analyse Matérielle, GPIO & Évolutivité** + +L'ESP32 possède des caractéristiques électriques et de boot strictes (Strapping Pins, Input-only pins, restrictions d'usage de l'ADC2 avec le WiFi). La sélection des GPIO pour les sondes actuelles et les extensions futures a été analysée de manière à préserver la stabilité du système. + +### **Tableau d'allocation et de mapping des GPIO** + +| GPIO Natif (ESP32) | Broche Standard (DevKit V1) | Broche alternative (Notation Arduino) | Fonction Actuelle | Type & Caractéristiques | Évolutivité / Usage Futur Prévu | +| :---- | :---- | :---- | :---- | :---- | :---- | +| **GPIO 4** | D4 | 4 | **Bus OneWire (DS18B20)** | Numérique I/O | Supporte l'ajout en parallèle d'autres sondes DS18B20. | +| **GPIO 21** | D21 | 21 | *Libre* | I/O (Bus I2C SDA) | Capteur de luminosité (BH1750) ou humidité/T° d'air (SHT31). | +| **GPIO 22** | D22 | 22 | *Libre* | I/O (Bus I2C SCL) | Horloge RTC externe ou capteurs I2C partagés. | +| **GPIO 32** | D32 | 32 | *Libre* | ADC1\_CH4 (Analogique) | Capteur d'humidité de sol (capacitif ou résistif). | +| **GPIO 33** | D33 | 33 | *Libre* | ADC1\_CH5 (Analogique) | Second capteur d'humidité ou entrée analogique. | +| **GPIO 25** | D25 | 25 | *Libre* | Numérique I/O / DAC | Commande d'actionneur / Relais (ex : Électrovanne arrosage). | +| **GPIO 26** | D26 | 26 | *Libre* | Numérique I/O / DAC | Commande d'actionneur 2 / Relais ou avertisseur sonore. | +| **GPIO 14** | D14 | 14 | *Libre* | Numérique (Interruption) | Capteur d'impulsions (ex: Pluviomètre à augets). | +| **GPIO 27** | D27 | 27 | *Libre* | Numérique (Interruption) | Bouton poussoir physique (ex: Reset paramètres ou forçage AP). | + +*Note sur le bus OneWire : Une résistance de pull-up externe de 4.7kΩ est obligatoire entre le VCC (3.3V) et la broche de données (GPIO 4).* + +## **3\. Architecture Logicielle & Arborescence PlatformIO** + +L'architecture du projet doit être modulaire (fichiers .h et .cpp séparés) pour éviter de surcharger le point d'entrée principal. +esp\_jardin/ +├── platformio.ini \# Configuration PlatformIO et dépendances bibliothèques +├── parametrage.md \# Fichier source des configurations par défaut (SSID, Topics, Intervalles...) +├── include/ +│ ├── config.h \# Généré d'après parametrage.md (Structures, constantes globales) +│ ├── network.h \# Déclarations WiFi (AP/STA), mDNS, OTA, WebSockets +│ ├── sensors.h \# Déclarations OneWire, DallasTemperature et gestion d'historique RAM +│ ├── web\_server.h \# Déclarations serveur HTTP, API REST +│ └── mqtt\_manager.h \# Déclarations client MQTT, logique de publication +├── src/ +│ ├── main.cpp \# Initialisation, machine à états et loop non bloquante +│ ├── network.cpp \# Gestion WiFi hybride, OTA, WebSockets +│ ├── sensors.cpp \# Acquisition T°C, validation métrologique, tampon circulaire RAM +│ ├── web\_server.cpp \# Routage endpoints REST, parsing JSON, service des pages web +│ └── mqtt\_manager.cpp \# Routage des messages MQTT, asynchronisme +├── data/ \# Fichiers optionnels pour SPIFFS/LittleFS (ex: CSS, JS, images) +│ └── index.html \# Page web dynamique responsive principale +└── design\_system/ \# Maquettes, styles CSS et frameworks JS fournis par le designer + └── ... + +## **4\. Source de Vérité Unique : parametrage.md** + +Toutes les configurations et constantes par défaut de l'application devront être implémentées d'après les valeurs suivantes, écrites dans parametrage.md à la racine : +\# Paramétrage Initial \- esp\_jardin + +\#\# Connexion WiFi +\- Mode Station (STA) : + \- SSID: "Mon\_Reseau\_WiFi" + \- PASS: "Mon\_Mot\_De\_Passe\_Securise" +\- Mode Access Point (AP de secours) : + \- AP\_SSID: "ESP\_CHEF\_JARDIN" + \- AP\_PASS: "Jardin2026" + \- Connection\_Timeout: 30000 ms (30 secondes) + +\#\# Acquisition & Fréquences +\- Fréquence de mesure (échantillonnage de base) : 10 secondes (10000 ms) +\- Taille de l'historique en RAM : 288 points par sonde (correspond à 24h avec 1 mesure échantillonnée toutes les 5 min pour le graphique). + +\#\# Broker MQTT +\- IP Broker: "10.0.0.3" +\- Port: 1883 +\- MQTT\_User: "" +\- MQTT\_Pass: "" + +\#\# Paramètres Spécifiques par Capteur (MQTT Custom) +\- Sonde 1 (Index 0 \- ex : Température Exterieur) : + \- Nom : "T°C Ext" + \- Topic: "maison/jardin/ext/temperature" + \- Intervalle de publication : 60000 ms (1 minute) + \- Variation minimale requise (Deadband) : 0.2 °C +\- Sonde 2 (Index 1 \- ex : Température Serre) : + \- Nom : "T°C Serre" + \- Topic: "maison/jardin/serre/temperature" + \- Intervalle de publication : 60000 ms (1 minute) + \- Variation minimale requise (Deadband) : 0.1 °C +\- Sonde 3 (Index 1 \- ex : Température du Sol) : + \- Nom : "T°C Sol" + \- Topic: "maison/jardin/sol/temperature" + \- Intervalle de publication : 60000 ms (1 minute) + \- Variation minimale requise (Deadband) : 0.1 °C + +## **5\. Spécifications Fonctionnelles Détaillées** + +### **5.1. Gestion de la connectivité réseau** + +1. **WiFi Hybride non-bloquant :** Au boot, l'ESP tente de se connecter en mode STA avec les identifiants fournis. S'il échoue après un temps d'attente spécifié, il initialise un point d'accès autonome (AP) nommé ESP\_CHEF\_JARDIN. +2. **mDNS :** L'appareil s'enregistre sur le réseau local. L'interface d'administration et les API doivent être joignables à l'adresse DNS multicast http://esp\_jardin.local. +3. **Mise à jour OTA :** Intégration de la bibliothèque ArduinoOTA avec mot de passe pour téléverser de nouveaux binaires à distance sans liaison physique USB. + +### **5.2. Acquisition, Traitement RAM & Validation Métrologique** + +1. **Précision numérique :** Les relevés de température doivent être formatés avec rigueur à **un seul chiffre après la virgule** (type float traité ou formaté via %.1f). +2. **Tableau Circulaire en RAM (Historique 24h) :** + * L'historique des 24 heures glissantes doit utiliser un tableau circulaire (CircularBuffer ou logique d'indexation fixe dans un tableau de 288 structures par sonde) pour s'affranchir de l'usure de la mémoire Flash. + * *Validation mémoire :* Chaque élément stockant le timestamp (uint32\_t) \+ les deux températures (2x float) représente 12 octets. 288 mesures consomment \~3.45 Ko, ce qui est extrêmement sûr pour les 520 Ko de SRAM de l'ESP32 (impact \< 1%). +3. **Robustesse matérielle :** Gestion des pannes de sondes Dallas (vérification des CRC et interception des codes d'erreur matériels types \-127.0 ou 85.0). Ces valeurs invalides ne doivent pas être écrites en RAM ni envoyées au broker MQTT. + +### **5.3. Interface Web Interactive (Responsive & WebSocket)** + +1. **WebSocket Temps Réel :** Dès qu'une nouvelle mesure est validée sur le bus OneWire, la valeur rafraîchie est sérialisée en JSON et poussée instantanément sur tous les clients connectés par WebSocket. Le polling HTTP est proscrit pour le temps réel. +2. **Design System & Adaptabilité :** + * L'interface doit s'appuyer sur la charte et les classes CSS du dossier design\_system. + * L'application Web doit être fluide et ergonomique sur les écrans étroits (smartphones) comme sur les écrans larges (moniteurs / laptops). +3. **Graphique Glissant :** Intégration d'un graphique (Chart.js ou équivalent via un CDN optimisé) représentant les 24h de mesures stockées en RAM. À l'ouverture, le graphique est initialisé avec l'historique complet (requête REST API), puis s'incrémente au fil de l'eau via les réceptions WebSocket. +4. **Console d'Administration :** Intégration d'un formulaire pour ajuster dynamiquement l'intervalle d'échantillonnage et les configurations des serveurs MQTT. + +### **5.4. API REST Standardisée** + +Créer des endpoints de requêtes HTTP GET pour la lecture directe et l'intégration externe (scripts automatisés, serveurs de protocoles MCP) : + +* **GET /api/status :** Renvoie l'état système (RSSI WiFi, Uptime, Mémoire RAM libre). +* **GET /api/temperatures :** Renvoie l'état instantané au format standardisé : + {"sonde\_1": 19.3, "sonde\_2": 11.8, "unit": "C"}. +* **GET /api/history :** Renvoie l'historique complet sous forme de tableau d'objets JSON pour reconstruire la courbe sur des serveurs tiers. + +### **5.5. Publication MQTT Avancée** + +Chaque capteur doit être géré de manière indépendante pour sa transmission : + +1. **Cycles asynchrones :** La publication s'effectue à l'aide d'une tâche temporelle non bloquante (utilisation stricte de millis()). +2. **Filtrage "Deadband" :** Si la différence absolue entre la température actuelle et la dernière valeur publiée est inférieure au seuil de variation (ex : 0.2°C pour la sonde 1), la publication est ignorée pour limiter la saturation de la bande passante, sauf si l'intervalle maximal de secours est dépassé. + +## **6\. Plan de Déploiement, Validation & Tests (Livrables attendus)** + +### **Étape A : Initialisation (Rapport d'analyse d'entrée)** + +L'agent doit formaliser l'architecture du projet et les fichiers platformio.ini et parametrage.md initiaux. + +### **Étape B : Production du Code Source Modulaire** + +Production des fichiers de code .h et .cpp sans **aucun blocage** de type delay(). L'agent doit commenter le code en français de manière didactique. + +### **Étape C : README de déploiement et d'utilisation** + +Rédaction d'un fichier README.md complet intégrant : + +1. Schéma électrique simplifié de connexion (rappel de la résistance pull-up 4.7kΩ). +2. Directives de compilation et d'écriture de la configuration. +3. Guide de première connexion au point d'accès de secours ESP\_CHEF\_JARDIN et configuration. +4. Schémas de données pour l'API REST. + +### **Étape D : Protocole de validation de robustesse** + +Section expliquant comment tester : + +1. La déconnexion sauvage du WiFi (le programme doit tenter une reconnexion automatique en boucle sans bloquer la boucle principale). +2. La déconnexion d'une des sondes physiques (affichage d'un code erreur visuel sur l'interface au lieu d'une fausse température de \-127°C). +3. L'indisponibilité temporaire du broker MQTT (mise en file d'attente ou rejet propre sans faire planter le microcontrôleur). \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..98c5e31 --- /dev/null +++ b/README.md @@ -0,0 +1,185 @@ +# ESP Jardin — Station de monitoring environnemental + +Firmware ESP32 pour une station d'acquisition de températures avec interface web temps réel, API REST et publication MQTT. + +--- + +## Matériel requis + +| Composant | Quantité | Notes | +|---|---|---| +| ESP32 DevKit V1 | 1 | ou équivalent 38 broches | +| Sonde DS18B20 | 3 | waterproof recommandé | +| Résistance 4.7 kΩ | 1 | pull-up obligatoire | +| Câbles Dupont | — | | + +### Câblage + +``` +DS18B20 (×3 en parallèle) + VCC → 3.3V + GND → GND + DATA → GPIO 4 + +Résistance 4.7 kΩ entre 3.3V et GPIO 4 (pull-up) +``` + +> **Important :** Sans la résistance pull-up, les sondes retournent systématiquement −127°C. + +--- + +## Prérequis logiciels + +- [VS Code](https://code.visualstudio.com/) + extension [PlatformIO](https://platformio.org/) +- Python 3 (requis par PlatformIO) + +--- + +## Installation et premier flash + +### 1. Configurer le WiFi + +Éditer `include/config.h` : + +```cpp +#define WIFI_SSID "VotreSSID" +#define WIFI_PASS "VotreMotDePasse" +``` + +### 2. Configurer le broker MQTT (optionnel) + +Dans `include/config.h` : + +```cpp +#define MQTT_BROKER "192.168.1.x" // IP du broker Mosquitto +#define MQTT_PORT 1883 +``` + +### 3. Compiler et flasher + +```bash +# Flash du firmware +pio run -t upload + +# Flash de l'interface web (LittleFS) +pio run -t uploadfs + +# Moniteur série (débogage) +pio device monitor +``` + +### 4. Vérifier le boot + +``` +[BOOT] esp_jardin v1.0 — démarrage... +[WIFI] Connexion STA → SSID: VotreSSID +[WIFI] Connecté — IP: 192.168.1.42 +[mDNS] Accessible via http://esp_jardin.local +[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 +``` + +--- + +## Accès à l'interface + +Une fois connecté à votre réseau : + +``` +http://esp_jardin.local # Via mDNS +http://192.168.1.42 # Via IP directe +``` + +--- + +## Mode Access Point de secours + +Si le WiFi est indisponible au démarrage, l'ESP crée automatiquement un point d'accès : + +| Paramètre | Valeur | +|---|---| +| SSID | `ESP_CHEF_JARDIN` | +| Mot de passe | `Jardin2026` | +| IP de l'interface | `192.168.4.1` | + +L'interface web reste accessible. Le broker MQTT est désactivé en mode AP. +L'ESP tente de se reconnecter au WiFi STA toutes les 60 secondes. + +--- + +## API REST + +| 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) | +| POST | `/api/config` | Mise à jour configuration | + +**Exemple `/api/temperatures` :** +```json +{ "sonde_1": "19.3", "sonde_2": "28.7", "sonde_3": null, "unit": "C" } +``` +`null` = sonde en erreur ou déconnectée. + +**Exemple POST `/api/config` :** +```bash +curl -X POST http://esp_jardin.local/api/config \ + -H "Content-Type: application/json" \ + -d '{"intervalleMs": 5000, "mqttBroker": "10.0.0.3", "mqttPort": 1883}' +``` + +--- + +## MQTT + +Topics publiés (retain=true) : + +| Sonde | Topic | Deadband | +|---|---|---| +| 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 | + +Payload : valeur numérique en string, ex : `"19.3"`. Les erreurs ne sont jamais publiées. + +--- + +## Mise à jour OTA (après déploiement) + +```bash +# Remplacer 192.168.1.42 par l'IP réelle de la carte +pio run -t upload --upload-port 192.168.1.42 + +# Mot de passe OTA : Jardin2026 +``` + +Le mot de passe OTA peut être changé dans `include/config.h` (`OTA_PASS`) et `platformio.ini` (`upload_flags = --auth=...`). + +--- + +## GPIO disponibles pour extensions futures + +| GPIO | Usage futur | Interface | +|---|---|---| +| 21 / 22 | Capteur BH1750 (luminosité) ou SHT31 (T°/Humidité) | I2C | +| 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 34–39) quand le WiFi est actif — conflit hardware ESP32. + +--- + +## Dépannage + +| 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 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` | diff --git a/amelioration.md b/amelioration.md new file mode 100644 index 0000000..da131d1 --- /dev/null +++ b/amelioration.md @@ -0,0 +1 @@ +- deepsleep ? \ No newline at end of file diff --git a/design_system/README.md b/design_system/README.md new file mode 100644 index 0000000..a0ee628 --- /dev/null +++ b/design_system/README.md @@ -0,0 +1,304 @@ +# mon design system — Gruvbox seventies + +> Design system rétro-futuriste pour applications de monitoring, ops, IoT, domotique. +> Orange brûlé, fond brun délavé en sombre / gris clair usé en clair. +> **Version 1.0** · deux thèmes (dark + light), 14+ composants React, palette GTK pour GNOME. + +--- + +## 🚀 Démarrage rapide (web) + +```html + + + + + + + + + + + + + + + + + + +
+ + + + + +``` + +Pour voir tout fonctionner, ouvre `examples/exemple-minimal.html`. + +--- + +## 📂 Contenu du package + +``` +export/ +├── README.md ← Ce fichier +├── consigne_design_system.md ← Brief pour agents IA (Claude, ChatGPT…) +├── tokens/ +│ ├── tokens.css ← Variables CSS web (dark + light) +│ ├── tokens.gnome.css ← GTK 4 / libadwaita (apps GNOME) +│ └── tokens.json ← Format générique (Tailwind, Figma…) +├── components/ +│ └── ui-kit.jsx ← 14 composants React (Button, IconButton, Toggle, Tooltip, +│ StatusLed, BatteryGauge, RadialGauge, BigRadialGauge, +│ Popup, TreeNav, Sparkline, LineChart, Icon, …) +└── examples/ + └── exemple-minimal.html ← Démo minimale autoportante +``` + +--- + +## 🎨 Ce qui est paramétrable + +### 1. Thème global + +```html + +``` + +Tu peux mettre `data-theme` sur **n'importe quel parent** pour basculer un sous-arbre uniquement (utile pour une preview en mode opposé dans un menu de réglages). + +### 2. Toutes les couleurs (CSS variables) + +Édite `tokens.css` ou surcharge dans ton propre CSS : + +```css +:root[data-theme="dark"] { + --accent: #fe8019; /* Couleur principale (orange seventies) */ + --accent-soft: #d65d0e; + --bg-1: #2a231d; /* Fond app */ + --bg-3: #3c332a; /* Cartes */ + --ink-1: #f2e5c7; /* Texte */ + --ok: #4dbb26; + --warn: #fabd2f; + --err: #fb4934; + --blue: #3db0d1; /* Datavis additionnel */ + --purple: #c882c8; +} +``` + +**4 statuts** (ok / warn / err / info) + **2 couleurs datavis** (blue / purple) + **6 niveaux de fond** + **4 niveaux d'encre** + **3 niveaux de bordure**. + +### 3. Polices + +Trois familles, toutes substituables : + +| Variable | Usage | Défaut | +|-----------------|-------------------------------------|---------------------| +| `--font-ui` | Interface (titres, corps, boutons) | Inter | +| `--font-mono` | Données, code, valeurs numériques | JetBrains Mono | +| `--font-terminal` | Logs, terminal embarqué, vibe rétro | Share Tech Mono | + +Pour changer, remplace simplement les `@import` Google Fonts et redéfinis les variables. + +### 4. Ombres et relief + +```css +--tile-3d /* Relief 3D marqué pour cartes */ +--shadow-1, -2, -3 /* Niveaux d'élévation */ +--shadow-press /* Inset pour état pressé */ +--hover-glow /* Halo accent au survol */ +``` + +### 5. Composants — props paramétrables + +Chaque composant accepte des props pour personnaliser sans toucher au CSS. Exemples : + +```jsx + + + + + + + + + + + + + Contenu + + + +``` + +Voir la doc complète des props : `Component Reference.html` dans le projet original. + +--- + +## 🐧 Utilisation dans une app GNOME (GTK 4 / libadwaita) + +Charge `tokens/tokens.gnome.css` comme provider CSS au démarrage de l'app. + +**Python (PyGObject)** : +```python +from gi.repository import Gtk, Gdk + +css_provider = Gtk.CssProvider() +css_provider.load_from_path("tokens.gnome.css") +Gtk.StyleContext.add_provider_for_display( + Gdk.Display.get_default(), + css_provider, + Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION +) +``` + +**GJS** : +```javascript +const provider = new Gtk.CssProvider(); +provider.load_from_path('tokens.gnome.css'); +Gtk.StyleContext.add_provider_for_display( + Gdk.Display.get_default(), + provider, + Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION +); +``` + +**Rust (gtk4-rs)** : +```rust +let provider = gtk::CssProvider::new(); +provider.load_from_path("tokens.gnome.css"); +gtk::style_context_add_provider_for_display( + &gdk::Display::default().unwrap(), + &provider, + gtk::STYLE_PROVIDER_PRIORITY_APPLICATION, +); +``` + +Le fichier override directement les couleurs sémantiques de libadwaita (`@window_bg_color`, `@accent_color`, etc.) ET ajoute des styles spécifiques pour les widgets courants : `button.suggested-action`, `entry`, `switch`, `scale`, `progressbar`, `notebook`, `popover`… + +Classes CSS supplémentaires à appliquer via `add_css_class()` : +- `.tile` / `.card` — Tuile en relief 3D +- `.mono` — Texte monospace JetBrains Mono +- `.terminal` — Texte terminal Share Tech Mono +- `.status.ok` / `.status.warn` / `.status.error` / `.status.info` — Badge de statut + +--- + +## 🔧 Intégration dans d'autres outils + +### Tailwind CSS + +Convertis `tokens.json` en `tailwind.config.js` : + +```js +const tokens = require('./tokens/tokens.json'); +module.exports = { + theme: { + extend: { + colors: { + accent: tokens.themes.dark.accent.primary.value, + ok: tokens.themes.dark.status.ok.value, + // … + }, + fontFamily: { + sans: [tokens.typography.fonts.ui.family, ...tokens.typography.fonts.ui.fallback], + mono: [tokens.typography.fonts.mono.family], + }, + }, + }, +}; +``` + +### Figma / outils de design + +`tokens.json` suit un schéma compatible avec la plupart des plugins de tokens (Figma Tokens, Style Dictionary). Importe-le directement. + +### Variables Sass / SCSS + +```scss +@use 'sass:map'; +$tokens: ( + accent: #fe8019, + bg-1: #2a231d, + ok: #4dbb26, +); +// … +``` + +--- + +## ⚙️ Personnalisation avancée + +### Créer un thème dérivé + +Duplique `tokens.css`, change le nom du sélecteur (`[data-theme="ocean"]` par exemple) et modifie les variables. Charge les deux fichiers — `data-theme` choisira automatiquement. + +### Ajouter une couleur status custom + +```css +:root[data-theme="dark"] { + --critical: #ff0080; + --critical-glow: rgba(255, 0, 128, 0.45); +} +``` + +Utilisable ensuite partout : `` nécessite une PR dans `ui-kit.jsx` (carte `map` dans `StatusLed`), mais en raw CSS tu peux utiliser la variable directement. + +### Désactiver les effets + +Tous les effets de `transition` / `transform` / `box-shadow` sont concentrés dans les classes `.interactive`, `.bg-hover`, `.gauge-hover`. Surcharge-les en CSS si besoin : + +```css +.interactive { transition: none !important; } +``` + +--- + +## ✅ Checklist d'intégration + +- [ ] Polices Google Fonts chargées (Inter, JetBrains Mono, Share Tech Mono) +- [ ] Font Awesome 6 chargé +- [ ] `tokens.css` (web) **ou** `tokens.gnome.css` (GTK) chargé +- [ ] Attribut `data-theme="dark"` (ou "light") sur `` ou un parent +- [ ] React 18 + Babel chargés (uniquement pour `ui-kit.jsx`) +- [ ] `ui-kit.jsx` chargé en `type="text/babel"` + +--- + +## 📋 Statuts du système + +| Couleur | Token | Hex (dark) | Hex (light) | Usage | +|---------|--------|------------|-------------|-----------------------------| +| Accent | `--accent` | `#fe8019` | `#af3a03` | Primaire, focus, sélection | +| OK | `--ok` | `#4dbb26` | `#3c911c` | Succès, état nominal | +| Warn | `--warn` | `#fabd2f` | `#b57614` | Attention, latence élevée | +| Err | `--err` | `#fb4934` | `#9d0006` | Erreur, alerte critique | +| Info | `--info` | `#83a598` | `#427b58` | Information neutre | +| Blue | `--blue` | `#3db0d1` | `#2d82a3` | Datavis catégorie 2 | +| Purple | `--purple` | `#c882c8` | `#8c468c` | Datavis catégorie 3 | + +--- + +## 🤖 Pour les agents IA + +Si tu utilises ce design system avec une IA (Claude, GPT, Copilot, etc.), partage-lui le fichier **`consigne_design_system.md`**. Il y trouvera toutes les règles d'utilisation, conventions, contre-exemples à éviter. + +--- + +**Licence** · Usage libre dans tes projets. Pas de garantie. diff --git a/design_system/components/ui-kit.jsx b/design_system/components/ui-kit.jsx new file mode 100644 index 0000000..92f9e76 --- /dev/null +++ b/design_system/components/ui-kit.jsx @@ -0,0 +1,656 @@ +/* ============================================================ + ui-kit.jsx + Composants haute-fid Gruvbox Seventies. + Tout est purement décoratif/interactif côté composant. + Effets : transparence (glass), hover glow, click 3D, tooltips. + ============================================================ */ + +const { useState, useRef, useEffect } = React; + +/* ============================================================ + Icônes — Font Awesome 6 Free. + Mapping nom logique → classe FA. Le CSS de FA est chargé en CDN + dans le . Le composant garde la MÊME API qu'avant (name, + size, style) pour ne rien casser ailleurs. + ============================================================ */ +const ICON_MAP = { + cpu: 'microchip', + memory: 'memory', + disk: 'hard-drive', + network: 'network-wired', + clock: 'clock', + grid: 'table-cells', + list: 'list', + cog: 'gear', + alert: 'triangle-exclamation', + bell: 'bell', + server: 'server', + chart: 'chart-line', + bars: 'chart-simple', + terminal: 'terminal', + refresh: 'arrows-rotate', + play: 'play', + pause: 'pause', + power: 'power-off', + sun: 'sun', + moon: 'moon', + search: 'magnifying-glass', + close: 'xmark', + chevR: 'chevron-right', + chevL: 'chevron-left', + chevD: 'chevron-down', + chevU: 'chevron-up', + plus: 'plus', + filter: 'filter', + download: 'download', + folder: 'folder', + node: 'circle-nodes', + user: 'user', +}; + +const Icon = ({ name, size = 16, style }) => { + const fa = ICON_MAP[name] || 'circle-question'; + return ( +