# shellydash — AGENTS.md ## Quick start ```bash cd /home/codex/shellydash venv/bin/python3 app.py # avvia su 0.0.0.0:5050 ``` Il `.env` carica automaticamente via `load_dotenv()` in `app.py` e `poller.py`. ## Stack - Python 3.14, Flask 3.1, SQLite, Chart.js 4.4 (CDN) - Venv: `venv/` (già creato) - Dipendenze: `flask`, `requests`, `python-dotenv` ## Architettura | File | Ruolo | |---|---| | `app.py` | Entrypoint Flask, 6 route API + serve `templates/index.html` | | `shelly_client.py` | Chiamate HTTP POST a Shelly Cloud Control API v2 | | `database.py` | SQLite with WAL mode, schema `readings`, energy aggregations | | `poller.py` | Thread background: poll Shelly ogni 15s → insert DB + cache `latest_parsed` | | `templates/index.html` | Dashboard HTML + JS (Chart.js gauge custom plugin, storico, energia) | ### Flusso dati ``` Shelly Cloud ← poller.poll_once() (ogni 15s) → database.py (SQLite) → app._latest_parsed (dict, in-memory) → /api/status (da cache, non DB) → /api/history (da DB) ``` ### API endpoints | Route | Descrizione | Fonte dati | |---|---|---| | `GET /api/status` | Letture live (produzione, consumo, delta, V, A, PF, temp) | cache poller | | `GET /api/history?hours=24` | Array timestamp → produzione/consumo | DB | | `GET /api/energy/today` | Energia odierna (prodotta, consumata, immessa) | DB (differenza energy counter) | | `GET /api/energy/monthly` | Breakdown giornaliero mese corrente | DB | | `GET /api/delta` | Surplus/deficit booleano per automazioni | cache poller | ## Shelly EM — assetto canali - **Un solo device** con ID `d885ac0b5860` (Shelly EM Gen3, modello S3EM-002CXCEU) - `em1:0` → produzione pannelli (pinza sull'uscita inverter) - `em1:1` → consumo casa/rete (pinza sull'ingresso inverter, valori negativi = prelievo) - `consumption_w` nelle API = `abs(ch1)` quando negativo - Auth via `auth_key` (parametro query `?auth_key=...`), **non** email/password - Endpoint: `https://shelly-255-eu.shelly.cloud/v2/devices/api/{action}` ## Convenzioni codice - `from __future__ import annotations` in ogni .py - Type hints ovunque - Logging via `logging.getLogger("shellydash.*")` - `.env` non tracciato in git (`.gitignore` lo esclude) ## Frontend (index.html) - **Non** usa framework JS — vanilla JS con Chart.js via CDN - Gauge semi-circolare con lancetta: plugin Chart.js custom (`gaugePlugin`), **non** libreria esterna - Due widget gauge: `#gaugeProd` (produzione, max 6000W, verde) e `#gaugeCons` (consumo, max 3000W, ambra) - Scala graduata con tacche maggiori (1000W) e minori (500W) disegnate su canvas - Auto-refresh ogni 15s via `setInterval(refreshAll, 15000)` - UI in italiano, tema scuro (#0f172a sfondo) ## Comandi utili ```bash # Avviare venv/bin/python3 app.py # Test API singola curl -s http://localhost:5050/api/status | python3 -m json.tool # Verificare import (senza avviare server) venv/bin/python3 -c "from app import app; print('ok')" # Installare nuove dipendenze venv/bin/pip install # E aggiungere a requirements.txt ``` ## Note operative - Il poller parte in un thread **dopo** il primo `poller.poll_once()`. Serve almeno un poll riuscito prima che `/api/status` risponda. - Il DB è in `data/shellydash.db` — escluso da git. - `POLL_INTERVAL` in `.env` (default 15s). - Non ci sono test (repo in fase iniziale). - Il device Shelly deve essere online e connesso al cloud.