Files
truetype 996664d991 docs: README con architettura, API, setup e riferimento canali
Aggiunta documentazione completa del progetto:
- Architettura e flusso dati
- Setup e configurazione
- API REST con esempi JSON
- Configurazione canali Shelly EM
- Stack tecnologico
2026-07-14 20:39:53 +02:00

172 lines
4.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ShellyDash ⚡
Dashboard web per il monitoraggio in tempo reale di un impianto fotovoltaico con **Shelly EM Gen3**.
Legge i dati da un Shelly EM (2 pinze: produzione pannelli e consumo casa/rete) via **Shelly Cloud API v2**, li memorizza su SQLite e li visualizza su una dashboard con gauge a lancetta semi-circolare e grafico storico.
## Funzionalità
- **Due gauge analogici**: produzione pannelli (0–6000W, verde) e consumo casa (0–3000W, ambra), con scala graduata e lancetta
- **Surplus/deficit** istantaneo: produzione − consumo
- **Energia odierna**: prodotto, consumato, immesso in rete
- **Grafico storico**: 24h / 3gg / 7gg produzione + consumo
- **API REST JSON** per automazioni e integrazioni
- **Auto-refresh** ogni 15 secondi
- **Tema scuro**, UI in italiano
## Architettura
```
shellydash/
├── app.py ← Entrypoint Flask (6 route API + serve frontend)
├── shelly_client.py ← Client HTTP per Shelly Cloud API v2
├── database.py ← SQLite (WAL mode), schema readings
├── poller.py ← Thread background polling periodico
├── templates/
│ └── index.html ← Dashboard: gauge Chart.js custom + grafico storico
├── data/
│ └── shellydash.db ← SQLite (gitignorato)
├── .env ← Credenziali Shelly (gitignorato)
├── AGENTS.md ← Istruzioni per AI agent
└── requirements.txt ← flask, requests, python-dotenv
```
### Flusso dati
```
Shelly Cloud
↕ HTTP POST (auth_key)
poller.poll_once() ← ogni 15s (thread background)
↕
shelly_client.py ← parse readings (em1:0, em1:1)
↕
database.py (SQLite) ← INSERT storico
↕
app._latest_parsed (dict) ← cache in-memory per /api/status
↕
app.py → /api/status ← da cache (risposta immediata)
→ /api/history ← da DB (storico)
→ /api/energy/* ← da DB (aggregazioni)
→ / → templates/index.html
```
## Setup
### Prerequisiti
- Python 3.14+
- Shelly EM Gen3 connesso al cloud Shelly
- Chiave API Cloud (trovabile in App Shelly → Impostazioni → Casa → Cloud)
### Installazione
```bash
cd /home/codex/shellydash
python3 -m venv venv
venv/bin/pip install -r requirements.txt
```
### Configurazione
Crea un file `.env` nella root del progetto (non tracciato in git):
```env
SHELLY_SERVER="https://shelly-255-eu.shelly.cloud"
SHELLY_AUTH_KEY="la_tua_auth_key"
SHELLY_DEVICE_ID="id_dispositivo"
POLL_INTERVAL=15
FLASK_PORT=5050
FLASK_HOST="0.0.0.0"
```
### Avvio
```bash
venv/bin/python3 app.py
```
Apri il browser su `http://localhost:5050`.
## API REST
Tutte le API restituiscono JSON con campo `ok` booleano.
### `GET /api/status`
Letture live in tempo reale (dalla cache del poller).
```json
{
"ok": true,
"ts": 1722520000,
"production_w": 1735.4,
"consumption_w": 134.4,
"delta_w": 1601.0,
"voltage": 229.8,
"ch0_current": 7.55,
"ch1_current": 0.59,
"ch0_pf": 0.99,
"ch1_pf": 0.85,
"temperature": 59.6,
"wifi_rssi": -67,
"online": true
}
```
### `GET /api/history?hours=24`
Array di readings storici dal database.
### `GET /api/energy/today`
Energia odierna in kWh.
### `GET /api/energy/monthly`
Breakdown giornaliero del mese corrente.
### `GET /api/delta`
Surplus/deficit booleano (utile per automazioni).
```json
{
"ok": true,
"delta_w": 1601.0,
"production_w": 1735.4,
"consumption_w": 134.4,
"surplus": true
}
```
## Shelly EM — Configurazione canali
Il progetto è tarato su un **Shelly EM Gen3** (S3EM-002CXCEU) con una singola unità e **due pinze**:
| Canale | ID | Misura | Segno |
|---|---|---|---|
| Produzione | `em1:0` | Uscita inverter → potenza generata | Sempre positivo |
| Consumo | `em1:1` | Ingresso inverter → prelievo/rete | Negativo = consumo, Positivo = immissione |
L'API normalizza automaticamente: `consumption_w = abs(ch1)` quando ch1 è negativo.
## Frontend
- **Framework**: nessuno — vanilla JavaScript
- **Grafici**: Chart.js 4.4.7 via CDN
- **Gauge**: plugin Chart.js custom (`gaugePlugin`) con disegno su canvas di:
- Scala graduata (tacche maggiori ogni 1000W, minori ogni 500W)
- Lancetta rotante
- Valore numerico al centro
- **Tema**: scuro (#0f172a sfondo)
- **Refresh**: `setInterval(refreshAll, 15000)`
## Stack tecnologico
| Componente | Tecnologia |
|---|---|
| Backend | Python 3.14, Flask 3.1 |
| Database | SQLite (WAL mode) |
| Cloud API | Shelly Cloud Control API v2 |
| Frontend | HTML5, CSS3, Chart.js 4.4 (CDN) |
| Ambiente | venv |
## Licenza
Progetto privato — uso personale.