Volver a la wiki

Validación de capturas disponibles en Signage y control por player

Problema resuelto

Las capturas de pantalla del player CCIB (player 3) llevaban más de 30 días fallando en silencio — el 100% de las veces. La tarea de captura encolaba automáticamente cada 30 minutos y se reencolaba para siempre:

Soluciones implementadas

1. Interruptor screenshots_enabled por player (migración 0015)

Se añade nuevo campo en SignagePlayer con default=True:

screenshots_enabled = models.BooleanField(
    default=True,
    help_text="Off = the screenshot dispatcher skips this player (e.g. no Agent can reach its LAN)",
)

Implementación en ambas funciones despachador:

Impacto operacional: El player CCIB (player 3) se apaga por datos tras el deploy (decisión de infraestructura), y el despachador deja de encolar tareas condenadas a fallar.

2. Validación screenshot_available (propiedad del modelo)

Se añade propiedad que valida existencia real del fichero en media:

@property
def screenshot_available(self) -> bool:
    """True solo si last_screenshot apunta a un fichero que EXISTE en media.
    
    La retención de 30 días puede borrar el JPG dejando la ruta huérfana:
    sin este check la UI pinta una imagen rota (ronda 13-08-2026, #223).
    """
    if not self.last_screenshot:
        return False
    import os
    from django.conf import settings
    
    return os.path.exists(os.path.join(settings.MEDIA_ROOT, self.last_screenshot))

Integración en APIs (3 endpoints):

Impacto UI: Desaparece la imagen rota; la pestaña Signage solo muestra capturas reales.

Tests de contrato (test_signage_screenshot_cutover.py)

Se añaden 2 nuevos tests:

  1. test_player_con_screenshots_off_no_se_despacha: Verifica que un player con screenshots_enabled=False no genera ninguna tarea de captura.
  2. test_screenshot_available_exige_fichero_real: Verifica que la propiedad screenshot_available devuelve False si la ruta no apunta a un fichero real, y True si existe.

Deuda conocida (task #223)

El tercer defecto de la cadena de captura:

El mensaje de error del Agente quedaba literalmente vacío (str(asyncio.TimeoutError()) = ""), lo que impedía diagnosis. Esto es código del Agent (local, .exe) y requiere una release del Agente con instalador.

Anotado en task #223 para el próximo ciclo del Agente. NO va en esta versión (v1.66.9).

Límites honestos

Si en el futuro se desean capturas reales del player CCIB, la solución es:

Línea de tiempo

Véase también

Subir