Alexei Rojas Quiroga
← Todos los proyectos

Proyecto personal

SmartValue Monitor

Panel solar y de batería sobre la API en la nube de un inversor, obtenida por ingeniería inversa

Estado
En vivo
Rol
En solitario: análisis de protocolo, API backend, frontend, diseño de persistencia, despliegue
Sitio en vivo GitHub

Arquitectura

  • Un código, dos despliegues
  • API del fabricante por ingeniería inversa
  • Simulación horaria de batería
  • Sin contraseñas almacenadas
  • Supabase con RLS

El panel llama a /api/smartvalue; el backend se autentica en la nube del fabricante, lee los datos en vivo del equipo (alimentados por el dongle) y guarda una lectura idempotente si la persistencia está activa.

Arquitectura · 10 nodos · 4 flujos
LO QUE CONSTRUÍReact · Next.jsPanel solarPotencia, SOC, ajustesy pronósticoDockerAutoalojamientoprivadoLa misma app en elpuerto 3000Cloudflare Pag…Entrada pública enel edgeEntrada del app router,modo públicoNext.js routeAPI de ajustesAjustes de usuario ydel sistemaNext.js route …Pronóstico solarSimulación del SOC debateríaNext.js routeAPI de datos delequipoAutenticación, datosdel equipo e históricoSupabase Postg…Almacén de lecturasy ajustesTablas con RLS,lecturas y RPC deajustesREST APINube del fabricanteTelemetría y consultade equiposWi-Fi dongleDatalogger delinversorEnvía telemetría porTCPOpen-MeteoPronósticometeorológicoIrradiancia horaria ydiaria1234
  • Servicio / cómputo
  • Almacén de datos
  • Cliente
  • Sistema externo
  • Síncrono
  • Asíncrono / bucle
Desplázate hacia los lados para ver todo el diagrama

Cómo fluye, paso a paso

Haz clic en un paso para saltar a él. Haz clic en un componente para ver detalles.

Qué hace

Un panel web para un sistema solar con batería de uso doméstico que usa inversores SmartValue. Inicia sesión en el servicio ValueClouds del fabricante, muestra datos de potencia en vivo y simula el estado de carga de la batería con un pronóstico solar basado en el clima para indicar cuánta carga extra es seguro usar.

El problema

La app móvil del fabricante es la única forma de ver el sistema y el dongle Wi-Fi no expone telemetría localmente. Los dueños no tienen una vista web compartible ni un pronóstico de si la batería durará la noche.

Qué construí

  • Ingeniería inversa de la APK del fabricante y documentación de cómo el dongle habla con la nube (datalogger TCP hacia el host m2m, API REST para la app), y construcción de un cliente.
  • Simulación hora por hora de la batería con eficiencias de carga/descarga, reservas y escenarios, expuesta como API de pronóstico que calcula la carga extra segura.
  • Persistencia multiusuario sin guardar secretos: las cuentas se almacenan solo como huellas HMAC-SHA-256 y las contraseñas nunca se persisten.
  • Las tablas de Supabase usan RLS sin políticas para anon/authenticated; solo el backend tiene la service-role key y los ajustes se guardan mediante una RPC transaccional.
  • Ingesta de lecturas idempotente con una clave SHA-256 determinista y pruebas automatizadas de la capa de persistencia.
  • Desplegable de dos formas desde un mismo código: contenedor Docker para uso privado o worker de Cloudflare Pages en modo público.

Decisiones clave y por qué

01

Usar la API en la nube del fabricante en vez de telemetría local

El análisis mostró que el dongle solo envía datos hacia la nube del fabricante, por lo que la fuente más simple y fiable es la misma API REST de la app; se conservó un decodificador TCP como alternativa independiente.

02

El modo público ignora credenciales del servidor

Con SMARTVALUE_PUBLIC_MODE el backend rechaza credenciales preconfiguradas, de modo que un despliegue compartido nunca expone la cuenta del dueño; cada visitante entra con la suya.

03

Identidad seudónima mediante huella HMAC

Guardar histórico por usuario requiere una clave estable sin almacenar la cuenta en claro. Un HMAC con secreto sobre la cuenta normalizada lo logra, a costa de que rotar el secreto sea una migración controlada.

04

La persistencia es opcional y solo desde el backend

Sin variables de Supabase el monitor sigue funcionando con ajustes temporales; el navegador nunca habla con la base, lo que mantiene la service-role key fuera del código cliente.

Stack tecnológico

Lenguajes
TypeScriptPython
Frontend
React 19vinext (Next.js on Vite)Tailwind CSS
Nube
Cloudflare Pages + Workers
Datos
Supabase (PostgreSQL, RLS)Drizzle ORM
DevOps
Docker Compose
Pruebas
Node test runner