Descripción
Registry centralizado que mapea un slug de vendor a la clase de adapter correspondiente. Resuelve la instancia correcta del adapter para un player digital signage, en función de su fabricante registrado.
Ubicación: signage/services/adapters/registry.py
Funciones públicas:
get_adapter(slug, ip, credentials, adapter_config) → SignageDeviceAdaptersupports_real_push(slug) → boolregister_adapter(slug, adapter_cls) → None(extensibilidad)
Historia de cambios (Hito B)
Antes (fallback silencioso)
- Mapeo incompleto: solo 4 vendors (
spinetix,brightsign,samsung,lg) tenían clase de adapter con push real. - Los otros 8 (Crestron, Philips, Barco, Christie, NEC/Sharp + 3 huérfanos) no tenían clase.
- Cuando se pedía push en un vendor sin adapter, caía automáticamente a
GenericSNMP. - Problema:
GenericSNMP.push_content()devolvíaFalsesin levantar excepción. - Efecto: La app reportaba “push soportado” pero el contenido se perdía en silencio (violaba Regla 13 “no fakes”).
Ahora (fallback explícito → ValueError)
- Mapeo completo y honesto:
- 7 con push real:
spinetix,brightsign,samsung,lg,yodeck,signagelive,iadea - 5 monitor-only (sin API de push pública):
crestron,philips,barco,christie,nec_sharp→ explícitamente resuelven aGenericSNMP - 1 genérico:
generic_snmp(fallback para endpoints desconocidos con flagpush_content: False)
- 7 con push real:
- Sin fallback silencioso: Si un slug no está registrado, lanza
ValueErrorexplícita. - Beneficio: Un call-site que pide push a un vendor desconocido falla audiblemente y puede ser capturado/manejado.
Firma pública
def get_adapter(
slug: str,
ip: str,
credentials: dict,
adapter_config: dict
) -> SignageDeviceAdapter:
"""
Resolver el adapter correcto por slug de vendor.
Raises:
ValueError: Si el slug no está registrado.
"""
...
def supports_real_push(slug: str) -> bool:
"""
Retorna True si el vendor tiene un adapter que implementa push real.
Monitor-only vendors y generic_snmp retornan False.
"""
...
def register_adapter(
slug: str,
adapter_cls: type[SignageDeviceAdapter]
) -> None:
"""Registrar un adapter para un vendor slug (extensibilidad)."""
...
Mapeo de registros
Real-push adapters (7)
spinetix → SpinetiXAdapter
brightsign → BrightSignAdapter
samsung → SamsungAdapter
lg → LGAdapter
yodeck → YodeckAdapter
signagelive → SignageliveAdapter
iadea → IAdeaAdapter
Monitor-only vendors (5)
crestron → GenericSNMPAdapter (SNMP status, no push)
philips → GenericSNMPAdapter (SNMP status, no push)
barco → GenericSNMPAdapter (SNMP status, no push)
christie → GenericSNMPAdapter (SNMP status, no push)
nec_sharp → GenericSNMPAdapter (SNMP status, no push)
Genéricos
generic_snmp → GenericSNMPAdapter (fallback explícito)
Constantes internas
_PUSH_SLUGS = frozenset({
"spinetix", "brightsign", "samsung", "lg",
"yodeck", "signagelive", "iadea"
})
_MONITOR_ONLY_SLUGS = frozenset({
"crestron", "philips", "barco", "christie", "nec_sharp"
})
_REGISTRY: dict[str, type[SignageDeviceAdapter]] = {}
Flujo de get_adapter()
- Lazy load: Carga el registro en memoria la primera vez (si no está ya cargado).
- Lookup: Busca
slugen_REGISTRY. - No encontrado:
- Antes (fallback): Resolvía a
GenericSNMPsilenciosamente. - Ahora: Lanza
ValueError(f"No signage adapter registered for slug '{slug}'. Known slugs: {sorted(_REGISTRY)}").
- Antes (fallback): Resolvía a
- Encontrado: Instancia
adapter_cls(ip, credentials, adapter_config)y retorna.
Flujo de supports_real_push(slug)
- Verifica si
slug in _PUSH_SLUGS. - Retorna
TrueoFalse. - Usado por
signage/api/players.pypara derivar el campopush_implementeden la respuesta delist_adapters().
Impacto en call-sites
Los 4 call-sites que usan get_adapter() ya capturan ValueError:
| Call-site | Ubicación | Manejo |
|---|---|---|
| Deploy Huey | signage/services/deployment_worker.py | Try/except, degrada a noop |
| Proof-of-play collector | signage/services/proof_of_play.py | Try/except, logea error |
| Screenshot taker | signage/services/screenshot_worker.py | Try/except, retorna None |
| Reboot handler | signage/api/display_control.py | Try/except, retorna error |
→ Todos ellos ya esperaban que get_adapter() podía fallar y lo manejan gracefully.
Véase también
- [[feature—signage—hito-b-honestidad-adapters]]
- [[entity—signage—service—yodeck-adapter]]
- [[entity—signage—service—signagelive-adapter]]
- [[entity—signage—service—iadea-adapter]]
- [[entity—signage—service—generic-snmp-adapter]]
- [[entity—signage—api—list-adapters]]
- [[entity—signage—model—signage-vendor-adapter]]