tail -f felipe-ra.com

Blog / Arquitectura

Arquitectura · Homelab

Videovigilancia a bajo costo

Como es normal en mis proyectos, busco muchas veces reciclar tecnología vieja o usar el menor presupuesto posible. La seguridad de mi casa no es la excepción.

01La razón que dio vida al proyecto

Un noche mientras estudiaba escuché un ruido; no le di importancia porque tengo vecinos que suelen ser animales nocturnos como yo. Al día siguiente me enteré de un posible intento de robo en una casa cercana.

Este hecho me llevó a darme cuenta de la precaria seguridad de mi propia casa. Es por esto que empecé a buscar cámaras de seguridad y alarmas en internet. El problema es que cosas como esta pueden ser bastante caras y cumplen funciones bastante simples viéndolo desde el ángulo técnico. Es por esto, que como buen ingeniero, que ve la complejidad real detrás de los productos, caí en el pensamiento de “puedo construirlo yo mismo”. Más aun considerando que ya estaba trabajando con Nabu y con microprocesadores ESP32 para distintos mini proyectos de prueba.

Entré al viejo confiable aliexpress y compré un par de ESP32CAM inicialmente, con la intención de más adelante agregar sensores de puertas y ventanas. Además combinado con Nabu y la memoria interna de este podría dejarlo tipo CCTV, grabando constantemente por varios días considerando la resolución de las cámaras.

02No todas las cámaras son iguales

Este apartado, además de contar mi experiencia, es también una recomendación por si quien lea esto quiere realizarlo por su propia cuenta. No todas las cámaras ESP32 son iguales. Personalmente tuve que aprenderlo cuando me llegó mi pedido desde china, ya que tenía dos modelos diferentes de sensor: OV2640 y GC2145. La diferencia principal entre estas no es un tema de potencia, es de familia de sensores. Por un lado tenemos el sensor OV2640 que está muy documentado y todos los proyectos que logré encontrar como ejemplo usaban este sensor, mientras que el GC2145 esta menos documentado y me costó bastante más poder hacerlo funcionar.

El módulo de cámara ESP32 con sensor OV2640
Fig. 1 — El módulo con sensor OV2640, el más documentado de los dos.

03Donde entra mi servidor en escena

Para conectar estas cámaras y hacerlas funcionar, es preciso configurar en el código el punto de acceso wifi y contraseña. Con esto listo, es necesario conectar un cargador de teléfono antiguo de 5V a la pared y conectarlo por usb C a las cámaras.

El problema real viene aquí: Cuando iniciaba la cámara y accedía desde mi teléfono a la ip de la esta en mi red LAN, el buffer generaba una transmisión sin inconvenientes, pero cuando abría al mismo tiempo desde mi computador el video, la imagen se congelaba y se caía en ambas transmisiones.

Lo anterior ocurría de forma independiente con ambas cámaras, por lo que, además de tener que solucionar este problema, debía encontrar la forma de ver ambas cámaras de forma simultánea, sin tener que cambiar la dirección a la que accedía cada vez. La solución fue bastante más intuitiva de lo que imaginé en principio y la homologué de un documental sobre cómo se transmitía el mundial de futbol del año 2025, en el que se explicaba que para poder realizar multi-transmisiones a diferentes canales de televisión, sin tener que generar una transmisión para cada uno de ellos, se generar una sola a un servidor central, el que podía procesar este video, poner todos las transiciones entre tomas y luego se realizaba una multi-transmisión a cada uno de los canales por separado. Esto se llama “patrón productor-consumidor” y es usado en eventos como este. (como se muestra en esta imagen).

Las dos cámaras transmiten a Nabu, que sirve ambas en un recurso HTTP por Tailscale
Fig. 2 — Cada cámara recibe una IP del router y transmite a Nabu, que levanta un recurso HTTP accesible por Tailscale con las dos cámaras.

Estimé que dicho esquema era una solución elegante, que me daba oportunidad no solo de controlar y procesar la imagen de ambas cámaras en una sola web que consultaba a Nabu desde tailscale desde cualquier parte del mundo, sino que también me servía para no exponer servicios desde mi LAN cerrada al exterior sin tener que pasar por Nabu, lo que rompería todo el propósito de tener una LAN sin salidas a internet.

04La caída

Hasta este punto el proyecto iba bien encaminado. El problema real se generó cuando empecé a notar que cada cierto tiempo, la cámara con el sensor GC2145 (aproximadamente cada 1 hora de forma constante) cortaba la transmisión y se perdía señal, quedando la imagen congelada en un frame del video. Esto de forma inicial me hizo pensar que el código podía estar fallando, pero en realidad después de revisar en conjunto al serial monitor de arduino IDE logré notar que se caía por exceder el límite del buffer usado. Es decir, la memoria ram de la cámara no estaba aguantando la transmisión de video constante.

Inicialmente pensé que aquello podría ser la lápida del proyecto, pero al investigar un poco más descubrí que las cámaras esp32 no solo poseen memoria RAM ( ~320-520 KB), sino también una memoria PSRAM que es más grande (~ 4-8 MB), pero por consecuencia de mucha mayor latencia (1/10 de la velocidad de la RAM). Al probar esta memoria para el buffer de la cámara noté que en realidad solo daba medio a 1 segundo de latencia en el video transmitido, nada que afectara a la larga en la visualización.

