Volver a la wiki

Digital Signage SaaS — Guía Completa

Digital Signage SaaS — Guía Completa

Versión: v1.0.52 Última actualización: 12-04-2026 App: signage/ (CMS) + monitoring/ (monitoreo + publish endpoints)


1. Visión General

CreaRack Pro incluye un sistema completo de Digital Signage SaaS (“Super-Elementi”) que permite:

Arquitectura

┌────────────────────────────────────────────────────────────┐
│                    CreaRack Pro SaaS                       │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌───────────┐   │
│  │ Content  │  │ Playlist │  │ Schedule │  │  Deploy   │   │
│  │ Manager  │→ │ Builder  │→ │ Engine   │→ │  Wizard   │   │
│  └──────────┘  └──────────┘  └──────────┘  └─────┬─────┘   │
│                                                  │         │
│  ┌─────────────────┐  ┌──────────────────────────┤         │
│  │  SVG Composer   │  │  Publish Service         │         │
│  │ (project.svg)   │  │  /publish/{token}/       │         │
│  └────────┬────────┘  │  spx-listing.xml         │         │
│           │           │  project.svg + media     │         │
│           │           └──────────────────────────┘         │
│           ↓                       ↓                        │
│  ┌─────────────────┐  ┌──────────────────────────┐         │
│  │ Client Portal   │  │   Local Agent (LAN)      │         │
│  │ /client/{token} │  │   WebDAV PUT + Configure │         │
│  └─────────────────┘  └────────────┬─────────────┘         │
│                                    ↓                       │
│                        ┌──────────────────────┐            │
│                        │  SpinetiX HMP        │            │
│                        │  Scheduled Download  │            │
│                        │  ← pulls content     │            │
│                        └──────────────────────┘            │
└────────────────────────────────────────────────────────────┘

2. Acceso

URLDescripción
/monitoring/signage/Página principal Digital Signage
/api/signage/API endpoints (48 endpoints)
/api/docsSwagger UI con todos los endpoints
/admin/signage/Admin Django (7 modelos)

Tabs Disponibles

TabFunción
OverviewDashboard: métricas fleet (Total/Online/CPU/Content Synced), Bandwidth In/Out charts, health rings, rankings, heatmap 24h
ContentMedia library: upload drag-drop, grid thumbnails, tags, preview modal, Add URL (web pages + streams), Publish (auto-configura SpinetiX), Deploy Selected (WebDAV push via Agent)
PlaylistsVisual playlist builder: split-panel modal (media library 60% + playlist items 40%), drag & drop, items tipo imagen/texto/ticker/color, duraciones individuales, fade transitions
SchedulesProgramación temporal con reglas (time_range, day_of_week, date_range, always), prioridades, timezone, default playlist
DeployWizard 3 pasos: seleccionar contenido (playlist/schedule) → seleccionar devices (checkbox, Select All) → review + deploy con progress bar en tiempo real
ClientsGestión de share links para portal externo: CRUD, permisos (4 niveles), PIN, expiración, approval workflow, cola de aprobaciones
CNSAI Insights (anomalías, recomendaciones)
ITSMGestión de incidentes, SLA, escalamiento

Device Detail (click en sidebar)

Al seleccionar un dispositivo en la sidebar, se abre un tab con:


3. Gestión de Contenido (Content Tab)

3.1 Subir Archivos

Métodos de upload:

  1. Drag & Drop: Arrastra archivos directamente a la zona de drop
  2. Botón Upload: Click en “Upload” y selecciona archivos

Formatos soportados:

TipoFormatosTamaño Máximo
ImagenJPEG, PNG, GIF, WebP, SVG, BMP, TIFF50 MB
VídeoMP4, WebM, MOV, AVI, MKV, OGG2 GB
HTML5HTML, ZIP100 MB
Web URLhttp://, https://N/A (sin archivo)
Live Streamrtsp://, rtp://, udp://, rtmp://N/A (sin archivo)

3.2 Añadir URLs y Streams

El botón “Add URL” en el Content tab permite registrar páginas web y streams como contenido sin subir archivos.

Flujo:

  1. Click en “Add URL” → modal con campos Name, URL, Type (Web URL / Live Stream), Tags
  2. El backend crea un MediaAsset con asset_type='url' o 'stream', file_path=URL, status='ready'
  3. El asset aparece en el grid con badge URL (violeta) o LIVE (cyan) y la dirección como texto
  4. Sin duración — URLs y streams se muestran indefinidamente hasta cambio de contenido

