Volver a proyectos
Analema logo

Analema

Herramienta web que permite visualizar las trayectorias solares y lunares desde cualquier ubicación geográfica.

Astronomía Automatización

Un sistema completo para la captura fotográfica automatizada y visualización interactiva de analemas solares y lunares.

Este proyecto automatiza la captura periódica de imágenes provenientes de webcams públicas, generando secuencias (timelapses) que evidencian el movimiento aparente del Sol y la Luna a lo largo del tiempo. Las imágenes son capturadas en momentos astronómicos precisos mediante GitHub Actions y consumidas luego en un Visualizador Web Moderno (PWA) de alto rendimiento. Todo el sistema funciona sin requerir bases de datos tradicionales, basándose en el propio sistema de archivos de un repositorio Git.


Arquitectura del Software

Para mantener el código mantenible, escalable y testable, el núcleo del orquestador fotográfico (src/) ha sido estructurado siguiendo estrictamente los preceptos de Clean Architecture y Domain-Driven Design (DDD).

1. Domain Layer

Es el corazón del software. Aquí residen las reglas de negocio puras, independientes de cualquier framework o infraestructura externa:

  • Entidades (Location, Camera): Un Location encapsula datos geográficos (país, estado, ciudad) y genera identificadores dinámicos. Una Camera está vinculada a un Location y mantiene su orientación cardinal.
  • Value Objects: Objetos como CelestialObject estandarizan el vocabulario de dominio.
  • Contratos (Interfaces): Abstracciones como ScheduleRepository que definen cómo el dominio espera obtener o persistir datos.

2. Application Layer

Contiene los casos de uso principales. Actúa como el orquestador que coordina el Dominio y la Infraestructura para cumplir con los requerimientos del sistema.

  • Scheduler: Es el encargado de revisar los horarios programados de cada Location. Si la hora actual de ejecución coincide (o se encuentra en el umbral) de una captura programada, coordina al servicio de captura correspondiente para obtener la imagen.

3. Infrastructure Layer

Donde el código interactúa con servicios externos, I/O, y frameworks:

  • Servicios de Captura: Se utiliza Puppeteer (PuppeteerCaptureService) para visitar páginas web de webcams públicas, esperar la carga de componentes multimedia y extraer limpiamente los fotogramas (screenshots) del flujo de video o canvas sin incluir la interfaz web.
  • ConfigScheduleRepository: Un repositorio dinámico que usa configuraciones para calcular horarios precisos de captura en las coordenadas de cada Location registradas en src/config/locations.ts.

Ciclo de Orquestación

El orquestador está diseñado para ejecutarse cíclicamente a través de GitHub Actions, optimizando recursos mediante un cronjob.

sequenceDiagram
    participant GH as GitHub Actions (Cron)
    participant App as Scheduler
    participant Repo as ConfigScheduleRepository
    participant Cam as PuppeteerCaptureService
    participant FS as File System / Git

    GH->>App: Ejecuta ciclo horario (minuto 0)
    App->>Repo: Consulta horas de captura para el día
    Repo-->>App: Retorna { sun: '12:05', moon: '03:45' }
    App->>App: Evalúa si la hora del sistema (America/La_Paz) coincide

    alt Coincide con evento Solar en el umbral
        App->>Cam: Lanza Puppeteer Headless
        Cam-->>App: Extrae y retorna buffer de imagen (Screenshot)
        App->>FS: Guarda archivo en 'captures/sun/{location}/{camera}/{YYYY-MM-DD}.jpg'
        GH->>FS: Realiza Git Commit y Push al repositorio
    end

Configuración y Variables de Entorno

El sistema se basa en configuraciones centralizadas, requiriendo muy poco para ejecutarse. Lo principal es la sincronización temporal.

VariableDescripción
TZCrítico: Asegura la configuración de la zona horaria en America/La_Paz (UTC-4). La aplicación utiliza este ancla para sincronizar y comparar los horarios astronómicos esperados con el cronjob horario.

Web Viewer

