Skip to content

FiDeLio/comb

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 

Repository files navigation

Sistema de DetecciΓ³n de Recargas y CΓ‘lculo de Consumo Real

Fecha: 6 de Noviembre 2025 MΓ³dulo: Combustible GPS + Estados Operacionales


🎯 Objetivo

Calcular el consumo real de combustible considerando:

  • Recargas externas (combustible agregado desde fuera)
  • Trasvasije interno (movimiento entre tanques del mismo nodo)
  • Ruido por movimiento del barco (variaciones por oleaje)
  • Consumo durante recarga (~80 L/h mientras se carga)

πŸ“Š Problema

Consumo Aparente vs Real

Ejemplo sin considerar recargas:

Stock Inicial (01/10): 5000L
Stock Final (31/10):  3000L
────────────────────────────
Consumo Aparente:      2000L  ❌ INCORRECTO

Si hubo una recarga de 12000L el 09/10:

Stock Inicial:         5000L
Recarga:              +12000L
Stock Final:           3000L
────────────────────────────
Consumo Real:         14000L  βœ… CORRECTO

πŸ” Algoritmo de DetecciΓ³n

1. AgrupaciΓ³n por Timestamp

Agrupa todos los sensores de combustible del nodo por timestamp para analizar la suma total:

{
  ts: '2025-10-09 12:00:00',
  sensors: {
    123: { value: 5000, name: 'Babor' },
    124: { value: 4500, name: 'Estribor' },
    125: { value: 3000, name: 'Popa' }
  },
  total: 12500  // ← Suma de todos los tanques
}

2. Umbrales de DetecciΓ³n

const THRESHOLDS = {
    NOISE: 200,                    // Β±200L variaciΓ³n por movimiento del barco
    EXTERNAL_REFILL_MIN: 5000,     // Recarga externa mΓ­nima
    TRANSFER_MIN: 500,             // Trasvasije mΓ­nimo detectable
    CONSUMPTION_DURING_REFILL: 80, // L/h mientras se carga
    MAX_REFILL_DURATION: 6         // MΓ‘ximo 6 horas para una recarga
};

3. DetecciΓ³n de Eventos

A. Recarga Externa

if (totalDiff > EXTERNAL_REFILL_MIN) {
    // Suma total del nodo aumentΓ³ >5000L
    // Ejemplo: 12500L β†’ 24500L = +12000L recarga
}

B. Trasvasije Interno

if (Math.abs(totalDiff) <= NOISE && tankDiff > TRANSFER_MIN) {
    // Suma total constante PERO un tanque subiΓ³
    // Ejemplo:
    // - Total: 12500L β†’ 12500L (sin cambio)
    // - Babor: 5000L β†’ 6000L (+1000L)
    // - Estribor: 4500L β†’ 3500L (-1000L)
    // = Trasvasije de Estribor β†’ Babor
}

C. Ruido (Filtrado)

if (Math.abs(totalDiff) <= NOISE) {
    // Variaciones pequeΓ±as por movimiento
    // Se ignoran en el cΓ‘lculo de consumo
}

4. Consumo durante Recarga

Durante una recarga, el barco sigue operando y consumiendo:

if (timeDiff > 0 && timeDiff <= MAX_REFILL_DURATION) {
    estimated_consumption = CONSUMPTION_DURING_REFILL * timeDiff;
    // Ej: Recarga de 3 horas = ~240L consumidos durante la carga
}

πŸ—οΈ Arquitectura

Backend

1. FuelRefillDetectionService.js (Nuevo)

Servicio especializado en detectar recargas y trasvasije:

class FuelRefillDetectionService {
    // Agrupa puntos por timestamp
    static groupByTimestamp(fuelData)

    // Detecta eventos de recarga/trasvasije
    static detectRefillEvents(fuelData)

    // Calcula consumo real
    static calculateRealConsumption(fuelData)
}

MΓ©todos principales:

// Detectar eventos
const events = FuelRefillDetectionService.detectRefillEvents(fuelData);
// Retorna:
{
    external_refills: [
        {
            type: 'EXTERNAL_REFILL',
            timestamp: '2025-10-09 12:00:00',
            amount: 12000,
            duration_hours: 3,
            estimated_consumption_during_refill: 240,
            tanks: { ... }
        }
    ],
    transfers: [
        {
            type: 'TRANSFER',
            timestamp: '2025-10-09 15:00:00',
            from: { id: 124, name: 'Estribor', amount: 1000 },
            to: { id: 123, name: 'Babor', amount: 1000 }
        }
    ],
    noise_filtered: 42  // Puntos ignorados por ruido
}

// Calcular consumo real
const analysis = FuelRefillDetectionService.calculateRealConsumption(fuelData);
// Retorna:
{
    real_consumption: 14000,
    apparent_consumption: 2000,
    total_refills: 12000,
    refill_count: 1,
    transfer_count: 1,
    events: { ... }
}

2. FuelConsumptionByStateService.js (Modificado)

Integra la detecciΓ³n de recargas en el anΓ‘lisis:

static async getFullAnalysis(nodeId, sensorNodeIds, companyId, startDate, endDate) {
    // ... obtener datos GPS y combustible ...

    // Detectar recargas y trasvasije
    const refillAnalysis = FuelRefillDetectionService.calculateRealConsumption(fuelData);

    // Calcular mΓ©tricas de L/h por estado
    const consumptionRates = {
        navegando: consumptionByState.navegando.total / navigationSummary.navegando.hours,
        fondeado: consumptionByState.fondeado.total / navigationSummary.fondeado.hours,
        detenido: consumptionByState.detenido.total / navigationSummary.detenido.hours
    };

    return {
        tracking: { ... },
        fuel: {
            data: fuelWithStates,
            consumptionByState,
            dailyConsumption,
            refillAnalysis  // ← Nuevo
        },
        ...
    };
}