SVG rendering en SpinetiX:

Protocolos de streaming soportados por SpinetiX:

Nota: HLS (.m3u8) NO está soportado nativamente por SpinetiX HMP. Para streams HTTP usar MP4 directo o RTSP. El SpinetiX necesita acceso de red al servidor de streaming.

Endpoints API:

EndpointMétodoDescripción
/api/signage/signage/media/urlPOSTCrear asset URL/stream (body: name, url, asset_type, tags)

3.3 Procesamiento Automático

Al subir un archivo, Huey ejecuta en background:

  1. Auto-detección de tipo: El backend corrige asset_type según MIME (video/mp4 → 'video'), independientemente de lo que envíe el frontend
  2. Extracción de metadatos: Resolución, duración, codec, bitrate, fps (ffprobe para vídeo, Pillow para imagen)
  3. Generación de thumbnail:
    • Imágenes: Pillow LANCZOS → 320px JPEG (quality 85)
    • Vídeos: ffmpeg extrae frame en 00:00:02 → 320px JPEG (-vframes 1 -vf scale=320:-1)
  4. Transcodificación (solo vídeos):
    • 1080p H.264 — compatibilidad universal
    • 720p H.264 — players con ancho de banda limitado
    • 4K H.265 — displays de alta resolución (solo si fuente ≥ 4K)

3.3 Gestión de Assets

3.4 Endpoints API

EndpointMétodoDescripción
/api/signage/signage/media/uploadPOSTUpload con multipart/form-data
/api/signage/signage/mediaGETListar assets (filtros: asset_type, tag, status)
/api/signage/signage/media/statsGETEstadísticas (conteo por tipo, tamaño total)
/api/signage/signage/media/tagsGETLista de tags únicos
/api/signage/signage/media/{id}GETDetalle de un asset
/api/signage/signage/media/{id}PATCHActualizar nombre/tags
/api/signage/signage/media/{id}DELETEEliminar asset + archivos
/api/signage/signage/media/{id}/reprocessPOSTRe-procesar (thumbnail + transcode)
/api/signage/signage/media/{id}/transcode-statusGETEstado de transcodificación
/api/signage/signage/media/{id}/thumbnailPOSTRegenerar thumbnail
/api/signage/signage/media/bulk-deletePOSTEliminar múltiples assets
/api/signage/signage/media/urlPOSTCrear asset URL o stream (sin archivo)

4. Playlists (Playlists Tab)

4.1 Crear Playlist

  1. Click “New Playlist”
  2. Asigna nombre y descripción
  3. Define items en formato JSON:
[
  {"asset_id": 1, "duration_seconds": 10, "transition": "fade", "order": 1},
  {"asset_id": 2, "duration_seconds": 15, "transition": "none", "order": 2},
  {"asset_id": 3, "duration_seconds": 20, "transition": "slide", "order": 3}
]
  1. Activa/desactiva Loop (reproducción continua)
  2. Click Save

4.2 Transiciones Disponibles

TransiciónDescripción
noneCorte directo
fadeFundido a negro
slideDeslizamiento lateral
dissolveDisolución cruzada

4.3 Operaciones

4.4 Endpoints API

EndpointMétodoDescripción
/api/signage/signage/playlistsGETListar playlists
/api/signage/signage/playlistsPOSTCrear playlist
/api/signage/signage/playlists/{id}GETDetalle
/api/signage/signage/playlists/{id}PATCHActualizar
/api/signage/signage/playlists/{id}DELETEEliminar
/api/signage/signage/playlists/{id}/duplicatePOSTDuplicar
/api/signage/signage/playlists/{id}/previewGETPreview con asset details

5. Schedules (Schedules Tab)

5.1 Crear Schedule

Un schedule define cuándo se reproduce qué playlist, usando reglas con prioridad.

{
  "name": "Horario Laboral",
  "timezone": "Europe/Madrid",
  "default_playlist_id": 1,
  "rules": [
    {
      "type": "day_of_week",
      "days": [0, 1, 2, 3, 4],
      "start": "09:00",
      "end": "18:00",
      "playlist_id": 2,
      "priority": 10
    },
    {
      "type": "time_range",
      "start": "12:00",
      "end": "14:00",
      "playlist_id": 3,
      "priority": 20
    }
  ]
}