Esta es una aplicación web interactiva diseñada específicamente para visualizar fluidamente decenas de miles de capturas fotográficas (timelapses) generadas por el orquestador principal del proyecto, evidenciando los trayectos del Sol y la Luna a lo largo de extensos períodos de tiempo.


Arquitectura UI y Experiencia de Usuario (UX)

La aplicación web ha sido concebida para brindar un rendimiento superior, especialmente al manipular un gran volumen de imágenes a alta resolución sin comprometer la memoria o fluidez del navegador.

Transiciones Fluidas

Se implementa una navegación que intercepta los clics del usuario y carga dinámicamente la siguiente página en el DOM sin recargar la pantalla completa. Esto asegura que el estado de la interfaz, como el tema visual o la navegación principal, se mantenga ininterrumpido.

Persistencia del Modo Oscuro

El esquema de color oscuro/claro es detectado desde el sistema y mantenido consistentemente a lo largo de las sesiones del usuario. Gracias a la sincronización con las transiciones de página, no existen parpadeos visuales (“flickering”) al navegar entre diferentes vistas.


El Corazón del Visor: El Reproductor

Un reto crítico al visualizar miles de imágenes (ej. un Analema anual tiene 365 cuadros de alta resolución) es el colapso de la memoria del dispositivo del usuario final. Para mitigarlo, el reproductor de imágenes se apoya en una arquitectura liviana y optimizada:

stateDiagram-v2
    [*] --> Initialization: Carga dataset URLs
    Initialization --> BufferedLoading: Pre-carga primera imagen (Preview)
    BufferedLoading --> BackgroundLoading: Carga progresiva de lotes
    BackgroundLoading --> Ready: Se alcanza el umbral mínimo (ej. 20%)
    Ready --> Playback: Usuario inicia reproducción
    Playback --> Tick: Actualiza imagen basado en FPS
    Tick --> UpdateFrame: Renderiza siguiente cuadro
    UpdateFrame --> Playback: Bucle si hay más cuadros

1. Carga Bufferizada Asíncrona (Buffered Loading)

En lugar de forzar al navegador a descargar todas las imágenes antes de permitir la interacción, el reproductor inicia un proceso en segundo plano que descarga las imágenes en pequeños lotes asíncronos. La reproducción se habilita una vez que un porcentaje mínimo de cuadros ya está disponible localmente, previniendo bloqueos visuales.

2. Control Dinámico de Velocidad

El usuario tiene control total sobre la velocidad de reproducción, que puede ser ajustada en tiempo real. El reproductor recalcula instantáneamente los intervalos de transición entre cuadros (FPS) sin interrupciones.


Indexación sin Bases de Datos Relacionales

Todo el sistema está diseñado para prescindir de infraestructuras complejas como bases de datos SQL o NoSQL.

En su lugar, el visor web indexa directamente la estructura de carpetas estáticas donde residen las imágenes (captures/) durante el proceso de compilación:

graph LR
    A["Proceso de Construcción"] -->|Lectura del sistema de archivos| B(Directorio estático 'captures/')
    B --> C{Parsea la estructura jerárquica}
    C -->|Clasificación por ubicación y cámara| D[Agrupa secuencias fotográficas]
    D --> E[Genera índice de metadatos JSON]
    E -.->|Alimenta las vistas web| F(Renderizado y Filtros UI)

Este índice ligero es consumido por la interfaz web, permitiendo aplicar filtros rápidos y precisos en el lado del cliente sin requerir peticiones de red adicionales ni latencia.


Listo para Dispositivos Móviles y Offline

El visor web incorpora características avanzadas para maximizar su alcance:

  • Metadatos Optimizados para asegurar que los enlaces compartidos en redes sociales incluyan imágenes y descripciones representativas.
  • Configurado como Aplicación Web Progresiva (PWA), permitiendo su instalación directa en dispositivos.
  • Modo Offline Básico, implementando políticas de caché mediante un Service Worker para ofrecer una experiencia continua incluso con redes inestables.
  • Tipografías Auto-alojadas, evitando tiempos de carga adicionales o dependencias de servidores externos.