FlotillasGPS - Sistema completo de monitoreo de flotillas GPS
Sistema completo para monitoreo y gestion de flotas de vehiculos con: - Backend FastAPI con PostgreSQL/TimescaleDB - Frontend React con TypeScript y TailwindCSS - App movil React Native con Expo - Soporte para dispositivos GPS, Meshtastic y celulares - Video streaming en vivo con MediaMTX - Geocercas, alertas, viajes y reportes - Autenticacion JWT y WebSockets en tiempo real Documentacion completa y guias de usuario incluidas.
This commit is contained in:
742
docs/guias/api-reference.md
Normal file
742
docs/guias/api-reference.md
Normal file
@@ -0,0 +1,742 @@
|
||||
# Referencia de API
|
||||
|
||||
Documentacion de la API REST de FlotillasGPS.
|
||||
|
||||
## Informacion General
|
||||
|
||||
- **Base URL**: `https://flotillas.tudominio.com/api/v1`
|
||||
- **Autenticacion**: JWT Bearer Token
|
||||
- **Formato**: JSON
|
||||
- **Documentacion interactiva**: `https://flotillas.tudominio.com/api/docs`
|
||||
|
||||
## Autenticacion
|
||||
|
||||
### Login
|
||||
|
||||
```http
|
||||
POST /auth/login
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"email": "admin@ejemplo.com",
|
||||
"password": "tu_password"
|
||||
}
|
||||
```
|
||||
|
||||
**Respuesta**:
|
||||
```json
|
||||
{
|
||||
"access_token": "eyJ...",
|
||||
"refresh_token": "eyJ...",
|
||||
"token_type": "bearer",
|
||||
"expires_in": 86400
|
||||
}
|
||||
```
|
||||
|
||||
### Refresh Token
|
||||
|
||||
```http
|
||||
POST /auth/refresh
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"refresh_token": "eyJ..."
|
||||
}
|
||||
```
|
||||
|
||||
### Usar Token
|
||||
|
||||
Incluir en todas las peticiones:
|
||||
```http
|
||||
Authorization: Bearer eyJ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Vehiculos
|
||||
|
||||
### Listar Vehiculos
|
||||
|
||||
```http
|
||||
GET /vehiculos
|
||||
```
|
||||
|
||||
**Parametros query**:
|
||||
- `activo`: boolean - Filtrar por activos
|
||||
- `grupo_id`: integer - Filtrar por grupo
|
||||
- `search`: string - Buscar por nombre/placa
|
||||
- `page`: integer - Pagina (default: 1)
|
||||
- `per_page`: integer - Items por pagina (default: 20)
|
||||
|
||||
**Respuesta**:
|
||||
```json
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"id": 1,
|
||||
"nombre": "Camion-01",
|
||||
"placa": "ABC-123",
|
||||
"marca": "Kenworth",
|
||||
"modelo": "T680",
|
||||
"ano": 2021,
|
||||
"tipo": "camion",
|
||||
"conductor": {
|
||||
"id": 1,
|
||||
"nombre": "Juan Perez"
|
||||
},
|
||||
"grupo": {
|
||||
"id": 1,
|
||||
"nombre": "Ruta Norte"
|
||||
},
|
||||
"estado": "en_ruta",
|
||||
"ultima_ubicacion": {
|
||||
"lat": 19.4326,
|
||||
"lng": -99.1332,
|
||||
"velocidad": 45,
|
||||
"tiempo": "2026-01-21T10:30:00Z"
|
||||
}
|
||||
}
|
||||
],
|
||||
"total": 12,
|
||||
"page": 1,
|
||||
"per_page": 20
|
||||
}
|
||||
```
|
||||
|
||||
### Obtener Vehiculo
|
||||
|
||||
```http
|
||||
GET /vehiculos/{id}
|
||||
```
|
||||
|
||||
### Crear Vehiculo
|
||||
|
||||
```http
|
||||
POST /vehiculos
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"nombre": "Camion-02",
|
||||
"placa": "DEF-456",
|
||||
"marca": "Freightliner",
|
||||
"modelo": "Cascadia",
|
||||
"ano": 2022,
|
||||
"tipo": "camion",
|
||||
"color": "Blanco",
|
||||
"capacidad_carga": 20000,
|
||||
"capacidad_combustible": 400,
|
||||
"grupo_id": 1,
|
||||
"conductor_id": 2
|
||||
}
|
||||
```
|
||||
|
||||
### Actualizar Vehiculo
|
||||
|
||||
```http
|
||||
PUT /vehiculos/{id}
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"nombre": "Camion-02 Actualizado",
|
||||
"conductor_id": 3
|
||||
}
|
||||
```
|
||||
|
||||
### Eliminar Vehiculo
|
||||
|
||||
```http
|
||||
DELETE /vehiculos/{id}
|
||||
```
|
||||
|
||||
### Obtener Ubicacion Actual
|
||||
|
||||
```http
|
||||
GET /vehiculos/{id}/ubicacion
|
||||
```
|
||||
|
||||
**Respuesta**:
|
||||
```json
|
||||
{
|
||||
"vehiculo_id": 1,
|
||||
"lat": 19.4326,
|
||||
"lng": -99.1332,
|
||||
"velocidad": 45,
|
||||
"rumbo": 180,
|
||||
"altitud": 2240,
|
||||
"motor_encendido": true,
|
||||
"bateria": 85,
|
||||
"combustible": 72,
|
||||
"tiempo": "2026-01-21T10:30:00Z",
|
||||
"direccion": "Av. Insurgentes Sur 1234, CDMX"
|
||||
}
|
||||
```
|
||||
|
||||
### Obtener Historial de Ubicaciones
|
||||
|
||||
```http
|
||||
GET /vehiculos/{id}/historial
|
||||
```
|
||||
|
||||
**Parametros query**:
|
||||
- `desde`: datetime - Fecha inicio (ISO 8601)
|
||||
- `hasta`: datetime - Fecha fin
|
||||
- `intervalo`: integer - Segundos entre puntos (para reducir datos)
|
||||
|
||||
---
|
||||
|
||||
## Conductores
|
||||
|
||||
### Listar Conductores
|
||||
|
||||
```http
|
||||
GET /conductores
|
||||
```
|
||||
|
||||
### Crear Conductor
|
||||
|
||||
```http
|
||||
POST /conductores
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"nombre": "Maria",
|
||||
"apellido": "Garcia",
|
||||
"telefono": "+525512345678",
|
||||
"email": "maria@ejemplo.com",
|
||||
"licencia_numero": "LIC-123456",
|
||||
"licencia_tipo": "C",
|
||||
"licencia_vencimiento": "2027-06-15"
|
||||
}
|
||||
```
|
||||
|
||||
### Generar Codigo de Acceso
|
||||
|
||||
```http
|
||||
POST /conductores/{id}/generar-codigo
|
||||
```
|
||||
|
||||
**Respuesta**:
|
||||
```json
|
||||
{
|
||||
"codigo": "123456",
|
||||
"expira": "2026-01-22T10:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Obtener Estadisticas
|
||||
|
||||
```http
|
||||
GET /conductores/{id}/estadisticas
|
||||
```
|
||||
|
||||
**Parametros query**:
|
||||
- `periodo`: string - "hoy", "semana", "mes", "ano"
|
||||
|
||||
---
|
||||
|
||||
## Ubicaciones
|
||||
|
||||
### Enviar Ubicacion (desde app/dispositivo)
|
||||
|
||||
```http
|
||||
POST /ubicaciones
|
||||
X-Device-ID: device_123
|
||||
X-API-Key: api_key_xxx
|
||||
|
||||
{
|
||||
"lat": 19.4326,
|
||||
"lng": -99.1332,
|
||||
"velocidad": 45,
|
||||
"rumbo": 180,
|
||||
"altitud": 2240,
|
||||
"precision": 10,
|
||||
"bateria": 85
|
||||
}
|
||||
```
|
||||
|
||||
### Enviar Batch de Ubicaciones
|
||||
|
||||
```http
|
||||
POST /ubicaciones/batch
|
||||
X-Device-ID: device_123
|
||||
X-API-Key: api_key_xxx
|
||||
|
||||
{
|
||||
"ubicaciones": [
|
||||
{
|
||||
"lat": 19.4326,
|
||||
"lng": -99.1332,
|
||||
"velocidad": 45,
|
||||
"tiempo": "2026-01-21T10:30:00Z"
|
||||
},
|
||||
{
|
||||
"lat": 19.4327,
|
||||
"lng": -99.1333,
|
||||
"velocidad": 47,
|
||||
"tiempo": "2026-01-21T10:30:10Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Viajes
|
||||
|
||||
### Listar Viajes
|
||||
|
||||
```http
|
||||
GET /viajes
|
||||
```
|
||||
|
||||
**Parametros query**:
|
||||
- `vehiculo_id`: integer
|
||||
- `conductor_id`: integer
|
||||
- `desde`: datetime
|
||||
- `hasta`: datetime
|
||||
- `estado`: string - "en_curso", "completado"
|
||||
|
||||
### Obtener Viaje
|
||||
|
||||
```http
|
||||
GET /viajes/{id}
|
||||
```
|
||||
|
||||
**Respuesta**:
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"vehiculo_id": 1,
|
||||
"conductor_id": 1,
|
||||
"inicio_tiempo": "2026-01-21T06:30:00Z",
|
||||
"fin_tiempo": "2026-01-21T11:45:00Z",
|
||||
"inicio_lat": 19.4326,
|
||||
"inicio_lng": -99.1332,
|
||||
"inicio_direccion": "Base Central",
|
||||
"fin_lat": 19.5000,
|
||||
"fin_lng": -99.2000,
|
||||
"fin_direccion": "Cliente Norte",
|
||||
"distancia_km": 89.3,
|
||||
"duracion_minutos": 315,
|
||||
"velocidad_promedio": 48,
|
||||
"velocidad_maxima": 82,
|
||||
"paradas": 3
|
||||
}
|
||||
```
|
||||
|
||||
### Obtener Datos para Replay
|
||||
|
||||
```http
|
||||
GET /viajes/{id}/replay
|
||||
```
|
||||
|
||||
**Respuesta**:
|
||||
```json
|
||||
{
|
||||
"viaje_id": 1,
|
||||
"puntos": [
|
||||
{
|
||||
"lat": 19.4326,
|
||||
"lng": -99.1332,
|
||||
"velocidad": 0,
|
||||
"tiempo": "2026-01-21T06:30:00Z"
|
||||
},
|
||||
{
|
||||
"lat": 19.4330,
|
||||
"lng": -99.1335,
|
||||
"velocidad": 25,
|
||||
"tiempo": "2026-01-21T06:30:10Z"
|
||||
}
|
||||
],
|
||||
"eventos": [
|
||||
{
|
||||
"tipo": "alerta",
|
||||
"tiempo": "2026-01-21T08:45:00Z",
|
||||
"descripcion": "Exceso de velocidad: 82 km/h"
|
||||
}
|
||||
],
|
||||
"paradas": [
|
||||
{
|
||||
"inicio": "2026-01-21T07:15:00Z",
|
||||
"fin": "2026-01-21T07:30:00Z",
|
||||
"lat": 19.4500,
|
||||
"lng": -99.1500,
|
||||
"tipo": "programada"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Alertas
|
||||
|
||||
### Listar Alertas
|
||||
|
||||
```http
|
||||
GET /alertas
|
||||
```
|
||||
|
||||
**Parametros query**:
|
||||
- `atendida`: boolean
|
||||
- `severidad`: string - "info", "media", "critica"
|
||||
- `tipo`: string
|
||||
- `vehiculo_id`: integer
|
||||
- `desde`: datetime
|
||||
- `hasta`: datetime
|
||||
|
||||
### Obtener Alertas Pendientes
|
||||
|
||||
```http
|
||||
GET /alertas/pendientes
|
||||
```
|
||||
|
||||
### Marcar como Atendida
|
||||
|
||||
```http
|
||||
PUT /alertas/{id}/atender
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"notas": "Contactado conductor, todo OK"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Geocercas
|
||||
|
||||
### Listar Geocercas
|
||||
|
||||
```http
|
||||
GET /geocercas
|
||||
```
|
||||
|
||||
### Crear Geocerca
|
||||
|
||||
```http
|
||||
POST /geocercas
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"nombre": "Zona Norte",
|
||||
"tipo": "poligono",
|
||||
"coordenadas": [
|
||||
{"lat": 19.5, "lng": -99.2},
|
||||
{"lat": 19.5, "lng": -99.1},
|
||||
{"lat": 19.4, "lng": -99.1},
|
||||
{"lat": 19.4, "lng": -99.2}
|
||||
],
|
||||
"color": "#22c55e",
|
||||
"alerta_entrada": false,
|
||||
"alerta_salida": true,
|
||||
"velocidad_maxima": 60,
|
||||
"vehiculos": [1, 2, 3]
|
||||
}
|
||||
```
|
||||
|
||||
### Crear Geocerca Circular
|
||||
|
||||
```http
|
||||
POST /geocercas
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"nombre": "Cliente ABC",
|
||||
"tipo": "circulo",
|
||||
"coordenadas": [{"lat": 19.4326, "lng": -99.1332}],
|
||||
"radio_metros": 500,
|
||||
"alerta_entrada": true,
|
||||
"alerta_salida": true
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Video
|
||||
|
||||
### Listar Camaras
|
||||
|
||||
```http
|
||||
GET /video/camaras
|
||||
```
|
||||
|
||||
### Obtener URL de Stream
|
||||
|
||||
```http
|
||||
GET /video/camaras/{id}/stream
|
||||
```
|
||||
|
||||
**Respuesta**:
|
||||
```json
|
||||
{
|
||||
"camara_id": 1,
|
||||
"webrtc_url": "http://servidor:8889/cam_1_frontal",
|
||||
"hls_url": "http://servidor:8888/cam_1_frontal/index.m3u8",
|
||||
"estado": "online"
|
||||
}
|
||||
```
|
||||
|
||||
### Listar Grabaciones
|
||||
|
||||
```http
|
||||
GET /video/grabaciones
|
||||
```
|
||||
|
||||
**Parametros query**:
|
||||
- `camara_id`: integer
|
||||
- `vehiculo_id`: integer
|
||||
- `tipo`: string - "continua", "evento", "manual"
|
||||
- `desde`: datetime
|
||||
- `hasta`: datetime
|
||||
|
||||
### Solicitar Video Historico
|
||||
|
||||
```http
|
||||
POST /video/grabaciones/solicitar
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"camara_id": 1,
|
||||
"desde": "2026-01-21T10:00:00Z",
|
||||
"hasta": "2026-01-21T10:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Combustible
|
||||
|
||||
### Registrar Carga
|
||||
|
||||
```http
|
||||
POST /combustible
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"vehiculo_id": 1,
|
||||
"litros": 45.5,
|
||||
"precio_litro": 23.50,
|
||||
"odometro": 45678,
|
||||
"estacion": "Pemex Centro"
|
||||
}
|
||||
```
|
||||
|
||||
### Obtener Consumo
|
||||
|
||||
```http
|
||||
GET /combustible/consumo
|
||||
```
|
||||
|
||||
**Parametros query**:
|
||||
- `vehiculo_id`: integer
|
||||
- `desde`: datetime
|
||||
- `hasta`: datetime
|
||||
|
||||
---
|
||||
|
||||
## Mantenimiento
|
||||
|
||||
### Listar Mantenimientos
|
||||
|
||||
```http
|
||||
GET /mantenimiento
|
||||
```
|
||||
|
||||
### Obtener Proximos Vencimientos
|
||||
|
||||
```http
|
||||
GET /mantenimiento/pendientes
|
||||
```
|
||||
|
||||
### Programar Mantenimiento
|
||||
|
||||
```http
|
||||
POST /mantenimiento
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"vehiculo_id": 1,
|
||||
"tipo_mantenimiento_id": 1,
|
||||
"fecha_programada": "2026-02-01",
|
||||
"odometro_programado": 50000,
|
||||
"notas": "Cambio de aceite y filtros"
|
||||
}
|
||||
```
|
||||
|
||||
### Completar Mantenimiento
|
||||
|
||||
```http
|
||||
PUT /mantenimiento/{id}/completar
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"fecha_realizada": "2026-02-01",
|
||||
"odometro_realizado": 49850,
|
||||
"costo": 1500.00,
|
||||
"proveedor": "Taller AutoServ",
|
||||
"notas": "Se cambio aceite sintetico"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Reportes
|
||||
|
||||
### Obtener Datos de Dashboard
|
||||
|
||||
```http
|
||||
GET /reportes/dashboard
|
||||
```
|
||||
|
||||
**Respuesta**:
|
||||
```json
|
||||
{
|
||||
"vehiculos": {
|
||||
"total": 12,
|
||||
"en_ruta": 8,
|
||||
"detenidos": 2,
|
||||
"offline": 1,
|
||||
"con_alerta": 1
|
||||
},
|
||||
"hoy": {
|
||||
"km_recorridos": 847,
|
||||
"viajes_completados": 8,
|
||||
"alertas": 5,
|
||||
"combustible_cargado": 250
|
||||
},
|
||||
"tendencias": {
|
||||
"km_vs_ayer": 12,
|
||||
"alertas_vs_ayer": -5
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Generar Reporte
|
||||
|
||||
```http
|
||||
POST /reportes/generar
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"tipo": "recorridos",
|
||||
"desde": "2026-01-01",
|
||||
"hasta": "2026-01-21",
|
||||
"vehiculos": [1, 2, 3],
|
||||
"formato": "pdf"
|
||||
}
|
||||
```
|
||||
|
||||
**Respuesta**:
|
||||
```json
|
||||
{
|
||||
"reporte_id": 1,
|
||||
"estado": "procesando",
|
||||
"url": null
|
||||
}
|
||||
```
|
||||
|
||||
### Descargar Reporte
|
||||
|
||||
```http
|
||||
GET /reportes/{id}/descargar
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## WebSocket
|
||||
|
||||
### Conexion
|
||||
|
||||
```javascript
|
||||
const ws = new WebSocket('wss://flotillas.tudominio.com/ws/v1/ubicaciones');
|
||||
|
||||
ws.onopen = () => {
|
||||
// Autenticar
|
||||
ws.send(JSON.stringify({
|
||||
type: 'auth',
|
||||
token: 'eyJ...'
|
||||
}));
|
||||
};
|
||||
|
||||
ws.onmessage = (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
console.log(data);
|
||||
};
|
||||
```
|
||||
|
||||
### Eventos de Ubicacion
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "vehiculo_ubicacion",
|
||||
"vehiculo_id": 1,
|
||||
"lat": 19.4326,
|
||||
"lng": -99.1332,
|
||||
"velocidad": 45,
|
||||
"rumbo": 180,
|
||||
"tiempo": "2026-01-21T10:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Eventos de Alerta
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "nueva_alerta",
|
||||
"alerta": {
|
||||
"id": 123,
|
||||
"vehiculo_id": 1,
|
||||
"tipo": "exceso_velocidad",
|
||||
"severidad": "media",
|
||||
"mensaje": "Exceso de velocidad: 87 km/h",
|
||||
"tiempo": "2026-01-21T10:30:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Codigos de Error
|
||||
|
||||
| Codigo | Descripcion |
|
||||
|--------|-------------|
|
||||
| 400 | Bad Request - Datos invalidos |
|
||||
| 401 | Unauthorized - Token invalido o expirado |
|
||||
| 403 | Forbidden - Sin permisos |
|
||||
| 404 | Not Found - Recurso no existe |
|
||||
| 422 | Validation Error - Error de validacion |
|
||||
| 429 | Too Many Requests - Rate limit excedido |
|
||||
| 500 | Internal Server Error |
|
||||
|
||||
**Formato de error**:
|
||||
```json
|
||||
{
|
||||
"detail": "Mensaje de error",
|
||||
"code": "ERROR_CODE",
|
||||
"errors": [
|
||||
{
|
||||
"field": "email",
|
||||
"message": "Email invalido"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Rate Limits
|
||||
|
||||
| Endpoint | Limite |
|
||||
|----------|--------|
|
||||
| General | 100 req/min |
|
||||
| Auth | 5 req/min |
|
||||
| Ubicaciones | 60 req/min |
|
||||
| Video Stream | 10 req/min |
|
||||
|
||||
Headers de respuesta:
|
||||
```
|
||||
X-RateLimit-Limit: 100
|
||||
X-RateLimit-Remaining: 95
|
||||
X-RateLimit-Reset: 1642771200
|
||||
```
|
||||
449
docs/guias/configuracion.md
Normal file
449
docs/guias/configuracion.md
Normal file
@@ -0,0 +1,449 @@
|
||||
# Guia de Configuracion
|
||||
|
||||
Configuracion detallada de todos los componentes del sistema FlotillasGPS.
|
||||
|
||||
## Variables de Entorno
|
||||
|
||||
El archivo `/opt/flotillas/.env` contiene todas las configuraciones del sistema.
|
||||
|
||||
### Base de Datos
|
||||
|
||||
```bash
|
||||
# PostgreSQL
|
||||
DATABASE_URL=postgresql://flotillas:PASSWORD@localhost:5432/flotillas_db
|
||||
|
||||
# Conexiones maximas al pool
|
||||
DB_POOL_SIZE=10
|
||||
DB_MAX_OVERFLOW=20
|
||||
```
|
||||
|
||||
### Redis
|
||||
|
||||
```bash
|
||||
# URL de conexion
|
||||
REDIS_URL=redis://localhost:6379
|
||||
|
||||
# Base de datos (0-15)
|
||||
REDIS_DB=0
|
||||
```
|
||||
|
||||
### Seguridad
|
||||
|
||||
```bash
|
||||
# Clave secreta para JWT (generar con: openssl rand -base64 64)
|
||||
JWT_SECRET=tu_clave_muy_larga_y_segura
|
||||
|
||||
# Expiracion de tokens
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES=1440 # 24 horas
|
||||
REFRESH_TOKEN_EXPIRE_DAYS=7
|
||||
|
||||
# Clave para encriptar datos sensibles
|
||||
ENCRYPTION_KEY=otra_clave_segura
|
||||
```
|
||||
|
||||
### Traccar
|
||||
|
||||
```bash
|
||||
# Conexion a Traccar
|
||||
TRACCAR_HOST=localhost
|
||||
TRACCAR_PORT=5055
|
||||
TRACCAR_FORWARD_URL=http://localhost:8000/api/v1/traccar/position
|
||||
```
|
||||
|
||||
### Video Streaming
|
||||
|
||||
```bash
|
||||
# MediaMTX
|
||||
MEDIAMTX_API=http://localhost:9997
|
||||
MEDIAMTX_RTSP=rtsp://localhost:8554
|
||||
MEDIAMTX_WEBRTC=http://localhost:8889
|
||||
MEDIAMTX_HLS=http://localhost:8888
|
||||
|
||||
# Directorio de grabaciones
|
||||
VIDEO_STORAGE_PATH=/opt/flotillas/videos
|
||||
VIDEO_RETENTION_DAYS=30
|
||||
```
|
||||
|
||||
### MQTT (Meshtastic)
|
||||
|
||||
```bash
|
||||
MQTT_HOST=localhost
|
||||
MQTT_PORT=1883
|
||||
MQTT_USER=mesh_gateway
|
||||
MQTT_PASSWORD=password_seguro
|
||||
MQTT_TOPIC=flotillas/mesh/#
|
||||
```
|
||||
|
||||
### Notificaciones
|
||||
|
||||
```bash
|
||||
# Email (SMTP)
|
||||
SMTP_HOST=smtp.tudominio.com
|
||||
SMTP_PORT=587
|
||||
SMTP_USER=notificaciones@tudominio.com
|
||||
SMTP_PASSWORD=password
|
||||
SMTP_FROM=FlotillasGPS <notificaciones@tudominio.com>
|
||||
|
||||
# Push Notifications (Firebase)
|
||||
FIREBASE_CREDENTIALS_FILE=/opt/flotillas/firebase-credentials.json
|
||||
```
|
||||
|
||||
### Dominio
|
||||
|
||||
```bash
|
||||
DOMAIN=flotillas.tudominio.com
|
||||
API_URL=https://flotillas.tudominio.com/api
|
||||
FRONTEND_URL=https://flotillas.tudominio.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuracion de Traccar
|
||||
|
||||
Archivo: `/opt/traccar/conf/traccar.xml`
|
||||
|
||||
```xml
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!DOCTYPE properties SYSTEM 'http://java.sun.com/dtd/properties.dtd'>
|
||||
<properties>
|
||||
<!-- Base de datos -->
|
||||
<entry key='database.driver'>org.postgresql.Driver</entry>
|
||||
<entry key='database.url'>jdbc:postgresql://localhost:5432/flotillas_db</entry>
|
||||
<entry key='database.user'>flotillas</entry>
|
||||
<entry key='database.password'>TU_PASSWORD</entry>
|
||||
|
||||
<!-- Deshabilitar web UI de Traccar (usamos nuestro dashboard) -->
|
||||
<entry key='web.enable'>false</entry>
|
||||
<entry key='api.enable'>false</entry>
|
||||
|
||||
<!-- Forward de posiciones a nuestra API -->
|
||||
<entry key='forward.enable'>true</entry>
|
||||
<entry key='forward.url'>http://localhost:8000/api/v1/traccar/position</entry>
|
||||
<entry key='forward.json'>true</entry>
|
||||
|
||||
<!-- Protocolos habilitados (agregar segun tus GPS) -->
|
||||
<entry key='gt06.port'>5023</entry>
|
||||
<entry key='tk103.port'>5002</entry>
|
||||
<entry key='gps103.port'>5001</entry>
|
||||
<entry key='osmand.port'>5055</entry>
|
||||
|
||||
<!-- Logging -->
|
||||
<entry key='logger.enable'>true</entry>
|
||||
<entry key='logger.level'>info</entry>
|
||||
</properties>
|
||||
```
|
||||
|
||||
### Protocolos GPS Comunes
|
||||
|
||||
| Protocolo | Puerto | Dispositivos |
|
||||
|-----------|--------|--------------|
|
||||
| osmand | 5055 | Apps moviles, GPS genericos |
|
||||
| gt06 | 5023 | Concox, Wetrack, JM01 |
|
||||
| tk103 | 5002 | TK103, GPS103 |
|
||||
| h02 | 5013 | Sinotrack ST-901 |
|
||||
| watch | 5093 | Smartwatches GPS |
|
||||
| teltonika | 5027 | Teltonika FM |
|
||||
|
||||
Para habilitar un protocolo adicional, agregar la linea:
|
||||
```xml
|
||||
<entry key='PROTOCOLO.port'>PUERTO</entry>
|
||||
```
|
||||
|
||||
Y abrir el puerto en el firewall:
|
||||
```bash
|
||||
ufw allow PUERTO/tcp
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuracion de MediaMTX
|
||||
|
||||
Archivo: `/etc/mediamtx/mediamtx.yml`
|
||||
|
||||
```yaml
|
||||
# Logging
|
||||
logLevel: info
|
||||
logDestinations: [stdout]
|
||||
|
||||
# API para control
|
||||
api: yes
|
||||
apiAddress: 127.0.0.1:9997
|
||||
|
||||
# RTSP Server (para recibir streams de camaras)
|
||||
rtsp: yes
|
||||
rtspAddress: :8554
|
||||
protocols: [tcp, udp]
|
||||
rtspAuthMethods: []
|
||||
|
||||
# WebRTC Server (para dashboard)
|
||||
webrtc: yes
|
||||
webrtcAddress: :8889
|
||||
webrtcAllowOrigin: '*'
|
||||
webrtcICEServers2:
|
||||
- urls: [stun:stun.l.google.com:19302]
|
||||
|
||||
# HLS Server (para app movil)
|
||||
hls: yes
|
||||
hlsAddress: :8888
|
||||
hlsAllowOrigin: '*'
|
||||
hlsAlwaysRemux: yes
|
||||
hlsSegmentCount: 3
|
||||
hlsSegmentDuration: 1s
|
||||
|
||||
# Grabacion
|
||||
record: no # Manejamos grabacion desde nuestra API
|
||||
recordPath: /opt/flotillas/videos/%path/%Y%m%d_%H%M%S.mp4
|
||||
|
||||
# Paths (camaras)
|
||||
paths:
|
||||
# Patron para camaras: cam_{vehiculo_id}_{posicion}
|
||||
cam~:
|
||||
source: publisher
|
||||
# Autenticacion para publicar
|
||||
publishUser: camuser
|
||||
publishPass: campass
|
||||
# Autenticacion para ver (vacio = sin auth, lo manejamos con JWT)
|
||||
readUser: ''
|
||||
readPass: ''
|
||||
```
|
||||
|
||||
### Agregar Camara Manualmente
|
||||
|
||||
```bash
|
||||
# Crear path para una camara
|
||||
curl -X POST http://localhost:9997/v2/config/paths/add/cam_1_frontal \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"source": "rtsp://usuario:password@192.168.1.100/stream1",
|
||||
"sourceOnDemand": true
|
||||
}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuracion de Cloudflare Tunnel
|
||||
|
||||
Archivo: `/etc/cloudflared/config.yml`
|
||||
|
||||
```yaml
|
||||
tunnel: TU_TUNNEL_ID
|
||||
credentials-file: /root/.cloudflared/TU_TUNNEL_ID.json
|
||||
|
||||
ingress:
|
||||
# API Backend
|
||||
- hostname: flotillas.tudominio.com
|
||||
path: /api/*
|
||||
service: http://localhost:8000
|
||||
|
||||
# WebSocket
|
||||
- hostname: flotillas.tudominio.com
|
||||
path: /ws/*
|
||||
service: http://localhost:8000
|
||||
|
||||
# Frontend (default)
|
||||
- hostname: flotillas.tudominio.com
|
||||
service: http://localhost:3000
|
||||
|
||||
# Catch-all
|
||||
- service: http_status:404
|
||||
```
|
||||
|
||||
### Comandos Utiles
|
||||
|
||||
```bash
|
||||
# Ver estado del tunnel
|
||||
cloudflared tunnel info TU_TUNNEL_ID
|
||||
|
||||
# Listar tunnels
|
||||
cloudflared tunnel list
|
||||
|
||||
# Ver conexiones activas
|
||||
cloudflared tunnel run --url http://localhost:3000
|
||||
|
||||
# Reiniciar
|
||||
systemctl restart cloudflared
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuracion de PostgreSQL
|
||||
|
||||
### Ajustes de Rendimiento
|
||||
|
||||
Archivo: `/etc/postgresql/15/main/postgresql.conf`
|
||||
|
||||
```ini
|
||||
# Memoria (ajustar segun RAM disponible)
|
||||
shared_buffers = 2GB # 25% de RAM
|
||||
effective_cache_size = 6GB # 75% de RAM
|
||||
work_mem = 256MB
|
||||
maintenance_work_mem = 512MB
|
||||
|
||||
# Conexiones
|
||||
max_connections = 100
|
||||
|
||||
# WAL
|
||||
wal_buffers = 64MB
|
||||
checkpoint_completion_target = 0.9
|
||||
|
||||
# Logging
|
||||
log_min_duration_statement = 1000 # Log queries > 1 segundo
|
||||
```
|
||||
|
||||
### TimescaleDB
|
||||
|
||||
```sql
|
||||
-- Ver chunks de la hypertable
|
||||
SELECT show_chunks('ubicaciones');
|
||||
|
||||
-- Comprimir chunks antiguos
|
||||
SELECT compress_chunk(c, if_not_compressed => true)
|
||||
FROM show_chunks('ubicaciones', older_than => INTERVAL '7 days') c;
|
||||
|
||||
-- Configurar compresion automatica
|
||||
SELECT add_compression_policy('ubicaciones', INTERVAL '7 days');
|
||||
|
||||
-- Configurar retencion automatica
|
||||
SELECT add_retention_policy('ubicaciones', INTERVAL '90 days');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuracion de Redis
|
||||
|
||||
Archivo: `/etc/redis/redis.conf`
|
||||
|
||||
```ini
|
||||
# Memoria
|
||||
maxmemory 512mb
|
||||
maxmemory-policy allkeys-lru
|
||||
|
||||
# Persistencia
|
||||
save 900 1
|
||||
save 300 10
|
||||
save 60 10000
|
||||
|
||||
# Solo conexiones locales
|
||||
bind 127.0.0.1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuracion de Firewall (UFW)
|
||||
|
||||
```bash
|
||||
# Ver estado actual
|
||||
ufw status verbose
|
||||
|
||||
# Reglas recomendadas
|
||||
ufw default deny incoming
|
||||
ufw default allow outgoing
|
||||
ufw allow ssh
|
||||
ufw allow 5055/tcp # GPS Traccar
|
||||
|
||||
# Si necesitas mas puertos GPS
|
||||
ufw allow 5001:5099/tcp # Rango de puertos Traccar
|
||||
|
||||
# Habilitar
|
||||
ufw enable
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuracion de Systemd Services
|
||||
|
||||
### flotillas-api.service
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=FlotillasGPS API Backend
|
||||
After=network.target postgresql.service redis.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory=/opt/flotillas/backend
|
||||
Environment="PATH=/opt/flotillas/venv/bin"
|
||||
EnvironmentFile=/opt/flotillas/.env
|
||||
ExecStart=/opt/flotillas/venv/bin/uvicorn app.main:app \
|
||||
--host 127.0.0.1 \
|
||||
--port 8000 \
|
||||
--workers 4 \
|
||||
--loop uvloop \
|
||||
--http httptools
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
### flotillas-web.service
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=FlotillasGPS Web Frontend
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory=/opt/flotillas/frontend
|
||||
ExecStart=/usr/bin/npx serve -s dist -l 3000
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuracion desde el Dashboard
|
||||
|
||||
Muchas configuraciones se pueden cambiar desde **Configuracion** en el dashboard:
|
||||
|
||||
### General
|
||||
- Zona horaria
|
||||
- Unidades (km/millas, litros/galones)
|
||||
- Moneda
|
||||
- Idioma
|
||||
|
||||
### Alertas
|
||||
- Velocidad maxima global
|
||||
- Tiempo de parada para alerta (minutos)
|
||||
- Tiempo offline para alerta (minutos)
|
||||
- Notificaciones por email
|
||||
|
||||
### Mapa
|
||||
- Proveedor de mapas
|
||||
- Estilo (claro/oscuro)
|
||||
- Capas por defecto
|
||||
|
||||
### Retencion de Datos
|
||||
- Dias de ubicaciones detalladas
|
||||
- Dias de ubicaciones agregadas
|
||||
- Dias de grabaciones de video
|
||||
- Dias de alertas
|
||||
|
||||
---
|
||||
|
||||
## Aplicar Cambios
|
||||
|
||||
Despues de modificar archivos de configuracion:
|
||||
|
||||
```bash
|
||||
# Recargar configuracion de systemd
|
||||
systemctl daemon-reload
|
||||
|
||||
# Reiniciar servicio especifico
|
||||
systemctl restart flotillas-api
|
||||
|
||||
# Reiniciar todos los servicios
|
||||
systemctl restart flotillas-api flotillas-web traccar mediamtx
|
||||
|
||||
# Verificar estado
|
||||
systemctl status flotillas-api flotillas-web traccar mediamtx
|
||||
```
|
||||
264
docs/guias/instalacion.md
Normal file
264
docs/guias/instalacion.md
Normal file
@@ -0,0 +1,264 @@
|
||||
# Guia de Instalacion
|
||||
|
||||
Esta guia cubre la instalacion completa del sistema FlotillasGPS en un servidor Proxmox.
|
||||
|
||||
## Requisitos Previos
|
||||
|
||||
### Hardware (VM en Proxmox)
|
||||
|
||||
| Recurso | Minimo | Recomendado |
|
||||
|---------|--------|-------------|
|
||||
| CPU | 2 cores | 4 cores |
|
||||
| RAM | 4 GB | 8 GB |
|
||||
| Disco Sistema | 40 GB SSD | 60 GB SSD |
|
||||
| Disco Videos | 500 GB HDD | 2 TB HDD |
|
||||
|
||||
### Software
|
||||
|
||||
- Proxmox VE 7.x o superior
|
||||
- ISO Ubuntu 22.04 LTS Server
|
||||
|
||||
### Red
|
||||
|
||||
- IP estatica para la VM
|
||||
- Puerto TCP 5055 accesible desde internet (para GPS)
|
||||
- Dominio configurado (para Cloudflare Tunnel)
|
||||
- Cuenta en Cloudflare (plan gratuito funciona)
|
||||
|
||||
## Paso 1: Crear VM en Proxmox
|
||||
|
||||
### Desde la interfaz web de Proxmox:
|
||||
|
||||
1. Click en "Create VM"
|
||||
2. **General**:
|
||||
- Name: `flotillas-server`
|
||||
- Start at boot: Si
|
||||
3. **OS**:
|
||||
- ISO image: ubuntu-22.04-live-server-amd64.iso
|
||||
4. **System**:
|
||||
- BIOS: Default
|
||||
- Machine: q35
|
||||
5. **Disks**:
|
||||
- Disco 1: 60 GB (SSD/local-lvm)
|
||||
- Agregar disco 2: 2 TB (HDD para videos)
|
||||
6. **CPU**:
|
||||
- Cores: 4
|
||||
- Type: host
|
||||
7. **Memory**:
|
||||
- Memory: 8192 MB
|
||||
8. **Network**:
|
||||
- Bridge: vmbr0
|
||||
- Model: VirtIO
|
||||
|
||||
### Instalar Ubuntu:
|
||||
|
||||
1. Iniciar VM y seguir instalador
|
||||
2. Configurar IP estatica o DHCP con reserva
|
||||
3. Crear usuario `admin`
|
||||
4. Instalar OpenSSH server
|
||||
5. Reiniciar
|
||||
|
||||
## Paso 2: Preparar el Sistema
|
||||
|
||||
Conectar por SSH:
|
||||
|
||||
```bash
|
||||
ssh admin@IP_DE_TU_VM
|
||||
```
|
||||
|
||||
Actualizar sistema:
|
||||
|
||||
```bash
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
sudo apt install -y git curl wget
|
||||
```
|
||||
|
||||
## Paso 3: Clonar Repositorio
|
||||
|
||||
```bash
|
||||
cd /opt
|
||||
sudo git clone https://git.consultoria-as.com/tu-usuario/flotillas-gps.git flotillas
|
||||
sudo chown -R $USER:$USER /opt/flotillas
|
||||
cd /opt/flotillas
|
||||
```
|
||||
|
||||
## Paso 4: Configurar Variables
|
||||
|
||||
Editar el script de instalacion para configurar tu dominio:
|
||||
|
||||
```bash
|
||||
nano deploy/scripts/install.sh
|
||||
```
|
||||
|
||||
Modificar las variables al inicio:
|
||||
|
||||
```bash
|
||||
DOMAIN="flotillas.tudominio.com" # Tu dominio
|
||||
ADMIN_EMAIL="admin@tudominio.com" # Email del admin
|
||||
```
|
||||
|
||||
## Paso 5: Ejecutar Instalacion
|
||||
|
||||
```bash
|
||||
sudo ./deploy/scripts/install.sh
|
||||
```
|
||||
|
||||
El script realizara automaticamente:
|
||||
|
||||
1. Instalar PostgreSQL 15 + TimescaleDB
|
||||
2. Instalar Redis
|
||||
3. Instalar Python 3.11 y Node.js 20
|
||||
4. Instalar Traccar Server
|
||||
5. Instalar MediaMTX (video streaming)
|
||||
6. Instalar Mosquitto MQTT
|
||||
7. Configurar la aplicacion
|
||||
8. Crear servicios systemd
|
||||
9. Configurar firewall
|
||||
10. Generar credenciales
|
||||
|
||||
**Duracion estimada: 10-15 minutos**
|
||||
|
||||
## Paso 6: Configurar Cloudflare Tunnel
|
||||
|
||||
### En el Dashboard de Cloudflare:
|
||||
|
||||
1. Ir a **Zero Trust** > **Access** > **Tunnels**
|
||||
2. Click **Create a tunnel**
|
||||
3. Nombre: `flotillas`
|
||||
4. Copiar el token del tunnel
|
||||
|
||||
### En tu servidor:
|
||||
|
||||
```bash
|
||||
# El instalador ya instalo cloudflared
|
||||
# Configurar con tu token
|
||||
sudo cloudflared service install TOKEN_QUE_COPIASTE
|
||||
```
|
||||
|
||||
### Configurar rutas en Cloudflare:
|
||||
|
||||
En el dashboard del tunnel, agregar Public Hostnames:
|
||||
|
||||
| Subdomain | Domain | Service |
|
||||
|-----------|--------|---------|
|
||||
| flotillas | tudominio.com | http://localhost:3000 |
|
||||
| flotillas | tudominio.com | http://localhost:8000 (path: /api/*) |
|
||||
| flotillas | tudominio.com | http://localhost:8000 (path: /ws/*) |
|
||||
|
||||
## Paso 7: Verificar Instalacion
|
||||
|
||||
### Verificar servicios:
|
||||
|
||||
```bash
|
||||
sudo systemctl status flotillas-api
|
||||
sudo systemctl status flotillas-web
|
||||
sudo systemctl status traccar
|
||||
sudo systemctl status mediamtx
|
||||
sudo systemctl status cloudflared
|
||||
```
|
||||
|
||||
Todos deben mostrar `active (running)`.
|
||||
|
||||
### Verificar acceso web:
|
||||
|
||||
Abrir en navegador: `https://flotillas.tudominio.com`
|
||||
|
||||
Deberia mostrar la pagina de login.
|
||||
|
||||
### Verificar puerto GPS:
|
||||
|
||||
```bash
|
||||
# Desde otra maquina
|
||||
nc -zv IP_DEL_SERVIDOR 5055
|
||||
```
|
||||
|
||||
Debe mostrar "Connection succeeded".
|
||||
|
||||
## Paso 8: Credenciales
|
||||
|
||||
Las credenciales se generaron durante la instalacion.
|
||||
|
||||
Ver credenciales guardadas:
|
||||
|
||||
```bash
|
||||
cat /opt/flotillas/.credentials
|
||||
```
|
||||
|
||||
Ejemplo de salida:
|
||||
|
||||
```
|
||||
=================================
|
||||
CREDENCIALES DE ACCESO
|
||||
=================================
|
||||
Dashboard: https://flotillas.tudominio.com
|
||||
Admin Email: admin@flotillas.tudominio.com
|
||||
Admin Password: xK9mN2pL5qR8
|
||||
Database Password: [guardado en .env]
|
||||
=================================
|
||||
```
|
||||
|
||||
**IMPORTANTE**: Guarda estas credenciales en un lugar seguro y cambia la contrasena del admin despues del primer login.
|
||||
|
||||
## Paso 9: Configurar DNS para GPS
|
||||
|
||||
Los dispositivos GPS necesitan conectarse al puerto 5055 de tu servidor.
|
||||
|
||||
### Opcion A: IP Publica directa
|
||||
|
||||
Si tu servidor tiene IP publica, configura los GPS con:
|
||||
- Servidor: `IP_PUBLICA`
|
||||
- Puerto: `5055`
|
||||
|
||||
### Opcion B: Port forwarding
|
||||
|
||||
Si el servidor esta detras de NAT:
|
||||
|
||||
1. En tu router, hacer port forward del puerto 5055 TCP hacia la IP de la VM
|
||||
2. Configurar GPS con tu IP publica o dominio DDNS
|
||||
|
||||
### Opcion C: Dominio con registro A
|
||||
|
||||
1. Crear registro A: `gps.tudominio.com` → IP_PUBLICA
|
||||
2. Configurar GPS con:
|
||||
- Servidor: `gps.tudominio.com`
|
||||
- Puerto: `5055`
|
||||
|
||||
## Solucion de Problemas
|
||||
|
||||
### El servicio no inicia
|
||||
|
||||
```bash
|
||||
# Ver logs detallados
|
||||
journalctl -u flotillas-api -n 100 --no-pager
|
||||
|
||||
# Verificar configuracion
|
||||
cat /opt/flotillas/.env
|
||||
```
|
||||
|
||||
### No puedo acceder al dashboard
|
||||
|
||||
```bash
|
||||
# Verificar tunnel
|
||||
cloudflared tunnel info flotillas
|
||||
|
||||
# Reiniciar tunnel
|
||||
sudo systemctl restart cloudflared
|
||||
```
|
||||
|
||||
### Los GPS no se conectan
|
||||
|
||||
```bash
|
||||
# Verificar que el puerto esta abierto
|
||||
sudo ufw status
|
||||
sudo netstat -tlnp | grep 5055
|
||||
|
||||
# Ver logs de Traccar
|
||||
journalctl -u traccar -f
|
||||
```
|
||||
|
||||
## Siguientes Pasos
|
||||
|
||||
1. [Configurar el sistema](configuracion.md)
|
||||
2. [Agregar vehiculos y dispositivos GPS](usuario-admin.md)
|
||||
3. [Configurar camaras de video](video-streaming.md)
|
||||
4. [Instalar app en celulares de conductores](usuario-conductor.md)
|
||||
392
docs/guias/meshtastic.md
Normal file
392
docs/guias/meshtastic.md
Normal file
@@ -0,0 +1,392 @@
|
||||
# Integracion Meshtastic
|
||||
|
||||
Guia para configurar dispositivos Meshtastic con FlotillasGPS.
|
||||
|
||||
## Que es Meshtastic
|
||||
|
||||
Meshtastic es una plataforma de comunicacion mesh usando radio LoRa:
|
||||
|
||||
- **Largo alcance**: 5-15+ km en condiciones ideales
|
||||
- **Sin infraestructura**: No requiere torres celulares ni internet
|
||||
- **Bajo costo**: Dispositivos desde $20 USD
|
||||
- **Bajo consumo**: Semanas de bateria
|
||||
|
||||
### Casos de Uso en Flotillas
|
||||
|
||||
- Vehiculos en zonas rurales sin cobertura celular
|
||||
- Operaciones en minas, campos, areas remotas
|
||||
- Backup cuando falla la red celular
|
||||
- Comunicacion en emergencias
|
||||
|
||||
---
|
||||
|
||||
## Arquitectura
|
||||
|
||||
```
|
||||
ZONA SIN COBERTURA CELULAR
|
||||
==========================
|
||||
|
||||
[Vehiculo 1] [Vehiculo 2]
|
||||
Meshtastic Meshtastic
|
||||
| |
|
||||
| Radio LoRa |
|
||||
+----------+----------+
|
||||
|
|
||||
v
|
||||
[Nodo Relay]
|
||||
(punto alto)
|
||||
|
|
||||
| Radio LoRa
|
||||
v
|
||||
|
||||
ZONA CON COBERTURA
|
||||
==================
|
||||
|
||||
[Gateway]
|
||||
Meshtastic + WiFi/4G
|
||||
|
|
||||
| MQTT / Internet
|
||||
v
|
||||
[Tu Servidor]
|
||||
FlotillasGPS
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Hardware Recomendado
|
||||
|
||||
### Para Vehiculos (Nodos Moviles)
|
||||
|
||||
| Dispositivo | Precio | GPS | Pantalla | Notas |
|
||||
|-------------|--------|-----|----------|-------|
|
||||
| LILYGO T-Beam | $35 | Si | No | Popular, bateria 18650 |
|
||||
| Heltec LoRa 32 V3 | $20 | Si | OLED | Compacto, economico |
|
||||
| RAK WisBlock | $40 | Si | Opcional | Modular, bajo consumo |
|
||||
|
||||
### Para Gateway (Fijo con Internet)
|
||||
|
||||
| Dispositivo | Precio | Notas |
|
||||
|-------------|--------|-------|
|
||||
| T-Beam + RPi | $70 | DIY, flexible |
|
||||
| Heltec + ESP32 | $25 | Simple, economico |
|
||||
| RAK WisGate | $150 | Comercial, robusto |
|
||||
|
||||
### Accesorios
|
||||
|
||||
- **Antena externa**: Mayor alcance (+3-6 dB)
|
||||
- **Caja impermeable**: IP65 para exterior
|
||||
- **Alimentacion 12V**: Adaptador para vehiculo
|
||||
|
||||
---
|
||||
|
||||
## Configuracion de Nodos
|
||||
|
||||
### 1. Instalar Firmware Meshtastic
|
||||
|
||||
1. Descargar [Meshtastic Flasher](https://flasher.meshtastic.org/)
|
||||
2. Conectar dispositivo por USB
|
||||
3. Seleccionar dispositivo y version
|
||||
4. Flash
|
||||
|
||||
### 2. Configuracion Basica (App Meshtastic)
|
||||
|
||||
Descargar app Meshtastic (Android/iOS) y conectar por Bluetooth:
|
||||
|
||||
**Device Settings**:
|
||||
```
|
||||
Role: ROUTER_CLIENT
|
||||
```
|
||||
|
||||
**Position Settings**:
|
||||
```
|
||||
GPS Mode: Enabled
|
||||
Position Broadcast Interval: 30 seconds
|
||||
Smart Position: Enabled
|
||||
```
|
||||
|
||||
**LoRa Settings**:
|
||||
```
|
||||
Region: US (o tu region)
|
||||
Modem Preset: LONG_FAST
|
||||
TX Power: 20 dBm (maximo legal)
|
||||
```
|
||||
|
||||
**Channel Settings**:
|
||||
```
|
||||
Name: flotilla
|
||||
PSK: [generar clave compartida]
|
||||
```
|
||||
|
||||
### 3. Configuracion via CLI (Avanzado)
|
||||
|
||||
```bash
|
||||
# Instalar meshtastic CLI
|
||||
pip install meshtastic
|
||||
|
||||
# Conectar y configurar
|
||||
meshtastic --set device.role ROUTER_CLIENT
|
||||
meshtastic --set position.gps_enabled true
|
||||
meshtastic --set position.position_broadcast_secs 30
|
||||
meshtastic --set lora.region US
|
||||
meshtastic --set lora.modem_preset LONG_FAST
|
||||
meshtastic --ch-set name flotilla --ch-index 0
|
||||
meshtastic --ch-set psk random --ch-index 0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuracion del Gateway
|
||||
|
||||
El gateway es el nodo que tiene conexion a internet y envia datos al servidor.
|
||||
|
||||
### Opcion 1: T-Beam + Raspberry Pi
|
||||
|
||||
1. Conectar T-Beam a RPi via USB
|
||||
2. Instalar meshtastic:
|
||||
```bash
|
||||
pip install meshtastic
|
||||
```
|
||||
|
||||
3. Configurar MQTT bridge:
|
||||
```bash
|
||||
meshtastic --set mqtt.enabled true
|
||||
meshtastic --set mqtt.address tu-servidor.com
|
||||
meshtastic --set mqtt.username mesh_gateway
|
||||
meshtastic --set mqtt.password tu_password
|
||||
meshtastic --set mqtt.root_topic flotillas/mesh
|
||||
meshtastic --set mqtt.encryption_enabled true
|
||||
meshtastic --set mqtt.json_enabled true
|
||||
```
|
||||
|
||||
### Opcion 2: ESP32 con WiFi
|
||||
|
||||
Configurar directamente en el dispositivo:
|
||||
|
||||
**MQTT Settings** (via app o CLI):
|
||||
```
|
||||
MQTT Enabled: true
|
||||
MQTT Server: tu-servidor.com:1883
|
||||
MQTT Username: mesh_gateway
|
||||
MQTT Password: tu_password
|
||||
Root Topic: flotillas/mesh
|
||||
JSON Enabled: true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuracion del Servidor
|
||||
|
||||
### 1. Mosquitto MQTT
|
||||
|
||||
Ya instalado por el script de instalacion. Verificar:
|
||||
|
||||
```bash
|
||||
systemctl status mosquitto
|
||||
```
|
||||
|
||||
Crear usuario para gateway:
|
||||
```bash
|
||||
mosquitto_passwd -c /etc/mosquitto/passwd mesh_gateway
|
||||
# Ingresar password
|
||||
```
|
||||
|
||||
Configuracion `/etc/mosquitto/conf.d/flotillas.conf`:
|
||||
```
|
||||
listener 1883
|
||||
allow_anonymous false
|
||||
password_file /etc/mosquitto/passwd
|
||||
```
|
||||
|
||||
Reiniciar:
|
||||
```bash
|
||||
systemctl restart mosquitto
|
||||
```
|
||||
|
||||
### 2. Verificar Recepcion de Mensajes
|
||||
|
||||
Suscribirse al topic para ver mensajes:
|
||||
|
||||
```bash
|
||||
mosquitto_sub -h localhost -t "flotillas/mesh/#" -u mesh_gateway -P tu_password
|
||||
```
|
||||
|
||||
Deberian aparecer mensajes JSON cuando los nodos envien posicion.
|
||||
|
||||
### 3. Configurar en FlotillasGPS
|
||||
|
||||
Variables de entorno en `.env`:
|
||||
```bash
|
||||
MQTT_HOST=localhost
|
||||
MQTT_PORT=1883
|
||||
MQTT_USER=mesh_gateway
|
||||
MQTT_PASSWORD=tu_password
|
||||
MQTT_TOPIC=flotillas/mesh/#
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Vincular Nodos a Vehiculos
|
||||
|
||||
### En el Dashboard
|
||||
|
||||
1. Ir a **Meshtastic** o detalle del vehiculo > **Dispositivo**
|
||||
2. Click **+ Agregar dispositivo Meshtastic**
|
||||
3. Ingresar:
|
||||
- **Node ID**: ID del nodo (ej: !a1b2c3d4)
|
||||
- **Nombre**: Identificador amigable
|
||||
- **Vehiculo**: Seleccionar vehiculo
|
||||
4. Click **Guardar**
|
||||
|
||||
### Obtener Node ID
|
||||
|
||||
En la app Meshtastic:
|
||||
- Ir a Settings > Device
|
||||
- El Node ID aparece como "!xxxxxxxx"
|
||||
|
||||
O via CLI:
|
||||
```bash
|
||||
meshtastic --info | grep "Node"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Panel Meshtastic en Dashboard
|
||||
|
||||
El panel muestra:
|
||||
|
||||
### Estado de Red
|
||||
- Nodos totales
|
||||
- Nodos online
|
||||
- Nodos offline
|
||||
- Calidad de senal promedio
|
||||
|
||||
### Mapa de Cobertura
|
||||
- Gateway
|
||||
- Nodos y conexiones
|
||||
- Alcance estimado
|
||||
|
||||
### Lista de Nodos
|
||||
| Nodo | Vehiculo | Bateria | Senal | Ultimo msg |
|
||||
|------|----------|---------|-------|------------|
|
||||
| !a1b2 | Camion-05 | 78% | -72dB | hace 30s |
|
||||
| !c3d4 | Van-03 | 45% | -89dB | hace 45s |
|
||||
|
||||
### Diagnosticos
|
||||
- Mensajes por minuto
|
||||
- Paquetes perdidos
|
||||
- Latencia promedio
|
||||
|
||||
---
|
||||
|
||||
## Topologia de Red
|
||||
|
||||
### Red Simple (Linea de Vista)
|
||||
|
||||
```
|
||||
[Vehiculo] <-- LoRa --> [Gateway] <-- Internet --> [Servidor]
|
||||
```
|
||||
|
||||
Alcance: 5-15 km con linea de vista
|
||||
|
||||
### Red con Relays
|
||||
|
||||
```
|
||||
[Vehiculo lejano]
|
||||
|
|
||||
| LoRa
|
||||
v
|
||||
[Vehiculo relay] <-- LoRa --> [Gateway]
|
||||
^
|
||||
| LoRa
|
||||
|
|
||||
[Otro vehiculo]
|
||||
```
|
||||
|
||||
Cada vehiculo puede actuar como relay si esta configurado como ROUTER_CLIENT.
|
||||
|
||||
### Consejos para Mejor Cobertura
|
||||
|
||||
1. **Gateway en punto alto**: Edificio, torre, cerro
|
||||
2. **Antenas externas**: Mejor ganancia
|
||||
3. **Evitar obstaculos**: Metal, concreto bloquean senal
|
||||
4. **Vehiculos como relays**: Configurar ROUTER_CLIENT
|
||||
|
||||
---
|
||||
|
||||
## Solucion de Problemas
|
||||
|
||||
### Nodo no aparece en el sistema
|
||||
|
||||
1. Verificar que el gateway recibe mensajes:
|
||||
```bash
|
||||
mosquitto_sub -h localhost -t "flotillas/mesh/#" -u mesh_gateway -P password
|
||||
```
|
||||
|
||||
2. Verificar que el nodo esta en el mismo canal:
|
||||
- Mismo nombre de canal
|
||||
- Misma PSK (clave)
|
||||
|
||||
3. Verificar alcance: El nodo debe estar dentro del alcance del gateway o de un relay.
|
||||
|
||||
### Ubicaciones no se actualizan
|
||||
|
||||
1. Verificar que GPS esta habilitado en el nodo:
|
||||
```bash
|
||||
meshtastic --info | grep "GPS"
|
||||
```
|
||||
|
||||
2. Verificar intervalo de broadcast:
|
||||
```bash
|
||||
meshtastic --get position.position_broadcast_secs
|
||||
```
|
||||
|
||||
3. El nodo debe tener fix GPS (ver LED o app)
|
||||
|
||||
### Conexion MQTT falla
|
||||
|
||||
1. Verificar Mosquitto:
|
||||
```bash
|
||||
systemctl status mosquitto
|
||||
```
|
||||
|
||||
2. Probar conexion:
|
||||
```bash
|
||||
mosquitto_pub -h localhost -t "test" -m "hello" -u mesh_gateway -P password
|
||||
```
|
||||
|
||||
3. Verificar firewall (si gateway es externo):
|
||||
```bash
|
||||
ufw allow 1883/tcp
|
||||
```
|
||||
|
||||
### Bateria se agota rapido
|
||||
|
||||
Optimizar configuracion:
|
||||
```bash
|
||||
# Aumentar intervalo de posicion
|
||||
meshtastic --set position.position_broadcast_secs 60
|
||||
|
||||
# Reducir potencia TX
|
||||
meshtastic --set lora.tx_power 17
|
||||
|
||||
# Habilitar modo ahorro
|
||||
meshtastic --set power.is_power_saving true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Limitaciones
|
||||
|
||||
- **No tiempo real**: Latencia de 10-60 segundos
|
||||
- **Solo ubicacion**: No video ni datos pesados
|
||||
- **Dependiente de relays**: Necesita nodos intermedios para grandes distancias
|
||||
- **Interferencia**: Otras redes LoRa pueden afectar
|
||||
|
||||
---
|
||||
|
||||
## Recursos
|
||||
|
||||
- [Documentacion Meshtastic](https://meshtastic.org/docs/)
|
||||
- [Flasher Web](https://flasher.meshtastic.org/)
|
||||
- [Comunidad Discord](https://discord.gg/meshtastic)
|
||||
- [Mapa de Nodos](https://meshtastic.liamcottle.net/)
|
||||
557
docs/guias/troubleshooting.md
Normal file
557
docs/guias/troubleshooting.md
Normal file
@@ -0,0 +1,557 @@
|
||||
# Solucion de Problemas
|
||||
|
||||
Guia para diagnosticar y resolver problemas comunes en FlotillasGPS.
|
||||
|
||||
## Diagnostico Rapido
|
||||
|
||||
### Verificar Estado de Servicios
|
||||
|
||||
```bash
|
||||
# Ver estado de todos los servicios
|
||||
systemctl status flotillas-api flotillas-web traccar mediamtx cloudflared redis postgresql
|
||||
|
||||
# Resumen rapido
|
||||
for svc in flotillas-api flotillas-web traccar mediamtx cloudflared; do
|
||||
echo "$svc: $(systemctl is-active $svc)"
|
||||
done
|
||||
```
|
||||
|
||||
### Verificar Logs
|
||||
|
||||
```bash
|
||||
# API Backend
|
||||
journalctl -u flotillas-api -f
|
||||
|
||||
# Frontend
|
||||
journalctl -u flotillas-web -f
|
||||
|
||||
# Traccar (GPS)
|
||||
journalctl -u traccar -f
|
||||
|
||||
# Cloudflare Tunnel
|
||||
journalctl -u cloudflared -f
|
||||
```
|
||||
|
||||
### Verificar Conectividad
|
||||
|
||||
```bash
|
||||
# Puerto GPS
|
||||
netstat -tlnp | grep 5055
|
||||
|
||||
# Puerto API
|
||||
curl http://localhost:8000/api/v1/health
|
||||
|
||||
# Puerto Frontend
|
||||
curl http://localhost:3000
|
||||
|
||||
# Base de datos
|
||||
psql -U flotillas -d flotillas_db -c "SELECT 1"
|
||||
|
||||
# Redis
|
||||
redis-cli ping
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Problemas de Acceso Web
|
||||
|
||||
### No puedo acceder al dashboard
|
||||
|
||||
**Sintomas**: El navegador muestra error de conexion o timeout.
|
||||
|
||||
**Verificar**:
|
||||
|
||||
1. Estado del tunnel de Cloudflare:
|
||||
```bash
|
||||
systemctl status cloudflared
|
||||
cloudflared tunnel info flotillas
|
||||
```
|
||||
|
||||
2. Estado del frontend:
|
||||
```bash
|
||||
systemctl status flotillas-web
|
||||
curl http://localhost:3000
|
||||
```
|
||||
|
||||
**Soluciones**:
|
||||
|
||||
- Reiniciar el tunnel:
|
||||
```bash
|
||||
systemctl restart cloudflared
|
||||
```
|
||||
|
||||
- Verificar configuracion DNS en Cloudflare dashboard
|
||||
|
||||
- Verificar que el dominio apunta al tunnel correcto
|
||||
|
||||
### Error 502 Bad Gateway
|
||||
|
||||
**Causa**: El backend no esta respondiendo.
|
||||
|
||||
**Verificar**:
|
||||
```bash
|
||||
systemctl status flotillas-api
|
||||
curl http://localhost:8000/api/v1/health
|
||||
```
|
||||
|
||||
**Soluciones**:
|
||||
```bash
|
||||
# Reiniciar backend
|
||||
systemctl restart flotillas-api
|
||||
|
||||
# Ver logs de error
|
||||
journalctl -u flotillas-api -n 100 --no-pager
|
||||
```
|
||||
|
||||
### Error de SSL/Certificado
|
||||
|
||||
**Causa**: Problema con Cloudflare.
|
||||
|
||||
**Soluciones**:
|
||||
|
||||
1. En Cloudflare dashboard, verificar que SSL este en "Full" o "Full (strict)"
|
||||
2. Verificar que el dominio este activo
|
||||
3. Esperar propagacion DNS (hasta 24 horas)
|
||||
|
||||
---
|
||||
|
||||
## Problemas con GPS
|
||||
|
||||
### Los dispositivos GPS no se conectan
|
||||
|
||||
**Sintomas**: Vehiculos aparecen offline, no se reciben ubicaciones.
|
||||
|
||||
**Verificar**:
|
||||
|
||||
1. Puerto 5055 abierto:
|
||||
```bash
|
||||
# Desde el servidor
|
||||
netstat -tlnp | grep 5055
|
||||
|
||||
# Desde fuera (otra maquina)
|
||||
nc -zv IP_SERVIDOR 5055
|
||||
```
|
||||
|
||||
2. Traccar funcionando:
|
||||
```bash
|
||||
systemctl status traccar
|
||||
journalctl -u traccar -f
|
||||
```
|
||||
|
||||
3. Firewall:
|
||||
```bash
|
||||
ufw status
|
||||
# Debe mostrar 5055/tcp ALLOW
|
||||
```
|
||||
|
||||
**Soluciones**:
|
||||
|
||||
- Abrir puerto en firewall:
|
||||
```bash
|
||||
ufw allow 5055/tcp
|
||||
```
|
||||
|
||||
- Verificar configuracion del GPS:
|
||||
- IP/dominio del servidor correcto
|
||||
- Puerto 5055
|
||||
- Protocolo correcto (ver manual del GPS)
|
||||
|
||||
- Reiniciar Traccar:
|
||||
```bash
|
||||
systemctl restart traccar
|
||||
```
|
||||
|
||||
### GPS conecta pero no aparece en el mapa
|
||||
|
||||
**Causa**: El dispositivo no esta vinculado a un vehiculo.
|
||||
|
||||
**Solucion**:
|
||||
|
||||
1. Verificar que el dispositivo esta registrado en Traccar:
|
||||
```bash
|
||||
# Ver dispositivos en Traccar
|
||||
curl http://localhost:8082/api/devices
|
||||
```
|
||||
|
||||
2. Vincular el dispositivo al vehiculo desde el dashboard
|
||||
|
||||
### Ubicaciones con retraso
|
||||
|
||||
**Causas posibles**:
|
||||
|
||||
1. Problema de red del GPS
|
||||
2. Intervalo de reporte muy largo
|
||||
3. Problema de procesamiento
|
||||
|
||||
**Verificar**:
|
||||
```bash
|
||||
# Ver ubicaciones recientes en DB
|
||||
psql -U flotillas -d flotillas_db -c "
|
||||
SELECT vehiculo_id, tiempo, lat, lng
|
||||
FROM ubicaciones
|
||||
ORDER BY tiempo DESC
|
||||
LIMIT 10;
|
||||
"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Problemas con la App Movil
|
||||
|
||||
### La app no envia ubicacion
|
||||
|
||||
**Verificar en el telefono**:
|
||||
|
||||
1. Permiso de ubicacion en "Siempre"
|
||||
2. GPS activado
|
||||
3. Datos moviles o WiFi activo
|
||||
4. App no en modo ahorro de bateria
|
||||
|
||||
**Verificar en el servidor**:
|
||||
```bash
|
||||
# Ver ultimas ubicaciones de apps
|
||||
journalctl -u flotillas-api | grep "ubicacion" | tail -20
|
||||
```
|
||||
|
||||
### App no puede conectar al servidor
|
||||
|
||||
**Causas**:
|
||||
|
||||
1. Sin conexion a internet
|
||||
2. Token expirado
|
||||
3. Dispositivo no registrado
|
||||
|
||||
**Solucion**:
|
||||
|
||||
1. Verificar conexion a internet
|
||||
2. Cerrar sesion y volver a entrar
|
||||
3. Verificar que el conductor tiene dispositivo asignado
|
||||
|
||||
### Notificaciones no llegan
|
||||
|
||||
**Verificar**:
|
||||
|
||||
1. Permiso de notificaciones en el telefono
|
||||
2. App no silenciada
|
||||
3. Token de push registrado
|
||||
|
||||
**En el servidor**:
|
||||
```bash
|
||||
# Ver logs de notificaciones
|
||||
journalctl -u flotillas-api | grep "push\|notification"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Problemas de Video
|
||||
|
||||
### Camara no conecta
|
||||
|
||||
**Verificar**:
|
||||
|
||||
1. URL del stream correcta
|
||||
2. Credenciales correctas
|
||||
3. Camara accesible desde el servidor
|
||||
|
||||
```bash
|
||||
# Probar conexion RTSP
|
||||
ffprobe rtsp://usuario:password@IP_CAMARA/stream
|
||||
```
|
||||
|
||||
**Soluciones**:
|
||||
|
||||
- Verificar que la camara y el servidor estan en la misma red (o hay ruta)
|
||||
- Verificar puerto de la camara no bloqueado
|
||||
- Probar con VLC desde otra maquina
|
||||
|
||||
### Video con lag/retraso
|
||||
|
||||
**Causas**:
|
||||
|
||||
1. Ancho de banda insuficiente
|
||||
2. Servidor sobrecargado
|
||||
3. Configuracion de bitrate muy alto
|
||||
|
||||
**Soluciones**:
|
||||
|
||||
- Reducir calidad del stream en configuracion de camara
|
||||
- Verificar uso de CPU/RAM del servidor
|
||||
- Usar HLS en lugar de WebRTC para conexiones lentas
|
||||
|
||||
### No se guardan grabaciones
|
||||
|
||||
**Verificar**:
|
||||
|
||||
1. Espacio en disco:
|
||||
```bash
|
||||
df -h /opt/flotillas/videos
|
||||
```
|
||||
|
||||
2. Permisos:
|
||||
```bash
|
||||
ls -la /opt/flotillas/videos
|
||||
```
|
||||
|
||||
**Solucion**:
|
||||
```bash
|
||||
# Liberar espacio
|
||||
find /opt/flotillas/videos -name "*.mp4" -mtime +30 -delete
|
||||
|
||||
# Arreglar permisos
|
||||
chown -R www-data:www-data /opt/flotillas/videos
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Problemas de Base de Datos
|
||||
|
||||
### Error de conexion a PostgreSQL
|
||||
|
||||
```bash
|
||||
# Verificar estado
|
||||
systemctl status postgresql
|
||||
|
||||
# Verificar que acepta conexiones
|
||||
psql -U flotillas -d flotillas_db -c "SELECT 1"
|
||||
```
|
||||
|
||||
**Soluciones**:
|
||||
```bash
|
||||
# Reiniciar PostgreSQL
|
||||
systemctl restart postgresql
|
||||
|
||||
# Ver logs
|
||||
journalctl -u postgresql -f
|
||||
```
|
||||
|
||||
### Base de datos lenta
|
||||
|
||||
**Verificar**:
|
||||
```bash
|
||||
# Ver consultas lentas
|
||||
psql -U flotillas -d flotillas_db -c "
|
||||
SELECT pid, now() - pg_stat_activity.query_start AS duration, query
|
||||
FROM pg_stat_activity
|
||||
WHERE state != 'idle'
|
||||
ORDER BY duration DESC;
|
||||
"
|
||||
```
|
||||
|
||||
**Soluciones**:
|
||||
|
||||
1. Ejecutar VACUUM:
|
||||
```bash
|
||||
psql -U flotillas -d flotillas_db -c "VACUUM ANALYZE;"
|
||||
```
|
||||
|
||||
2. Verificar indices:
|
||||
```bash
|
||||
psql -U flotillas -d flotillas_db -c "\di"
|
||||
```
|
||||
|
||||
### Disco lleno por ubicaciones
|
||||
|
||||
**Verificar**:
|
||||
```bash
|
||||
psql -U flotillas -d flotillas_db -c "
|
||||
SELECT pg_size_pretty(pg_total_relation_size('ubicaciones'));
|
||||
"
|
||||
```
|
||||
|
||||
**Solucion**: Comprimir datos antiguos (TimescaleDB):
|
||||
```bash
|
||||
psql -U flotillas -d flotillas_db -c "
|
||||
SELECT compress_chunk(c)
|
||||
FROM show_chunks('ubicaciones', older_than => INTERVAL '7 days') c;
|
||||
"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Problemas de Rendimiento
|
||||
|
||||
### Servidor lento
|
||||
|
||||
**Verificar recursos**:
|
||||
```bash
|
||||
# CPU y RAM
|
||||
htop
|
||||
|
||||
# Disco
|
||||
iostat -x 1
|
||||
|
||||
# Conexiones de red
|
||||
ss -s
|
||||
```
|
||||
|
||||
**Soluciones**:
|
||||
|
||||
1. Aumentar RAM de la VM
|
||||
2. Agregar mas cores de CPU
|
||||
3. Usar SSD para base de datos
|
||||
4. Optimizar consultas lentas
|
||||
|
||||
### API responde lento
|
||||
|
||||
**Verificar**:
|
||||
```bash
|
||||
# Tiempo de respuesta
|
||||
time curl http://localhost:8000/api/v1/health
|
||||
|
||||
# Workers activos
|
||||
ps aux | grep uvicorn
|
||||
```
|
||||
|
||||
**Soluciones**:
|
||||
|
||||
1. Aumentar workers en el servicio:
|
||||
```bash
|
||||
# Editar /etc/systemd/system/flotillas-api.service
|
||||
# Cambiar --workers 4 a --workers 8
|
||||
systemctl daemon-reload
|
||||
systemctl restart flotillas-api
|
||||
```
|
||||
|
||||
2. Verificar conexiones a Redis:
|
||||
```bash
|
||||
redis-cli info clients
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Problemas de Meshtastic
|
||||
|
||||
### Nodos no aparecen
|
||||
|
||||
**Verificar MQTT**:
|
||||
```bash
|
||||
# Estado de Mosquitto
|
||||
systemctl status mosquitto
|
||||
|
||||
# Suscribirse para ver mensajes
|
||||
mosquitto_sub -h localhost -t "flotillas/mesh/#" -u mesh_gateway -P password
|
||||
```
|
||||
|
||||
**Verificar configuracion del gateway**:
|
||||
- MQTT habilitado
|
||||
- Servidor y credenciales correctos
|
||||
- Topic correcto
|
||||
|
||||
### Ubicaciones de mesh no se guardan
|
||||
|
||||
**Verificar**:
|
||||
```bash
|
||||
journalctl -u flotillas-api | grep "meshtastic\|mesh"
|
||||
```
|
||||
|
||||
**Solucion**: Verificar que el servicio MQTT esta corriendo en el backend.
|
||||
|
||||
---
|
||||
|
||||
## Backup y Restauracion
|
||||
|
||||
### Backup falla
|
||||
|
||||
**Verificar**:
|
||||
```bash
|
||||
# Espacio en disco
|
||||
df -h /opt/flotillas/backups
|
||||
|
||||
# Permisos
|
||||
ls -la /opt/flotillas/scripts/backup.sh
|
||||
```
|
||||
|
||||
**Ejecutar manualmente para ver errores**:
|
||||
```bash
|
||||
/opt/flotillas/scripts/backup.sh 2>&1 | tee /tmp/backup.log
|
||||
```
|
||||
|
||||
### Restauracion falla
|
||||
|
||||
**Verificar integridad del backup**:
|
||||
```bash
|
||||
gunzip -t /opt/flotillas/backups/db_FECHA.sql.gz
|
||||
```
|
||||
|
||||
**Restaurar paso a paso**:
|
||||
```bash
|
||||
# Parar servicios
|
||||
systemctl stop flotillas-api
|
||||
|
||||
# Recrear base de datos
|
||||
psql -U postgres -c "DROP DATABASE flotillas_db;"
|
||||
psql -U postgres -c "CREATE DATABASE flotillas_db OWNER flotillas;"
|
||||
|
||||
# Restaurar
|
||||
gunzip -c backup.sql.gz | psql -U flotillas -d flotillas_db
|
||||
|
||||
# Iniciar servicios
|
||||
systemctl start flotillas-api
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Comandos Utiles de Diagnostico
|
||||
|
||||
```bash
|
||||
# Estado general del sistema
|
||||
systemctl status flotillas-api flotillas-web traccar mediamtx cloudflared
|
||||
|
||||
# Uso de recursos
|
||||
htop
|
||||
df -h
|
||||
free -h
|
||||
|
||||
# Logs en tiempo real
|
||||
journalctl -u flotillas-api -f
|
||||
|
||||
# Conexiones activas
|
||||
ss -tlnp
|
||||
|
||||
# Verificar puertos
|
||||
netstat -tlnp
|
||||
|
||||
# Test de API
|
||||
curl -s http://localhost:8000/api/v1/health | jq
|
||||
|
||||
# Test de base de datos
|
||||
psql -U flotillas -d flotillas_db -c "SELECT COUNT(*) FROM vehiculos;"
|
||||
|
||||
# Ultimas ubicaciones
|
||||
psql -U flotillas -d flotillas_db -c "
|
||||
SELECT v.nombre, u.tiempo, u.lat, u.lng, u.velocidad
|
||||
FROM ubicaciones u
|
||||
JOIN vehiculos v ON u.vehiculo_id = v.id
|
||||
ORDER BY u.tiempo DESC
|
||||
LIMIT 10;
|
||||
"
|
||||
|
||||
# Alertas pendientes
|
||||
psql -U flotillas -d flotillas_db -c "
|
||||
SELECT COUNT(*) as pendientes FROM alertas WHERE atendida = false;
|
||||
"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Contacto de Soporte
|
||||
|
||||
Si no puedes resolver el problema:
|
||||
|
||||
1. Recolectar informacion:
|
||||
```bash
|
||||
# Crear archivo de diagnostico
|
||||
{
|
||||
echo "=== FECHA ==="
|
||||
date
|
||||
echo "=== SERVICIOS ==="
|
||||
systemctl status flotillas-api flotillas-web traccar mediamtx cloudflared
|
||||
echo "=== RECURSOS ==="
|
||||
free -h
|
||||
df -h
|
||||
echo "=== LOGS RECIENTES ==="
|
||||
journalctl -u flotillas-api -n 50 --no-pager
|
||||
} > /tmp/diagnostico.txt
|
||||
```
|
||||
|
||||
2. Enviar `diagnostico.txt` al equipo de soporte
|
||||
412
docs/guias/usuario-admin.md
Normal file
412
docs/guias/usuario-admin.md
Normal file
@@ -0,0 +1,412 @@
|
||||
# Manual del Administrador
|
||||
|
||||
Guia completa para administrar el sistema FlotillasGPS.
|
||||
|
||||
## Acceso al Sistema
|
||||
|
||||
### Iniciar Sesion
|
||||
|
||||
1. Abrir `https://flotillas.tudominio.com` en el navegador
|
||||
2. Ingresar email y contrasena
|
||||
3. Click en "Ingresar"
|
||||
|
||||
### Cambiar Contrasena
|
||||
|
||||
1. Click en tu nombre (esquina superior derecha)
|
||||
2. Seleccionar "Configuracion"
|
||||
3. En la seccion "Seguridad", click "Cambiar contrasena"
|
||||
4. Ingresar contrasena actual y nueva
|
||||
5. Click "Guardar"
|
||||
|
||||
---
|
||||
|
||||
## Dashboard Principal
|
||||
|
||||
El dashboard muestra un resumen de tu flota:
|
||||
|
||||
### KPIs Principales
|
||||
|
||||
- **Total Vehiculos**: Cantidad de vehiculos registrados
|
||||
- **En Ruta**: Vehiculos actualmente en movimiento
|
||||
- **Detenidos**: Vehiculos detenidos (motor encendido)
|
||||
- **Offline**: Vehiculos sin conexion
|
||||
- **Alertas**: Alertas pendientes de atencion
|
||||
|
||||
### Mapa Resumen
|
||||
|
||||
Muestra la ubicacion de todos los vehiculos. Click en un vehiculo para ver detalles.
|
||||
|
||||
### Alertas Recientes
|
||||
|
||||
Ultimas alertas generadas. Click en "Ver todas" para ir al centro de alertas.
|
||||
|
||||
### Actividad Reciente
|
||||
|
||||
Timeline de eventos del dia: viajes iniciados, entregas, cargas de combustible, etc.
|
||||
|
||||
---
|
||||
|
||||
## Gestion de Vehiculos
|
||||
|
||||
### Agregar Vehiculo
|
||||
|
||||
1. Ir a **Flota** > **Vehiculos**
|
||||
2. Click en **+ Agregar**
|
||||
3. Completar informacion:
|
||||
- **Nombre**: Identificador interno (ej: "Camion-01")
|
||||
- **Placa**: Numero de placa
|
||||
- **Marca/Modelo/Ano**: Datos del vehiculo
|
||||
- **Tipo**: Auto, Camioneta, Camion, Moto, etc.
|
||||
- **Grupo**: Asignar a un grupo (opcional)
|
||||
4. Click **Guardar**
|
||||
|
||||
### Asignar Dispositivo GPS
|
||||
|
||||
Despues de agregar el vehiculo:
|
||||
|
||||
1. En el detalle del vehiculo, ir a pestaña **Dispositivo**
|
||||
2. Click **Asignar dispositivo**
|
||||
3. Seleccionar tipo:
|
||||
- **Traccar**: GPS hardware tradicional
|
||||
- **App Movil**: Celular del conductor
|
||||
- **Meshtastic**: Dispositivo LoRa
|
||||
4. Ingresar identificador del dispositivo (IMEI o ID)
|
||||
5. Click **Guardar**
|
||||
|
||||
### Asignar Conductor
|
||||
|
||||
1. En el detalle del vehiculo, ir a pestaña **General**
|
||||
2. En "Conductor asignado", seleccionar de la lista
|
||||
3. Click **Guardar**
|
||||
|
||||
### Ver Ubicacion en Tiempo Real
|
||||
|
||||
1. Ir a **Mapa**
|
||||
2. Buscar el vehiculo en la lista lateral o en el mapa
|
||||
3. Click en el marcador para ver popup con:
|
||||
- Velocidad actual
|
||||
- Direccion aproximada
|
||||
- Estado del motor
|
||||
- Nivel de combustible (si disponible)
|
||||
|
||||
### Ver Historial de Viajes
|
||||
|
||||
1. En el detalle del vehiculo, ir a pestaña **Viajes**
|
||||
2. Seleccionar rango de fechas
|
||||
3. Click en un viaje para ver detalles
|
||||
4. Click **Replay** para reproducir el recorrido en el mapa
|
||||
|
||||
---
|
||||
|
||||
## Gestion de Conductores
|
||||
|
||||
### Agregar Conductor
|
||||
|
||||
1. Ir a **Flota** > **Conductores**
|
||||
2. Click **+ Agregar**
|
||||
3. Completar informacion:
|
||||
- Nombre y apellido
|
||||
- Telefono (usado para login en app)
|
||||
- Email (opcional)
|
||||
- Numero de licencia
|
||||
- Tipo de licencia
|
||||
- Vencimiento de licencia
|
||||
4. Click **Guardar**
|
||||
|
||||
### Generar Codigo de Acceso para App
|
||||
|
||||
1. En el detalle del conductor, click **Generar codigo**
|
||||
2. Se mostrara un codigo de 6 digitos
|
||||
3. Compartir con el conductor para que instale la app
|
||||
|
||||
### Ver Estadisticas del Conductor
|
||||
|
||||
En el detalle del conductor:
|
||||
|
||||
- **Km recorridos**: Este mes y total
|
||||
- **Score de eficiencia**: Basado en velocidad, frenados, aceleraciones
|
||||
- **Viajes completados**: Cantidad de viajes
|
||||
- **Tiempo en ruta**: Horas conduciendo
|
||||
- **Infracciones**: Excesos de velocidad, salidas de geocerca
|
||||
|
||||
---
|
||||
|
||||
## Centro de Alertas
|
||||
|
||||
### Tipos de Alertas
|
||||
|
||||
| Tipo | Severidad | Descripcion |
|
||||
|------|-----------|-------------|
|
||||
| Exceso de velocidad | Media | Vehiculo supero limite |
|
||||
| Salida de geocerca | Critica | Salio de zona permitida |
|
||||
| Entrada a geocerca restringida | Critica | Entro a zona prohibida |
|
||||
| Parada prolongada | Media | Detenido mas de X minutos |
|
||||
| Motor encendido detenido | Baja | Motor ON sin movimiento |
|
||||
| Bateria baja | Media | Bateria del GPS baja |
|
||||
| Vehiculo offline | Media | Sin señal por X minutos |
|
||||
| Frenado brusco | Baja | Desaceleracion fuerte |
|
||||
| Aceleracion brusca | Baja | Aceleracion fuerte |
|
||||
|
||||
### Atender una Alerta
|
||||
|
||||
1. Ir a **Alertas**
|
||||
2. Click en la alerta para ver detalles
|
||||
3. Revisar ubicacion en el mapa
|
||||
4. Opcionalmente, agregar una nota
|
||||
5. Click **Marcar como atendida**
|
||||
|
||||
### Configurar Reglas de Alertas
|
||||
|
||||
1. Ir a **Configuracion** > **Alertas**
|
||||
2. Ajustar parametros:
|
||||
- Velocidad maxima global
|
||||
- Tiempo de parada para alerta
|
||||
- Tiempo offline para alerta
|
||||
3. Activar/desactivar notificaciones por email
|
||||
|
||||
---
|
||||
|
||||
## Geocercas
|
||||
|
||||
Las geocercas son zonas geograficas que generan alertas cuando un vehiculo entra o sale.
|
||||
|
||||
### Crear Geocerca
|
||||
|
||||
1. Ir a **Control** > **Geocercas**
|
||||
2. Click **+ Nueva**
|
||||
3. En el mapa, dibujar la zona:
|
||||
- **Poligono**: Click en cada vertice, doble-click para cerrar
|
||||
- **Circulo**: Click en el centro, arrastrar para definir radio
|
||||
- **Rectangulo**: Click y arrastrar
|
||||
4. Configurar:
|
||||
- **Nombre**: Identificador de la zona
|
||||
- **Color**: Para visualizacion en mapa
|
||||
- **Alertar al entrar**: Si/No
|
||||
- **Alertar al salir**: Si/No
|
||||
- **Limite de velocidad**: Velocidad maxima dentro (opcional)
|
||||
- **Horario activo**: Dias y horas en que aplica
|
||||
5. Seleccionar vehiculos a los que aplica
|
||||
6. Click **Guardar**
|
||||
|
||||
### Tipos de Uso Comunes
|
||||
|
||||
- **Zona de operacion**: Alerta si el vehiculo SALE
|
||||
- **Zona restringida**: Alerta si el vehiculo ENTRA
|
||||
- **Clientes**: Detectar llegada/salida de clientes
|
||||
- **Zonas de velocidad**: Limite de velocidad en zonas escolares, etc.
|
||||
|
||||
---
|
||||
|
||||
## Video en Vivo
|
||||
|
||||
### Requisitos
|
||||
|
||||
- Camara compatible (dashcam con RTSP, DVR, camara IP)
|
||||
- Camara conectada a la red del vehiculo
|
||||
- Vehiculo con conexion de datos
|
||||
|
||||
### Agregar Camara
|
||||
|
||||
1. En el detalle del vehiculo, ir a pestaña **Video**
|
||||
2. Click **+ Agregar camara**
|
||||
3. Configurar:
|
||||
- **Nombre**: Ej. "Frontal", "Interior"
|
||||
- **Posicion**: Frontal, Trasera, Interior, etc.
|
||||
- **Tipo**: RTSP, ONVIF, etc.
|
||||
- **URL**: URL del stream (ej: rtsp://192.168.1.100/stream)
|
||||
- **Usuario/Contrasena**: Si requiere autenticacion
|
||||
4. Click **Probar conexion**
|
||||
5. Si funciona, click **Guardar**
|
||||
|
||||
### Ver Video en Vivo
|
||||
|
||||
1. Ir a **Video** > **En Vivo**
|
||||
2. Seleccionar layout (1, 2x2, 3x3, 4x4)
|
||||
3. Click en una celda para seleccionar camara
|
||||
4. Controles disponibles:
|
||||
- **Pantalla completa**: Maximizar camara
|
||||
- **Captura**: Tomar foto
|
||||
- **Grabar**: Iniciar grabacion manual
|
||||
|
||||
### Ver Grabaciones
|
||||
|
||||
1. Ir a **Video** > **Grabaciones**
|
||||
2. Filtrar por:
|
||||
- Vehiculo
|
||||
- Camara
|
||||
- Fecha y hora
|
||||
- Tipo (continua, evento, manual)
|
||||
3. Click en una grabacion para reproducir
|
||||
4. Descargar si es necesario
|
||||
|
||||
---
|
||||
|
||||
## Reportes
|
||||
|
||||
### Generar Reporte
|
||||
|
||||
1. Ir a **Reportes**
|
||||
2. Seleccionar tipo:
|
||||
- **Recorridos**: Km, tiempos, rutas
|
||||
- **Combustible**: Consumo, cargas, rendimiento
|
||||
- **Conductores**: Desempeno, infracciones
|
||||
- **Alertas**: Resumen de incidentes
|
||||
- **Mantenimiento**: Servicios realizados y pendientes
|
||||
- **Ejecutivo**: Resumen general
|
||||
3. Configurar parametros:
|
||||
- Periodo (hoy, semana, mes, personalizado)
|
||||
- Vehiculos (todos o seleccion)
|
||||
- Formato (PDF, Excel, CSV)
|
||||
4. Click **Generar**
|
||||
5. Descargar cuando este listo
|
||||
|
||||
### Programar Reportes Automaticos
|
||||
|
||||
1. Ir a **Reportes** > **Programados**
|
||||
2. Click **+ Programar**
|
||||
3. Seleccionar tipo y parametros
|
||||
4. Configurar frecuencia:
|
||||
- Diario (hora)
|
||||
- Semanal (dia y hora)
|
||||
- Mensual (dia del mes)
|
||||
5. Ingresar emails de destinatarios
|
||||
6. Click **Guardar**
|
||||
|
||||
---
|
||||
|
||||
## Mantenimiento
|
||||
|
||||
### Tipos de Mantenimiento
|
||||
|
||||
Configurar en **Configuracion** > **Tipos de Mantenimiento**:
|
||||
|
||||
- Cambio de aceite (cada X km o X dias)
|
||||
- Rotacion de llantas
|
||||
- Revision de frenos
|
||||
- Afinacion
|
||||
- Revision general
|
||||
|
||||
### Programar Mantenimiento
|
||||
|
||||
1. En detalle del vehiculo, ir a pestaña **Mantenimiento**
|
||||
2. Click **+ Programar**
|
||||
3. Seleccionar tipo de servicio
|
||||
4. Ingresar:
|
||||
- Fecha programada o Km programado
|
||||
- Taller/Proveedor
|
||||
- Costo estimado
|
||||
- Notas
|
||||
5. Click **Guardar**
|
||||
|
||||
### Registrar Servicio Realizado
|
||||
|
||||
1. En el mantenimiento programado, click **Completar**
|
||||
2. Ingresar:
|
||||
- Fecha real
|
||||
- Odometro actual
|
||||
- Costo real
|
||||
- Notas del servicio
|
||||
- Adjuntar factura (opcional)
|
||||
3. Click **Guardar**
|
||||
|
||||
El sistema programara automaticamente el siguiente servicio segun los intervalos configurados.
|
||||
|
||||
---
|
||||
|
||||
## Combustible
|
||||
|
||||
### Registrar Carga
|
||||
|
||||
Los conductores pueden registrar cargas desde la app. Tambien puedes hacerlo manualmente:
|
||||
|
||||
1. En detalle del vehiculo, ir a pestaña **Combustible**
|
||||
2. Click **+ Registrar carga**
|
||||
3. Ingresar:
|
||||
- Litros
|
||||
- Precio por litro
|
||||
- Odometro
|
||||
- Estacion (opcional)
|
||||
4. Click **Guardar**
|
||||
|
||||
### Ver Consumo y Rendimiento
|
||||
|
||||
En la pestaña **Combustible** del vehiculo:
|
||||
|
||||
- Grafico de consumo mensual
|
||||
- Rendimiento promedio (km/L)
|
||||
- Comparativa con otros vehiculos
|
||||
- Historial de cargas
|
||||
|
||||
---
|
||||
|
||||
## Mensajes a Conductores
|
||||
|
||||
### Enviar Mensaje
|
||||
|
||||
1. En detalle del conductor, click **Enviar mensaje**
|
||||
2. O ir a **Comunicacion** > **Mensajes**
|
||||
3. Seleccionar conductor(es)
|
||||
4. Escribir mensaje
|
||||
5. Click **Enviar**
|
||||
|
||||
El conductor recibira notificacion push en la app.
|
||||
|
||||
### Ver Respuestas
|
||||
|
||||
Los mensajes y respuestas aparecen como conversacion en el detalle del conductor.
|
||||
|
||||
---
|
||||
|
||||
## Configuracion del Sistema
|
||||
|
||||
### General
|
||||
|
||||
- **Zona horaria**: Importante para reportes correctos
|
||||
- **Unidades**: Kilometros/Millas, Litros/Galones
|
||||
- **Moneda**: Para costos de combustible y mantenimiento
|
||||
|
||||
### Alertas
|
||||
|
||||
- Velocidad maxima global
|
||||
- Tiempo de parada para alerta
|
||||
- Tiempo offline para alerta
|
||||
- Notificaciones por email
|
||||
|
||||
### Retencion de Datos
|
||||
|
||||
- Ubicaciones detalladas: X dias
|
||||
- Videos: X dias
|
||||
- Alertas: X dias
|
||||
|
||||
---
|
||||
|
||||
## Backup y Restauracion
|
||||
|
||||
### Backup Manual
|
||||
|
||||
```bash
|
||||
ssh admin@servidor
|
||||
/opt/flotillas/scripts/backup.sh
|
||||
```
|
||||
|
||||
Los backups se guardan en `/opt/flotillas/backups/`
|
||||
|
||||
### Restaurar Backup
|
||||
|
||||
```bash
|
||||
/opt/flotillas/scripts/restore.sh /opt/flotillas/backups/db_20260121.sql.gz
|
||||
```
|
||||
|
||||
### Backups Automaticos
|
||||
|
||||
Se ejecutan diariamente a las 3:00 AM. Se mantienen los ultimos 7 dias.
|
||||
|
||||
---
|
||||
|
||||
## Soporte
|
||||
|
||||
Para problemas tecnicos:
|
||||
|
||||
1. Revisar [Solucion de Problemas](troubleshooting.md)
|
||||
2. Revisar logs: `journalctl -u flotillas-api -f`
|
||||
3. Contactar soporte tecnico
|
||||
332
docs/guias/usuario-conductor.md
Normal file
332
docs/guias/usuario-conductor.md
Normal file
@@ -0,0 +1,332 @@
|
||||
# Manual del Conductor - App FlotillasGPS
|
||||
|
||||
Guia completa para usar la aplicacion movil de FlotillasGPS.
|
||||
|
||||
## Instalacion de la App
|
||||
|
||||
### Android
|
||||
|
||||
1. Abrir Play Store
|
||||
2. Buscar "FlotillasGPS Conductor"
|
||||
3. Instalar la aplicacion
|
||||
4. Abrir la app
|
||||
|
||||
### iPhone
|
||||
|
||||
1. Abrir App Store
|
||||
2. Buscar "FlotillasGPS Conductor"
|
||||
3. Instalar la aplicacion
|
||||
4. Abrir la app
|
||||
|
||||
---
|
||||
|
||||
## Primer Inicio de Sesion
|
||||
|
||||
### Obtener Codigo de Acceso
|
||||
|
||||
Tu administrador te proporcionara:
|
||||
- Tu numero de telefono registrado
|
||||
- Un codigo de acceso de 6 digitos
|
||||
|
||||
### Iniciar Sesion
|
||||
|
||||
1. Abrir la app
|
||||
2. Ingresar tu numero de telefono
|
||||
3. Ingresar el codigo de 6 digitos
|
||||
4. Tocar **Ingresar**
|
||||
|
||||
### Permisos Necesarios
|
||||
|
||||
La app te pedira permisos. Es importante aceptarlos todos:
|
||||
|
||||
| Permiso | Para que se usa |
|
||||
|---------|-----------------|
|
||||
| Ubicacion (siempre) | Enviar tu posicion aunque la app este cerrada |
|
||||
| Notificaciones | Recibir mensajes del administrador |
|
||||
| Camara | Tomar fotos de tickets (opcional) |
|
||||
|
||||
**IMPORTANTE**: Sin el permiso de ubicacion "siempre", la app no puede rastrear tu posicion correctamente.
|
||||
|
||||
---
|
||||
|
||||
## Pantalla Principal
|
||||
|
||||
Al abrir la app veras:
|
||||
|
||||
### Estado del Vehiculo
|
||||
|
||||
- Nombre del vehiculo asignado
|
||||
- Estado de conexion GPS (verde = enviando)
|
||||
- Placa
|
||||
|
||||
### Boton de Viaje
|
||||
|
||||
- **INICIAR VIAJE**: Toca para comenzar un viaje
|
||||
- **EN VIAJE**: Muestra que estas en ruta
|
||||
|
||||
### Resumen del Dia
|
||||
|
||||
- Kilometros recorridos hoy
|
||||
- Tiempo en ruta
|
||||
- Numero de viajes
|
||||
- Tu score de eficiencia
|
||||
|
||||
---
|
||||
|
||||
## Iniciar un Viaje
|
||||
|
||||
1. En la pantalla principal, toca **INICIAR VIAJE**
|
||||
2. Confirma el inicio
|
||||
3. La app comenzara a registrar tu recorrido
|
||||
|
||||
Durante el viaje:
|
||||
- Tu ubicacion se envia cada 10 segundos
|
||||
- El administrador puede ver tu posicion en tiempo real
|
||||
- Se registran velocidad, paradas y ruta
|
||||
|
||||
---
|
||||
|
||||
## Durante el Viaje
|
||||
|
||||
### Ver el Mapa
|
||||
|
||||
La pantalla de viaje muestra:
|
||||
- Tu ubicacion actual (punto azul)
|
||||
- Tu ruta recorrida (linea)
|
||||
- Proxima parada si hay ruta asignada
|
||||
|
||||
### Registrar una Parada
|
||||
|
||||
Cuando hagas una parada:
|
||||
|
||||
1. Toca **PARADA**
|
||||
2. Selecciona el tipo:
|
||||
- Comida/Descanso
|
||||
- Carga de combustible
|
||||
- Entrega a cliente
|
||||
- Problema mecanico
|
||||
- Trafico
|
||||
- Otro
|
||||
3. Agrega notas si es necesario
|
||||
4. Toca **CONFIRMAR**
|
||||
|
||||
La parada queda registrada con:
|
||||
- Hora de inicio
|
||||
- Ubicacion
|
||||
- Tipo de parada
|
||||
|
||||
Cuando reanudes, toca **CONTINUAR VIAJE**.
|
||||
|
||||
---
|
||||
|
||||
## Cargar Combustible
|
||||
|
||||
Cuando cargues combustible:
|
||||
|
||||
1. Durante una parada, selecciona **Carga de combustible**
|
||||
2. O desde el menu, toca **Combustible**
|
||||
3. Ingresa los datos:
|
||||
- **Litros**: Cantidad cargada
|
||||
- **Precio por litro**: Costo
|
||||
- **Odometro**: Kilometraje actual
|
||||
- **Estacion**: Nombre (opcional)
|
||||
4. Toca **FOTO** para fotografiar el ticket
|
||||
5. Toca **GUARDAR**
|
||||
|
||||
Esto ayuda al administrador a:
|
||||
- Calcular el rendimiento del vehiculo
|
||||
- Llevar control de gastos
|
||||
- Detectar consumos anomalos
|
||||
|
||||
---
|
||||
|
||||
## Finalizar Viaje
|
||||
|
||||
Cuando llegues a tu destino final:
|
||||
|
||||
1. Toca **FINALIZAR VIAJE**
|
||||
2. Confirma la finalizacion
|
||||
3. Se guardara el resumen:
|
||||
- Distancia total
|
||||
- Tiempo de viaje
|
||||
- Paradas realizadas
|
||||
|
||||
---
|
||||
|
||||
## Mensajes
|
||||
|
||||
### Ver Mensajes
|
||||
|
||||
1. Toca el icono de mensajes o la notificacion
|
||||
2. Veras la lista de mensajes del administrador
|
||||
3. Toca un mensaje para leerlo completo
|
||||
|
||||
### Los mensajes no leidos aparecen con punto rojo
|
||||
|
||||
Tipos de mensajes comunes:
|
||||
- Cambios de ruta
|
||||
- Instrucciones especiales
|
||||
- Recordatorios
|
||||
- Avisos importantes
|
||||
|
||||
---
|
||||
|
||||
## Emergencia (SOS)
|
||||
|
||||
En caso de emergencia:
|
||||
|
||||
1. Toca el boton **EMERGENCIA** o **SOS**
|
||||
2. **Manten presionado por 3 segundos**
|
||||
3. Se enviara automaticamente:
|
||||
- Tu ubicacion exacta
|
||||
- Alerta al administrador
|
||||
- Marca de tiempo
|
||||
|
||||
El administrador recibira una notificacion inmediata.
|
||||
|
||||
### Cuando usar el SOS:
|
||||
|
||||
- Accidente
|
||||
- Robo o asalto
|
||||
- Emergencia medica
|
||||
- Vehiculo descompuesto en zona peligrosa
|
||||
- Cualquier situacion de peligro
|
||||
|
||||
### Contacto de emergencia
|
||||
|
||||
La app muestra el numero de telefono de emergencia de tu empresa. Puedes tocarlo para llamar directamente.
|
||||
|
||||
---
|
||||
|
||||
## Mi Perfil
|
||||
|
||||
### Ver mis Estadisticas
|
||||
|
||||
1. Toca **Perfil** en la barra inferior
|
||||
2. Veras:
|
||||
- Tu score de eficiencia (1-5 estrellas)
|
||||
- Km recorridos este mes
|
||||
- Viajes completados
|
||||
- Porcentaje de entregas a tiempo
|
||||
|
||||
### Que afecta mi Score
|
||||
|
||||
| Positivo | Negativo |
|
||||
|----------|----------|
|
||||
| Entregas a tiempo | Excesos de velocidad |
|
||||
| Conduccion suave | Frenados bruscos |
|
||||
| Respetar limites | Aceleraciones fuertes |
|
||||
| Registrar paradas | Desvios de ruta |
|
||||
|
||||
---
|
||||
|
||||
## Configuracion de la App
|
||||
|
||||
### Ajustes disponibles
|
||||
|
||||
1. Toca **Perfil** > **Configuracion**
|
||||
|
||||
| Opcion | Descripcion |
|
||||
|--------|-------------|
|
||||
| Notificaciones | Activar/desactivar alertas |
|
||||
| Tema | Claro u oscuro |
|
||||
| Sonidos | Sonidos de notificacion |
|
||||
| Idioma | Espanol/Ingles |
|
||||
|
||||
### Permisos de Ubicacion
|
||||
|
||||
Si tienes problemas con el GPS:
|
||||
|
||||
1. Ir a **Configuracion** del telefono
|
||||
2. Buscar la app **FlotillasGPS**
|
||||
3. Tocar **Permisos**
|
||||
4. Asegurar que **Ubicacion** este en **Siempre permitir**
|
||||
|
||||
---
|
||||
|
||||
## Uso sin Conexion a Internet
|
||||
|
||||
La app funciona aunque no tengas internet:
|
||||
|
||||
- Tu ubicacion se sigue registrando
|
||||
- Los datos se guardan en el telefono
|
||||
- Cuando vuelvas a tener conexion, se envian automaticamente
|
||||
|
||||
**Maximo almacenamiento offline**: 1000 ubicaciones (~3 horas de viaje)
|
||||
|
||||
---
|
||||
|
||||
## Consejos para Mejor Funcionamiento
|
||||
|
||||
### Bateria
|
||||
|
||||
La app usa aproximadamente 5% de bateria por hora. Para optimizar:
|
||||
|
||||
- Mantener el telefono cargado en el vehiculo
|
||||
- No cerrar la app manualmente
|
||||
- No usar ahorradores de bateria que cierren apps
|
||||
|
||||
### GPS
|
||||
|
||||
Para mejor precision:
|
||||
|
||||
- Colocar el telefono donde vea el cielo (parabrisas)
|
||||
- No cubrir el telefono
|
||||
- Mantener GPS activado
|
||||
|
||||
### Datos Moviles
|
||||
|
||||
Consumo aproximado: 5 MB por dia de uso continuo.
|
||||
|
||||
---
|
||||
|
||||
## Preguntas Frecuentes
|
||||
|
||||
### La app no envia mi ubicacion
|
||||
|
||||
1. Verificar permiso de ubicacion "Siempre"
|
||||
2. Verificar que GPS este activado
|
||||
3. Verificar conexion a internet
|
||||
4. Reiniciar la app
|
||||
|
||||
### No recibo mensajes
|
||||
|
||||
1. Verificar permiso de notificaciones
|
||||
2. Verificar que la app no este en ahorro de bateria
|
||||
3. Verificar conexion a internet
|
||||
|
||||
### El boton de viaje no aparece
|
||||
|
||||
Puede que no tengas un vehiculo asignado. Contacta a tu administrador.
|
||||
|
||||
### Olvide mi codigo de acceso
|
||||
|
||||
Contacta a tu administrador para que genere un nuevo codigo.
|
||||
|
||||
### Como cambio de vehiculo
|
||||
|
||||
Tu administrador debe reasignarte desde el sistema web.
|
||||
|
||||
---
|
||||
|
||||
## Soporte
|
||||
|
||||
Si tienes problemas con la app:
|
||||
|
||||
1. Intenta reiniciar la app
|
||||
2. Verifica tu conexion a internet
|
||||
3. Contacta a tu administrador
|
||||
|
||||
---
|
||||
|
||||
## Resumen Rapido
|
||||
|
||||
| Accion | Como hacerlo |
|
||||
|--------|--------------|
|
||||
| Iniciar viaje | Pantalla principal > INICIAR VIAJE |
|
||||
| Registrar parada | Durante viaje > PARADA |
|
||||
| Cargar combustible | Durante parada > Combustible |
|
||||
| Finalizar viaje | Durante viaje > FINALIZAR |
|
||||
| Ver mensajes | Icono mensajes o notificacion |
|
||||
| Emergencia | Boton SOS (mantener 3 seg) |
|
||||
| Ver estadisticas | Perfil |
|
||||
377
docs/guias/video-streaming.md
Normal file
377
docs/guias/video-streaming.md
Normal file
@@ -0,0 +1,377 @@
|
||||
# Configuracion de Video Streaming
|
||||
|
||||
Guia para configurar camaras y video streaming en FlotillasGPS.
|
||||
|
||||
## Arquitectura de Video
|
||||
|
||||
```
|
||||
Camaras en Vehiculos Servidor Dashboard/App
|
||||
| | |
|
||||
[Dashcam] --RTSP--> [MediaMTX] --WebRTC--> [Navegador]
|
||||
[DVR] --RTSP--> | --HLS----> [App Movil]
|
||||
[Cam IP] --RTSP--> |
|
||||
|
|
||||
[Grabaciones]
|
||||
/opt/flotillas/videos/
|
||||
```
|
||||
|
||||
## Tipos de Camaras Soportadas
|
||||
|
||||
### 1. Dashcams con RTSP
|
||||
|
||||
Marcas recomendadas:
|
||||
- **Viofo** (A129, A139) - Excelente calidad, WiFi
|
||||
- **BlackVue** (DR900X, DR750X) - Premium, Cloud opcional
|
||||
- **Thinkware** (U1000, Q800) - Buena integracion
|
||||
|
||||
Requisitos:
|
||||
- Soporte RTSP
|
||||
- Conexion WiFi o Ethernet
|
||||
- Alimentacion 12V continua
|
||||
|
||||
### 2. DVR Vehiculares
|
||||
|
||||
Para flotas comerciales:
|
||||
- **Hikvision Mobile DVR** - 4/8 canales
|
||||
- **Dahua Mobile DVR** - Industrial
|
||||
- **Howen** - Economico
|
||||
|
||||
Caracteristicas:
|
||||
- Multiples canales (interior, exterior, lateral)
|
||||
- Almacenamiento local SD/HDD
|
||||
- 3G/4G integrado
|
||||
|
||||
### 3. Camaras IP Genericas
|
||||
|
||||
Cualquier camara con:
|
||||
- Protocolo RTSP u ONVIF
|
||||
- Resolucion minima 720p
|
||||
- Alimentacion PoE o 12V
|
||||
|
||||
### 4. Celular como Dashcam
|
||||
|
||||
La app FlotillasGPS puede usar la camara del celular:
|
||||
- Sin costo adicional
|
||||
- Calidad depende del celular
|
||||
- Consume bateria y datos
|
||||
|
||||
---
|
||||
|
||||
## Configuracion de Camaras
|
||||
|
||||
### Obtener URL RTSP
|
||||
|
||||
Formato tipico:
|
||||
```
|
||||
rtsp://usuario:password@IP:puerto/stream
|
||||
```
|
||||
|
||||
Ejemplos por marca:
|
||||
|
||||
| Marca | URL RTSP |
|
||||
|-------|----------|
|
||||
| Hikvision | `rtsp://admin:pass@IP:554/Streaming/Channels/101` |
|
||||
| Dahua | `rtsp://admin:pass@IP:554/cam/realmonitor?channel=1&subtype=0` |
|
||||
| Viofo | `rtsp://IP:554/live/ch00_0` |
|
||||
| Generic | `rtsp://IP:554/stream1` |
|
||||
|
||||
### Verificar Stream
|
||||
|
||||
Antes de agregar al sistema, probar con VLC o ffprobe:
|
||||
|
||||
```bash
|
||||
# Con ffprobe
|
||||
ffprobe rtsp://admin:pass@192.168.1.100:554/stream1
|
||||
|
||||
# Con VLC
|
||||
vlc rtsp://admin:pass@192.168.1.100:554/stream1
|
||||
```
|
||||
|
||||
### Agregar Camara en el Dashboard
|
||||
|
||||
1. Ir a detalle del vehiculo > pestaña **Video**
|
||||
2. Click **+ Agregar camara**
|
||||
3. Completar:
|
||||
- **Nombre**: Ej. "Frontal", "Interior"
|
||||
- **Posicion**: Frontal, Trasera, Interior, Lateral izq/der
|
||||
- **Tipo**: RTSP, ONVIF
|
||||
- **URL Stream**: URL RTSP completa
|
||||
- **Usuario/Password**: Si requiere autenticacion
|
||||
4. Click **Probar conexion**
|
||||
5. Si funciona, click **Guardar**
|
||||
|
||||
---
|
||||
|
||||
## Configuracion de MediaMTX
|
||||
|
||||
### Configuracion Basica
|
||||
|
||||
El archivo `/etc/mediamtx/mediamtx.yml` ya viene configurado. Opciones importantes:
|
||||
|
||||
```yaml
|
||||
# WebRTC (para dashboard web)
|
||||
webrtc: yes
|
||||
webrtcAddress: :8889
|
||||
webrtcAllowOrigin: '*'
|
||||
|
||||
# HLS (para app movil y compatibilidad)
|
||||
hls: yes
|
||||
hlsAddress: :8888
|
||||
hlsSegmentDuration: 1s
|
||||
hlsSegmentCount: 3
|
||||
```
|
||||
|
||||
### Agregar Camara Manualmente
|
||||
|
||||
Si necesitas agregar una camara directamente:
|
||||
|
||||
```bash
|
||||
# Via API de MediaMTX
|
||||
curl -X POST http://localhost:9997/v2/config/paths/add/cam_vehiculo1_frontal \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"source": "rtsp://admin:pass@192.168.1.100:554/stream1",
|
||||
"sourceOnDemand": true,
|
||||
"sourceOnDemandStartTimeout": "10s",
|
||||
"sourceOnDemandCloseAfter": "10s"
|
||||
}'
|
||||
```
|
||||
|
||||
### Verificar Streams Activos
|
||||
|
||||
```bash
|
||||
# Listar paths
|
||||
curl http://localhost:9997/v2/paths/list
|
||||
|
||||
# Ver estado de un path
|
||||
curl http://localhost:9997/v2/paths/get/cam_vehiculo1_frontal
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Conexion de Red
|
||||
|
||||
### Opcion 1: Router 4G en Vehiculo
|
||||
|
||||
```
|
||||
[Camara] --Ethernet/WiFi--> [Router 4G] --Internet--> [Servidor]
|
||||
```
|
||||
|
||||
Configuracion:
|
||||
1. Router 4G con IP publica o VPN
|
||||
2. Port forward del puerto RTSP al servidor
|
||||
3. O usar VPN para conexion segura
|
||||
|
||||
Routers recomendados:
|
||||
- Teltonika RUT240/RUT955
|
||||
- Mikrotik LtAP
|
||||
- Sierra Wireless
|
||||
|
||||
### Opcion 2: Camara con 4G Integrado
|
||||
|
||||
Camaras con SIM integrada:
|
||||
- Hikvision DS-2CD6425G1
|
||||
- Dahua IPC-HFW4X31E-SE
|
||||
|
||||
Ventaja: Sin router adicional
|
||||
Desventaja: Mas costoso, SIM por camara
|
||||
|
||||
### Opcion 3: VPN Site-to-Site
|
||||
|
||||
```
|
||||
[Vehiculo] --VPN--> [Servidor]
|
||||
|
|
||||
[Camara con IP local]
|
||||
```
|
||||
|
||||
Configuracion:
|
||||
1. Router en vehiculo con cliente VPN (WireGuard/OpenVPN)
|
||||
2. Servidor con servidor VPN
|
||||
3. Acceso a camara via IP de VPN
|
||||
|
||||
---
|
||||
|
||||
## Grabacion de Video
|
||||
|
||||
### Tipos de Grabacion
|
||||
|
||||
1. **Continua**: Graba todo el tiempo
|
||||
2. **Por eventos**: Solo cuando hay alertas
|
||||
3. **Manual**: Iniciada por el operador
|
||||
4. **Programada**: En horarios especificos
|
||||
|
||||
### Configuracion de Grabacion
|
||||
|
||||
En el dashboard, por camara:
|
||||
|
||||
- **Grabar continuo**: Si/No
|
||||
- **Grabar eventos**: Si/No
|
||||
- **Calidad continuo**: Baja/Media/Alta
|
||||
- **Calidad eventos**: Media/Alta
|
||||
- **Pre-evento**: Segundos antes del evento (buffer)
|
||||
- **Post-evento**: Segundos despues del evento
|
||||
- **Solo con motor encendido**: Si/No
|
||||
|
||||
### Almacenamiento
|
||||
|
||||
Estimacion de espacio:
|
||||
|
||||
| Calidad | Bitrate | Por hora | Por dia (10h) |
|
||||
|---------|---------|----------|---------------|
|
||||
| Baja (480p) | 1 Mbps | 450 MB | 4.5 GB |
|
||||
| Media (720p) | 2 Mbps | 900 MB | 9 GB |
|
||||
| Alta (1080p) | 4 Mbps | 1.8 GB | 18 GB |
|
||||
|
||||
Para 20 vehiculos con grabacion continua 720p:
|
||||
- Por dia: 180 GB
|
||||
- Por mes: 5.4 TB
|
||||
|
||||
Recomendacion:
|
||||
- Grabacion continua solo en horario laboral
|
||||
- O solo grabacion por eventos
|
||||
|
||||
### Retencion
|
||||
|
||||
Configurar en **Configuracion** > **Retencion de datos**:
|
||||
|
||||
- Videos continuos: 7-14 dias
|
||||
- Videos de eventos: 30-90 dias
|
||||
|
||||
Script de limpieza automatica:
|
||||
```bash
|
||||
# Ejecutar diariamente via cron
|
||||
find /opt/flotillas/videos -name "*.mp4" -mtime +30 -delete
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Ver Video en el Dashboard
|
||||
|
||||
### Video en Vivo
|
||||
|
||||
1. Ir a **Video** > **En Vivo**
|
||||
2. Seleccionar layout (1, 2x2, 3x3)
|
||||
3. Click en celda para seleccionar camara
|
||||
4. Controles:
|
||||
- **Pantalla completa**: Expandir
|
||||
- **Captura**: Tomar screenshot
|
||||
- **Grabar**: Iniciar grabacion manual
|
||||
|
||||
### Video Sincronizado con Viaje
|
||||
|
||||
1. Ir a **Viajes** > seleccionar viaje > **Replay**
|
||||
2. El video se sincroniza con la posicion en el mapa
|
||||
3. Usar timeline para navegar
|
||||
|
||||
### Buscar Grabaciones
|
||||
|
||||
1. Ir a **Video** > **Grabaciones**
|
||||
2. Filtrar por:
|
||||
- Vehiculo
|
||||
- Camara
|
||||
- Fecha/hora
|
||||
- Tipo (continua, evento, manual)
|
||||
3. Click para reproducir
|
||||
4. Descargar si es necesario
|
||||
|
||||
---
|
||||
|
||||
## Eventos de Video
|
||||
|
||||
### Deteccion Automatica
|
||||
|
||||
El sistema puede detectar eventos basados en:
|
||||
|
||||
- **Datos de GPS**: Frenado brusco, aceleracion, impacto
|
||||
- **Sensores de camara**: G-sensor integrado
|
||||
- **Alertas del sistema**: Al generar alerta, marca el video
|
||||
|
||||
### Configurar Deteccion
|
||||
|
||||
En **Configuracion** > **Video** > **Eventos**:
|
||||
|
||||
- Umbral de frenado brusco: -0.5 G
|
||||
- Umbral de aceleracion: 0.4 G
|
||||
- Umbral de impacto: 2.0 G
|
||||
|
||||
### Revisar Eventos
|
||||
|
||||
1. Ir a **Video** > **Eventos**
|
||||
2. Lista de eventos con severidad
|
||||
3. Click para ver clip
|
||||
4. Marcar como revisado
|
||||
5. Agregar notas
|
||||
|
||||
---
|
||||
|
||||
## Solucion de Problemas de Video
|
||||
|
||||
### Camara no conecta
|
||||
|
||||
1. Verificar URL RTSP es correcta
|
||||
2. Verificar credenciales
|
||||
3. Verificar conectividad de red
|
||||
4. Probar con ffprobe:
|
||||
```bash
|
||||
ffprobe -v error rtsp://admin:pass@IP:554/stream
|
||||
```
|
||||
|
||||
### Video con lag alto
|
||||
|
||||
Posibles causas:
|
||||
- Ancho de banda insuficiente
|
||||
- Servidor sobrecargado
|
||||
- Bitrate muy alto
|
||||
|
||||
Soluciones:
|
||||
- Reducir calidad en camara
|
||||
- Usar sub-stream (menor resolucion)
|
||||
- Verificar conexion de datos del vehiculo
|
||||
|
||||
### Video se corta frecuentemente
|
||||
|
||||
Posibles causas:
|
||||
- Conexion 4G inestable
|
||||
- Timeout de conexion
|
||||
|
||||
Soluciones:
|
||||
- Aumentar timeouts en MediaMTX
|
||||
- Configurar reconexion automatica
|
||||
- Usar buffering mas largo
|
||||
|
||||
### No se guardan grabaciones
|
||||
|
||||
Verificar:
|
||||
```bash
|
||||
# Espacio en disco
|
||||
df -h /opt/flotillas/videos
|
||||
|
||||
# Permisos
|
||||
ls -la /opt/flotillas/videos
|
||||
|
||||
# Logs de MediaMTX
|
||||
journalctl -u mediamtx -f
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Seguridad
|
||||
|
||||
### Autenticacion
|
||||
|
||||
- URLs RTSP internas no expuestas a internet
|
||||
- Acceso a video solo via dashboard autenticado
|
||||
- Tokens temporales para streams
|
||||
|
||||
### Encriptacion
|
||||
|
||||
- RTSP puede usar RTSPS (SSL)
|
||||
- WebRTC usa DTLS (encriptado por defecto)
|
||||
- HLS puede usar HTTPS
|
||||
|
||||
### Mejores Practicas
|
||||
|
||||
1. No exponer puertos de video directamente a internet
|
||||
2. Usar VPN para acceso remoto a camaras
|
||||
3. Cambiar credenciales default de camaras
|
||||
4. Actualizar firmware de camaras regularmente
|
||||
Reference in New Issue
Block a user