5.2 Tipos de Reglas

TipoCamposEjemplo
alwaysplaylist_id, prioritySiempre activa (baja prioridad)
time_rangestart, end, playlist_id, priority09:00-18:00 horario laboral
day_of_weekdays[], start, end, playlist_id, priorityLunes-Viernes + rango horario
date_rangestart_date, end_date, playlist_id, priorityCampaña navideña 15-31 dic

Días: 0=Lunes, 1=Martes, …, 6=Domingo (ISO weekday)

5.3 Evaluación de Prioridad

El engine evalúa las reglas así:

  1. Filtra por ventana de validez (valid_from/valid_until)
  2. Filtra reglas que matchean con el momento actual
  3. Selecciona la de mayor prioridad
  4. Si ninguna matchea → usa la default_playlist

Ejemplo: Con prioridad 20 (almuerzo) y 10 (horario laboral), entre 12:00-14:00 gana la de almuerzo.

5.4 Soporte SMIL

Los schedules se pueden exportar a formato SMIL XML (W3C 3.0) para players SpinetiX e IAdea que usan SMIL nativo.

5.5 Endpoints API

EndpointMétodoDescripción
/api/signage/signage/schedulesGETListar schedules
/api/signage/signage/schedulesPOSTCrear schedule
/api/signage/signage/schedules/{id}GETDetalle
/api/signage/signage/schedules/{id}PATCHActualizar
/api/signage/signage/schedules/{id}DELETEEliminar
/api/signage/signage/schedules/{id}/active-playlistGETPlaylist activa ahora

6. Despliegue de Contenido (Deployments)

6.1 Flujo de Deployment

Crear Deployment → Asignar Players → Huey Task (async)
    │
    ├→ Resolver adapter por player
    ├→ Descifrar credenciales (Fernet AES)
    ├→ Push archivos via VAL (WebDAV, REST, Cloud API)
    ├→ Set playlist/schedule via VAL
    └→ Guardar resultados por player

6.2 Estados

EstadoSignificado
pendingCreado, esperando ejecución
deployingEn progreso
deployedTodos los players OK
partialAlgunos players fallaron
failedTodos fallaron

6.3 Retry

Los deployments failed o partial se pueden reintentar con el endpoint de retry.

6.4 Endpoints API

EndpointMétodoDescripción
/api/signage/signage/deploymentsPOSTCrear deployment
/api/signage/signage/deploymentsGETListar deployments
/api/signage/signage/deployments/{id}GETEstado y resultados
/api/signage/signage/deployments/{id}/retryPOSTReintentar
/api/signage/signage/deployments/{id}DELETEEliminar registro
/api/signage/signage/deployments/{id}/resultsGETResultados per-player

7. Control de Displays

7.1 Protocolos Soportados

ProtocoloPuertoVendorsCapacidades
Samsung MDCTCP:1515SamsungPower, Volume, Brightness, Input
LG ProtocolTCP:9761LGPower, Volume, Brightness, Input
PJLinkTCP:4352Barco, Christie, NEC/SharpPower, Input, Mute, Status

7.2 Fuentes de Entrada

Cada protocolo soporta distintas entradas: hdmi1, hdmi2, hdmi3, hdmi4, dp, dp2, dvi, vga, url, etc.

7.3 Endpoints API

EndpointMétodoDescripción
/api/signage/signage/players/{id}/power-onPOSTEncender display
/api/signage/signage/players/{id}/power-offPOSTApagar display
/api/signage/signage/players/{id}/volumePOSTVolumen (0-100)
/api/signage/signage/players/{id}/brightnessPOSTBrillo (0-100)
/api/signage/signage/players/{id}/inputPOSTCambiar entrada
/api/signage/signage/players/{id}/rebootPOSTReiniciar player

Body para volume/brightness: {"level": 75} Body para input: {"source": "hdmi1"}


8. Proof of Play

8.1 Recolección Automática

Huey ejecuta automáticamente:

8.2 Reportes

Tres formatos disponibles:

FormatoEndpointUso
JSON/api/signage/signage/reports/proof-of-playIntegración con dashboards
HTML/api/signage/signage/reports/proof-of-play/htmlVisualización + impresión
CSV/api/signage/signage/reports/proof-of-play/csvExcel, análisis de datos

Parámetros: ?days=7&player_id=5

8.3 Estadísticas

