Quando i tuoi sensori IoT diventano più di 3-4 e vuoi grafici a 30 giorni o medie orarie, MySQL non basta più. Il combo classico è InfluxDB (database time-series specializzato) + Grafana (dashboard). Setup standard in 10 minuti con Docker.
1. Docker Compose
Crea ~/iot-stack/docker-compose.yml:
version: "3.8"
services:
influxdb:
image: influxdb:2.7
container_name: influxdb
restart: unless-stopped
ports:
- "8086:8086"
volumes:
- ./influxdb-data:/var/lib/influxdb2
- ./influxdb-config:/etc/influxdb2
environment:
- DOCKER_INFLUXDB_INIT_MODE=setup
- DOCKER_INFLUXDB_INIT_USERNAME=admin
- DOCKER_INFLUXDB_INIT_PASSWORD=ChangeMe123!
- DOCKER_INFLUXDB_INIT_ORG=casa
- DOCKER_INFLUXDB_INIT_BUCKET=sensori
- DOCKER_INFLUXDB_INIT_RETENTION=90d
- DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=my-super-secret-token
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: unless-stopped
ports:
- "3000:3000"
volumes:
- ./grafana-data:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=ChangeMe123!
depends_on:
- influxdb
cd ~/iot-stack
docker compose up -d
2. Verifica accesso
- InfluxDB UI:
http://server:8086(admin / ChangeMe123!). - Grafana:
http://server:3000(admin / ChangeMe123!).
3. Inviare dati da un ESP32 via HTTP
Esempio Arduino IDE: ogni 60s manda temperatura e umidità a InfluxDB.
#include <WiFi.h>
#include <HTTPClient.h>
const char* WIFI_SSID = "CasaWifi";
const char* WIFI_PASS = "...";
const char* INFLUX_URL = "http://192.168.1.10:8086/api/v2/write?org=casa&bucket=sensori";
const char* INFLUX_TOKEN = "my-super-secret-token";
void inviaDati(float temp, float umid) {
HTTPClient http;
http.begin(INFLUX_URL);
http.addHeader("Authorization", String("Token ") + INFLUX_TOKEN);
http.addHeader("Content-Type", "text/plain");
String payload = "salotto temp=" + String(temp) + ",umid=" + String(umid);
int code = http.POST(payload);
http.end();
}
Formato dati InfluxDB ("line protocol"): misura,tag1=valore1 campo1=valore,campo2=valore [timestamp_ns]
4. Inviare dati da Home Assistant
HA ha integrazione nativa per InfluxDB. In configuration.yaml:
influxdb:
api_version: 2
ssl: false
host: 192.168.1.10
port: 8086
token: my-super-secret-token
organization: casa
bucket: sensori
tags:
source: home_assistant
include:
entities:
- sensor.temperatura_salotto
- sensor.umidita_salotto
5. Connettere Grafana a InfluxDB
- Grafana → Connections → Data Sources → Add → "InfluxDB".
- Query language: Flux (raccomandato per InfluxDB 2.x).
- URL:
http://influxdb:8086(nome del container interno). - Organization:
casa. - Token:
my-super-secret-token. - Default bucket:
sensori. - "Save & test" → deve dire OK.
6. Prima dashboard
Crea una dashboard, aggiungi un pannello. Esempio Flux query per la temperatura:
from(bucket: "sensori")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r._measurement == "salotto")
|> filter(fn: (r) => r._field == "temp")
|> aggregateWindow(every: 5m, fn: mean)
|> yield(name: "mean")
Per visualizzare temperatura + umidità sullo stesso pannello, fai due query separate o usa filter(... |> ["temp", "umid"]) con grouping.
7. Retention policy
InfluxDB con RETENTION=90d cancella i dati più vecchi di 90 giorni. Per dati di lungo periodo crei un secondo bucket con retention 5 anni e una "task" Flux che ogni giorno aggrega le medie orarie. Così risparmi spazio (10-100x) mantenendo i trend a lungo termine.