1
03-debug-simulador.md
hack_23031391_8ff9d8 edited this page 2026-05-23 02:33:55 +00:00

Debug del Simulador

Herramientas y comandos para verificar el estado del simulador y troubleshooting avanzado.


Verificar que el simulador está corriendo

Método 1: Endpoint de status

curl http://localhost:8000/admin/route/RUTA-01/status

Si está corriendo:

{
  "route_id": "RUTA-01",
  "current_position_id": 3,
  "current_position_name": "Parque Xochipilli",
  "status": "EN_RUTA",
  "last_update": "2026-05-22T19:35:12.123456"
}

Si NO está corriendo:

{
  "detail": "Ruta no encontrada o simulador detenido"
}

Método 2: Logs del servidor

En la terminal donde corre uvicorn, deberías ver:

INFO:     Tick simulador: RUTA-01 -> posición 3
INFO:     Broadcast WebSocket a address_id 1: aproximandose
INFO:     Tick simulador: RUTA-01 -> posición 4

Si NO ves logs cada 10s → el simulador está detenido.


Arrancar el simulador

curl -X POST http://localhost:8000/admin/route/RUTA-01/start

Response esperada:

{
  "message": "Ruta RUTA-01 iniciada",
  "route_id": "RUTA-01",
  "status": "EN_RUTA"
}

Detener el simulador

curl -X POST http://localhost:8000/admin/route/RUTA-01/stop

Response:

{
  "message": "Ruta RUTA-01 detenida",
  "route_id": "RUTA-01"
}

Inspeccionar la base de datos

Abrir con sqlite3

cd basura_backend
sqlite3 basura.db

# Comandos útiles:
.tables                           # Listar tablas
.schema truck_status              # Ver estructura de tabla

SELECT * FROM truck_status;       # Ver estado actual
SELECT * FROM rutas;              # Ver rutas disponibles
SELECT * FROM puntos_ruta WHERE ruta_id = 'RUTA-01' ORDER BY orden;  # Waypoints
SELECT * FROM notificaciones ORDER BY creada_en DESC LIMIT 10;  # Últimas 10 notificaciones

.quit

Verificar datos del seed

-- Debe haber 1 ruta
SELECT COUNT(*) FROM rutas;
-- Resultado: 1

-- Debe haber 5 puntos de ruta
SELECT COUNT(*) FROM puntos_ruta WHERE ruta_id = 'RUTA-01';
-- Resultado: 5

-- Debe haber 1 usuario demo
SELECT * FROM users;
-- Resultado: id=1, email='demo@ejemplo.com'

-- Debe haber 1 domicilio
SELECT * FROM addresses;
-- Resultado: id=1, user_id=1, route_id='RUTA-01'

Problemas comunes del simulador

El camión no avanza

Síntoma: current_position_id no cambia.

Diagnóstico:

# 1. Verificar que el simulador está corriendo
curl http://localhost:8000/admin/route/RUTA-01/status

# 2. Verificar logs del servidor
# Deberías ver "Tick simulador" cada 10s

Causa 1: El simulador nunca se arrancó.

Solución:

curl -X POST http://localhost:8000/admin/route/RUTA-01/start

Causa 2: El camión ya llegó al último punto.

Solución:

-- Reiniciar posición a 1
sqlite3 basura.db "UPDATE truck_status SET current_position_id = 1 WHERE route_id = 'RUTA-01';"

-- Arrancar de nuevo
curl -X POST http://localhost:8000/admin/route/RUTA-01/start

Causa 3: El status es AVERIADA.

Solución:

-- Cambiar status a EN_RUTA
sqlite3 basura.db "UPDATE truck_status SET status = 'EN_RUTA' WHERE route_id = 'RUTA-01';"

No llegan notificaciones WebSocket

Síntoma: Flutter conecta pero no recibe eventos.

Diagnóstico:

# 1. Conectar con wscat
wscat -c ws://localhost:8000/ws/1

# 2. Arrancar simulador
curl -X POST http://localhost:8000/admin/route/RUTA-01/start

# 3. Esperar 10 segundos
# ¿Recibes eventos?

Causa 1: El ETA es muy grande (>10 min).

Solución: Esperar o forzar proximidad:

-- Poner el camión cerca del domicilio
sqlite3 basura.db "UPDATE truck_status SET current_position_id = 4 WHERE route_id = 'RUTA-01';"

Causa 2: Las preferencias de notificación están desactivadas.

Solución:

SELECT * FROM notification_preferences WHERE user_id = 1;
-- Si notify_proximity = False:
UPDATE notification_preferences SET notify_proximity = 1 WHERE user_id = 1;

Causa 3: El address_id no pertenece a RUTA-01.

Solución:

SELECT route_id FROM addresses WHERE id = 1;
-- Si es NULL o diferente a 'RUTA-01':
UPDATE addresses SET route_id = 'RUTA-01' WHERE id = 1;

El simulador se detiene solo

Síntoma: El simulador arranca pero se detiene después de unos segundos.

Diagnóstico:

# Revisar logs del servidor
# Busca errores como:
# ERROR: Exception in simulator

