
GT Home
App de domótica construida desde cero: controla y monitoriza tu hogar desde cualquier dispositivo, en tiempo real.
GT HOME
Sensor Monitor
Temperatura — Hoy
Alto
Buena
8.2
PM2.5
15.1
PM10
6.5
NO₂
42.3
O₃
Paneles de Control
Módulos adicionales integrados en el ecosistema ESP32 con monitorización en tiempo real.
Sensores inalámbricos 433 MHz
Sensores magnéticos inalámbricos de 433 MHz en cada marco. Un módulo receptor conectado al ESP32 decodifica las señales y actualiza el mapa en planta al instante.
3 zonas con control de humedad
Electroválvulas controladas por sensores de humedad del suelo con programación inteligente.
Monitoreo de nivel de depósitos
Sensores ultrasónicos JSN-SR04T (sumergibles) montados en la parte superior de cada depósito miden la distancia al agua mediante pulsos de ultrasonido de 40kHz, calculando el volumen exacto y la autonomía restante en tiempo real.
Barrera invisible con detección instantánea
Emisor láser y fototransistor con detección por zonas en milisegundos.
Cómo está construido
Desglose completo del sistema: desde el sensor físico hasta el dashboard en el navegador.
Hardware
2× ESP32 Dev Boards
Dos microcontroladores independientes con WiFi integrada. Uno para exterior (cubierto, cerca de la vivienda) y otro para interior. Cada uno ejecuta el mismo firmware compilado con distinto identificador.
Sensores DHT11
Sensor digital de temperatura (±2°C) y humedad (±5% RH). Lectura cada 2 segundos; los datos se envían al servidor cada 2 minutos para minimizar el tráfico y el consumo energético.
LD2410D — Radar de presencia (Planificado)
Sensor de presencia humana por radar de ondas milimétricas de 24 GHz. Sin cámara ni compromiso de privacidad. Detecta presencia estática (persona sentada o durmiendo) y movimiento. Cada habitación tendrá su propio sensor conectado al ESP32 interior.
Módulos Relé (Planificado)
Módulos relé controlados por el ESP32 interior para el encendido y apagado automático de luces. Activados por la detección de presencia del LD2410D, con reglas configurables por horario y zona.
Detección de Ventanas y Puertas
Sensores magnéticos inalámbricos 433 MHz
Sensores magnéticos de apertura/cierre montados en marcos de ventanas y puertas. Transmiten su estado mediante RF a 433 MHz (OOK). Sin cables, alimentados por batería, con alcance de hasta 100 metros en espacio abierto. Cada sensor lleva un identificador único codificado en la trama RF.
Módulo Receptor RF 433 MHz + ESP32 interior
Un módulo receptor superheterodino (RXB6 o similar) conectado al ESP32 interior captura las señales de todos los sensores. El ESP32 decodifica las tramas OOK mediante la librería rc-switch, identifica qué sensor cambió de estado y envía el evento al servidor vía WiFi.
Mapa en planta en tiempo real
El frontend recibe el estado (abierto/cerrado) de cada sensor mediante WebSocket y lo renderiza en un mapa visual por zonas (Salón, Cocina, Habitación). Los sensores abiertos activan una notificación push tipo tarjeta deslizante con icono de alerta, indicando qué ventana de qué zona está abierta.
Glow de borde rojo pulsante
Cuando hay sensores abiertos en una zona, su tarjeta muestra un borde rojo con glow animado mediante box-shadow multicapa (rgba(239,68,68) a distintas opacidades y radios de desenfoque), con la animación glowPulse que oscila entre 0.4 y 0.9 de opacidad cada 2.4 segundos.
Riego Automático por Zonas
3 sensores de humedad del suelo capacitivos
Sensores capacitivos de humedad (no corrosivos, a diferencia de los resistivos) instalados en Jardín Delantero, Jardín Trasero y Huerto. Lectura analógica mediante GPIO del ESP32 exterior, calibrados para detectar desde sequía (0%) hasta saturación (100%).
Electroválvulas + Módulos MOSFET
Cada zona tiene una electroválvula de 12V controlada por un módulo MOSFET (relé de estado sólido) desde el ESP32 exterior. Cuando la humedad del suelo cae por debajo del umbral configurado por zona, el ESP32 activa el MOSFET que alimenta la electroválvula, abriendo el paso de agua.
Lógica de lazo cerrado sin temporizadores
Cada zona del jardín tiene su propio sensor de humedad y el sistema riega solo cuando el suelo lo pide, ajustando la frecuencia según la temporada y las necesidades de cada zona. No hay programación horaria fija. La lógica corre íntegramente en el ESP32 exterior, que decide en cada ciclo si debe regar.
Panel de control en dashboard
El frontend muestra las 3 zonas en cuadrícula de 3 columnas con nombre, porcentaje de humedad actual, barra de progreso horizontal coloreada dinámicamente (verde #10b981 para ≥70%, azul #0ea5e9 para 30-70%, ámbar #f59e0b para <30%), y estado textual (Regando con glow azul / Completo / Riego programado).
Monitoreo de Depósitos de Agua
2 sensores ultrasónicos JSN-SR04T
Sensores de ultrasonidos resistentes a la intemperie con encapsulado IP67 y rango de -20°C a 80°C. Emiten pulsos de 40kHz y miden el tiempo de retorno del eco para calcular la distancia a la superficie del agua. Instalados en la parte superior de cada depósito, apuntando verticalmente hacia abajo.
Cálculo de volumen en tiempo real
El ESP32 exterior dispara los sensores cíclicamente, mide la distancia y calcula el porcentaje de llenado y el volumen estimado en litros basado en las dimensiones de cada depósito. Los datos se envían al servidor y se muestran en el frontend con formato "620L / 1000L".
Visualización con onda de agua animada
Cada barra de nivel usa un clipPath SVG con trayectorias bezier (2 ciclos coseno) para crear un efecto de onda en el borde derecho del relleno. Animación continua mediante SMIL animateTransform con translateY lineal (4s por ciclo), y el clipPath usa clipPathUnits='objectBoundingBox' para escalar correctamente en cada barra.
Código de colores por nivel de llenado
Las barras cambian de color según el nivel: verde brillante (#10b981 → #6ee7b7) para ≥80%, azul cielo (#0ea5e9 → #7dd3fc) para 30-79%, ámbar (#f59e0b → #fbbf24) para <30%. Incluyen un gradiente blanco superpuesto (transparente → rgba(255,255,255,0.20)) para efecto de profundidad tipo cristal.
Alarma Láser Perimetral
Barrera invisible con emisor láser + fototransistor
Un diodo láser emite un haz colimado hacia un fototransistor en el lado opuesto de la zona a proteger. Cuando el haz se interrumpe, la resistencia del fototransistor cambia y el ESP32 interior lo detecta como un flanco digital en microsegundos. Sin falsos positivos por luz ambiental gracias a la modulación del haz.
2 zonas de detección independientes
El sistema tiene dos zonas (Acceso Principal y Acceso Trasero), cada una con su propio par emisor láser + fototransistor conectado a pines digitales independientes del ESP32 interior. Cada zona se monitoriza y notifica por separado.
Detección en milisegundos con notificación push
Cuando una zona se dispara, el ESP32 detecta el cambio de estado digital en menos de 1ms y envía el evento al servidor. El frontend recibe el evento vía WebSocket y muestra inmediatamente la zona en estado de intrusión: fondo rojo pulsante, glow animado idéntico al de ventanas, etiqueta ALARMA intermitente y notificación push deslizante.
Animación de barrido tipo scanline
En estado de intrusión, la tarjeta de la zona disparada muestra una animación de barrido vertical con pseudo-elemento CSS (scanLine keyframe de translateY), simulando un escáner de seguridad activo que recorre la tarjeta de arriba a abajo cada 2 segundos.
Firmware
PlatformIO + Arduino Framework
Entorno de desarrollo con gestión de dependencias y compilación cross-platform. El framework Arduino proporciona las bibliotecas de alto nivel para DHT11, WiFi y OTA.
Compilación Dual desde un solo source
Un único archivo main.cpp se compila dos veces mediante build_flags de PlatformIO. Cada binario recibe un SENSOR_ID distinto ("esp32-dht11-exterior" / "esp32-dht11-interior") que determina qué datos envía y cómo se etiquetan en la base de datos.
OTA Updates
Actualización inalámbrica de firmware vía ArduinoOTA con contraseña. Se ejecuta tanto en el loop principal como dentro de los delay internos (3 ciclos de 33ms por envío), garantizando que nunca se pierda la capacidad de actualización remota.
HTTPS Directo a PocketBase
Conexión HTTPS mediante WiFiClientSecure con POST JSON directamente a la REST API de PocketBase. Sin autenticación por token — el servidor confía por IP. Sin certificado SSL validado (setInsecure) para simplificar el firmware.
Sincronización NTP
Los ESP32 sincronizan su reloj con pool.ntp.org (fallback a time.nist.gov) antes de cada envío, asegurando que los timestamps de las lecturas sean precisos incluso tras cortes de energía.
Base de Datos
Colección sensor_readings
Almacena cada lectura individual de los ESP32: temperatura (number, °C), humedad (number, %), sensorId (text — exterior o interior) y created (autodatetime). Escritura pública desde los ESP32, acceso público vía REST o WebSocket.
Colección environment_readings
Almacena datos ambientales externos obtenidos de Open-Meteo: uv_index, european_aqi, pm2_5, pm10, nitrogen_dioxide, ozone, y 6 tipos de polen (alder, birch, grass, mugwort, olive, ragweed). Una entrada por hora.
Suscripciones WebSocket en tiempo real
El frontend se suscribe a eventos create en sensor_readings mediante pb.collection("sensor_readings").subscribe("*"). Cada nuevo registro se añade instantáneamente al estado de React sin necesidad de polling, con un límite de 2000 registros en memoria.
Frontend
React 19 + Vite 8 + Tailwind v4
Aplicación SPA moderna sin router (pantalla única de dashboard). Vite 8 con compilador basado en Oxc para builds ultrarrápidos. Tailwind CSS v4 con variables CSS para tema oscuro/claro.
Recharts con bucketing dinámico
Gráficos interactivos impulsados por el algoritmo snapBucket(), que calcula intervalos de agrupación adaptativos según el rango temporal visible. El resultado se suaviza con smoothData() (media móvil ponderada). Los spans van desde 1 minuto hasta 60 minutos.
Gráfico 50/50 exterior
El panel exterior muestra mitad datos históricos del DHT11 y mitad pronóstico de Open-Meteo, separados por una ReferenceLine vertical en el instante actual. Dos puntos adyacentes evitan que smoothData() mezcle ambos conjuntos.
Tema oscuro / claro con persistencia
Detecta la preferencia del sistema (prefers-color-scheme), permite alternar manualmente, y persiste la elección en localStorage. Sincroniza el meta theme-color con el fondo actual.
PWA + Service Worker
Instalable en el escritorio del móvil u ordenador vía vite-plugin-pwa. El service worker gestiona la caché y la actualización automática cuando se despliega una nueva versión.
Watch Face para Wear OS
Trusted Web Activity (TWA) empaquetada con Bubblewrap. La app detecta el parámetro ?mode=watch y carga un dashboard optimizado para pantalla redonda de 466×466px con navegación por deslizamiento y polling cada 2 minutos.
APIs Externas
Open-Meteo Weather API
Pronóstico gratuito sin API key. Proporciona temperatura y humedad a 5 días con resolución horaria desde las coordenadas 40.2333, -4.3833. Refresco cada 10 minutos en el frontend.
Open-Meteo Air Quality API
Datos actualizados de calidad del aire según el índice AQI europeo. Incluye concentraciones de partículas PM2.5 y PM10, dióxido de nitrógeno (NO₂), ozono (O₃) y 6 tipos de polen alergénico con sus niveles de riesgo.
Despliegue
Docker Multi-stage (build ~30MB)
Construcción en dos etapas: node:22-alpine compila la app con pnpm, y nginx:alpine sirve los archivos estáticos en el puerto 80. La imagen final pesa aproximadamente 30MB.
nginx Reverse Proxy + WebSocket
Proxy inverso que redirige /api/* al PocketBase backend con soporte de upgrade WebSocket y timeout de 24 horas para mantener las conexiones persistentes abiertas. Las rutas no-API cargan index.html (SPA fallback).
PocketBase auto-gestionado
Instancia de PocketBase alojada en el mismo dominio (gthome.mgtserver.es). Sirve tanto la API REST como la interfaz web de administración y las conexiones WebSocket en tiempo real.
SSL/TLS extremo a extremo
Todo el tráfico viaja sobre HTTPS. El frontend se sirve con SSL gracias a nginx, la comunicación con PocketBase también es HTTPS, y los ESP32 envían datos mediante WiFiClientSecure.