El Vault es un coordinador que corre 24/7 y captura, día a día y planta por planta, cada canal que GreenPowerMonitor expone — strings, cajas, inversores, medidor y meteo — a un archivo permanente que controlamos nosotros. Lento, constante, a prueba de caídas.
Una sola regla de diseño: un plant-día por tick. En vez de un script gigante que baja todo de una y se cae a la mitad, una tabla en MySQL es la única fuente de verdad y cada tick de cron retoma exacto donde quedó el anterior.
Un cron llama por HTTPS a trigger.php?mode=vault-tick&key=…. El secreto se valida con hash_equals. (Se usa trigger por web porque el host a veces bloquea crontab directo.)
Recupera trabajos colgados (>30 min → pending), luego toma 1 fila: status IN (pending,backoff), next_attempt vencido, ORDER BY priority, pull_date → la historia más vieja primero.
Autentica (token cacheado 20 h), pide la lista de Element y Datasource, y recorre los ~4.500 datasources en lotes de 10 contra /api/DataList/v2 a 15 min, con 500 ms de pausa entre lotes. Si un lote falla, reintenta de a 3, luego de a 1, para aislar el ID malo.
Streaming a VER_2025-05-10.json con {meta, elements, datasources, values, stats}. Dump crudo: cada canal, sin filtrar — puerta de un solo sentido: un canal mal filtrado se pierde para siempre, el disco es trivial.
Archivo >100 KB → done. 429/503/timeout → backoff (30 min × intentos). 401/403 → frena TODO 60 min (GPM pudo revocar acceso). 5 intentos → failed y sigue.
Tres capas, una sola responsabilidad cada una: el dato crudo en disco, la coordinación en MySQL, y la vista para humanos en la web. Todo en el servidor cPanel home/ienergia; nada de esto pasa por GPM una segunda vez.
Un archivo = un día completo de una planta entera, a 15 min. Accesible por URL. Los días viejos se comprimen a .gz.
La memoria del Vault. Stateless entre corridas: reiniciar el server, matar el proceso o cerrar el browser no pierde nada.
vault_queue — la cola (única verdad)vault_state — halt_until, last_tick, last_resultidata_plants — catálogo + mapping de IDsDashboards de solo lectura, auto-refresco. Un calendario por planta desde el COD hasta hoy, celda a celda.
Números en vivo del vault_coverage.php, leídos hoy. Hergo está casi completo; iEnergia tiene las plantas más antiguas (Calle Larga arranca en 2019, +2.600 días) y va parcial; Obton recién entra a la cola — solo Llancay está sembrado.
| Planta | COD | Días | Capturado | Progreso |
|---|
GPM no es consistente: ni los nombres de planta ni los nombres de canal coinciden entre proyectos. El Vault resuelve esto en dos capas — y la jugada clave es no resolver la segunda capa al bajar.
GPM llama a las plantas "CL - Aldebaran", "Hergo", "Hergo Los Eucaliptos"… El normalizador de discover.php quita acentos y el prefijo "CL - ", y empata por posición. El resultado se congela en idata_plants.source_plant_id.
Cada planta nombra distinto la caja, el string y la potencia. En vez de mapear al vuelo (y arriesgar perder un canal), el Vault baja todo crudo y guarda los nombres tal cual. El mapping de roles (string, CB, IMD, tracker) se resuelve después, offline, sobre el JSON ya seguro.
El problema de la capa 2, concreto — cómo nombran la misma cosa (caja 4, string 8, potencia DC) cuatro plantas distintas:
| Planta | Caja | String | Canal de potencia DC del string |
|---|---|---|---|
| Verona | SCB 04 | String 05.01 | ✓ DC POWER STRING 08 |
| Salerno | String Box 01.01 | String 10.05.04 | ✓ DC POWER STRING 04 |
| Calle Larga | CB01 | CB01-S01S02 | ~ Power (genérico) |
| San Vicente | CB 01.01 | String 02.11.09 | ✗ no existe (solo corriente) |
Por eso la decisión de bajar crudo y completo no es pereza — es la única forma de que esa inconsistencia se pueda arreglar algún día sin haber tirado datos a la basura. El JSON guarda el árbol de elementos completo, así que el mapping de roles siempre se puede recomputar.
El histórico es una carrera contra el reloj: GPM puede cortar el acceso en cualquier momento. El Vault está diseñado para sobrevivir todo lo que le pase al servidor.
La cola en MySQL es la única verdad. Reiniciar, matar el proceso o cortar la conexión → el siguiente tick sigue igual.
No confía en el exit code: si el archivo quedó >100 KB es éxito; si "tuvo éxito" pero el archivo es chico, borra el parcial y reintenta.
429/timeout → reintenta en 30 min × intentos. Respeta Retry-After. Cinco fallos → marca failed y sigue con otro día.
Un 401/403 detiene TODOS los ticks 60 min — GPM pudo revocar acceso; no insistir y quemar el rate limit.
Lotes de 10 → si fallan, de 3 → de 1. Un datasource corrupto no tumba el día entero.
ignore_user_abort + sin límite de tiempo: un tick dura ~9 min, pero si el curl del cron corta antes, el trabajo continúa.
“Lento, constante, sin parar.” Un plant-día cada 15 minutos no parece mucho, pero corre 24/7 sin supervisión y nunca pierde el lugar. Cada hueco gris que se vuelve verde es un día de generación que ya no depende de que GPM siga prestándonos sus servidores.
— mandato del 4-jun-2026 · programa actual: backfill priorizado por antigüedad