El endpoint /api/signage/signage/playback-stats devuelve:

8.4 Endpoints API

EndpointMétodoDescripción
/api/signage/signage/playback-logsGETListar logs (filtros: player_id, days, limit)
/api/signage/signage/playback-statsGETEstadísticas agregadas
/api/signage/signage/playback-logs/collectPOSTTrigger manual de recolección
/api/signage/signage/screenshots/capturePOSTTrigger manual de screenshots
/api/signage/signage/players/{id}/screenshotGETÚltimo screenshot de un player
/api/signage/signage/reports/proof-of-playGETReporte JSON
/api/signage/signage/reports/proof-of-play/htmlGETReporte HTML standalone
/api/signage/signage/reports/proof-of-play/csvGETReporte CSV (download)

9. Players y Vendor Adapters

9.1 Registrar un Player

POST /api/signage/signage/players
{
  "display_name": "Lobby Display 1",
  "location": "Edificio A, Planta Baja",
  "adapter_id": 1,
  "device_profile_id": 42,
  "api_credentials": {
    "username": "admin",
    "password": "secreto123"
  }
}

Las credenciales sensibles (password, api_key, secret, token) se cifran automáticamente con Fernet AES-128.

9.2 Vendors Soportados (12)

VendorTipoContent PushDisplay Control
SpinetiXJSON-RPCWebDAV—
BrightSignRESTCloud API—
SamsungRESTMagicINFOMDC TCP:1515
LGRESTSuperSignTCP:9761
CrestronRESTUploadCIP
PhilipsRESTWave/CMNDSICP
IAdeaRESTSMIL HTTP—
BarcoRESTUploadPJLink
ChristieRESTUploadPJLink
NEC/SharpRESTUploadPJLink
YodeckRESTCloud API—
SignageliveRESTCloud API—

9.3 Auto-Provision

Los players detectados via SNMP en Auto-Provision (Step 3) se pueden enviar directamente al Digital Signage Monitor con la tarjeta “Send to Digital Signage”.

9.4 Endpoints API

EndpointMétodoDescripción
/api/signage/signage/playersGETListar players
/api/signage/signage/playersPOSTRegistrar player
/api/signage/signage/players/{id}GETDetalle
/api/signage/signage/players/{id}PATCHActualizar
/api/signage/signage/players/{id}DELETEEliminar
/api/signage/signage/adaptersGETListar adapters disponibles

10. Referencia Rápida

Modelos

ModeloScopeDescripción
SignageVendorAdapterGlobalConfig por vendor (12 seeded)
SignagePlayerOrgPlayer físico vinculado a DeviceProfile
MediaAssetOrgContenido multimedia (imagen/vídeo/HTML5/URL/stream)
PlaylistOrgColección ordenada de assets
ScheduleOrgReglas temporales → playlists
PlaybackLogOrgRegistro de reproducción (alto volumen)
ContentDeploymentOrgTracking de despliegues a players
ClientShareLinkOrgLink compartible para clientes externos (token UUID)
PortalChangeLogOrgAuditoría + cola de aprobación del portal

Huey Tasks

TaskFrecuenciaFunción
process_media_assetOn uploadThumbnail + metadata + transcode
run_deploymentOn demandPush content via VAL
collect_playback_logsCada 15 minRecolectar logs de players
capture_screenshotsCada 30 minCapturar screenshots
cleanup_old_dataDiario 3AMLimpiar screenshots 30d + logs 90d

Estructura de Archivos

