Skip to main content

Device Presence System

Il sistema di presenza traccia lo stato online/offline dei dispositivi GPS in tempo reale.

Architettura​

Flusso Eventi​

Device si connette​

  1. Decoder rileva nuova connessione TCP
  2. Pubblica su stream presence:
    {"unique_id": "019175767229", "event": "online", "time": 1702...}
  3. db-persister consuma e aggiorna DB:
    UPDATE devices SET status = 'online', last_update = NOW() WHERE unique_id = '...';
  4. websocket consuma e fa broadcast ai client:
    {"type": "device_status", "data": {"deviceId": 1, "status": "online"}}

Device si disconnette​

Due scenari:

TipoDescrizioneTempo rilevamento
Disconnessione pulitaDevice invia FIN packet TCPImmediato
Disconnessione sporcaDevice si spegne improvvisamenteTimeout TCP (30-120s)

Disconnessione TCP​

Disconnessione "pulita" (FIN packet)​

Device GPS --> FIN --> Server
Server --> ACK --> Device GPS
Server --> FIN --> Device GPS
Device GPS --> ACK --> Server

Risultato: Disconnessione immediata, il decoder rileva subito e pubblica offline

Disconnessione "sporca" (device si spegne)​

Device GPS ❌ (nessun pacchetto)
Server --> aspetta... aspetta... --> TIMEOUT!

Risultato: Il server non sa che il device Γ¨ morto finchΓ© non scade il timeout TCP

Soluzioni per Timeout​

MetodoCome funziona
TCP Keep-AliveIl server invia periodicamente pacchetti "sei vivo?"
Application-level heartbeatIl device deve inviare un pacchetto ogni X secondi
Timeout applicativoSe non ricevi dati per X minuti β†’ considera offline

Stream Redis​

presence​

Stream per eventi online/offline dei device.

# Visualizza ultimi 5 eventi
docker exec redis redis-cli XRANGE presence - + COUNT 5

# Leggi in tempo reale
docker exec redis redis-cli XREAD BLOCK 0 STREAMS presence $

# Conta eventi
docker exec redis redis-cli XLEN presence

Formato messaggio:

unique_id: "019175767229"
device_id: "1" # ID interno decoder (non database!)
event: "online" | "offline"
time: "1702..."
remote: "192.168.1.1:12345"

Consumer​

db-persister​

Consuma stream presence con consumer group persister-workers:

  • Aggiorna devices.status nel database
  • Aggiorna devices.last_update
  • Log: Device XXXXX status updated to 'online'

websocket​

Consuma stream presence con xread semplice:

  • Cerca device_id reale nel DB tramite unique_id
  • Broadcasting device_status a tutti gli utenti autorizzati
  • Log: Broadcasted device X status 'online' to Y users

Web App​

La web-app ottiene lo status in due modi:

  1. All'avvio - REST API GET /api/devices:

    {"id": 1, "name": "PET", "status": "online", ...}
  2. In tempo reale - WebSocket:

    {"type": "device_status", "data": {"deviceId": 1, "status": "online"}}

Grafana Dashboard​

Dashboard Device Presence Monitor mostra:

  • 🟒 Devices Online Now
  • πŸ”΄ Devices Offline (5m)
  • πŸ“ˆ Online/Offline Events Over Time
  • πŸ“Š Status Distribution
  • πŸ“œ Presence Events Log