Skip to main content

Real-Time Data Flow - Testing & Verification Guide

Questo documento descrive i flussi di dati real-time fondamentali di Visla e come verificarli. È essenziale per il testing e il debugging del sistema.

🎯 Overview​

I dati GPS fluiscono dal dispositivo fisico fino alle app attraverso questa pipeline:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”   TCP    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”   Redis    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   WS    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Device β”‚ ──────► β”‚ Decoder β”‚ ─────────► β”‚ Services β”‚ ──────► β”‚ Frontend β”‚
β”‚ (GPS) β”‚ β”‚ (Java) β”‚ Streams β”‚ (Python) β”‚ β”‚ (Web/App)β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

1. πŸ“‘ Flusso Presenza (Online/Offline)​

Pipeline Completa​

Device TCP Connect  β†’  Decoder (Java)  β†’  Redis Stream 'presence'
↓ ↓
SessionManager WebSocket Consumer
↓ ↓
publish("online") Devices Service (DB)
↓ ↓
Device TCP Disconnect ───► Frontend (WS message)
publish("offline")

Come Verificare​

1.1 Decoder (Java) - Verifica sessioni attive​

# SSH sul server
ssh pi@192.168.68.80

# Mostra sessioni TCP attive
docker logs decoder 2>&1 | grep -i "session\|online\|offline" | tail -20

1.2 Redis Stream - Verifica eventi presence​

# Leggi ultimi eventi dal stream presence
docker exec redis redis-cli XREAD COUNT 10 STREAMS presence 0

# Output atteso:
# "protocolId": "351840620257810"
# "event": "online" | "offline"
# "time": "1705829999999"

1.3 WebSocket Service - Verifica consumer​

# Log del websocket consumer
docker logs websocket 2>&1 | grep -i "presence" | tail -20

1.4 Database - Verifica stato persistito​

docker exec postgres psql -U devices -d devices -c \
"SELECT device_id, name, status, last_update FROM user_device_attributes;"

1.5 Frontend - Verifica stato UI​

  1. Apri DevTools β†’ Network β†’ WebSocket
  2. Cerca messaggi con type: "device_status"
  3. Verifica che lo stato UI corrisponda

⚠️ Problemi Comuni e Soluzioni​

ProblemaCausaSoluzione
Device sempre OFFLINE al reloadTimezone mancante in lastUpdateAggiungere Z suffix ai datetime
Device OFFLINE dopo 5minFallback frontend attivoVerificare che decoder invii dati
Stato non si aggiorna real-timeConsumer non attivoRiavviare websocket service
Status "online" in DB ma device spentoDecoder non ha inviato "offline"Verificare SessionManager

2. πŸ“ Flusso Posizioni​

Pipeline Completa​

Device GPS Fix  β†’  Decoder  β†’  Redis 'positions:raw'  β†’  Positions Service
↓
Validation + DB
↓
Redis 'positions:validated'
↓
WebSocket Consumer
↓
Frontend (mappa)

Come Verificare​

2.1 Decoder - Posizioni ricevute​

docker logs decoder 2>&1 | grep -i "position\|lat\|lon" | tail -10

2.2 Redis - Stream posizioni​

# Posizioni grezze (dal decoder)
docker exec redis redis-cli XLEN positions:raw

# Posizioni validate (pronte per frontend)
docker exec redis redis-cli XLEN positions:validated

# Leggi ultimi messaggi
docker exec redis redis-cli XREAD COUNT 5 STREAMS positions:validated 0

2.3 Database - Posizioni salvate​

docker exec postgres psql -U positions -d positions -c \
"SELECT device_id, latitude, longitude, fix_time
FROM positions ORDER BY id DESC LIMIT 5;"

2.4 Frontend - Posizioni sulla mappa​

  1. DevTools β†’ Network β†’ WS
  2. Cerca messaggi type: "position"
  3. Verifica coordinate e timestamp

Dati Trasmessi con le Posizioni​

Le "posizioni" in realtΓ  contengono molto piΓΉ delle coordinate:

CategoriaCampi
Posizionelatitude, longitude, altitude, speed, course
TempodeviceTime, fixTime, serverTime
QualitΓ  GPSsatellites, hdop, valid
BatteriabatteryLevel, battery (voltage), charging
Reterssi (GSM signal), network
Veicoloignition, power (12V/24V), odometer
Allarmialarm, alarms[]

3. ⏰ Formato Timestamp e Timezone​

Regola Fondamentale​

Tutti i timestamp devono essere in UTC con suffix Z

βœ… Corretto:  "2026-01-21T09:58:10.252626Z"
❌ Errato: "2026-01-21T09:58:10.252626" (senza Z = interpretato come local time)