signage/
├── models.py                    — 7 modelos core + imports portal
├── models_portal.py             — 2 modelos portal (ClientShareLink, PortalChangeLog)
├── admin.py                     — Admin para 9 modelos
├── apps.py                      — AppConfig
├── tasks.py                     — 5 Huey tasks
├── views.py                     — Client portal view (public, token-based)
├── urls.py                      — /client/<token> route
├── api/
│   ├── __init__.py              — Router assembly (10 sub-routers)
│   ├── schemas.py               — Pydantic schemas
│   ├── content.py               — 11 endpoints media CRUD
│   ├── players.py               — 6 endpoints player CRUD
│   ├── playlists.py             — 7 endpoints playlist CRUD
│   ├── schedules.py             — 6 endpoints schedule CRUD
│   ├── deployments.py           — 6 endpoints deployment
│   ├── display_control.py       — 6 endpoints display control
│   ├── proof_of_play.py         — 8 endpoints proof-of-play
│   ├── share_links.py           — 6 endpoints link management
│   ├── portal.py                — 12 endpoints client portal (public)
│   └── approvals.py             — 4 endpoints approval workflow
├── services/
│   ├── file_storage.py          — Upload, validación, paths
│   ├── thumbnail.py             — Pillow + ffmpeg thumbnails
│   ├── transcode.py             — ffmpeg H.264/H.265 pipeline
│   ├── deployment.py            — Push content via VAL
│   ├── adapters/
│   │   ├── base.py              — Abstract SignageDeviceAdapter
│   │   ├── registry.py          — Factory: resolve by slug
│   │   ├── spinetix.py          — JSON-RPC + WebDAV
│   │   ├── brightsign.py        — BSN.cloud REST
│   │   ├── samsung.py           — MagicINFO API
│   │   ├── lg.py                — SuperSign API
│   │   └── generic_snmp.py      — Fallback SNMP-only
│   ├── scheduling/
│   │   ├── engine.py            — Evaluate rules → active playlist
│   │   └── smil_generator.py    — JSON → SMIL XML
│   ├── display_control/
│   │   ├── samsung_mdc.py       — TCP:1515 binary
│   │   ├── lg_protocol.py       — TCP:9761 ASCII
│   │   ├── pjlink.py            — TCP:4352 standard
│   │   └── controller.py        — Unified dispatcher
│   └── proof_of_play/
│       ├── collector.py          — Fetch logs via VAL
│       ├── screenshot.py         — Capture + cleanup
│       └── reporter.py           — JSON/HTML/CSV reports
└── migrations/
    ├── 0001_initial.py           — 7 modelos core
    ├── 0002_seed_adapters.py     — 12 vendor adapters
    ├── 0003_portal_share_links.py — ClientShareLink + PortalChangeLog
    └── 0004_portal_approval_fields.py — Approval workflow fields

11.1 Concepto

El Client Portal permite a clientes externos editar contenido de señalización digital sin necesidad de cuenta CreaRack. El equipo técnico genera un link compartible con permisos específicos; el cliente abre el link y puede subir imágenes, modificar playlists y schedules.

POST /api/signage/signage/share-links
{
  "name": "Hotel Marriott - Lobby",
  "client_name": "Juan García",
  "client_email": "juan@marriott.com",
  "pin": "1234",
  "permission_level": "playlist",
  "require_approval": true,
  "playlist_ids": [1, 2],
  "player_ids": [5, 6],
  "schedule_ids": [3]
}

URL resultante: https://crearack.com/client/<uuid-token>

11.3 Niveles de Permiso

NivelSubir contenidoEditar playlistEditar scheduleVer players
view_onlySi
content_onlySiSi
playlistSiSiSi
scheduleSiSiSiSi

11.4 Modo Aprobación

Cuando require_approval = true:

  1. Los cambios del cliente se guardan como pendientes (no se aplican)
  2. El equipo técnico ve los cambios en /api/signage/signage/approvals/pending
  3. Puede aprobar (se aplica el cambio) o rechazar (con nota explicativa)
  4. El cliente ve el estado en su historial

11.5 Seguridad

AspectoImplementación
AutenticaciónToken UUID en la URL (no necesita login)
PIN opcional4-10 dígitos verificados antes de acceder
ExpiraciónFecha de expiración configurable
Revocaciónis_active = false invalida inmediatamente
ScopingSolo ve players, playlists y schedules asignados
Audit trailToda acción registrada con IP + timestamp
CSPPágina standalone, skip CSP (no tiene acceso a rutas internas)

11.6 Lo que el cliente ve

El portal es una página web standalone (dark theme, responsive) con:

EndpointMétodoDescripción
/api/signage/signage/share-linksGETListar links
/api/signage/signage/share-linksPOSTCrear link
/api/signage/signage/share-links/{id}GETDetalle
/api/signage/signage/share-links/{id}PATCHActualizar
/api/signage/signage/share-links/{id}DELETEEliminar
/api/signage/signage/share-links/{id}/logsGETVer historial de cambios

11.8 Endpoints API — Client Portal (público, token-based)