Causa 1: Error en el código del simulador.

Solución:

# Revisar logs completos
uvicorn app.main:app --reload --log-level debug

Causa 2: El camión llegó al último punto.

Solución:

# El simulador se detiene automáticamente al final
# Esto es comportamiento esperado

Ajustar velocidad del simulador

Acelerar para demos

# En .env
SIM_TICK_SECONDS=5           # Tick cada 5s (más rápido)
SIM_SPEED_MULTIPLIER=2.0     # Doble velocidad

Reinicia el backend:

uvicorn app.main:app --reload

Ralentizar para debug

# En .env
SIM_TICK_SECONDS=30          # Tick cada 30s
SIM_SPEED_MULTIPLIER=0.5     # Mitad de velocidad

Forzar eventos manualmente

Forzar avería

curl -X POST http://localhost:8000/alerts/breakdown \
  -H "Content-Type: application/json" \
  -d '{"route_id": "RUTA-01"}'

Efecto:

  • Detiene el simulador
  • Cambia status a AVERIADA
  • Broadcast WebSocket falla_mecanica a todos los domicilios

Forzar retraso

curl -X POST http://localhost:8000/admin/route/RUTA-01/delay \
  -H "Content-Type: application/json" \
  -d '{"delay_minutes": 15}'

Efecto:

  • Cambia status a RETRASADA
  • Broadcast WebSocket ruta_tarde

Forzar proximidad (para testing)

-- Mover el camión al penúltimo punto
sqlite3 basura.db "UPDATE truck_status SET current_position_id = 4 WHERE route_id = 'RUTA-01';"

-- Arrancar simulador
curl -X POST http://localhost:8000/admin/route/RUTA-01/start

-- En 10s, recibirás evento "aproximandose"

Monitorear en tiempo real

Ver logs del simulador

# En la terminal del backend
tail -f <archivo-de-logs>

# O con uvicorn:
uvicorn app.main:app --reload --log-level info

Logs esperados cada 10s:

INFO:     Tick simulador: RUTA-01 -> posición 2
INFO:     ETA calculado para address_id 1: 18 minutos
INFO:     Tick simulador: RUTA-01 -> posición 3
INFO:     ETA calculado para address_id 1: 12 minutos
INFO:     Tick simulador: RUTA-01 -> posición 4
INFO:     ETA calculado para address_id 1: 6 minutos
INFO:     Broadcast WebSocket a address_id 1: aproximandose

Ver tabla de notificaciones

-- Ver últimas 20 notificaciones enviadas
SELECT 
    tipo, 
    address_id, 
    eta_minutos, 
    mensaje, 
    creada_en 
FROM notificaciones 
ORDER BY creada_en DESC 
LIMIT 20;

Ejemplo de salida:

aproximandose|1|8|El camión llega en ~8 minutos|2026-05-22 19:35:00
aproximandose|1|9|El camión llega en ~9 minutos|2026-05-22 19:34:50
ruta_iniciada|1|NULL|El camión comenzó su recorrido|2026-05-22 19:00:00

Resetear el simulador completamente

# 1. Detener el backend (Ctrl+C)

# 2. Borrar la BD
rm basura.db

# 3. Arrancar de nuevo (recrea BD + seed)
uvicorn app.main:app --reload

# 4. Verificar que el seed fue creado
curl http://localhost:8000/admin/route/RUTA-01/status

# 5. Arrancar simulador
curl -X POST http://localhost:8000/admin/route/RUTA-01/start

Troubleshooting avanzado

Ver el código del simulador

# app/services/simulador.py

def tick_simulador(self):
    # Este método se ejecuta cada SIM_TICK_SECONDS
    # 1. Avanza current_position_id
    # 2. Calcula ETA para cada address
    # 3. Si ETA <= umbral, broadcast WebSocket
    
    # Agregar prints para debug:
    print(f"DEBUG: current_position = {current_position_id}")
    print(f"DEBUG: ETA calculado = {eta_minutos}")

Ver el broadcast WebSocket

# app/services/ws_manager.py

async def broadcast_zona(self, zona_key: str, payload: dict):
    # Agregar log:
    print(f"DEBUG: Broadcasting a zona {zona_key}: {payload}")
    # ...

Verificar APScheduler

# app/services/simulador.py

# Ver jobs activos
from apscheduler.schedulers.asyncio import AsyncIOScheduler

scheduler = AsyncIOScheduler()
jobs = scheduler.get_jobs()
print(f"DEBUG: Jobs activos: {len(jobs)}")
for job in jobs:
    print(f"  - {job.id}: {job.next_run_time}")

Checklist de debug

  • Backend está corriendo (curl /health)
  • Simulador está arrancado (GET /admin/route/.../status)
  • Logs muestran "Tick simulador" cada 10s
  • truck_status.current_position_id incrementa
  • ETA se calcula correctamente (GET /eta/1)
  • WebSocket conecta (wscat -c ws://...)
  • Eventos llegan a Flutter
  • Preferencias de notificación activadas
  • address_id pertenece a la ruta correcta

Siguiente paso