5.2 KiB
5.2 KiB
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
# 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):
{
"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_idecliente_idvengono estratti dal topic (non dal payload)severita:critical,warning,infotipo:movimento_terreno,inclinazione,vibrazioni,cedimento,altro
Telemetria (/telemetry)
Topic: terrain/{cliente_id}/{sito_id}/telemetry
Payload (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):
{
"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:
# 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)
# 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:
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
cd /home/alex/devel/web-app-python
source .venv/bin/activate
python scripts/test_mqtt_improved.py
2. Monitor MQTT (subscriber)
# 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
# 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:
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
docker-compose logs -f mosquitto
Log Backend MQTT
# Filtro solo log MQTT
grep "MQTT" logs/app.log | tail -50
Statistiche Broker
# Connetti e visualizza statistiche
mosquitto_sub -h localhost -t '$SYS/#' -v