Guía técnica y manual de usuario
Cómo se cargan los datos de XM y SIMEM, cómo se calculan los indicadores y cómo leer cada tablero. Las capturas son del tablero real; toca los números sobre ellas para ver qué es cada elemento.
Arquitectura técnica
Backend hexagonal en cuatro capas: la dependencia siempre apunta hacia adentro y solo dos archivos, los composition roots, conectan interfaces con implementaciones.
| Capa | Responsabilidad | Ejemplos |
|---|---|---|
domain/ | Entidades, value objects y servicios de cálculo puros, sin dependencias externas | CalculoHidricoService, AutonomiaService, ProyeccionDiariaService |
application/ | Casos de uso, DTOs (Pydantic) y puertos | ObtenerResumenNacional, GenerarPrediccion, ObtenerSendaVolumen, SeriesAgregadas |
infrastructure/ | Adaptadores: DuckDB, clientes SIMEM/XM, Holt-Winters, importador de Outputs | DuckDBMedicionRepository, SimemXmFuenteMediciones |
presentation/ | API REST con FastAPI: routers, errores y CORS | embalses_router, senda_volumen_router |
flowchart LR U["Analista"] --> W["Sitio web
Next.js 16 + React 19"] W -->|"reescribe /api/v1/*"| A["API REST
FastAPI"] A --> D[("DuckDB
hidrologia.duckdb")] S["Sincronizador
CLI Python"] --> D S --> X["SIMEM y API de XM"] I["Importador de Outputs
CLI Python"] --> D O["Excel del modelo
de largo plazo"] --> I
El sitio y la API son dos proyectos de Vercel. El navegador solo conoce el dominio del sitio, que reenvía /api/v1/* a la API, por eso no hay CORS en producción. La API nunca llama a servicios externos al responder: lee solo de la base local.
| Puerto (interfaz) | Adaptador | Para qué |
|---|---|---|
EmbalseRepository, MedicionRepository, MetadatosRepository | Repositorios DuckDB | Embalses, mediciones diarias y procedencia de los datos |
ProyeccionSendaRepository | DuckDBProyeccionSendaRepository | Proyección de largo plazo importada de Outputs |
FuenteMedicionesPort | SimemXmFuenteMediciones (real) y fuente sintética (demos sin red) | Descargar y normalizar datos |
ForecastingPort | HoltWintersForecastingService | Respaldo estadístico cuando no hay proyección publicada |
sequenceDiagram actor U as Usuario participant W as Sitio (Next.js) participant A as API (FastAPI) participant C as Caso de uso participant R as Repositorios participant D as DuckDB U->>W: Abre el tablero W->>A: GET /api/v1/embalses/resumen A->>C: ObtenerResumenNacional.ejecutar() C->>R: última medición por embalse R->>D: SELECT ... FROM mediciones D-->>R: filas R-->>C: entidades del dominio C-->>A: DTO con KPI, regiones y embalses A-->>W: JSON W-->>U: tarjetas, gráficos y tabla
Modelo de datos
Un solo archivo DuckDB de unos 11 MB: cuatro tablas de embalses y las de cada modelo analítico (carbón, DNS y los resultados de gas, optimización y apagón). Una conexión única se serializa con un lock, porque FastAPI atiende peticiones en varios hilos.
| Tabla | Clave | Contenido |
|---|---|---|
embalses | id | Código XM, nombre, región hidrológica y si es un agregado |
mediciones | (embalse_id, fecha) | Una fila por embalse y día desde 2022-01-01. 41.882 filas |
fuente_datos | id = 1 | Fuente, fecha de corte, momento de actualización y si los datos son reales |
proyecciones_senda | (embalse_id, mes) | P10, P50, P90 y origen. 288 filas: 24 series × 12 meses |
carbon_* (10 tablas) | — | Corrida del modelo de carbón térmico: histórico, proyección P10/P50/P90, trimestres, inventario, comparación con XM, validación y supuestos |
dns_* (8 tablas) | — | Modelo de demanda no atendida: subáreas, 15.799 eventos DNS y EDAC, zonas priorizadas, cambios de reporte, métricas, importancia de variables y pronóstico |
modelo_resultados | modelo_id | Último resultado importado de gas, optimización y apagón (JSON validado por el dominio) |
Diccionario de datos de mediciones
| Campo | Unidad | Origen | Si falta |
|---|
None, nunca cero. Recorre dominio, DuckDB, API (null) y pantalla (“—”). El %V. útil no se recorta en 100 %: XM publica valores mayores cuando el volumen supera la capacidad nominal.--reiniciar borra mediciones, embalses y fuente_datos, pero no proyecciones_senda ni las tablas de los modelos (carbon_*, dns_*, modelo_resultados). Una base con el esquema sintético anterior se rechaza con un error explícito.Los 24 embalses por región
| Región | Embalses |
|---|---|
| Antioquia | Ituango, Miraflores, Guatapé (Peñol), Playas, Porce II, Porce III, Punchiná, Río Grande 2, San Lorenzo, Troneras |
| Caldas | Amaní (Miel I) |
| Caribe | Urrá I |
| Centro | Agregado Bogotá, Betania, El Quimbo, Muna, Prado, Sogamoso (Topocoro) |
| Oriente | Chuza, Esmeralda, Guavio |
| Valle | Alto Anchicayá, Calima, Salvajina |
Integraciones y fuentes de datos
Cuatro fuentes de datos y tres servicios de plataforma. Ninguna fuente requiere credenciales: SIMEM y la API de XM son públicas.
| Integración | Qué aporta | Cómo entra |
|---|---|---|
SIMEM 138ED1 | Capacidad y volumen útil diario por embalse (m³) y región | CLI de sincronización, HTTPS |
SIMEM 1445AC | Descargas: turbinada, no turbinada, vertimiento (m³/día) | CLI de sincronización |
SIMEM 02B289 | Aportes por serie de río (m³/s) y su media histórica | CLI de sincronización |
API de XM VoluUtilDiarEner | Energía útil almacenada por embalse (kWh a GWh) | CLI de sincronización |
API de XM CapaUtilDiarEner | Capacidad útil en energía (GWh): peso de agregación | CLI de sincronización |
| Modelo de largo plazo (Outputs) | Proyección a 12 meses P10/P50/P90 por embalse y TOTAL | Excel importado con CLI |
| Identidad GOV.CO | Franja, logo del Ministerio, paleta y tipografías | Archivos en frontend/public/marca/ |
Mapeo de ríos a embalses
SIMEM publica aportes por serie de río. El diccionario SERIE_A_EMBALSE asigna cada serie a su embalse y suma las que alimentan al mismo. De las 48 series de 02B289, 22 no se asignan (desvíos, Bajo Anchicayá y otras). El 21-sep-2026 esto da 49,49 % frente a 50,58 % con todas las series.
Servicios de plataforma
GitHub: repositorio público, rama main protegida y CI. Vercel: dos proyectos, el sitio por Git y la API por CLI. Google Fonts vía next/font: Nunito Sans, Montserrat y Geist Mono.
Modelo de cargue e integración de datos
Cómo llega un dato desde XM hasta un tablero: descarga, normalización, carga idempotente en DuckDB, servicio por API y lectura en el sitio. Este apartado es la base para construir tableros nuevos.
4.1 Diagrama de flujo de datos
flowchart LR
subgraph FUENTES["Fuentes públicas"]
S1["SIMEM 138ED1
volumen y capacidad"]
S2["SIMEM 1445AC
descargas"]
S3["SIMEM 02B289
aportes por río"]
X1["API XM
energía y capacidad GWh"]
end
subgraph CARGUE["Cargue (CLI Python)"]
C["Clientes HTTP
bloques de 30 días"] --> N["Normalización pura
unidades y mapeo río→embalse"]
N --> U["Upsert idempotente
desde última fecha − 7 días"]
end
subgraph MODELO["Modelo de largo plazo"]
E["Excel P10/P50/P90"] --> V["Importador con validaciones"]
end
S1 & S2 & S3 & X1 --> C
U --> M[("mediciones
embalses
fuente_datos")]
V --> P[("proyecciones_senda")]
M --> API["API FastAPI
solo lectura"]
P --> API
API --> SITIO["Sitio Next.js
reescritura /api/v1/*"]
SITIO --> T["Tableros"]
4.2 Mapa de conexión interactivo
Toca cualquier elemento: el mapa resalta lo que lo alimenta o lo consume y muestra su ficha.
4.3 Secuencia de una sincronización
sequenceDiagram
actor O as Operador
participant CLI as sincronizar.py
participant SI as SIMEM
participant XM as API de XM
participant DB as DuckDB
O->>CLI: --fuente simem (API local detenida)
CLI->>DB: última fecha guardada
DB-->>CLI: 2026-09-22
Note over CLI: desde = última fecha − 7 días
CLI->>SI: 138ED1, 1445AC, 02B289 (desde..hasta)
SI-->>CLI: filas por embalse y día
loop bloques de 30 días
CLI->>XM: VoluUtilDiarEner y CapaUtilDiarEner
XM-->>CLI: kWh por embalse
end
Note over CLI: convierte m³ a Mm³, m³/día a m³/s, kWh a GWh
y asigna cada río a su embalse
CLI->>DB: upsert de mediciones y embalses
CLI->>DB: fuente_datos (corte, es_real)
CLI-->>O: Sincronizado: 24 embalses, fecha de corte
O->>O: scripts/desplegar-vercel.sh
4.4 Periodicidad
| Flujo | Publica la fuente | Cargue vigente | Ventana | Propuesta |
|---|---|---|---|---|
| SIMEM y API de XM | Diaria, con 1 a 2 días de rezago | Manual, bajo demanda | Última fecha guardada − 7 días | Diaria, por la mañana |
| Modelo de largo plazo | Por corrida (última: 2026-09-23) | Manual, con el importador | Reemplaza toda la proyección (12 meses) | Tras cada corrida del modelo |
Insumo ENSO (NOOA) | Mensual | No se carga: lo usa el modelo | — | Actualizar antes de cada corrida |
| Publicación de la API | — | Manual: desplegar-vercel.sh | La base viaja con el despliegue | Automatizar tras cada cargue |
| Sitio web | — | Automático por Git | Cada merge a main | Sin cambios |
Simulador: ¿qué tan viejo es el dato que ve el usuario?
Antigüedad = rezago de XM + días entre sincronizaciones (+ 1 día si la API se publica al día siguiente). El corte que muestra el pie es siempre la última fecha con datos cargados.
4.5 Linaje de datos por tablero
Elige un tablero para ver el camino completo de sus datos, desde la fuente hasta el componente que los dibuja.
4.6 Controles de calidad en el cargue
Sincronización SIMEM/XM
- Conversión de unidades con funciones puras, probadas sin red.
- Upsert idempotente: repetir el cargue no duplica filas.
- Datos faltantes como
None; el peso de agregación se imputa con la capacidad publicada más cercana. - Regiones desconocidas y errores de red con mensaje explícito.
- Cliente de XM en bloques de 30 días.
Importador de Outputs
- Columnas
CodigoEmbalse,Fecha,P10,P50,P90. - Rechaza fechas inválidas, meses repetidos y valores fuera de 0–1 (porcentajes ya multiplicados por 100).
- Rechaza bandas con P10 > P50 o P50 > P90.
- Rechaza embalses que no existen en la base.
- Reemplaza la proyección completa en una sola operación.
4.7 Cómo construir un tablero nuevo
El patrón es el mismo para todos los tableros existentes. Marca los pasos a medida que avanzas; el progreso queda en tu navegador.
# Cargar y publicar datos nuevos cd backend && source .venv/bin/activate python -m infrastructure.ingesta.sincronizar --fuente simem # con la API local detenida python -m infrastructure.ingesta.importar_proyeccion --xlsx "<ruta>/proyeccion_montecarlo_enso <fecha>.xlsx" cd .. && scripts/desplegar-vercel.sh # publica la API con la base actual
Importadores de los modelos analíticos
Los modelos no se descargan de una API: sus salidas se importan desde la carpeta de cada proyecto. Todos validan los archivos antes de escribir, reemplazan en una transacción (si algo falla queda la corrida anterior) y no se borran con --reiniciar.
| Modelo | Comando (desde backend/, con la API detenida) | Lee |
|---|---|---|
| Carbón térmico | python -m infrastructure.ingesta.importar_modelo_carbon --carpeta "../../Modelo de carbón térmico" | resultados/ y datos/ del proyecto |
| Demanda no atendida | python -m infrastructure.ingesta.importar_modelo_dns --carpeta "../../2. Modelo DNS" | CSV de Datos/outputs y Datos/outputs_datos |
| Apagón (visor interactivo) | python -m infrastructure.ingesta.importar_escenarios_apagon --carpeta <proyecto> | Ejecuta el script del modelo en las 468 combinaciones de controles (≈2,5 min; requiere las dependencias del modelo) |
| Gas · Optimización · Apagón | python -m infrastructure.ingesta.importar_resultado_modelo --modelo <gas|optimizacion|apagon> --carpeta <proyecto> | Libro Excel pronostico_v2 (gas), JSON de 05_resultados (optimización), CSV/JSON de resultados_modelo_riesgo_apagon |
Cálculos y modelos
Los cálculos hidráulicos son funciones puras en domain/services; los agregados y las proyecciones se arman en application.
%V. útil y nivel de riesgo
%V_útil = volumen útil del día ÷ capacidad útil del día × 100
La capacidad es la que XM publica ese mismo día, porque la revisa con el tiempo. La clasificación tiene cinco niveles y es la misma para embalses, regiones y el sistema.
| Nivel | %V. útil | Código de la API |
|---|---|---|
| Normal | más de 80 % | NORMAL |
| Estable | de 70 % a 80 % (80 incluido) | ESTABLE |
| Alerta temprana | de 60 % a menos de 70 % | ALERTA_TEMPRANA |
| Situación delicada | de 50 % a menos de 60 % | SITUACION_DELICADA |
| Crítico | menos de 50 % | CRITICO |
Probador de niveles
Agregados nacional y regional
El %V. útil de un conjunto de embalses es el promedio ponderado por la capacidad útil en energía (GWh) de cada embalse ese día, como hace la métrica oficial de XM. Un embalse de caída alta almacena mucha más energía por metro cúbico que uno de caída baja.
%V_agregado = Σ(%V_i × w_i) ÷ Σ w_i con w_i = capacidad útil en energía (GWh)
Reproduce el agregado oficial del SIN con un error medio de 0,046 puntos porcentuales sobre 1.725 días. Incluye el Agregado Bogotá.
Ponderar por energía o promediar sin más
Aportes, autonomía y capacidad guardada
Aportes % = Σ aportes (m³/s) ÷ Σ media histórica (m³/s) × 100 (solo embalses con ambos datos) Autonomía = volumen útil ÷ (turbinado + vertimientos − aportes) (Mm³/día; None si aportes ≥ salidas) Capacidad guardada = Σ energía útil almacenada (GWh) (si falta, no se suma)
La autonomía no incluye evaporación porque XM no la publica, y en embalses en cadena (por ejemplo Punchiná) puede resultar engañosamente baja.
Proyección de largo plazo y pronóstico diario
| Elemento | Cómo se obtiene |
|---|---|
| Valor central | P50 de la corrida Monte Carlo del modelo Prophet + XGBoost con escenarios ENSO |
| Banda | Escenarios P10 a P90. No es un intervalo de confianza; al inicio puede ser casi nula |
| Cobertura | 12 meses (oct-2026 a sep-2027) por embalse y para TOTAL; 1, 3, 6 y 12 meses toman los primeros meses |
| Sin proyección publicada | Respaldo Holt-Winters estacional (12 periodos, tendencia amortiguada, IC 95 % por Monte Carlo) con backtest walk-forward de 6 meses contra persistencia |
| Pronóstico diario | La misma proyección interpolada linealmente: cada valor mensual es el promedio de su mes, situado a mitad de mes. Nace en el último dato y llega hasta el último mes publicado (unos 358 días) |
| Agregados regionales y Agregado Bogotá | Usan el respaldo Holt-Winters |
horizonte_meses) y como días de 30 en el pronóstico diario (horizonte: 30, 90, 180, 360). Semáforo de la senda sobre el mínimo proyectado: rojo < 55 %, ámbar < 65 %, verde ≥ 65 %.API REST
Disponible en https://plataforma-embalses-api.vercel.app (local: http://localhost:8000) con OpenAPI en /docs. Todas las rutas cuelgan de /api/v1.
Códigos de respuesta
- 200 consulta correcta
- 404 embalse inexistente o sin mediciones (incluye una región inválida), o modelo de carbón o DNS aún no importado, o un modelo analítico que no existe
- 422 horizonte, historia, días de inventario, período u origen fuera de la lista permitida (responden con los valores válidos), o una región o subárea de DNS que no existe, parámetro no numérico o historia insuficiente (menos de 30 días para el pronóstico, menos de 9 meses para la senda)
Formato de errores
Los errores de dominio responden {"detalle": …} y los de validación de parámetros {"detail": …}. El cliente del sitio lee ambos.
Plataformas, despliegue y operación
El sitio se despliega solo por Git y la API se publica a mano, porque la base de datos no está en el repositorio.
| Componente | Plataforma | Cómo se despliega |
|---|---|---|
| Sitio web | Vercel, proyecto tableros-analiticos, raíz frontendtableros-analiticos.vercel.app (la dirección anterior, plataforma-embalses.vercel.app, redirige a esta) | Automático: cada merge a main es producción; cada PR genera una vista previa protegida por el login de Vercel |
| API | Vercel, proyecto plataforma-embalses-api, sin enlace a Git…/docs | Manual: scripts/desplegar-vercel.sh |
| Base de datos | Archivo DuckDB empaquetado con la API | Se copia a backend/data/ (ignorado por git) y viaja con el despliegue |
| Código y CI | GitHub, repositorio público | Pull request y merge con squash |
flowchart TD
PR["Pull request"] --> CI{"CI: backend y frontend"}
CI -->|"falla"| PR
CI -->|"verde"| M["Merge con squash a main"]
M --> VS["Vercel publica el sitio"]
L["Cargue local de datos"] --> SC["desplegar-vercel.sh"] --> VA["Vercel publica la API
con la base nueva"]
VS -. "reescribe /api/v1/*" .-> VA
Cómo encajan en Vercel
- El sitio reescribe
/api/v1/*hacia la API con la variableAPI_URL. - La API es una función Python (
backend/index.py, 60 s máximo, Python 3.12). Al arrancar copia la base a/tmp, porque el disco es de solo lectura. - El paquete pesa unos 310 MB y hay arranque en frío.
Variables de entorno
NEXT_PUBLIC_API_BASE_URL | Frontend: base de la API (local http://localhost:8000; producción /) |
API_URL | Frontend: destino de la reescritura |
HIDROLOGIA_DB_PATH | Backend: ruta de la base |
CORS_ALLOWED_ORIGINS | Backend: orígenes permitidos |
Procedimientos de mantenimiento
- Actualizar datos: detener la API local, sincronizar y publicar la API.
- Corrida nueva del modelo: importar el Excel y publicar la API.
- Cambiar el sitio: PR con chequeos en verde y merge con squash. Si depende de endpoints nuevos, publicar la API antes del merge.
- Nunca desplegar el sitio con
vercel deploydesdefrontend/. - Credenciales:
vercel linkdeja un token temporal en.env.local; el script lo retira y.env*está ignorado por git.
Calidad y pruebas
1.050 pruebas automatizadas (583 de backend, 430 unitarias de frontend y 37 de extremo a extremo con navegador real), sin red ni base externa, en cada pull request. Se comprobó que detectan fallos introduciendo regresiones a propósito.
Backend · 583 (pytest)
Frontend · 430 (Vitest) + 37 e2e
Mapa de la pantalla
Se entra por tableros-analiticos.vercel.app desde cualquier navegador actual, sin usuario ni contraseña. Toca una zona para ir a su capítulo.
El encabezado y el pie
- Corte al …: fecha del último dato disponible. Todo lo que ves corresponde a ese día. XM publica con uno o dos días de rezago.
- Botón de tema: alterna claro y oscuro; se recuerda en tu navegador y, la primera vez, sigue el sistema.
- Pie: muestra Datos reales, la fuente y el corte. Si los datos fueran de demostración diría Datos no reales en ámbar.
Filtros
Cuatro campos iguales y un botón. Cada uno tiene un botón ⓘ con su explicación.
Región y embalse gobiernan todo el tablero a la vez: tarjetas, gráfico principal, distribución regional, senda de largo plazo y tabla. Las fechas solo mueven el histórico diario del gráfico principal.
| Elemento | Región elegida | Embalse elegido |
|---|---|---|
| Tarjetas | Valores de esa región; el título pasa a «% Volumen útil · Región X» | Valores del embalse; el título lleva su nombre y dice «1 embalse monitoreado» |
| Gráfico principal | Agregado de la región | Serie del embalse |
| Distribución regional | Solo esa región | Solo la región del embalse |
| Senda de largo plazo | Agregado de la región | Senda del embalse |
| Tabla | Embalses de la región | Solo ese embalse |
| Filtro | Qué cambia | Qué no cambia |
|---|---|---|
| Desde / Hasta | El tramo histórico diario del gráfico principal (por defecto 180 días) | Las tarjetas, la distribución regional y la tabla (siempre el último corte) y la senda (toda la historia mensual); la proyección parte del último dato |
- Al abrir la página los filtros están en «Todas las regiones» y «Todos los embalses»: el gráfico principal y la senda muestran el total nacional.
- Al cambiar de región, el embalse vuelve a «Todos los embalses» y todo muestra el agregado de esa región.
- «Todos los embalses» muestra el total nacional o, con región, el agregado de esa región; elegir un embalse lo reduce todo a ese embalse.
- Un clic en una fila de la tabla elige ese embalse. La tabla queda con una sola fila: elige «Todos los embalses» o pulsa Restablecer para volver.
- “Desde” no puede pasar de “Hasta”, y viceversa.
- Restablecer filtros devuelve región y embalse a “Todos” y las fechas a 180 días.
Estados que conviene ver
Tarjetas de indicadores
Cuatro tarjetas de igual tamaño resumen el estado del sistema en el último corte.
| Tarjeta | Cómo leerla | Al 25-oct-2026 |
|---|---|---|
| % Volumen útil nacional | Porcentaje de la capacidad útil que está llena, ponderado por energía. El cambio frente a ayer y a 7 días va en verde si sube y en rojo si baja | 76,7 % · +0,12 p.p. diario · +0,42 p.p. semanal |
| Aportes (% media histórica) | 100 % es un año típico; menos indica un periodo más seco | 65,5 % |
| Capacidad guardada | Energía almacenada hoy en el volumen útil | 13.548 GWh |
| Riesgo del sistema | Insignia del nivel de riesgo (Normal, Estable, Alerta temprana, Situación delicada o Crítico; ver la sección 5) y número de embalses monitoreados | Estable · 24 embalses |
Un guion “—” significa que XM no publicó el dato; nunca es un cero.
Gráfico principal: %V. útil vs. aportes y proyección
La historia reciente y el futuro esperado del embalse elegido. Con “Todos los embalses” muestra el total nacional o el de la región.
| Elemento | Aspecto | Significado |
|---|---|---|
| % Volumen útil | Línea azul continua | Serie diaria del porcentaje de capacidad llena |
| Aportes (% media histórica) | Línea amarilla | Puede superar 100 % y tiene huecos donde XM no publica |
| Proyección %V. útil | Azul oscura punteada | Camino esperado desde el último dato |
| Escenarios P10–P90 (ENSO) | Banda azul clara | Escenarios pesimista y optimista; nace sin ancho y puede ser angosta |
- 1m, 3m, 6m, 12m: cuánto se proyecta: 30, 90, 180 o 360 días. Con 12 meses llega a mediados de septiembre de 2027: la curva termina donde publica el modelo, así que cuantos más días pasan desde su corrida, menos días se proyectan.
- Si el subtítulo dice “escenarios P10–P90”, la banda no es un intervalo de confianza. Si dice “IC 95%”, es el respaldo Holt-Winters (Agregado Bogotá y agregados regionales), que no incorpora el clima.
- El eje vertical se ajusta a los datos: los picos de aportes lo estiran.
Distribución regional del %V. útil
Barras horizontales de menor a mayor. Cada barra promedia los embalses de la región ponderados por energía.
- El color sigue el riesgo: verde normal, cian estable, ámbar alerta temprana, naranja situación delicada y rojo crítico. Al corte del 25-oct-2026, Oriente está en Normal; Antioquia, Caribe, Caldas y Centro en Estable; y Valle en Situación delicada.
- Al pasar el cursor por una barra aparece su valor. Con una región elegida solo se muestra esa región, y con un embalse elegido, solo la región a la que pertenece.
| Región | %V. útil | Aportes (% media) | Energía útil (GWh) | Embalses |
|---|---|---|---|---|
| Valle | 58,3 % | 94,9 % | 457 | 3 |
| Centro | 72,2 % | 78,4 % | 4.590 | 6 |
| Caldas | 73,3 % | 38,7 % | 186 | 1 |
| Caribe | 74,9 % | 58,8 % | 105 | 1 |
| Antioquia | 76,5 % | 54,0 % | 4.809 | 10 |
| Oriente | 88,5 % | 62,6 % | 3.400 | 3 |
Oriente (88,5 %) es la única región en Normal y Valle (58,3 %) la única en Situación delicada. Caldas (38,7 %) y Antioquia (54,0 %) tienen los aportes más bajos frente a su media.
Senda del volumen útil: proyección de largo plazo
El %V. útil mensual observado desde enero de 2022 y su proyección, por defecto para el total nacional.
Lector de la senda nacional (proyección real del modelo)
| Control | Qué hace |
|---|---|
| Sin selector propio | La senda sigue los filtros del tablero: un embalse, el agregado de una región o el total nacional |
| 1m, 3m, 6m, 12m | Meses proyectados; por defecto 12m |
| Último observado | %V. útil del último mes con datos (el mes en curso es un promedio parcial): 75,8 % en oct-2026 |
| Mínimo proyectado | Valor esperado más bajo del horizonte, coloreado por el semáforo de la senda: 35,4 % en mar-2027 |
- Semáforo de la senda: rojo bajo 55 %, ámbar bajo 65 %, verde desde 65 %. Es distinto de la clasificación de cinco niveles porque juzga un mínimo futuro.
- Con la proyección del modelo aparece un recuadro azul “Sobre esta proyección” en lugar de la tabla de validación, porque los Outputs no traen validación fuera de muestra.
- Con el respaldo Holt-Winters (Agregado Bogotá) aparece la tabla walk-forward: modelo, MAE y R² contra la persistencia.
Tabla de embalses y reportes
Una fila por embalse con el dato más reciente. Sigue los filtros: con una región muestra sus embalses (con Centro, 6 filas) y con un embalse elegido, solo esa fila.
| Columna | Qué muestra |
|---|---|
| Embalse | Nombre; el Agregado Bogotá lleva la etiqueta “Agregado” |
| Región | Región hidrológica |
| % Vol. útil | Porcentaje de agua útil con su insignia de riesgo |
| Aportes (% media) | “—” en Muna y en el Agregado Bogotá |
| Vertimientos / Turbinado m³/s | Caudal descargado sin generar / caudal que pasa por turbinas |
| Energía útil GWh | Energía almacenada según XM |
| Autonomía (días) | Estimación de días hasta agotar el volumen útil; “—” si los aportes superan las salidas; engañosa en embalses en cadena como Punchiná |
| Reporte | CSV y JSON con la serie diaria de los últimos 180 días |
- Ordenar: clic en un encabezado; otro clic invierte. Arranca por % Vol. útil de menor a mayor.
- Buscar: por nombre o región mientras escribes.
- Seleccionar: clic en una fila la resalta y cambia el gráfico principal. Los enlaces CSV/JSON no cambian la selección.
fecha,pct_volumen_util,energia_util_gwh,aportes_m3s,aportes_pct_media,vertimientos_m3s,turbinado_m3s
Archivo <CODIGO>_reporte.csv (por ejemplo PENOL_reporte.csv). Una celda vacía es un dato no publicado, nunca un cero. Para otro rango: GET /api/v1/embalses/{id}/reporte?formato=csv&fecha_inicio=…&fecha_fin=….
Panel principal: Tableros Analíticos
La página de inicio (/) es el acceso a todos los tableros. Está organizada en dos grupos para que se vea de un vistazo qué ya muestra resultados y qué todavía no.
| Grupo | Tableros | Qué significa |
|---|---|---|
| Tableros con datos | Embalses, Carbón térmico, Demanda no atendida | Muestran información real y actualizable, con filtros y su fecha de corte |
| Modelos en desarrollo | Gas natural, Optimización hidrotérmica, Riesgo de apagón | Aún no tienen resultados finales: muestran su ficha, su estado real y cómo cargar los resultados cuando el modelo los entregue (borde punteado y marca «En desarrollo») |
- Dos accesos por tarjeta: el título abre el tablero (toda la tarjeta es clicable) y «Guía de este tablero» abre el capítulo de esta guía que lo explica.
- Cada tarjeta dice en una frase qué se puede ver, tres temas concretos y de dónde salen los datos.
- Dentro de cualquier tablero, el botón Tableros del encabezado vuelve al panel y Información abre esta guía en otra pestaña.
- Un tablero nuevo se agrega con una entrada en
frontend/lib/tableros.ts, su ruta enfrontend/lib/rutas.tsy una carpeta enapp/; el panel lo muestra solo.
Rutas y direcciones: cada vista tiene su URL
Cada tablero tiene una ruta propia y cada filtro y cada alternancia queda en la dirección de la página. Puedes copiar el enlace para compartir la vista exacta, recargar sin perderla o volver con «atrás». Lo que vale su valor por defecto no aparece en la dirección.
| Ruta | Parámetros |
|---|---|
/ | Panel principal |
/embalses | region, embalse, desde y hasta (AAAA-MM-DD), h (30, 90, 180 o 360 días del gráfico principal), hs (1, 3, 6 o 12 meses de la senda), q (búsqueda de la tabla), orden y dir (asc o desc) |
/carbon | historia (12, 36, 60 o 0), horizonte (1, 3, 6 o 9), unidad (gbtu o kt), dias (15, 30, 45 o 60) |
/dns | periodo (12, 36, 60 o 0), region, subarea, origen (programada o no_programada), medida (eventos o energia), ampliar (zonas, modelo) |
/gas, /optimizacion, /apagon | desde y hasta (AAAA-MM) y, según el modelo, sus filtros (en gas, serie y variable), cuando hay resultados. /apagon usa modo, oni, simulaciones y horizonte |
/informacion | Esta guía (#ancla del capítulo) |
- Ejemplo:
/dns?periodo=12®ion=Caribe&origen=programadaabre el tablero de demanda no atendida de los últimos 12 meses, en el Caribe, solo eventos programados. - Direcciones alternativas:
/tableros,/demanda-no-atendida,/riesgo-apagon,/gas-naturaly otras redirigen a la ruta canónica. - Seguridad: cada parámetro se valida contra la misma lista cerrada que acepta la API. Un valor inválido (por ejemplo
horizonte=2) se ignora y queda el valor por defecto; nunca llega a la API ni rompe la página. - Historial: cambiar un filtro reemplaza la entrada del historial (no la apila), así «atrás» vuelve a la pantalla anterior y no al filtro anterior.
- Una dirección que no existe muestra una página 404 con el camino de vuelta al panel y la lista de tableros.
Tablero de carbón térmico: mapa de la pantalla
Mismo esquema que el de embalses: encabezado, filtros, tarjetas, gráficos y detalle. Toca un número para ver qué es cada zona.
Filtros del tablero de carbón
Cuatro campos y «Restablecer filtros». Solo ofrecen valores que la API acepta; cada uno tiene su botón ⓘ.
| Filtro | Opciones (por defecto) | Qué cambia |
|---|---|---|
| Historia | 12, 36 (defecto), 60 meses o toda | Solo los meses de consumo observado del gráfico principal |
| Horizonte | 1, 3, 6 o 9 meses (9) | Tarjetas, gráfico principal, trimestres, inventario y comparación con XM |
| Unidad | GBTU/día (defecto) o kt/día | Tarjetas y gráficos de consumo, sin volver a consultar; el inventario siempre está en kt |
| Días de inventario | 15, 30, 45 (defecto) o 60 | La tarjeta y el gráfico de inventario |
- kt/día = GBTU/día ÷ 26,27 (poder calorífico, MBTU/t).
- Restablecer filtros devuelve los cuatro a su valor por defecto.
Tarjetas de indicadores del carbón
| Tarjeta | Qué significa |
|---|---|
| Pico esperado | Mes de mayor consumo (P50) dentro del horizonte, con su rango P10–P90 |
| Uso del techo térmico | % del techo físico (403,3 GBTU/día) que se usaría en el pico. Semáforo: holgado < 85 %, ajustado 85–100 %, supera el techo > 100 %; se muestra además el récord histórico (340,5, mar-2024) |
| Prob. de superar el récord | % de las simulaciones que superan el récord histórico mensual en el mes del pico |
| Inventario de N días | kt de carbón para cubrir N días de consumo en el mes del pico (P50 y P90) |
Gráficos del tablero de carbón
- Consumo de carbón térmico: línea azul = observado (solo meses completos), línea punteada oscura = proyección P50, banda = escenarios P10–P90; las líneas horizontales son el techo (rojo) y el récord (ámbar). Si el mes en curso tiene datos parciales, una nota los informa aparte.
- Consumo por trimestre (Mt): barras P50 y tabla con P10–P90. Un trimestre que no cabe completo en el horizonte se atenúa y se rotula «parcial».
- Inventario requerido (kt): barras por mes, P50 (central) y P90 (adverso).
- Modelo frente a XM: proyección P50 y banda frente al caso estocástico de XM; avisa en cuántos meses XM supera el techo físico: consulta a XM ese supuesto antes de usarlo como referencia.
Validación, supuestos y limitaciones
- Criterios: el modelo cumple 35 de 38 criterios de validez. Primero se muestran los que no cumplen (son limitaciones reales); los que cumplen están en un desplegable.
- Error medio (MAE) por horizonte: compara el modelo con métodos ingenuos (persistencia, estacional, climatología).
- Episodios críticos: cómo se habría comportado en El Niño 2014-16, 2018-19 y 2023-24 (real, P50, error y cobertura P10–P90).
- Supuestos: ecuaciones, muestra de estimación, techo, simulaciones, poder calorífico y la proyección de XM comparada. La proyección no reemplaza el despacho ni el análisis de XM.
Tablero de demanda no atendida (DNS): mapa de la pantalla
Analiza los eventos de demanda no atendida (la energía que el sistema deja de suministrar) y de desconexión automática de carga (EDAC) que se reportan a SIMEM por subárea operativa, desde 2013. Toca un número para ver qué es cada zona.
Filtros y tarjetas del tablero DNS
| Filtro | Opciones | A qué llega |
|---|---|---|
| Período | 12, 36 (defecto), 60 meses o todo el histórico | Tarjetas, serie, patrones y causas. No cambia zonas, cambios de reporte ni modelo: son resultados sobre todo el histórico |
| Región | Las del catálogo, más «Sin asignar» | Todos los bloques; al cambiarla, la subárea vuelve a «Todas» |
| Subárea | Solo las de la región elegida (o todas) | Todos los bloques. También se elige con un clic en una zona del ranking |
| Origen | Programada o no programada (o ambas) | Tarjetas, serie, patrones y causas; con origen activo no se muestra el pronóstico porque el modelo no lo separa |
- Eventos y energía no atendida: la variación es frente al período anterior de igual duración; subir es desfavorable (rojo) y bajar favorable (verde). Con «todo el histórico» no hay con qué comparar.
- Eventos críticos: los que dejan sin atender 100 MWh (100.000 kWh) o más.
- Eventos no programados: los que no estaban planeados; debajo se informa cuántos EDAC hubo.
- Restablecer filtros devuelve los cuatro a su valor por defecto.
Gráficos, causas y modelo predictivo
- Serie mensual: eventos o energía (botones Eventos / Energía). El último mes está atenuado si aún no termina. El punto de pronóstico es lo que el modelo estima para ese mes sumando las subáreas del filtro.
- Paneles ampliables: «Priorización de zonas» y «Modelo predictivo» son largos, así que por defecto miden lo mismo que el panel de al lado (para conservar la simetría) y se desplazan por dentro. El botón Ver todo los extiende para ver todos los datos y Ver menos los devuelve; el estado queda en la dirección (
?ampliar=zonas,modelo). - Priorización de zonas: índice 0-100 con magnitud (40 %), frecuencia (20 %), criticidad (20 %) y tendencia (20 %); los pesos son una decisión editorial. En rojo, las zonas cuya energía de los últimos 24 meses empeoró frente a los 24 previos.
- Patrones: por hora, día y franja. Se excluyen los eventos con «hora desconocida» (00:00:00 exacto, valor por defecto de SIMEM).
- Causas: la reportada por el operador o, si falta, inferida del texto (reglas y TF-IDF). Se avisa qué porcentaje es inferido.
- Cambios en la forma de reportar: subáreas con más descripciones genéricas y menos causa conocida desde un mes; explican parte del aumento de eventos en 2024-2025.
- Modelo predictivo: error (MAE, RMSE) de cada algoritmo frente a la persistencia; un modelo que no la supera no se reporta como exitoso.
Tableros de gas, optimización hidrotérmica y riesgo de apagón
Los tres tienen la misma estructura. Gas y apagón ya tienen resultados importados; optimización solo tiene una prueba técnica sin resultados, así que muestra la ficha y cómo cargarlos. Nunca se inventan cifras. La captura muestra el estado de un modelo sin resultados.
| Tablero | Estado según sus documentos | Cuando haya resultados |
|---|---|---|
| Gas natural | Con resultados: pronóstico coherente por campo y nacional (v2), curvas de Arps, backtesting y comparación con la oferta declarada | Filtros Campo y Variable (fiscalizado, comercializado, entregado a gasoducto): cambian el gráfico y las tablas |
| Optimización hidrotérmica | Evaluación técnica favorable para el alcance actual, pero la corrida es una prueba INSUFFICIENT_RISK_SAMPLE marcada publishable = false | Resumen de la corrida con advertencia si no es publicable |
| Riesgo de apagón (visor interactivo) | Con resultados: 18 meses de horizonte con semáforo mensual, probabilidad de déficit, margen de reserva, demanda frente a oferta y generación por fuente | Gráficos con bandas P10-P90 y semáforo como insignia con texto (Verde, Amarillo, Rojo) |
- Estado: «Sin resultados publicados» (ámbar), «Prueba técnica: no publicable» (rojo) o «Con resultados importados» (verde).
- Cifras documentadas: datos que ya están en los documentos; cada tarjeta dice de cuál.
- Ficha: pregunta, método, datos, alcance, limitaciones y siguientes pasos, en secciones plegables.
- Con resultados aparecen los filtros del modelo y Desde / Hasta, que recortan a la vez todos los gráficos y tablas, además de indicadores con nivel, advertencias y la procedencia de la corrida. Las líneas punteadas son referencias (por ejemplo, la curva de Arps).
Actualizar los tableros con archivos
La página /actualizar (enlace «Acceso para actualizar datos» al pie del panel) permite cargar los archivos nuevos de un modelo sin usar la línea de comandos. Requiere una cuenta; cada acceso y cada carga queda registrado.
| Paso | Qué haces | Qué pasa |
|---|---|---|
| 1. Iniciar sesión | Usuario y contraseña | Cinco intentos fallidos bloquean la cuenta 15 minutos. La sesión vence a los 30 minutos sin actividad. |
| 2. Elegir el tablero | Solo ves los que tu cuenta puede actualizar | La elección queda en la dirección (?tablero=gas). |
| 3. Cargar los archivos | Un campo por archivo, con su formato y si es obligatorio | Excel (.xlsx), CSV, JSON o Parquet según el modelo. Los CSV grandes se comprimen solos al enviarse. |
| 4. Revisar archivos | Pulsa «Revisar archivos» | No se guarda nada. Verás un resumen (filas, fechas, series) y las advertencias del modelo, o la lista de errores con su motivo. |
| 5. Aplicar | Marca la confirmación y pulsa «Aplicar actualización» | Reemplaza los datos del tablero en una sola operación. Si algo falla, los datos anteriores se conservan. |
- Roles: el administrador actualiza todos los tableros y ve la bitácora; el cargador solo los que se le asignaron.
- Riesgo de apagón (visor): el módulo no ejecuta el modelo. Se genera la tanda de 468 escenarios con
importar_escenarios_apagon --exportar-csvy se carga el CSV. - Sin base externa: si el entorno no guarda datos de forma permanente, puedes revisar archivos pero no aplicarlos (la página lo avisa).
Ayuda contextual, tema y preguntas frecuentes
Botones de ayuda ⓘ
Cada encabezado técnico, filtro, selector y columna tiene un botón circular azul claro.
| Cursor encima | Aparece la explicación; se oculta al salir |
| Tecla Tab | Se muestra al enfocar |
| Toque en celular | Abre; tocar fuera cierra |
| Escape, scroll o redimensionar | Cierra |
Tema oscuro y celular
Preguntas frecuentes
¿Por qué el corte no es el día de hoy?
¿Los filtros afectan todo el tablero?
¿Qué significa un guion “—”?
¿Por qué el total proyecta bajar a 35 % si hoy está en 77 %?
¿Por qué la banda casi no se ve al inicio?
¿Por qué el Agregado Bogotá o una región muestran “IC 95%”?
¿Por qué la primera carga tarda unos segundos?
¿Cada cuánto se actualizan los datos?
¿Son proyecciones oficiales?
Límites conocidos y glosario
| Tema | Detalle |
|---|---|
| Actualización | Manual: sincronizar en local y volver a publicar la API |
| Cobertura de la proyección | 12 meses (oct-2026 a sep-2027); sin proyección por región ni para el Agregado Bogotá |
| Validación | Los Outputs no traen validación fuera de muestra; el ajuste dentro de muestra del total nacional es de 2,0 pp de error medio |
| Banda | Escenarios P10–P90 que solo varían el clima; en 69 de 288 casos tiene ancho cero |
| Prophet | En los 24 embalses el componente Prophet es una constante igual al último valor observado; el aporte del modelo es el ajuste de XGBoost |
| Aportes | 26 de 48 series de río; Muna y el Agregado Bogotá no tienen |
| Valores sobre 100 % | El histórico por embalse puede superar 100 % (1.988 filas, sobre todo Playas); hoy ninguno lo supera |
| Datos de origen | El dataset oficial 1d3ef8 trae valores atípicos (0 % el 20-ago-2023 en varios embalses); la plataforma calcula el % desde volumen y capacidad |
| Rendimiento | Paquete de API de unos 310 MB y arranque en frío |
| Identidad | Los logos son del Ministerio de Minas y Energía y se usan solo con su autorización; la plataforma no es un producto oficial |
| Término | Significado |
|---|
Fuentes y referencias
Cifras y comportamientos salen del código y la base de la plataforma al corte del 25-oct-2026, de las pruebas automatizadas y de las comparaciones contra los insumos y resultados del modelo de largo plazo. SIMEM y la API de XM se consumen mediante los clientes del backend; no se consultaron sus portales para redactar esta guía.
- Repositorio, README y pruebas
- Sitio en producción · API y OpenAPI
- Ministerio de Minas y Energía: paleta GOV.CO, tipografías y logos
- Insumos del modelo (
138ED1,1445AC,02B289,1d3ef8,NOOA) y resultados (resultados 20260923.xlsx,proyeccion_montecarlo_enso 20260923.xlsx) en la carpeta1. Modelo niveles de embalsesdel proyecto de modelado