Semana del 18 al 24 de mayo de 2026
Resumen: Una semana de mucho código bajo el capó: el módulo VULCAN estrena animaciones volumétricas del polvo en 3D, el streaming gana un sistema de guardia nocturna para el token de YouTube, y ALOY aprende a leer el correo de EUMETSAT para distinguir fallos propios de cortes externos.
🌫️ Polvo del Sahara en tres dimensiones
El salto grande de esta semana llega desde VULCAN. Tenía en mente desde hace tiempo representar el polvo del Sahara no como un mapa plano sino como lo que realmente es: un volumen estratificado en altura, con capas que se mueven y se concentran de forma distinta a 500, 2.000 o 3.000 metros. Esta semana he terminado un primer prototipo funcional con datos reales del modelo MONARCH de Copernicus Atmosphere (CAMS).

La animación dura 45 segundos y se divide en tres actos. Primero, una grúa de cámara que baja desde 15.000 km de altura sobre el Atlántico con un giro de 90°. Luego un traveling lateral de 1.200 km durante el que aparece el volumen de polvo semitransparente evolucionando hora a hora en 7 niveles de altitud. Y en el tercer acto la cámara asciende 3.000 km y vuela hacia el norte del Sahara manteniendo la mirada fijada en Madrid. Dos detalles técnicos que me gustaron especialmente: la sombra proyectada en el suelo —la integral vertical de polvo pintada como una mancha ámbar bajo la nube— y que los tres segundos de pausa al final los genera ffmpeg repitiendo el último frame, sin renderizarlos.
Para el mapa base he pasado del stock_img() de Cartopy (que en este dominio daba 260×165 píxeles) a leer directamente la capa Natural Earth de 10.800×21.600 px con acceso por bloques de memoria, sin cargar los 700 MB completos en RAM. Queda pendiente resolver un límite que de momento no tiene solución con mis credenciales actuales: el modelo MONARCH no llega al sur del paralelo 30°N, lo que deja fuera el Sáhara profundo.
🎛️ Guardia nocturna para el token de YouTube
El token OAuth de YouTube lleva semanas siendo el talón de Aquiles del streaming. Esta semana he reescrito la gestión de errores en reiniciar_stream_obs.py desde cero. El bug crítico era que cualquier error de red —una desconexión momentánea, un timeout— se capturaba junto a los errores de token revocado genuino, y el script machacaba el token renombrándolo a .revocado aunque fuera perfectamente válido. Ahora hay tres capas diferenciadas: errores de transporte (reintentar sin tocar nada), token realmente revocado (renombrar y alertar), y excepciones inesperadas (conservar el token y avisar).
Para facilitar la renovación manual cuando sí haga falta, he creado atlas/renovar_token.py, un script interactivo que abre el navegador para el flujo OAuth, con su acceso directo en el escritorio. Y como segunda línea de defensa, atlas/atlas_token_check.py actúa como guardia nocturna a las 23:00: revisa el token una hora antes del reinicio automático de medianoche y, si está revocado o ausente, lanza una alerta CRITICAL con el tiempo de reacción disponible.
🤖 ALOY aprende a leer el correo
ALOY —el agente de monitorización y reparación autónoma— ha recibido dos mejoras esta semana. La primera: un nuevo colector que se conecta al buzón de Gmail por IMAP y busca correos de EUMETSAT y de la API de Copernicus en las últimas 24 horas. Si un fallo del pipeline coincide en tiempo con un aviso de servicio externo, ALOY lo reclasifica como external_outage y lo añade al contexto del diagnóstico, así no intenta reparar algo que depende de un servicio ajeno. EUMETSAT ya enviaba avisos estructurados desde hace meses (10 en lo que va de 2026); ahora los aprovechamos.
La segunda mejora: los diagnósticos de texto han migrado a Qwen2.5:7b corriendo en local con Ollama. La RTX 5060 los resuelve unas ocho veces más rápido que por CPU. Solo la visión del stream —el screenshot que verifica que la escena OBS tiene buen aspecto— sigue pasando por GPT-4o, que sigue siendo el más fiable para esa tarea.
🧩 Overlay canónico compartido
Hasta ahora cada script calculaba su propia conversión UTC→hora local y dibujaba el timestamp de frame a su manera. He centralizado todo eso en shared/frame_overlay.py: un módulo con cuatro funciones (fmt_local, fmt_local_from_str, add_overlay_ax y save_frame_with_overlay) que cubren tanto mapas 2D de Matplotlib como capturas 3D de PyVista. A partir de ahora es norma obligatoria del proyecto: cualquier script nuevo importa desde ahí. El primer en migrar ha sido precisamente el script 3D de polvo.
🧪 Lo que ha quedado en el tintero
El snapshot semanal de YouTube (métricas del canal) lleva dos semanas sin generarse: el token de autenticación está caducado y el sandbox de Linux desde el que corre la tarea Cowork bloquea el servidor OAuth de Google. La solución es moverlo al Task Scheduler de Windows, igual que el resto de scripts OAuth, pero todavía no he dado ese paso. El límite sur del modelo MONARCH en el paralelo 30°N tampoco tiene solución a corto plazo con las credenciales actuales de Copernicus.
📆 Próxima entrada: semana del 25 al 31 de mayo de 2026.