EndpointMétodoDescripción
/api/signage/client-portal/{token}/infoGETInfo y permisos
/api/signage/client-portal/{token}/verify-pinPOSTVerificar PIN
/api/signage/client-portal/{token}/playersGETPlayers asignados
/api/signage/client-portal/{token}/playlistsGETPlaylists asignadas
/api/signage/client-portal/{token}/schedulesGETSchedules asignados
/api/signage/client-portal/{token}/mediaGETAssets de las playlists
/api/signage/client-portal/{token}/media/uploadPOSTSubir archivo
/api/signage/client-portal/{token}/playlists/{id}PATCHModificar playlist
/api/signage/client-portal/{token}/playlists/{id}/replace-assetPOSTReemplazar asset
/api/signage/client-portal/{token}/schedules/{id}PATCHModificar schedule
/api/signage/client-portal/{token}/historyGETHistorial de cambios
/api/signage/client-portal/{token}/pending-countGETCambios pendientes

12. SpinetiX Integration (Scheduled Download)

Documentación técnica completa: Documentation/backend/SPINETIX_INTEGRATION.md

12.1 Protocolo de Publicación

CreaRack actúa como servidor de contenido para SpinetiX via Scheduled Download:

  1. CreaRack genera dinámicamente spx-listing.xml (WebDAV multistatus) + project.svg + media files
  2. El SpinetiX descarga desde https://crearack.com/publish/{token}/
  3. El contenido se actualiza automáticamente en cada ciclo (hourly) o inmediatamente tras Publish

12.2 Endpoints Públicos (sin autenticación)

EndpointDescripción
GET /publish/{token}/Root — devuelve 501 para forzar fallback a spx-listing.xml
GET /publish/{token}/spx-listing.xmlÍndice WebDAV DAV:multistatus de todos los ficheros
GET /publish/{token}/project.svgProyecto SVG dinámico (slideshow con transitions)
GET /publish/{token}/index.svgAlias de project.svg (entry point SpinetiX)
GET /publish/{token}/{filename}Media asset file

12.3 SVG Composer

Módulo signage/services/svg_composer.py genera project.svg con soporte para:

TipoDescripciónSVG Element
imageImagen fullscreen con preserveAspectRatio<image>
videoVídeo con duración real del asset<video>
urlPágina web renderizada por motor Chromium del SpinetiX<iframe src="..." frameWidth frameHeight>
streamStream en vivo (RTSP/RTP/UDP), sin duración, playback continuo<video spx:buffering="3" spx:silent="true">
textTexto con font, color, background rect<text>
colorSlide de color sólido<rect>
tickerTexto scrolling horizontal (always-visible overlay)<text> + <animateTransform>
overlayImagen siempre visible (logo, watermark)<image>

Transiciones: transition: 'fade' usa opacity animate (0.5s crossfade), 'none' usa visibility discrete. URL y stream no participan en transiciones de timing — se muestran indefinidamente.

12.4 Auto-Configure via Agent

El Agent (POST /signage/configure) configura el SpinetiX automáticamente:

  1. GET Control Center → extrae CSRF cookie (URL-decode)
  2. POST form con Server URI + update mode
  3. POST con update=now para forzar descarga inmediata

12.5 Flujo Completo de Publish

1. Usuario: Content tab → Publish → selecciona devices + playlist
2. SaaS: Crea SignagePlayer, genera publish URL, vincula playlist
3. Agent: Configura Scheduled Download en SpinetiX (CSRF + form POST)
4. Agent: Fuerza descarga inmediata (update=now)
5. SpinetiX: GET spx-listing.xml → GET project.svg → GET media files
6. SpinetiX: Muestra contenido en pantalla
7. Heartbeat: Cada fetch actualiza player.last_heartbeat + status

12.6 Monitoreo SNMP del SpinetiX

MétricaOIDNota
CPU Usage1.3.6.1.2.1.25.3.3.1.2.196608Index no estándar (196608)
Memory Used1.3.6.1.2.1.25.2.3.1.6.1Valor en KB raw
Bandwidthsnmp_bandwidth_in/out_mbpsVia interface eth0
Pingping_latency_msICMP round-trip

13. UX y Modales

13.1 SignageModalHelper

Módulo reutilizable SignageModalHelper.js reemplaza todos los prompt()/confirm() nativos:

import { SignageModal } from './SignageModalHelper.js';

// Input modal con campos configurables
const result = await SignageModal.input('Title', [
    { name: 'text', label: 'Content', type: 'text' },
    { name: 'color', label: 'Color', type: 'color', value: '#ffffff' },
    { name: 'size', label: 'Size', type: 'number', value: 48 },
    { name: 'option', label: 'Choice', type: 'select', options: [{value:'a',label:'A'}] },
]);