Lo único que me faltaba solucionar era y puse como cortafuegos, realizar un reinicio automático dentro del firmware de forma que si detectaba que no estaba conectada a la red LAN se realizaría un reinicio al sistema cada cierto tiempo (se colocó el timer para evitar que se reiniciara en caso de una caída de la red LAN de forma inmediata).

A la par, diseñé un plan de contingencia en el evento en que la memoria se viera superada, caso en el que mandaría un reinicio automático a la cámara sin tener que esperar tiempo.

05Grabación en Nabu

En este punto el sistema ya funcionaba, y era momento de avanzar al último escalón a resolver: el poder grabar de forma constante estas cámaras para obtener repeticiones en caso de ser necesarias.

Para realizarlo tuve que usar la memoria de mi servidor y realizando cálculos con la ayuda de Claude pude definir que tenía la autonomía para grabar más de 20 días de forma continua, usando la misma transmisión que recibía el servidor desde las cámaras de forma independiente.

Este cálculo se realizó en base al bitrate del H.264, que ya refleja la resolución y los fps, determinando cuánto pesa un tramo de 10 minutos. (las grabaciones quedan en piezas de 10 minutos para evitar perder todo un archivo de video cuando una cámara está caída, periodo en el que no se registra el input de la cámara).

Con esto y una regla de tres, podemos obtener cuantos días tenemos de grabación considerando que dejé aproximadamente 100 – 150 GB de memoria solo para grabaciones.

Al finalizar un periodo de 20 días, las grabaciones más antiguas se eliminan, liberando espacio para no saturar la memoria.

Para finalizar, todas las grabaciones son accesibles a través de tailscale conectándome a Nabu y se guardan en un directorio específicamente creado para esto.

06Conclusiones

Este proyecto empezó solucionando una necesidad real, guiándome en un camino de conocimiento que, en parte, ya poseía, ya que el uso de ESP32 era algo que tenía de proyectos anteriores de menor escala relacionado con sensores de movimiento, temperatura y ruido, pero que significó un nuevo aprendizaje en el uso de cámaras ESP32. Considerando además que ya tenía experiencia en tratamientos de imágenes con mis trabajos publicados en la IEEE de tracking de iris con cámaras de baja resolución, (Consultar mi CV en esta página para encontrar la publicación), este desafío me motivó a aventurarme en microprocesadores como fuentes de trabajo para este sistema auto-alojado.

¿Qué pude sacar en limpio de todo esto? Los conocimientos de transmisiones productor-consumidor y su aplicación a menor escala me ayudaron a entender cómo funcionan los sistemas cerrados CCTV y que, a pesar de haber tenido problemas que pude resolver con investigación, no son tan complejos como servicio, lo que contrasta con los altos valores que muchas veces se pagan por sistemas completos como estos y que no solo cuestan mucho, sino que tampoco entregan garantías de inaccesibilidad a ellos por terceros estar expuestos a internet.

Lo descrito es lo que lo tornó interesante para mí y me impulsó a dedicar este post, pues se trata de sistemas que funcionan a diario a la vista de todos y a pesar de que ya tenía conocimientos técnicos sobre el tema, también me permiten ejemplificar que el hecho de comprar sistemas como estos solamente pasa por “sacarlo de la caja y usarlo” más que “es un sistema complejo”, concepto que muchas veces la gente confunde pensando que tienen el control total sobre los productos y sistemas que ocupan.

Es efectivo que las cámaras que compré son de muy bajas de resolución y valor (no superando los 10 dólares), y a pesar de que esa era la magia del proyecto, también da margen de mejora, comprando cámaras ESP32 con sensores de mayor resolución, lo que tampoco eleva tanto el valor como para aun así querer comprar un sistema pre-fabricado (considerando las contras de usar sistemas en la nube para seguridad del hogar).

Para finalizar (y viéndolo desde una perspectiva de seguridad), al igual que en otros proyectos, es la dependencia de Nabu para mantener estos servicios activos lo que sigue siendo un desafío, ya que si llegase a caer el servidor, con ella, en efecto dominó, caerían la transmisión y grabación de las cámaras.

Esto por ahora no me urge, aunque tengo considerada soluciones como: Primero, separar los servicios de grabación y transmisión en distintos nodos de la red LAN, de forma que no dependa solo de una máquina el transmitir y grabar, permitiéndome también tener una memoria exclusiva para las grabaciones y posible tratamiento de datos en un futuro. Segundo, es el hecho de tener memorias RAM tan bajas de cada cámara trabajando para la transmisión de video y detección de caídas al mismo tiempo. Es decir que en un futuro, si quisiera invertir un poco más en esto, podría agregar una ESP32 y trabajar la transmisión por separado en cada cámara, para no depender de toda la memoria ram de cada una para mantenerse alerta en caso de caídas de la red LAN o de la propia ESP32CAM.