258 lines
5.2 KiB
Markdown
258 lines
5.2 KiB
Markdown
# 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
|
|
```
|