Volver a la wiki

Gráficas de SAI y WiFi vacías por desajuste de nombre de campo entre tablero/informe y servidor

Cuándo

21-09-2026, 22-09-2026 y 23-09-2026 — cinco commits de la misma familia de bug, en SAI, WiFi y cartelería.

Síntomas visibles

Causa raíz

Cinco variantes del mismo problema de fondo — el tablero lee un campo que el servidor ya no manda con ese nombre o esa forma, y falla en silencio devolviendo un valor por defecto en vez de un error:

  1. El descriptor del tablero de SAI pedía charge/load; el servidor manda battery_charge/output_load. Sin ningún test que comparara ambos lados del contrato, la discrepancia pasó desapercibida desde la v1.40.3.
  2. UPS_REPORT_METRICS en el backend solo enumeraba 5 de las 8 claves posibles, y una con el nombre viejo (temperature) en vez del real (battery_temperature).
  3. El perfil de fabricante APC (migración 0033, ampliada en la 0040 solo para Riello/Salicru/Tripp Lite/Delta) nunca tuvo las claves input_frequency/output_current — no es un desajuste de nombre sino una ausencia total en el perfil.
  4. MonitoringDashboard.extractDeepMetric (compartido por los tableros de SAI, WiFi y cartelería) solo leía device.deep_snmp_data; los listados (/ups/status-list, /ups/deep-data) dejaron de mandar esa estructura anidada y entregan la métrica como campo plano (output_load: 44.3). No es un desajuste de NOMBRE como las variantes 1-3, sino de FORMA (anidado vs plano) — el mismo test de contrato tablero-servidor de la variante 1 no lo habría cazado, porque compara nombres de campo, no su forma.
  5. En cartelería, /signage/status-list sí manda cpu_usage/memory_usage por pantalla, pero el código solo copiaba la CPU con un nombre interno (_statusCpu); extractDeepMetric nunca la encontraba con el nombre que de verdad busca.

Fix aplicado

Lecciones

Un descriptor de tablero escrito a mano y un serializador de servidor escrito a mano, sin un test que los compare, divergen silenciosamente — y la gráfica o el anillo vacío se confunde fácilmente con “este modelo no reporta el dato” en vez de “el código pide la clave equivocada, o la busca con la forma equivocada”. La primera regresión de SAI llevaba desde la v1.40.3 sin detectarse; la de extractDeepMetric también — dos días después de escribir esta misma página, con el mismo origen (la migración a la base común MonitoringDashboard, v1.40.3) pero un mecanismo distinto (anidado vs plano) que el test de contrato de las variantes 1-3 no cubría, porque compara nombres, no formas.

Preventivos futuros

Los dos tests de contrato (tablero-servidor, informe-servidor) siguen como gate: cualquier cambio futuro que renombre un campo en un lado sin el otro rompe CI. El caso APC (fdf291dc) sigue pendiente de verificación contra un equipo real. extractDeepMetric tiene ahora su propio test de regresión (campo plano primero, deep_snmp_data como fallback) — pero sigue sin existir un test de contrato que cubra la FORMA del dato (anidado vs plano) para los tres dominios a la vez, solo el nombre. Si una futura migración vuelve a cambiar la forma de un campo consumido por extractDeepMetric, este incidente puede repetirse una sexta vez.

Véase también

Subir