Saltar a contenido

OTA Firmware Management (Nexus Energy)

Este documento describe la arquitectura, flujo de trabajo y pasos operativos para la gestión de actualizaciones OTA (Over‑The‑Air) de firmware de los dispositivos ESP32 dentro de la plataforma Nexus Energy.


1. Visión General

  • Objetivo: Permitir a los platform_admins subir versiones de firmware, asignarlas a sitios y notificar a los dispositivos ESP32 cuando exista una actualización disponible.
  • Componentes clave:
  • D1 tables (firmware_versions, firmware_assignments, firmware_update_logs).
  • R2 bucket (nexus-firmware) para almacenar los binarios .bin.
  • Endpoints:
    • POST /api/v1/ingest – punto de entrada de telemetría de los gateways. Detecta la versión reportada y devuelve instrucciones OTA si corresponde.
    • GET /api/v1/firmware/{semver}/download – descarga pública del binario desde R2.
  • UI admin – pestaña OTA Firmware en la sección de administración de la plataforma, con formularios de subida, asignación y tablas de estado.

2. Modelo de Datos (D1)

Tabla Campos principales Descripción
firmware_versions id, semver, name, changelog, file_size, sha256, r2_key, created_at Metadatos de cada release.
firmware_assignments site_id (PK), firmware_version_id, assigned_at Relación 1‑1 sitio → versión asignada.
firmware_update_logs id, site_id, device_identifier, from_version, to_version, status, error_message, created_at, updated_at Historial de intentos OTA (pending, downloading, success, failed).

El campo sites.current_firmware_version almacena la última versión que el sitio reportó.


3. Flujo OTA (del dispositivo)

  1. POST a /api/v1/ingest con payload JSON estándar. Nuevo campo firmware_version (ej. "1.0.0").
  2. El endpoint:
  3. Guarda toda la telemetría como siempre.
  4. Busca la asignación de firmware del sitio.
  5. Si la versión asignada difiere de firmware_version → crea (o reutiliza) un registro pending en firmware_update_logs y responde:
    { "update_available": true, "firmware": { "version": "1.2.0", "url": "https://.../api/v1/firmware/1.2.0/download", "sha256": "<hash>", "size": 123456 } }
    
  6. Si ambas versiones coinciden → actualiza sites.current_firmware_version, marca logs success y responde update_available: false.
  7. El ESP32 descarga el binario desde la URL proporcionada, verifica el SHA‑256 y realiza la instalación.
  8. Tras una instalación exitosa el dispositivo envía de nuevo su firmware_version en la siguiente telemetría; el backend marca el log como success.
  9. Si el dispositivo informa update_status: "failed" el backend marca el log failed y guarda el mensaje de error.

4. Subida de Firmware (admin UI)

  • Formulario (?/uploadFirmware):
  • Campos: semver, firmware_name, changelog, archivo .bin.
  • Validación de semver (X.Y.Z).
  • Calcula SHA‑256 con Web Crypto API.
  • Sube el binario a R2 bajo la clave firmware/v{semver}/nexus-firmware-{semver}.bin.
  • Persiste metadatos en firmware_versions.

  • Asignación (?/assignFirmware):

  • Selección de versión y multi‑select de sitios.
  • Inserta/actualiza firmware_assignments (ON CONFLICT → update).
  • Los sitios sin asignación permanecen en estado Sin asignar.

5. Interfaz de Estado (admin UI)

  • Versiones de Firmware – tabla con SemVer, nombre, tamaño, SHA‑256, fecha.
  • Estado por Sitio – muestra versión asignada vs versión reportada y badge de estado (Al día, Pendiente, Sin asignar).
  • Historial OTA – lista de logs con sitio, dispositivo, versiones de → a, estado (Éxito, Fallido, Pendiente) y timestamp.

6. Operación y Mantenimiento

  1. Subir nueva versión:
  2. Navega a la pestaña OTA FirmwareSubir Firmware.
  3. Completa los campos y pulsa Subir Firmware.
  4. Asignar a sitios:
  5. En la misma pestaña, elige la versión recién creada y los sitios objetivo.
  6. Pulsa Asignar.
  7. Monitorear actualizaciones:
  8. Revisa la tabla Historial de Actualizaciones OTA para detectar fallos o dispositivos que no han actualizado.
  9. Los logs failed pueden re‑intentarse borrando el registro o reasignando la versión.
  10. Rollback (opcional):
  11. Subir una nueva versión con un número inferior al actual o re‑asignar la versión anterior a los sitios afectados.

7. Pruebas Manuales

7.1. Simular Telemetría con curl

curl -X POST https://nexus-energy.pages.dev/api/v1/ingest \
  -H "Content-Type: application/json" \
  -H "X-Nexus-Token: <site-token>" \
  -d '{
        "gateway_id": "site-123",
        "firmware_version": "1.0.0",   # versión actual del ESP32
        "devices": []
      }'
- Respuesta esperada (si hay una asignación a 1.2.0):
{"update_available":true,"firmware":{"version":"1.2.0","url":"https://.../api/v1/firmware/1.2.0/download","sha256":"<hash>","size":123456}}
- Respuesta esperada (si ya está al día):
{"update_available":false}

7.2. Verificar Descarga

curl -O -L "https://nexus-energy.pages.dev/api/v1/firmware/1.2.0/download" 
sha256sum 1.2.0.bin   # debe coincidir con el hash registrado

7.3. Simular fallo de actualización

curl -X POST https://nexus-energy.pages.dev/api/v1/ingest \
  -H "Content-Type: application/json" \
  -H "X-Nexus-Token: <site-token>" \
  -d '{
        "gateway_id": "site-123",
        "firmware_version": "1.0.0",
        "update_status": "failed",
        "update_error": "Checksum mismatch",
        "target_version": "1.2.0",
        "devices": []
      }'
- El log correspondiente quedará con status: "failed" y el mensaje de error visible en la tabla Historial de Actualizaciones OTA.


8. Seguridad y Buenas Prácticas

  • R2 bucket está configurado como privado; solo se expone mediante la URL firmada por Cloudflare Workers.
  • SHA‑256 se verifica en el dispositivo antes de aplicar el binario.
  • Todos los endpoints requieren el token de sitio (X‑Nexus‑Token) y la autorización de platform_admin para operaciones de gestión.
  • Los logs OTA se purgan automáticamente después de 30 días mediante una tarea cron (no incluida aquí, pero recomendable).

9. Referencias de Código

  • src/lib/db/types.ts – tipos FirmwareVersion, FirmwareAssignment, FirmwareUpdateLog.
  • src/lib/db/index.ts – factory con métodos getFirmwareVersions, insertFirmwareVersion, assignFirmwareToSites, getSiteFirmwareAssignment, insertUpdateLog, resolveUpdateLog, getUpdateLogs, updateSiteCurrentFirmware.
  • src/routes/api/v1/firmware/[semver]/download/+server.ts – endpoint público de descarga.
  • src/routes/api/v1/ingest/+server.ts – lógica OTA integrada.
  • src/routes/app/admin/platform/+page.server.ts y +page.svelte – UI y acciones de administración.

Este documento debe incluirse en la navegación de MkDocs bajo la sección de Gestión (Administración).