📝 README professionnel pour présentation jury
This commit is contained in:
295
README.md
295
README.md
@@ -1,39 +1,282 @@
|
|||||||
# Projet EchoCharge (EcoCharge)
|
<p align="center">
|
||||||
|
<img src="https://img.shields.io/badge/⚡-EcoCharge-facc15?style=for-the-badge&labelColor=0f172a" alt="EcoCharge"/>
|
||||||
|
</p>
|
||||||
|
|
||||||
EcoCharge est une application web développée avec Python, Flask et PostgreSQL. Elle est entièrement conteneurisée avec Docker pour un déploiement et une exécution faciles.
|
<h1 align="center">🌱 EcoCharge — Station Solaire Autonome</h1>
|
||||||
|
|
||||||
## Prérequis
|
<p align="center">
|
||||||
|
<b>Plateforme de monitoring en temps réel d'une station solaire autonome,<br>
|
||||||
|
hébergée sur Raspberry Pi et alimentée par des capteurs ESP32.</b>
|
||||||
|
</p>
|
||||||
|
|
||||||
- [Docker](https://docs.docker.com/get-docker/)
|
<p align="center">
|
||||||
- [Docker Compose](https://docs.docker.com/compose/install/)
|
<img src="https://img.shields.io/badge/Python-3.10-3776AB?style=flat-square&logo=python&logoColor=white" />
|
||||||
|
<img src="https://img.shields.io/badge/Flask-3.0-000000?style=flat-square&logo=flask&logoColor=white" />
|
||||||
|
<img src="https://img.shields.io/badge/PostgreSQL-15-4169E1?style=flat-square&logo=postgresql&logoColor=white" />
|
||||||
|
<img src="https://img.shields.io/badge/Docker-Compose-2496ED?style=flat-square&logo=docker&logoColor=white" />
|
||||||
|
<img src="https://img.shields.io/badge/ESP32-IoT-E7352C?style=flat-square&logo=espressif&logoColor=white" />
|
||||||
|
<img src="https://img.shields.io/badge/Raspberry%20Pi-Serveur-A22846?style=flat-square&logo=raspberrypi&logoColor=white" />
|
||||||
|
</p>
|
||||||
|
|
||||||
## Structure du Projet
|
---
|
||||||
|
|
||||||
- `app.py` : Serveur web principal (Flask).
|
## 📋 Table des matières
|
||||||
- `database.sql` : Script d'initialisation de la base de données. Il est automatiquement exécuté par Docker au premier lancement.
|
|
||||||
- `docker-compose.yml` : Configuration Docker pour les services (Base de données et le Web).
|
|
||||||
- `requirements.txt` : Dépendances Python (Flask, Flask-Cors, psycopg2-binary).
|
|
||||||
- `templates/` : Templates HTML (Dashboard, etc.).
|
|
||||||
- `static/` : Fichiers statiques (CSS, JS, images).
|
|
||||||
|
|
||||||
## Lancement de l'application
|
- [Présentation du projet](#-présentation-du-projet)
|
||||||
|
- [Architecture du système](#-architecture-du-système)
|
||||||
|
- [Capteurs et matériel utilisé](#-capteurs-et-matériel-utilisé)
|
||||||
|
- [Fonctionnalités](#-fonctionnalités)
|
||||||
|
- [Dashboard en temps réel](#-dashboard-en-temps-réel)
|
||||||
|
- [API REST](#-api-rest)
|
||||||
|
- [Stack technique](#-stack-technique)
|
||||||
|
- [Mise en route (démonstration)](#-mise-en-route-démonstration)
|
||||||
|
- [Structure du projet](#-structure-du-projet)
|
||||||
|
- [Sécurité](#-sécurité)
|
||||||
|
- [Auteurs](#-auteurs)
|
||||||
|
|
||||||
1. Clonez ce dépôt.
|
---
|
||||||
2. Assurez-vous que Docker est démarré sur votre machine.
|
|
||||||
3. À la racine du projet, exécutez la commande suivante :
|
|
||||||
|
|
||||||
```sh
|
## 🎯 Présentation du projet
|
||||||
docker-compose up --build
|
|
||||||
|
**EcoCharge** est un système complet de monitoring d'énergie solaire conçu dans le cadre d'un projet académique. Il permet de collecter, stocker et visualiser en temps réel les données issues de capteurs physiques connectés à un panneau solaire.
|
||||||
|
|
||||||
|
L'ensemble du système est **entièrement autonome** : le serveur web, la base de données et l'interface de supervision sont hébergés directement sur un **Raspberry Pi**, accessible sur le réseau local. L'ESP32 collecte les mesures des capteurs et les transmet automatiquement au serveur via des requêtes HTTP.
|
||||||
|
|
||||||
|
> **Objectif** : Offrir une interface de supervision professionnelle permettant de suivre la production solaire, les conditions environnementales et l'état global du système, avec un système d'alertes configurable.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗 Architecture du système
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ RÉSEAU LOCAL │
|
||||||
|
│ 192.168.20.0/24 │
|
||||||
|
│ │
|
||||||
|
│ ┌──────────────────┐ HTTP POST /api/data │
|
||||||
|
│ │ ESP32 │ ─────────────────────────────┐ │
|
||||||
|
│ │ (Microcontrôleur)│ (envoi toutes les ~5s) │ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ │ ┌─────┐ ┌──────┐│ ▼ │
|
||||||
|
│ │ │DHT11│ │INA219││ ┌─────────────────────────────────┐ │
|
||||||
|
│ │ └─────┘ └──────┘│ │ RASPBERRY PI │ │
|
||||||
|
│ └──────────────────┘ │ 192.168.20.204 │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ ┌───────────┐ ┌────────────┐ │ │
|
||||||
|
│ ┌──────────────────┐ │ │ Flask │ │ PostgreSQL │ │ │
|
||||||
|
│ │ Navigateur │◄───────│ │ (Python) │◄─│ (BDD) │ │ │
|
||||||
|
│ │ (Dashboard) │ :5001 │ │ Port 5000 │ │ Port 5432 │ │ │
|
||||||
|
│ │ PC / Mobile │ │ └───────────┘ └────────────┘ │ │
|
||||||
|
│ └──────────────────┘ │ │ │
|
||||||
|
│ │ Docker Compose │ │
|
||||||
|
│ └─────────────────────────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────────────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
4. L'application Web sera accessible sur `http://localhost:5001`.
|
**Flux de données** :
|
||||||
5. La base de données PostgreSQL sera exposée sur le port `5432` (utile pour s'y connecter avec DBeaver ou pgAdmin).
|
1. Les capteurs (DHT11 + INA219) mesurent les grandeurs physiques
|
||||||
|
2. L'**ESP32** lit les capteurs et envoie les données en JSON via `POST /api/data`
|
||||||
|
3. Le serveur **Flask** reçoit, vérifie les seuils d'alerte et stocke en base **PostgreSQL**
|
||||||
|
4. Le **Dashboard** interroge l'API (`/api/latest`, `/api/history`) toutes les 4 secondes
|
||||||
|
5. Les graphiques et indicateurs se mettent à jour **en temps réel**
|
||||||
|
|
||||||
## Identifiants de la Base de Données
|
---
|
||||||
|
|
||||||
Les informations de connexion à la base de données sont configurées dans le fichier `docker-compose.yml` :
|
## 🔧 Capteurs et matériel utilisé
|
||||||
|
|
||||||
- **Base de données** : `ecocharge`
|
| Composant | Rôle | Données mesurées |
|
||||||
- **Utilisateur** : `ecocharge_user`
|
|-----------|------|------------------|
|
||||||
- **Mot de passe** : `ecocharge_password`
|
| **ESP32** | Microcontrôleur IoT | Collecte et transmission des données via Wi-Fi |
|
||||||
- **Port** : `5432`
|
| **DHT11** | Capteur environnemental | Température ambiante (°C), Humidité relative (%) |
|
||||||
|
| **INA219** | Capteur électrique (I²C) | Tension (V), Courant (A), Puissance calculée P = U × I (W) |
|
||||||
|
| **Panneau solaire** | Source d'énergie | Production d'énergie mesurée par l'INA219 |
|
||||||
|
| **Raspberry Pi** | Serveur embarqué | Héberge Docker, Flask, PostgreSQL |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✨ Fonctionnalités
|
||||||
|
|
||||||
|
### 📊 Dashboard temps réel
|
||||||
|
- **Météo locale** — Conditions météo actuelles via l'API Open-Meteo (Paris)
|
||||||
|
- **Capteur DHT11** — Température et humidité en temps réel
|
||||||
|
- **Mesures électriques INA219** — Tension, courant et puissance avec jauge visuelle animée
|
||||||
|
- **État du système** — Statut de chaque composant (ESP32, DHT11, INA219, Raspberry Pi)
|
||||||
|
- **Détection EN LIGNE / HORS LIGNE** — L'ESP32 est considéré hors ligne si aucune donnée n'arrive pendant 60 secondes
|
||||||
|
- **Graphiques historiques** — Deux graphiques Chart.js avec double axe Y :
|
||||||
|
- Historique environnement (Température + Humidité)
|
||||||
|
- Historique électrique (Puissance + Courant)
|
||||||
|
|
||||||
|
### ⚠️ Système d'alertes intelligent
|
||||||
|
Le serveur analyse chaque mesure reçue et déclenche une alerte si :
|
||||||
|
- La **température** dépasse le seuil configuré (défaut : 60°C)
|
||||||
|
- La **tension** mesurée est trop faible (défaut : 0.2V)
|
||||||
|
- La **puissance** calculée est insuffisante (défaut : 0.1W)
|
||||||
|
|
||||||
|
Les seuils sont **entièrement configurables** par l'administrateur depuis le panel d'administration.
|
||||||
|
|
||||||
|
### 🔐 Panel d'administration
|
||||||
|
- Authentification sécurisée (mot de passe hashé avec Werkzeug)
|
||||||
|
- Sessions persistantes de 2 heures
|
||||||
|
- Configuration des seuils d'alerte en temps réel
|
||||||
|
- Protection de toutes les routes sensibles
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📺 Dashboard en temps réel
|
||||||
|
|
||||||
|
Le dashboard est composé de **4 blocs principaux** et **2 graphiques** :
|
||||||
|
|
||||||
|
| Bloc | Description |
|
||||||
|
|------|-------------|
|
||||||
|
| 🌤 **Météo & Env.** | Météo web (API) + Température/Humidité locale (DHT11) |
|
||||||
|
| ⚡ **Mesures Électriques** | Jauge de puissance animée + Tension, Courant, Puissance (INA219) |
|
||||||
|
| 🖥 **État du Système** | Statut de chaque composant + badge d'alerte global |
|
||||||
|
| ⚙️ **Administration** | Accès aux paramètres système + déconnexion |
|
||||||
|
| 📈 **Historique Environnement** | Graphique Température + Humidité (15 dernières mesures) |
|
||||||
|
| 📉 **Historique Électrique** | Graphique Puissance + Courant (15 dernières mesures) |
|
||||||
|
|
||||||
|
> Le rafraîchissement est automatique : les cartes se mettent à jour toutes les **4 secondes**, les graphiques toutes les **8 secondes**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔌 API REST
|
||||||
|
|
||||||
|
L'ESP32 communique avec le serveur via une API REST simple et documentée :
|
||||||
|
|
||||||
|
| Méthode | Endpoint | Description |
|
||||||
|
|---------|----------|-------------|
|
||||||
|
| `GET` | `/api/status` | Vérifie que l'API est opérationnelle |
|
||||||
|
| `POST` | `/api/data` | Réception des données capteurs (ESP32 → Serveur) |
|
||||||
|
| `GET` | `/api/latest` | Dernière mesure enregistrée + ancienneté |
|
||||||
|
| `GET` | `/api/history?limit=15` | Historique des N dernières mesures |
|
||||||
|
|
||||||
|
### Exemple de payload envoyé par l'ESP32
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"temperature_ext": 23.5,
|
||||||
|
"humidity_ext": 45.2,
|
||||||
|
"system_status": "OK",
|
||||||
|
"voltage_pv": 12.8,
|
||||||
|
"current_pv": 0.35,
|
||||||
|
"power_pv": 4.48,
|
||||||
|
"luminosity": 850
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exemple de réponse `/api/latest`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 142,
|
||||||
|
"created_at": "2026-06-04 11:15:30",
|
||||||
|
"data_age_seconds": 3.2,
|
||||||
|
"temperature_ext": 23.5,
|
||||||
|
"humidity_ext": 45.2,
|
||||||
|
"voltage_pv": 12.8,
|
||||||
|
"current_pv": 0.35,
|
||||||
|
"power_pv": 4.48,
|
||||||
|
"battery_alert": "none"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠 Stack technique
|
||||||
|
|
||||||
|
| Couche | Technologie | Version |
|
||||||
|
|--------|-------------|---------|
|
||||||
|
| **Backend** | Python / Flask | 3.10 / 3.0.0 |
|
||||||
|
| **Base de données** | PostgreSQL (Alpine) | 15 |
|
||||||
|
| **Frontend** | HTML5, CSS3, JavaScript | — |
|
||||||
|
| **UI Framework** | Bootstrap 5 (Dark Theme) | 5.3.2 |
|
||||||
|
| **Graphiques** | Chart.js | Dernière |
|
||||||
|
| **Icônes** | Bootstrap Icons | 1.11.1 |
|
||||||
|
| **Conteneurisation** | Docker & Docker Compose | — |
|
||||||
|
| **Serveur** | Raspberry Pi (Debian) | — |
|
||||||
|
| **Microcontrôleur** | ESP32 (Wi-Fi) | — |
|
||||||
|
| **Communication** | HTTP REST (JSON) | — |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Mise en route (démonstration)
|
||||||
|
|
||||||
|
### Prérequis
|
||||||
|
- Le **Raspberry Pi** doit être connecté au réseau local `192.168.20.x`
|
||||||
|
- L'**ESP32** doit être alimenté et configuré pour envoyer les données au serveur
|
||||||
|
|
||||||
|
### Démarrage
|
||||||
|
|
||||||
|
**1. Allumer le Raspberry Pi**
|
||||||
|
|
||||||
|
Il suffit de brancher le Raspberry Pi. Les conteneurs Docker sont configurés avec `restart: unless-stopped`, ce qui signifie que le serveur web et la base de données **démarrent automatiquement** au boot.
|
||||||
|
|
||||||
|
**2. Accéder au Dashboard**
|
||||||
|
|
||||||
|
Depuis n'importe quel appareil connecté au même réseau local, ouvrir un navigateur et accéder à :
|
||||||
|
|
||||||
|
```
|
||||||
|
http://192.168.20.204:5001
|
||||||
|
```
|
||||||
|
|
||||||
|
**3. Se connecter**
|
||||||
|
|
||||||
|
| Champ | Valeur |
|
||||||
|
|-------|--------|
|
||||||
|
| Identifiant | `admin` |
|
||||||
|
| Mot de passe | `admin123` |
|
||||||
|
|
||||||
|
**4. Visualiser les données**
|
||||||
|
|
||||||
|
Une fois connecté, le dashboard affiche automatiquement les données en temps réel dès que l'ESP32 est alimenté et envoie des mesures.
|
||||||
|
|
||||||
|
> 💡 **Aucune configuration supplémentaire n'est nécessaire.** Le système est entièrement autonome : il suffit d'allumer le Raspberry Pi et l'ESP32.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 Structure du projet
|
||||||
|
|
||||||
|
```
|
||||||
|
projetecho/
|
||||||
|
├── app.py # Application Flask principale (routes + logique métier)
|
||||||
|
├── config.py # Configuration (variables d'environnement / BDD)
|
||||||
|
├── create_admin.py # Script de création du compte administrateur
|
||||||
|
├── database.sql # Schéma SQL (tables : users, settings, telemetry)
|
||||||
|
├── requirements.txt # Dépendances Python (Flask, psycopg2, Flask-CORS)
|
||||||
|
├── Dockerfile # Image Docker pour le serveur web
|
||||||
|
├── docker-compose.yml # Orchestration des services (web + PostgreSQL)
|
||||||
|
├── .dockerignore # Fichiers exclus du build Docker
|
||||||
|
├── .gitignore # Fichiers exclus du versioning Git
|
||||||
|
│
|
||||||
|
├── templates/
|
||||||
|
│ ├── index.html # Dashboard principal (Bootstrap 5 Dark)
|
||||||
|
│ ├── login.html # Page de connexion administrateur
|
||||||
|
│ └── admin_dashboard.html # Panel de configuration des seuils
|
||||||
|
│
|
||||||
|
└── static/
|
||||||
|
├── style.css # Styles personnalisés (thème sombre, jauges, animations)
|
||||||
|
└── script.js # Logique JS (polling API, graphiques Chart.js, statut)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔒 Sécurité
|
||||||
|
|
||||||
|
- **Mots de passe hashés** — Utilisation de `werkzeug.security` (PBKDF2-SHA256)
|
||||||
|
- **Sessions sécurisées** — Cookie `HttpOnly`, `SameSite=Lax`, durée limitée à 2h
|
||||||
|
- **Protection des routes** — Décorateur `@admin_required` sur toutes les pages sensibles
|
||||||
|
- **Requêtes préparées** — Utilisation de requêtes paramétrées PostgreSQL (protection injection SQL)
|
||||||
|
- **CORS activé** — Contrôle des origines autorisées via Flask-CORS
|
||||||
|
- **Variables d'environnement** — Les credentials de la base de données sont injectées via Docker Compose
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 👥 Auteurs
|
||||||
|
|
||||||
|
Projet réalisé dans le cadre d'un projet académique.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<b>⚡ EcoCharge — Surveiller l'énergie solaire, simplement.</b>
|
||||||
|
</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user