// Confirm modal
const ok = await SignageModal.confirm('Delete this item?', 'Delete');

// Alert modal (replaces native alert)
await SignageModal.alert('Active Playlist:\nRule matched...', 'Schedule Status');

// Device selection modal (groups + checkboxes + Select All)
const devices = await SignageModal.selectDevices('Publish "image.jpg"', 'Publish');
// Returns [{id, name, ip}, ...] or null if cancelled

Tipos de campo: text, password, number, color (con picker + hex input), select, textarea.

selectDevices() muestra un modal unificado con:

13.2 Playlist Builder

Modal split-panel (1500px × 90vh):

9 tipos de transición disponibles:

TransiciónSVG ImplementationDescripción
Cross Dissolveopacity crossfadeDisolución cruzada entre slides
Fade to Blackopacity 1→0→1Fundido a negro entre slides
Slide LeftanimateTransform translateDeslizamiento hacia la izquierda
Slide RightanimateTransform translateDeslizamiento hacia la derecha
Slide UpanimateTransform translateDeslizamiento hacia arriba
Slide DownanimateTransform translateDeslizamiento hacia abajo
Zoom InanimateTransform scaleZoom de entrada
Zoom OutanimateTransform scaleZoom de salida
Cutvisibility discreteCorte directo (sin animación)

Cada item almacena su propio tipo de transición + duración. Las transiciones se muestran como badges entre los slides en el panel de playlist.

Live Preview Monitor (footer del builder):

Save & Publish: Botón que guarda la playlist y abre inmediatamente el modal de selección de dispositivos para publicar

13.3 Auto-Refresh SpinetiX (httpPublish)

Tras Publish, el Agent fuerza la descarga inmediata en el SpinetiX:

  1. GET / → sesión + CSRF
  2. POST /user/login con UserLogin[username/password] + X-Requested-With: XMLHttpRequest
  3. POST /controlcenter/main/content → guarda config Scheduled Download
  4. POST /controlcenter/operation/httpPublish con action=publish + uri + CSRF + X-Requested-With: XMLHttpRequest

Clave: El header X-Requested-With: XMLHttpRequest es obligatorio — sin él el endpoint devuelve HTML en vez de ejecutar la acción AJAX.

13.4 Credenciales Automáticas

Módulo compartido SignageCredentials.js con función resolveSignageCredentials():

Flujo de resolución (3 pasos, primero que resuelve gana):

  1. sessionStorage → cache signage_creds (persiste en la pestaña del navegador)
  2. Credential Store API → GET /api/credentials/ busca primera credential con sección HTTP → GET /api/credentials/{id}/decrypt obtiene username/password en plaintext
  3. Modal prompt → solo si las dos anteriores están vacías (con hint “save in Config > Credentials to skip”)

Seguridad: El endpoint publish-setup NO devuelve passwords en la respuesta JSON. Las credenciales se resuelven exclusivamente en el frontend via la API de Credential Store.

Backend: StoredCredential.get_section('http') descifra automáticamente los campos sensibles con Fernet y devuelve {username, password}.

13.5 Publish Flow Completo (actualizado 25-03-2026)

1. Usuario: Click Publish en thumbnail (o botón Publish general)
2. Frontend: SignageModal.selectDevices() → modal unificado con:
   - Filtro por Groups
   - Checkbox "All" + checkboxes individuales
   - Status dots (online/offline)
   → Devuelve array de dispositivos seleccionados
3. Frontend: resolveSignageCredentials() → 3-step chain
   (sessionStorage → Credential Store API → modal prompt)
4. Por cada dispositivo seleccionado:
   a. SaaS: POST /signage/publish-setup
      → Crea SignagePlayer + bind playlist/schedule
      → Devuelve publish_url (sin passwords)
   b. Frontend: POST Agent /signage/configure con publish_url + creds
5. Agent:
   a. GET / → sesión + CSRF
   b. POST /user/login → autenticación Yii
   c. POST /controlcenter/main/content → guarda Scheduled Download URL
   d. POST /controlcenter/operation/httpPublish → descarga inmediata
6. SpinetiX: Descarga spx-listing.xml + project.svg + media
7. Pantalla: Muestra nuevo contenido (imágenes + vídeos)