Chi Converte in Local Time?​

LayerResponsabilitΓ 
DecoderSalva sempre in UTC
DatabaseTimestamp senza timezone (ma sempre UTC)
API BackendRestituisce con suffix Z
FrontendConverte in timezone utente da user.timezone

Conversione Frontend​

// L'utente ha impostato Europe/Rome
const userTimezone = user.timezone; // "Europe/Rome"

// Timestamp dal backend (UTC)
const serverTime = new Date("2026-01-21T10:00:00Z");

// Converti in local
const localTime = serverTime.toLocaleString('it-IT', {
timeZone: userTimezone
});
// Output: "21/01/2026, 11:00:00" (UTC+1)

Come Verificare​

# API restituisce Z suffix?
curl -s http://localhost:3000/api/devices | jq '.[0].lastUpdate'
# Deve terminare con "Z"

4. πŸ”” Altri Flussi Real-Time​

4.1 Eventi​

Decoder  β†’  Positions Service (detect event)  β†’  Events Service  β†’  Redis 'events'
↓
WebSocket + Notifications

Tipi di eventi:

  • deviceOnline / deviceOffline
  • deviceMoving / deviceStopped
  • geofenceEnter / geofenceExit
  • alarm (SOS, vibration, speeding, etc.)
  • ignitionOn / ignitionOff

4.2 Geofence​

Position Update  β†’  Geofence Service  β†’  Check intersections
↓
Event: geofenceEnter/Exit
↓
Notification Service

4.3 Notifiche Push​

Event Generated  β†’  Notification Service  β†’  FCM/APNs
↓
Check user preferences
↓
Send push / email / call

5. πŸ§ͺ Checklist di Verifica​

Pre-Deploy Checklist​

  • Presenza: Device online/offline riflette sessione TCP decoder
  • Posizioni: Le coordinate arrivano dal decoder al frontend
  • Timestamp: Tutti con suffix Z (UTC)
  • Fallback 5min: Device senza dati per 5min = OFFLINE
  • Reload pagina: Status corretto immediatamente (no flash OFFLINEβ†’ONLINE)

Componenti da Verificare​

ComponenteComando VerificaOutput Atteso
Decoderdocker logs decoderTCP sessions, position parsing
Redis Streamsredis-cli XLEN presenceCount > 0 se device attivi
Positions Servicedocker logs positionsProcessing positions
WebSocketdocker logs websocketBroadcasting to clients
Devices DBQuery user_device_attributesstatus = online/offline

Test End-to-End​

  1. Accendi device GPS β†’ Verifica status: online in DB e frontend
  2. Spegni device GPS β†’ Verifica status: offline entro 2 min (decoder timeout 100s)
  3. Muovi device β†’ Verifica posizione aggiornata su mappa
  4. Entra in geofence β†’ Verifica evento e notifica
  5. Ricarica pagina β†’ Status deve essere corretto immediatamente

6. πŸ“Š Metriche e Monitoring​

Latenza Attesa​

HopLatenza Tipica
Device β†’ Decoder1-2s (rete mobile)
Decoder β†’ Redis< 10ms
Redis β†’ WebSocket< 10ms
WebSocket β†’ Browser< 50ms
Totale E2E< 3 secondi

Redis Stream Health​

# Verifica consumer groups
docker exec redis redis-cli XINFO GROUPS positions:validated

# Verifica pending messages (lag)
docker exec redis redis-cli XPENDING positions:validated websocket-positions

7. πŸ”§ Troubleshooting Comune​

Device sempre OFFLINE​

# 1. Verifica decoder ha sessione attiva
docker logs decoder 2>&1 | grep "351840620257810"

# 2. Verifica presenza su Redis
docker exec redis redis-cli XREAD COUNT 10 STREAMS presence 0

# 3. Verifica DB
docker exec postgres psql -U devices -d devices -c \
"SELECT status, last_update FROM user_device_attributes WHERE device_id = 44;"

Posizioni non si aggiornano​

# 1. Decoder riceve dati?
docker logs decoder 2>&1 | grep -i "position" | tail -5

# 2. Positions service processa?
docker logs positions 2>&1 | tail -20

# 3. WebSocket broadcast?
docker logs websocket 2>&1 | grep -i "position" | tail -10

Notifiche non arrivano​

# 1. Evento generato?
docker logs events 2>&1 | grep -i "event" | tail -10

# 2. Notification service attivo?
docker logs notifications 2>&1 | tail -20

# 3. Token FCM registrato?
docker exec postgres psql -U notification -d notification -c \
"SELECT user_id, platform FROM notification_tokens;"