3. FuelKpiController.js (CachΓ© agregado)

async getConsumptionByState(req, res) {
    // Intentar obtener del cachΓ© Redis
    const cached = await this.cache.get('result', { ... });

    if (cached) {
        return res.json({ success: true, ...cached, cached: true });
    }

    // Calcular y guardar en cachΓ©
    const analysis = await FuelConsumptionByStateService.getFullAnalysis(...);
    await this.cache.set('result', { ... }, analysis);

    res.json({ success: true, ...analysis });
}

TTL del cachΓ©:

  • Datos recientes (<7 dΓ­as): 5 minutos
  • Datos antiguos (>7 dΓ­as): 30 minutos

Frontend

1. Tarjetas de Resumen (Actualizado)

Ahora muestran L/h ademΓ‘s de horas y distancia:

renderStateSummary() {
    navegandoRate.textContent = `β›½ ${summary.navegando.liters_per_hour.toFixed(1)} L/h`;
    fondeadoRate.textContent = `β›½ ${summary.fondeado.liters_per_hour.toFixed(1)} L/h`;
    detenidoRate.textContent = `β›½ ${summary.detenido.liters_per_hour.toFixed(1)} L/h`;
}

2. Alertas de Eventos (Nuevo)

renderRefillAlerts() {
    // Detectar si hay eventos
    if (hasEvents) {
        // Mostrar alertas de recargas externas
        // Mostrar alertas de trasvasije
        // Mostrar consumo real vs aparente
    }
}

VisualizaciΓ³n:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ πŸ›’οΈ Eventos Detectados                              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ πŸ”‹ Recargas Externas:                              β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
β”‚   β”‚ 09/10/2025 12:30:00                     β”‚      β”‚
β”‚   β”‚ ⬆️ +12000L (~240L consumidos durante)   β”‚      β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚
β”‚                                                     β”‚
β”‚ πŸ”„ Trasvasije Interno:                             β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
β”‚   β”‚ 09/10/2025 15:00:00                     β”‚      β”‚
β”‚   β”‚ Estribor ➑️ Babor                        β”‚      β”‚
β”‚   β”‚ ~1000L trasvasados                      β”‚      β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Consumo Aparente: 2000L                            β”‚
β”‚ Consumo Real: 14000L                               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“ˆ MΓ©tricas Calculadas

Por Estado Operacional

{
    navegando: {
        hours: 18.8,
        distance: 156.2,
        liters_per_hour: 95.3,  // ← Nuevo
        consumption: 1792
    },
    fondeado: {
        hours: 1.5,
        distance: 0.2,
        liters_per_hour: 12.7,  // ← Nuevo
        consumption: 19
    },
    detenido: {
        hours: 9.8,
        distance: 0.0,
        liters_per_hour: 8.5,   // ← Nuevo
        consumption: 83
    }
}

AnΓ‘lisis de Recargas

{
    real_consumption: 14000,
    apparent_consumption: 2000,
    total_refills: 12000,
    refill_count: 1,
    transfer_count: 1,
    events: {
        external_refills: [...],
        transfers: [...],
        noise_filtered: 42
    }
}

βœ… Beneficios

  1. Consumo real preciso: Considera todas las recargas
  2. DetecciΓ³n automΓ‘tica: No requiere input manual
  3. Distingue trasvasije: No confunde con recarga externa
  4. Filtra ruido: Ignora variaciones por movimiento
  5. MΓ©tricas por estado: L/h navegando, fondeado, detenido
  6. CachΓ© inteligente: Respuestas rΓ‘pidas con Redis
  7. Alertas visuales: Usuario ve eventos detectados

πŸ§ͺ Casos de Prueba

Caso 1: Recarga Externa Simple

Entrada:
  Punto 1: Total = 5000L
  Punto 2: Total = 17000L (+12000L)

Resultado:
  βœ… Recarga externa detectada: +12000L
  βœ… Consumo real calculado correctamente

Caso 2: Trasvasije Sin Recarga

Entrada:
  Punto 1: Babor=5000L, Estribor=4500L, Total=9500L
  Punto 2: Babor=6000L, Estribor=3500L, Total=9500L

Resultado:
  βœ… Trasvasije detectado: Estribor β†’ Babor (1000L)
  βœ… NO detectado como recarga externa

Caso 3: Ruido por Movimiento

Entrada:
  Punto 1: Total = 9500L
  Punto 2: Total = 9600L (+100L)

Resultado:
  βœ… Filtrado como ruido (<200L)
  βœ… NO afecta cΓ‘lculo de consumo

πŸ“ Archivos Modificados

Backend

  • βœ… services/FuelRefillDetectionService.js (Nuevo)
  • βœ… services/FuelConsumptionByStateService.js (Modificado)
  • βœ… controllers/apps/sensorMonitor/api/FuelKpiController.js (CachΓ© agregado)

Frontend

  • βœ… public/javascripts/apps/sensorMonitor/kpi/fuel/fuelGpsStates.js
    • Alertas de recargas
    • MΓ©tricas L/h en tarjetas

Implementado: 6 de Noviembre 2025 Autor: Sistema Kalafate IoT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published