Ir al contenido

Dashboards

Los dashboards son la forma en que operadores y clientes ven realmente los datos de CORE-M. El constructor de dashboards compone widgets en una cuadrícula adaptable, los conecta a fuentes de datos mediante aliases, y los renderiza sobre ventanas de tiempo realtime o históricas. Esta página cubre las interioridades del constructor: cómo las ediciones se mantienen consistentes bajo concurrencia, qué ofrece el catálogo de widgets, cómo las ventanas de tiempo y la aggregation se mapean sobre los dos almacenes de telemetry, y cómo se comparten, exportan y versionan los dashboards.

Los registros de dashboard contienen dashboard_id, tenant_id, name, description, layout_json, alias_config, timewindow_config, permissions y version, con clave {tenant_id}:{dashboard_id}.

Los dashboards se editan de forma colaborativa, por lo que el constructor usa concurrencia optimista basada en la version del dashboard (un etag). Guardas contra la versión que cargaste; el servidor acepta solo si nada cambió por debajo de ti.

flowchart TD
  load([Load DB1 at version 7]) --> edit["Edit layout locally"]
  edit --> save{Save based on v7}
  save -->|server still at v7| ok["Apply change,<br/>version → 8,<br/>push dashboard.updated"]
  save -->|server now at v8| conflict["ABORTED / HTTP 409<br/>response includes current_version=8"]
  conflict --> reload([Reload latest and retry])

Un guardado exitoso incrementa la versión (7 → 8) y envía dashboard.updated a los visores WebSocket. Un guardado obsoleto — editar contra la versión 7 cuando el servidor ya está en la 8 — se rechaza con ABORTED / HTTP 409, la respuesta incluye current_version=8, y no se aplica ningún cambio. La UI expone esto para que el editor pueda recargar y reintentar en lugar de pisar silenciosamente el trabajo de otra persona.

El constructor ofrece un catálogo de tipos de widget integrados. Cada entrada del catálogo define un widget_type_id, name, category, un config_schema_json (para que la configuración se valide con errores a nivel de campo), default_config_json, query_capabilities y required_permissions.

WidgetQué muestra
Gráfico de líneas de telemetry (timeseries_line_chart)Métricas de series temporales para uno o varios dispositivos
Tabla de alarmsLista de alarms filtrada y con actualización en vivo
Tabla de entidadesActivos / dispositivos y sus campos
Mapa / indicador / controlWidgets geoespaciales, de valor único y de comandos
Estado de pruebasRecuentos del ciclo de vida de pruebas agrupados por estado
Texto / markdownAnotación estática

Dos widgets que merecen una mirada más detenida:

  • Gráfico de líneas de telemetry. Su configuración requiere un alias de fuente de datos, claves de métrica, una ventana de tiempo, una aggregation y opciones de visualización. La configuración inválida se rechaza con errores de validación a nivel de campo.
  • Estado de pruebas. Consulta los recuentos actuales del ciclo de vida de pruebas agrupados por estado y muestra los recuentos accepted, pending_batch, anchored, confirmed, final y failed — una vista directa del ciclo de vida de pruebas.

Los widgets referencian aliases en lugar de IDs de dispositivo codificados. Un alias como selected_boilers se resuelve en tiempo de ejecución a un conjunto concreto de dispositivos (p. ej. D1, D2); el runtime del dashboard consulta esos dispositivos y registra los aliases resueltos en la respuesta para trazabilidad. Los aliases son lo que hace que un dashboard sea reutilizable entre conjuntos de dispositivos sin recablear cada widget.

Ventanas de tiempo, aggregation y downsampling

Sección titulada «Ventanas de tiempo, aggregation y downsampling»

La ventana de tiempo de un dashboard es realtime o histórica, y la elección determina qué almacén de telemetry la respalda.

Una ventana realtime (p. ej. tipo realtime, intervalo 15m) está impulsada por la suscripción en vivo: el BFF del dashboard envía puntos por WebSocket desde telemetry.live.{tenant}.{device}, y los widgets conservan solo la ventana visible móvil (los últimos 15 minutos). Esto se mapea sobre el hot store, que mantiene exactamente esa ventana móvil más un backfill rápido al cargar el gráfico.

Las consultas históricas eligen una función de aggregation aplicada por bucket:

none, avg, min, max, sum, count, first, last, delta, percentile.

(La ruta de percentile cubre resúmenes estilo p50/p95/p99 usados para vistas de latencia y distribución.)

Los tenants tienen un presupuesto máximo de puntos por consulta (max_dashboard_points). Cuando una consulta lo excedería, el runtime o bien hace downsampling para encajar o bien la rechaza con RESOURCE_EXHAUSTED, según la política del widget — y la respuesta identifica el ajuste limitante para que el usuario sepa qué cambiar (acortar el rango, hacer más grueso el intervalo o agregar). Esto evita que una consulta descuidada de “en bruto, 90 días, 1 segundo” intente enviar millones de puntos a un navegador.

La biblioteca de recursos del tenant contiene imágenes, símbolos SVG, símbolos SCADA, plantillas JSON y assets de widgets. Los recursos subidos son content-addressed e indexados con content_hash, mime_type, size_bytes y propietario.

Una subida segura se sanea, se almacena con su content hash, y aparece de inmediato en el selector de recursos del constructor.

Los dashboards se exportan e importan como bundles con versionado de esquema y validación de dependencias.

  • Export produce un bundle que contiene el JSON del dashboard, las configuraciones de los widgets, las configuraciones de los aliases, las referencias a recursos, schema_version y content hashes. Lo crucial: no se incluyen secretos ni claves de API — los bundles son seguros para compartir.
  • Import valida las dependencias antes de aplicar. Si un bundle referencia un hash de recurso (p. ej. H1) que no está presente ni en la biblioteca de recursos del tenant ni en el payload del bundle, la importación se rechaza con FAILED_PRECONDITION y la respuesta enumera los hashes de recurso faltantes para que puedas suministrarlos.

Los content hashes son lo que hace que la importación sea determinista: un símbolo SCADA referenciado es exactamente los bytes que se exportaron, o la importación falla de forma ruidosa en lugar de sustituir silenciosamente.

Los dashboards admiten acceso de edición para tenant-admin, permisos de visualización/edición para miembros, y acceso de visualización para clientes mediante asignaciones:

  • Un member con el permiso dashboards cuyo grupo tiene asignado un dashboard lo ve renderizado solo con los widgets cuyas fuentes de datos subyacentes puede acceder.
  • Un usuario de cliente ve solo los dashboards asignados a su cliente; solicitar un dashboard no asignado se rechaza con PERMISSION_DENIED. La asignación y la revocación en tiempo real se cubren en el entity model.

Los dashboards mantienen versiones active y draft, y cada guardado incrementa la versión usada para la comprobación de concurrencia optimista. Combinado con los bundles de export, esto da una vía de promoción limpia: edita un draft, expórtalo, e impórtalo en otro tenant o entorno con validación completa de dependencias.