Terrain Monitor Backend
Sistema backend per il monitoraggio di terreni (frane, gallerie, ponti, dighe) con notifiche push real-time per app mobile Android e iOS.
Architettura
Sistema Monitoraggio ’ MQTT ’ Backend (FastAPI) ’ Firebase FCM ’ App Mobile
“
PostgreSQL DB
Componenti Principali
- FastAPI: REST API per autenticazione, gestione allarmi e storico
- PostgreSQL: Database per clienti, siti, utenti e allarmi
- MQTT Client: Riceve allarmi dal sistema centralizzato
- Firebase FCM: Invia notifiche push alle app mobile
- SQLAlchemy: ORM per gestione database
Struttura Progetto
web-app-python/
app/
api/ # Endpoint API REST
auth.py # Autenticazione e gestione utenti
allarmi.py # Gestione allarmi
core/ # Configurazione core
config.py # Settings da env
database.py # Setup database
security.py # JWT e password hashing
models/ # Modelli SQLAlchemy
cliente.py
sito.py
utente.py
allarme.py
schemas/ # Schemi Pydantic per validazione
auth.py
allarme.py
services/ # Servizi business logic
firebase.py # Integrazione FCM
mqtt/ # Client MQTT e handler
client.py # Client MQTT
handler.py # Processamento allarmi
main.py # Applicazione FastAPI
main.py # Entry point
pyproject.toml # Dipendenze
.env.example # Template variabili ambiente
README.md
Setup
1. Requisiti
- Python 3.12+
- PostgreSQL 14+
- Broker MQTT (es. Mosquitto)
- Firebase project con FCM abilitato
2. Installazione
# Crea virtual environment
python -m venv .venv
source .venv/bin/activate # Linux/Mac
# .venv\Scripts\activate # Windows
# Installa dipendenze
pip install -e .
3. Configurazione Database
# Crea database PostgreSQL
createdb terrain_monitor
# oppure con psql
psql -U postgres
CREATE DATABASE terrain_monitor;
4. Configurazione Firebase
- Vai su Firebase Console
- Crea un nuovo progetto
- Abilita Cloud Messaging
- Scarica le credenziali di servizio:
- Settings ’ Service Accounts ’ Generate new private key
- Salva il file come
firebase-credentials.jsonnella root del progetto
5. Variabili d'Ambiente
# Copia il template
cp .env.example .env
# Modifica .env con i tuoi valori
nano .env
Configurazione minima:
DATABASE_URL=postgresql://user:password@localhost:5432/terrain_monitor
SECRET_KEY=genera-una-chiave-segreta-forte
MQTT_BROKER_HOST=localhost
FIREBASE_CREDENTIALS_PATH=./firebase-credentials.json
6. Avvio Applicazione
# Avvio in modalità development
python main.py
# oppure con uvicorn direttamente
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
L'API sarà disponibile su: http://localhost:8000
API Endpoints
Autenticazione
POST /auth/token- Login (OAuth2 password flow)POST /auth/login- Login (JSON)POST /auth/register-fcm-token- Registra FCM token dispositivoGET /auth/me- Info utente corrente
Allarmi
GET /allarmi- Lista allarmi (con filtri e paginazione)GET /allarmi/{id}- Dettaglio allarmePATCH /allarmi/{id}- Aggiorna stato allarmeGET /allarmi/sito/{sito_id}- Allarmi per sito specifico
Documentazione Interattiva
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
Database Schema
Tabelle Principali
clienti
- id, nome, email, telefono, indirizzo
- Relazioni: siti[], utenti[]
siti
- id, cliente_id, nome, tipo, coordinate
- Tipi: frana, galleria, ponte, diga, versante, edificio
- Relazioni: allarmi[]
utenti
- id, cliente_id, email, password_hash, fcm_token
- Ruoli: admin, operatore, visualizzatore
allarmi
- id, sito_id, tipo, severita, stato
- Severità: critical, warning, info
- Stati: nuovo, visualizzato, in_gestione, risolto
- timestamp_rilevamento, dati_sensori (JSON)
MQTT Integration
Topic Structure
terrain/alarms/{sito_id}
Payload Format (JSON)
{
"sito_id": 123,
"tipo": "movimento_terreno",
"severita": "critical",
"titolo": "Movimento terreno rilevato",
"descrizione": "Rilevato movimento anomalo di 12.5mm",
"valore_rilevato": 12.5,
"valore_soglia": 10.0,
"unita_misura": "mm",
"timestamp": "2025-10-18T10:30:00Z",
"dati_sensori": {
"sensore_1": 12.5,
"sensore_2": 8.3
}
}
Flusso Allarme
- Sistema centralizzato pubblica su MQTT
- Backend riceve messaggio e lo valida
- Salva allarme nel database
- Recupera utenti del cliente associato
- Invia notifica push tramite FCM a tutti i dispositivi
Notifiche Push (FCM)
Priorità
- CRITICAL: Notifica con suono, vibrazione, priorità massima
- WARNING: Notifica standard
- INFO: Notifica silenziosa, solo badge
Payload Notifica
{
"notification": {
"title": "CRITICAL: Ponte Morandi",
"body": "Movimento terreno rilevato"
},
"data": {
"alarm_id": "456",
"sito_id": "123",
"sito_nome": "Ponte Morandi",
"tipo": "movimento_terreno",
"severita": "critical",
"timestamp": "2025-10-18T10:30:00Z"
}
}
Testing
Test Manuale MQTT
# Pubblica un messaggio di test
mosquitto_pub -h localhost -t "terrain/alarms/123" -m '{
"sito_id": 123,
"tipo": "movimento_terreno",
"severita": "critical",
"titolo": "Test allarme",
"descrizione": "Questo è un test",
"valore_rilevato": 15.0,
"valore_soglia": 10.0,
"unita_misura": "mm",
"timestamp": "2025-10-18T10:30:00Z"
}'
Test API
# Login
curl -X POST http://localhost:8000/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "password"}'
# Lista allarmi
curl -X GET http://localhost:8000/allarmi \
-H "Authorization: Bearer YOUR_TOKEN"
Deployment
Produzione con Docker
FROM python:3.12-slim
WORKDIR /app
COPY pyproject.toml .
RUN pip install -e .
COPY . .
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
Variabili d'Ambiente Produzione
DEBUG=False
DATABASE_URL=postgresql://user:pass@db-host:5432/terrain_monitor
SECRET_KEY=chiave-molto-forte-e-casuale
MQTT_BROKER_HOST=mqtt.example.com
MQTT_USERNAME=username
MQTT_PASSWORD=password
Sicurezza
- JWT Tokens: Autenticazione stateless
- Password Hashing: bcrypt
- Multi-tenant: Isolamento dati per cliente
- CORS: Configurabile per domini specifici
- HTTPS: Obbligatorio in produzione
Sviluppi Futuri
- WebSocket per notifiche real-time in web app
- Rate limiting su API
- Grafici e analytics allarmi
- Export dati (CSV, PDF)
- Sistema di escalation automatica
- Integrazione con sistemi esterni (email, SMS)
Licenza
MIT License - Vedi file LICENSE per dettagli
Description
Languages
Python
98.1%
Shell
1.9%