Playback Settings: El modal incluye un panel fijo con Duration (1-300s), Loop, Transition (Fade/Cut), Pause between loops (0-60s) y Fit mode (Fill/Fit/Center). Los settings se guardan en SignagePlayer.display_info['playback'] y el SVG Composer los aplica al generar project.svg.

Auto-refresh preview: Tras publicar, se dispara un CustomEvent('signage-published') que fuerza el refresco automático del iframe de Content Preview en el device detail.

13.6 Soporte de Vídeo en SVG

El SVG Composer genera elementos <video> para SpinetiX con estas reglas:

<!-- Estructura SVG para vídeo en playlist mixta -->
<g visibility="hidden">
    <animate attributeName="visibility" values="hidden;hidden;visible;hidden;hidden"
             keyTimes="0;0.6;0.6;0.8;1" dur="30s" repeatCount="indefinite" calcMode="discrete"/>
    <video x="0" y="0" width="1920" height="1080"
           xlink:href="video.mp4" dur="5.87s"
           preserveAspectRatio="xMidYMid slice" repeatCount="indefinite"/>
</g>

Hint en modal: El panel de Playback Settings muestra “Videos always play their full duration” para informar al usuario.

13.7 Clear Playback + Pause/Resume

Pause / Resume (botón btn-info en toolbar Content):

Clear Playback (botón btn-warning):

AcciónColorDescripción
Corporate ImageVioletaImagen corporativa fullscreen — botón “Open”/“Change” para cargar, persistente por org
Black ScreenGrisPantalla negra
Test PatternAzulBarras SMPTE + “CreaRack Test Pattern”
Restart ContentVerdeFuerza re-descarga sin cambiar contenido
Clear All ContentRojoElimina playlist/schedule, pantalla negra

Corporate Image persistencia: El corporate_asset_id se guarda en player.display_info y se resuelve desde status-list al reabrir el modal. El upload fuerza tag corporate y reemplaza la imagen anterior (dedup automático).

13.8 Operation History (Rollback)

Sistema de caché-backup para recuperar operaciones en señalización crítica.

Modelo SignageOperation (migración signage/0006):

Auto-logging: Cada publish-setup y clear_action graba la operación antes de ejecutar.

Frontend: Botón “History” en toolbar → modal con tabla:

API:

EndpointMétodoDescripción
/api/monitoring/signage/operationsGETLista últimas 50 operaciones (soporta filtro source=content|playlist)
/api/monitoring/signage/operations/{id}/restorePOSTRollback a estado anterior + devuelve publish_url

13.9 Playlist Tab

Tab autónomo dedicado exclusivamente a playlists creadas por el usuario (no auto-generadas).

Filtrado is_auto: Solo muestra playlists con is_auto=false. Las playlists auto-generadas (prefijo _auto_*) creadas por Publish from Content se ocultan automáticamente.

Toolbar autónomo con 4 acciones:

PUBLISHED badge: Badge verde en las playlists que están actualmente asignadas a players activos.

Real playlists preserve durations: Cuando se publica desde el Playlist tab, las duraciones configuradas en cada item se respetan. El override de Playback Settings (Duration) solo aplica a auto-playlists generadas desde Content.

Auto-purge: Las playlists _auto_* con más de 24h de antigüedad se eliminan automáticamente, manteniendo un máximo de 20 auto-playlists recientes.


14. Schedule Matrix (27-03-2026)

Visual scheduler with Day/Week/Month views for programming playlists on devices.

Views:

Schedule Block Modal:

Auto-publishing:

Conflict Detection:

15. History Tab (27-03-2026)

Replaces old Deploy tab. Full operation history dashboard.

16. Client Projects (27-03-2026)

Multi-client content management with isolated project scoping.

Model ClientProject (migration 0008):

Admin (Clients tab):

Client Portal (/client/{token}/):

API Endpoints:

EndpointMétodoDescripción
/api/signage/signage/client-projectsGETList projects
/api/signage/signage/client-projectsPOSTCreate project
/api/signage/signage/client-projects/{id}GET/PATCH/DELETECRUD
/client/{token}/GETPublic portal page
/client/{token}/uploadPOSTClient file upload
/client/{token}/create-playlistPOSTClient playlist creation
/client/{token}/publishPOSTClient publish to device

Mantenido por: Claude (Anthropic) + Equipo CreaRack

Véase también

Subir