app backend prima

This commit is contained in:
2025-10-20 19:10:08 +02:00
commit 438255d27b
42 changed files with 4622 additions and 0 deletions

257
MQTT_ARCHITECTURE.md Normal file
View File

@@ -0,0 +1,257 @@
# Architettura MQTT - Sistema di Monitoraggio Terreni
## 📡 Struttura Topic
La nuova architettura usa una struttura gerarchica dei topic MQTT per garantire scalabilità e multi-tenancy:
```
terrain/{cliente_id}/{sito_id}/{message_type}
```
### Tipi di Messaggi
| Topic Type | Descrizione | QoS | Frequenza |
|------------|-------------|-----|-----------|
| `alarms` | Allarmi critici/warning/info | 1 | On-event |
| `telemetry` | Dati sensori periodici | 0 | 1-60 min |
| `status` | Stato gateway/sensori | 0 | Periodico |
### Esempi
```bash
# Allarme critico per il sito 17 del cliente 5
terrain/5/17/alarms
# Telemetria sensori
terrain/5/17/telemetry
# Stato del gateway
terrain/5/17/status
```
## 📋 Formato Messaggi
### Allarmi (`/alarms`)
**Topic**: `terrain/{cliente_id}/{sito_id}/alarms`
**Payload** (JSON):
```json
{
"tipo": "movimento_terreno",
"severita": "critical",
"titolo": "Movimento terreno rilevato",
"descrizione": "Rilevato movimento anomalo...",
"valore_rilevato": 25.5,
"valore_soglia": 10.0,
"unita_misura": "mm",
"timestamp": "2025-10-19T10:30:00Z",
"dati_sensori": {
"sensore_1": 25.5,
"sensore_2": 18.3
}
}
```
**Note**:
- `sito_id` e `cliente_id` vengono estratti dal topic (non dal payload)
- `severita`: `critical`, `warning`, `info`
- `tipo`: `movimento_terreno`, `inclinazione`, `vibrazioni`, `cedimento`, `altro`
### Telemetria (`/telemetry`)
**Topic**: `terrain/{cliente_id}/{sito_id}/telemetry`
**Payload** (JSON):
```json
{
"timestamp": "2025-10-19T10:30:00Z",
"sensori": {
"inclinometro_1": {
"valore": 12.5,
"unita": "gradi",
"stato": "ok"
},
"temperatura": {
"valore": 15.5,
"unita": "celsius"
}
},
"batteria": 85,
"segnale": -65
}
```
### Status (`/status`)
**Topic**: `terrain/{cliente_id}/{sito_id}/status`
**Payload** (JSON):
```json
{
"timestamp": "2025-10-19T10:30:00Z",
"gateway_online": true,
"sensori_attivi": 4,
"sensori_totali": 4,
"ultimo_heartbeat": "2025-10-19T10:29:00Z",
"errori": []
}
```
## 🔌 Sottoscrizioni Backend
Il backend si sottoscrive usando wildcards MQTT:
```python
# Sottoscrivi a tutti gli allarmi
client.subscribe("terrain/+/+/alarms", qos=1)
# Sottoscrivi a tutta la telemetria
client.subscribe("terrain/+/+/telemetry", qos=0)
# Sottoscrivi a tutti i messaggi di status
client.subscribe("terrain/+/+/status", qos=0)
```
**Wildcards**:
- `+` : single-level wildcard (un livello)
- `#` : multi-level wildcard (tutti i livelli rimanenti)
## 🔒 Sicurezza
### Development
- Autenticazione: Anonymous (allow_anonymous = true)
- Encryption: Nessuna
### Production (TODO)
```conf
# mosquitto.conf
allow_anonymous false
password_file /mosquitto/config/passwd
# TLS/SSL
listener 8883
cafile /mosquitto/certs/ca.crt
certfile /mosquitto/certs/server.crt
keyfile /mosquitto/certs/server.key
```
## 💾 Persistenza
Mosquitto è configurato con persistenza su disco:
```conf
persistence true
persistence_location /mosquitto/data/
autosave_interval 300 # Salva ogni 5 minuti
```
**Vantaggi**:
- Messaggi QoS > 0 non persi in caso di restart
- Sottoscrizioni persistenti
- Retained messages salvati
## 🧪 Test
### 1. Invia allarme di test
```bash
cd /home/alex/devel/web-app-python
source .venv/bin/activate
python scripts/test_mqtt_improved.py
```
### 2. Monitor MQTT (subscriber)
```bash
# Installa mosquitto-clients
sudo apt-get install mosquitto-clients
# Sottoscrivi a tutti gli allarmi
mosquitto_sub -h localhost -t "terrain/+/+/alarms" -v
# Sottoscrivi a tutti i messaggi
mosquitto_sub -h localhost -t "terrain/#" -v
```
### 3. Pubblica messaggio manuale
```bash
# Allarme critico
mosquitto_pub -h localhost \
-t "terrain/5/17/alarms" \
-m '{"tipo":"movimento_terreno","severita":"critical","titolo":"Test","timestamp":"2025-10-19T10:30:00Z"}' \
-q 1
```
## 📊 Helper Python
Usa l'helper `MQTTTopics` per costruire topic standardizzati:
```python
from app.mqtt.topics import MQTTTopics
# Costruisci topic
topic = MQTTTopics.build_topic(
cliente_id=5,
sito_id=17,
topic_type="alarms"
)
# Output: "terrain/5/17/alarms"
# Parse topic
info = MQTTTopics.parse_topic("terrain/5/17/alarms")
# Output: {'cliente_id': 5, 'sito_id': 17, 'topic_type': 'alarms'}
# Pattern sottoscrizione
pattern = MQTTTopics.get_subscription_pattern("alarms")
# Output: "terrain/+/+/alarms"
```
## 🚀 Migrazione dal Vecchio Sistema
### Prima (vecchio)
```
Topic: terrain/alarms/1
Payload: {"sito_id": 17, "tipo": "...", ...}
```
### Dopo (nuovo)
```
Topic: terrain/5/17/alarms
Payload: {"tipo": "...", ...} # sito_id estratto dal topic
```
### Retrocompatibilità
Il sistema continua a funzionare con il vecchio formato, ma è consigliato migrare ai nuovi topic per:
- ✅ Migliore separazione multi-tenant
- ✅ Filtraggio per cliente
- ✅ Scalabilità
- ✅ Standard IoT
## 📈 Performance
- **Max throughput**: ~10,000 msg/sec (con QoS 0)
- **Latenza**: < 10ms (LAN)
- **Retained messages**: 1000 max
- **Connections**: Illimitate (configurabile)
## 🔍 Monitoraggio
### Log Mosquitto
```bash
docker-compose logs -f mosquitto
```
### Log Backend MQTT
```bash
# Filtro solo log MQTT
grep "MQTT" logs/app.log | tail -50
```
### Statistiche Broker
```bash
# Connetti e visualizza statistiche
mosquitto_sub -h localhost -t '$SYS/#' -v
```