DOMOTICA LOW COST CON RASPBERRY PI
Cómo domotizar tu casa con una Raspberry PI y por $360
HARDWARE
El pequeño y robusto portátil Siemens con aproximadamente diez años de antiguedad sigue funcionando como el primer día, con incluso unos grados menos de temperatura y sin apenas mantenimiento. Sin embargo ahora toca hablar de otro pequeño proyecto que llevé a cabo hace unas semanas y que voy a detallar a continuación… La Raspberry PI
Como saben la Raspberry Pi es un mini ordenador con procesador ARM 700Mhz que tan sólo vale $360 Como tal, es accesible al bolsillo de todos y cuenta con unas características muy interesantes.
La placa programable de bajo nivel que contiene llamó mi atención desde el primer momento. Mis nociones en electrónica eran limitadas, así que tuve que tirar de google para al menos aclarar ciertos conceptos básicos y descubrir qué posiblidades tenía. De lo primero que me cercioré gracias a la red de redes era la existencia de los puertos GPIO. Puertos de entrada-salida que pueden ser controlados por el usuario… veamos… que puedo aplicar 0 ó 1 cuando me plazca. También, claro está, puedo leer en qué estado se encuentran los mismos en el caso de interesarme.
Me regalaron la Raspberry PI en un hackaton y no le había prestado mucha atención por falta de tiempo y tampoco tenía claro realmente qué tipo de proyecto podía crear con ella. No tenía intención ninguna de usarlo como MediaCenter teniendo una SmartTV y mucho menos como sistema de escritorio… más que nada por la ausencia de monitor. ¿Servidor? ¿Otro? ¿Realmente me iba a poner a probar como servidor otro dispositivo y escribir sobre ello? Sí y no. Ya se van a dar cuenta porqué.
Es entonces cuando nació la idea de poder controlar partes básicas de mi casa por medio de estos puertos. Pero antes de nada hablemos un poco de las peculiaridades de los mismos. En primer lugar, cuando el estado del puerto es 1, se aplica un voltaje de 3.3 voltios, cuando el 0, obviamente, ninguno, A ver cómo hacemos para que se lleven bien 3.3V DC con unos bonitos 220V AC que circulan por mi casa.
Antes de entrar en materia, quise hacer unas pequeñas pruebas y compré un Kit con las cosas básicas:
Protoboard
LEDs
Cables
Resistencias
Los LEDs eran de varios colores y no pude sucumbir a la tentación de hacer un bonito semáforo. Como la placa de la Raspberry no está protegida, tuve que tener especial cuidado al elegir las resistencias y tiré por lo alto aunque los LEDs no brillen en demasía. El lenguage de programación elegido para este caso es Python y tengo que decir que me ha sorprendido su potencia y facilidad.
La distro elegida para esta causa fue, naturalmente, Raspbian, la cual es la más fiel a Debian y además cuenta ya con el entorno de desarrollo Python instalado. Tan sólo tuve que instalar unas librerías para controlar los GPIO y listo. Como comentaba anteriormente, hice mis primeras pruebas con los LEDs y aunque llevo muchos años trabajando en el mundo de la informática, a mí me sigue todavía llamando la atención cómo podía hacer parpadear LEDs a mi antojo, no sé… llámenme romántico xD.
RELÉS
Los relés eran una parte básica del proyecto. Necesitaba algo puramente mecánico que dejara pasar la electricidad ante cualquier evento. Hay un sin fin de relés disponibles con varios rangos de entrada y salida, pero a decir verdad, eran todos muy limitados y ninguno cumplía con mis premisas. Algunos sí se adaptaban a mis necesidades, pero como bien dice el título del presente blog, quería algo Low Cost.
Después de plantearme construir algún tipo de circuito manual para manejar tales rangos, no sé cómo fui a parar a la página de un simpático americano más bien rellenito que me dio a conocer unas de los aparatos que acabaría radicalmente con mi dolor de cabeza.
SOLID STATE RELAY
Parecía un producto caído del cielo. Ya ni siquiera no era mecánico, que es maravilloso, sino que además manejaba rangos de entrada DC de 3 a 32V… y no se pierdan, el rango de salida era AC de 24 a 380V con un máximo de 25A. En cuestión, este el producto que adquirí:
Aunque hay un sin fin de marcas y modelos, finalmente me decidí como les he comentado por este en cuestión ya que aguanta más amperaje y por lo que pude ver, FOTEK es una marca “consagradísima” de electrónica de Taiwan.
Antes de entrar en materia, primero tenía que saber qué partes de la casa podía controlar y cómo. Mi morada no es nada del otro mundo… de hecho es pequeña y, bueno, en teoría eso me favorecía a la hora de los relés usados. Dispongo de un salón con cocina integrada, baño y tan sólo una habitación. También cuento con una terraza que dispone a su vez de iluminación.
El siguiente paso es sencillo… ¿dónde puedo colocar la Raspberry, los relés y el cableado? Pues en el único sitio donde se encuentra todo centralizado… en el cuadro eléctrico. Sí, a mi también me tembló el pulso cuando pensé en colocar allí un mini ordenador de $360 con la bonita responsabilidad de salvaguardar la iluminación de mi casa.
Como ya he comentado, hice una pruebas básicas con Python controlando los leds y los nuevos relés para comprobar que efectivamente funcionaban observando sus estados . Lo siguiente era estudiar cómo estaba diseñada la instalación eléctrica y ver qué posibilidades tenía. Unos de los fusibles controlaba las luces del salón y de la cocina, recuerden, integrada. El siguiente controlaba mi habitación y, maldición, también el baño. No era partidario de incluir esta fase dentro del proyecto, pero no tenía otro remedio.
Otro de los fusibles daba al traste con la energía de los enchufes. Pensaba yo, ufa no, que serían los aquellos localizados en el salón y que habría otro extra para aquellos colocados en la habitación. Pero no, cortaba la energía de todo lo enchufado excepto los enchufes que requirieran más potencia como lavadora, horno y frigorífico; ya que estos contaban con sus propios fusibles.
Para aquellos más avispados, atentos a la siguiente explicación. Como saben la Raspberry cuenta con su puerto HDMI y pueden usar así un monitor, pero claro está que donde radica su versatilidad es en poder conectar por VNC y por SSH sin necesidad de tal armason. ¿Qué pasa si corto la energía de los enchufes? Tendría que conectarlos manualmente en el cuadro eléctrico o llevar el router a algún enchufe no afectado para recuperar la conexión con mi RBPI.
Mi lugar de residencia es en el norte de Argentina y como tal, cálida como es, muchas de las casas cuentan con unos paneles solares en los tejados para generar agua caliente. El problema es que en invierno, a veces el sol no es suficiente y contamos con un interruptor en el pasillo para calentar el agua usando la energía eléctrica. les cuento esto porque de ese interruptor, en vez de llegar como de costumbre el cable marrón de FASE, llegaban los dos, FASE y NEUTRO. Es así como fabriqué un enchufe de la nada y fuera de peligro y apagones. Al tener el router en modo repetidor, tampoco me hacía falta que llegase ningún cable de teléfono. El router repite la señal wifi de un hotspot de pago cercano y así me aseguro de que mi raspberry no pierde internet nunca.
Colocando la RBPI y la protoboard en la compuerta del cuadro eléctrico.
Una vez decidido qué partes tenía la posibilidad de controlar, llegó el momento de montar el sistema con RBPI y relés en el cuadro electrico. Mi intención era que una vez todo montado, tuviera la posibilidad de cerrar de nuevo el armario, por lo que tuve que medir los espacios que tenía y poner las piezas en sitios concretos.
En la imagen publicada pueden ver en principio dónde coloqué la RBPI y la protoboard. Hay dos grupos de tres cables que provienen de los GPIO. Tres de ellos para los tres relés, y los otros tres para alimentar tres Leds que usaré como monitor de temperatura. Dado que el cuadro estará cerrado la mayor parte del tiempo, es posible que la temperatura suba mucho debido a que el aire de dentro no se renueva. Quiero encontrar una solución a eso, pero hasta entonces, un pequeño ventilador en el procesador bajaba la temperatura hasta los 38º. Es por eso que cuento con los Leds en forma de semáforo. Con un script en Bash y ejecutado cada minuto, visualmente puedo hacerme a la idea del calor que está pasando el sistema. Además, ahora he colocado los LEds en la esquina para poder así ver el color de los mismos con el armario cerrado.
< 38º – 42º VERDE
42º – 47º VERDE-AMARILLO
48º – 52º AMARILLO – ROJO
> 52 ROJO
Otro de los problemas que tuve a la hora de montar el sistema en el cuadro eléctrico fue la fuente de alimentación. La que yo tenía era tan sólo de 700mA y no era suficiente para mover Raspbian (SO), el dongle WIFI y una cámara que tenía pensado poner para monitorizar la casa en mi ausencia. Luego tuve la gran idea de comprar otra cámara y poder así alternar entre ver mi cuarto y en salón cuando más me plazca.
Es por eso que adquirí por Mercadolibre una USB Hub compatible con Raspberry y alimentado por su propia fuente de 2A. Eso se tornaba también en un problema, ya que no sabía donde colocar dos fuentes de alimentación en un espacio tan reducido como el cuadro eléctrico. Y no, alimentar la Raspberry por usb usando el Hub no funciona ya que el flujo de intensidad fluctúa y la hace comportarse de forma inestable.
Así es como quedó el diseño preliminar antes de acoplarlo al cuadro eléctrico, aunque he hecho algunas pequeñas modificaciones que ya veran en el vídeo. Como ven he conectado tan solo una masa de la entrada DC de la raspberry en serie al igual que la FASE en la salida AC. Los cables restantes van directamente conectados al cuadro electrico.
Fui consciente del peligro que entrama que todo la intensidad de corriente para por esos pequeños cables. De los relés no tengo que preocuparme, ya que aguantan un máximo de 25A. De los cables para alimentar luces, tampoco era problema, puesto que con toda la iluminación conectada, no llega tirando por lo alto a 400W. Pero de los enchufes tengo que tener especial cuidado, porque conectando el tostador + estufa + secador podríamos llegar a los 20A fácilmente y los cables no están preparados para semejante intensidad. Como se puede observar, los cables que uso, aun siendo FASE y NEUTRO, uso los dos para evitarme como he comentado, calentamientos innecesarios. Aunque sí es verdad que tengo mucho cuidado a la hora de enchufar cosas.
De todas formas, ahora que voy a contratar mi propio internet, creo que voy a tener que buscar otro uso al tercer relé y así de paso me quito la preocupación de ver ardiendo el sistema entero por sobrecarga.
Así quedó el sistema una vez acoplado todo. les aseguro que cierra perfectamente
SOFTWARE
sí, muy bonito, la puerta cierra perfectamente… pero ahora qué. Hagámoslo, funcionar con algunas líneas de código. Mi meta era clara, quería hacer un programita elegante y simple para mis propósitos. Aunque la aplicación en sí no va a ser utilizada por otros usuarios, quise aplicar un férreo control de validaciones y por supuesto, que admita en el caso de que los haya, nuevos relés para otra futura instalación. No piensen que es una obra de arte, aunque en mi trabajo veo mucho código, no me considero un programador, aunque nunca es tarde si la dicha es buena.
Como comenté anteriormente, opté por Python para realizar la aplicación “Domo” ya que el entorno está instalado en la distribución Raspbian para RBP y verdaderamente es un lujo trabajar con él. Poco después de preparar el entorno, me sentía más cómodo programando en un editor con alguna ayuda integrada.
Me instalé para ello PyScripter Portable disponible dentro de Portable Python y para modificar directamente los archivos de la Raspberry tiré, lógicamente, del magnífico WinSCP con una pequeña ayudita que hará las delicias de muchos… En lugar de tirar del editor por defecto, instalé aparte el Sublime Text 2 y lo definí como editor predeterminado del WInSCP. Una verdadera maravilla.
Mi idea era editar directamente los archivos en el editor con SublimeText, que en sí corrige varios cosas, ya que en Python hay que tener especial cuidado porque todo funciona a través de tabulaciones. Si en tiempo de ejecución ocurrían problemas que no sabía a primera vista interpretar, tiraba del PyScripter para detectar los fallos más fácilmente.
Empecemos destripando el código:
Desde el principio quería que la aplicación aceptara argumentos. Me parecía mucho más cómodo que crear un menú con diferentes opciones y de lo que se trataba era de accionar rápidamente cualquiera de los relés. Usé para ellos el atributo argv del objeto sys. Pueden pasar tantos argumentos como quieras siendo almacenados en un array.
Los argumentos de entrada son muy simples. Tan sólo introduzco 0 ó 1 para determinar el estado de los relés. Ahora comentaré porqué acepto más argumentos que los ya comentados. Como ven, puedo aceptar más de un argumento debido a una propiedad que aún estoy intentando integrar para hacer parpadear las luces de la casa a mi antojo. Mi intención no es crear una casa de esas navideñas, sino que simule presencia en mi casa, ya que cuando vuelvo a la madre patria por vacaciones lo hago por un largo periodo de tiempo y nunca está demás tomar precauciones.
Tengo que madurar aún la idea, y voy a quitar esas líneas innecesarias que afean un poco el código. Prefiero hacer otro script que invoque a este programa para manejar la simulación ya que es algo que tan sólo usaré en días de largas ausencias.
Esta función no tiene ninguna complicación. Tan sólo me aseguro que no cometa el error de introducir un estado que no sea 0 ó 1 y, obviamente, no intentar encender o apagar partes de la casa que no existen.
Las líneas anteriores tampoco tienen complicación. Es básicamente donde se realizan las acciones que invoco desde el Main que veremos más tarde. En primer lugar me aseguro que el usuario no tenga intención de hacer parpadear la casa y simplemente me dispongo a apagar o encender las partes deseadas.
Antes de nada abro un fichero plano para guardar cómo quedarán los estados después de la ejecución. A continuación, simplemente con un simple FOR, recorro tantas partes como haya definido y se aplica el resultado. Si añado más relés a la vivienda, es una parte del código que no se debe tocar, puesto que la variable “n” almacena el número de relés de los que dispongo.
Por favor, ignorar las líneas referentes al parpadeo. Las dejo si por casualidad sirven de ayuda, pero semejantes líneas merecen arder en el infierno para siempre. Para terminar, defino la función que leerá el fichero que contiene el último estado de los relés. Será llamada si ejecutamos el programa sin argumentos.
El cuerpo MAIN tampoco puede ser más simple. Si ignoramos la comprobación que hago para el dichoso parpadeo, no hago más que definir en un array las partes de la casa y el número de GPIO que tienen asignado.
Las restantes líneas contienen la llamada a la función “Action” y que puedo llamar de diferentes maneras depende, cómo no, de el dichoso parpadeo. Simplemente añadía a la función el número de parpadeos y cuánto tiempo en segundos había entre ellos.
Hasta aquí la pequeña criatura que ilumina mis momentos de tiniebla. Insisto en que las cosas se pueden hacer mucho mejor y estoy abierto a toda crítica constructiva que se precie. Al fin y al cabo y como he comentado, ya no ejerzo la programación y tan sólo la tengo como hobbie.
FRONT-END
Supongamos que llego a casa después de un arduo y sinuoso día de trabajo. Debido al calor sofocante he bebido cantidades ingentes de agua y requiero vaciar la vejiga y no es plan de orinar a oscuras. Queda muy bien la pantallita negra para alardear con los amigos sin embargo es de agradecer contar con una interfaz donde poder apagar y encender fácilmente las luces. Si a eso le añades unas camaras conectadas a la RBPI, la fabulosa idea empieza a tomar forma.
Insisto que el único usuario soy yo, pero ya lo dice el refrán… “las cosas bien hechas, bien parecen”. Sí he realizado bastante diseño web y he toqueteado muchas cosas, pero juro que odio con todas mis fuerzas todo lo relativo a HMTL, CSS y la madre que los paseó a todos. Aún así me armé de valor para realizar una simple interfaz donde pudiera visualizar las imágenes de la habitación y el salón y además unos botones muy grosos para manejarlas.
Me compré dos cámaras muy simples Logitech c130 que funcionaban sin la necesidad de instalar ningún driver e instalé el software “motion” que aunque no es del todo fácil, pero con la ayuda de internet y una tarde tienes lo básico para hacerlo funcionar.
Aunque tampoco es lo más elegante, usando PHP tienes la intrucción “exec” donde puedes ejecutar cualquier comando en la máquina remota. Me venía muy bien para mi propósito, sin embargo había una cosa con la que no había planeado. El uso de un enlace, sea un link o un botón, conlleva que la página web se recargue. No era un problema muy grande, pero quería evitar que con cada pulsación el usuario tuviera que esperar a que las imágenes se generaran otra vez.
Tuve algunos problemas de ancho de banda con los usb que solventé bajando la calidad de las imágenes y ya por fin soy capaz de visualizar las dos cámaras sin problemas, pero con un retraso de unos cuatro segundos. Motion también te ofrece la posibilidad que ejecutar cualquier comando sea cual sea el evento. Por ejemplo, puedo hacer parpadear las luces si detecta movimiento e incluso hacer sonar por los altavoces una alarma y ahuyentar así a los cacos.
Volviendo a la interfaz web y evitar así que la página recargue, me centré en el uso de AJAX y con una función para cada relé me las apañé para poder encender y apagar con sólo apretar el botón. Fácil, sencillo y puedes visualizar en la cámara sin cortes si la acción ha dado resultado o no.
He aquí la página web.
Pasando el cursor por las imágenes de la cámara, se mostrará unas flechas que te permiten visualizar la otra cámara. Pedí por DX un servomotor y será el paso siguiente del proyecto junto con unos altavoces para no sólo hacer sonar alarmas, sino también como un equipo decente de sonido mientras hago las labores del hogar.
El servomotor me permite con una solo cámara hacerla girar los grados que desee y poder visualizar incluso el baño. Los controles se añadirían en la interfaz web y es a día de hoy el siguiente paso y que documentaré tan pronto como lo instale. Obviamente perdería las prestaciones de “detector de movimiento”, pero creo que vale la pena.
Lamentablemente no les puedo dar la url de la interfaz web porque quiero vivir tranquilo sin tener que sufrir decenas de apagones diarios. He creado también un simple script para levantar y desactivar la interfaz cuando me plazca dejando tan sólo el servidor SSH como método primario.
En definitiva el proyecto puede crecer mucho, pero siendo honesto no tiene mucha utilidad. A todo mortal nos gusta pulsar el interruptor para que luz se encienda y no tener que ir con el teléfono pulsando botones todo el tiempo. Además, aunque a día de hoy la Raspberry me está respondiendo perfectamente, el hecho de que un dispositivo de $360 sea el que mantenga la luz de mi casa es cuanto menos una locura. Aunque he sido lo suficientemente cuerdo para dejar fuera de la ecuación al frigorifico y demás electrodomésticos por si acaso ocurre algo en mi ausencia.
Bienvenidos son todos de darme nuevas ideas y, por favor, corregirme si en algo me he equivocado o se puede hacer mucho mejor en lo referente al código publicado, ya que de la interfaz web ni me atrevo. Por último, les dejo un vídeo de demostración para que vean el sistema funcionando in situ.
link: https://www.youtube.com/watch?v=AzOsrUsctD0