04-12-2015, 12:08 PM
(Última modificación: 10-12-2015, 05:00 PM por sistemasorp.)
En esta serie de post voy a publicar todos los detalles del proyecto de domótica que envié para que se expusiera en la Bilbao Maker Faire 2015.
La idea general es poder controlar dos lámparas de 220V a través de internet o localmente.
Cómo hay distintos dispositivos (móviles, tablets, pc, portátiles) con distintos sistemas operativos, la interfaz para controlar esas lámparas tiene que ser web para que desde cualquier navegador moderno se pueda manejar sin tener que instalar ninguna aplicación. También es necesario que varias personas puedan interactuar con las lámparas al mismo tiempo y que los resultados se vean en todos los dispositivos a la vez en tiempo real.
El usuario se conecta a un servidor web en internet y el sistema también se conecta a este mismo servidor para que coordine todo el funcionamiento entre los usuarios y el sistema. La opción de que todo estuviese en el sistema no era posible porque por un lado no sabía si había wifi en el local de la Maker Faire y por otro esta no iba a tener los puertos abiertos para su correcto funcionamiento.
En local el operador puede enceder o apagar las lámparas, bloquear o no las acciones de los usuarios o apagar el sistema pulsando los botones correspondientes. También el operador puede visualizar en el display el estado de las lámparas, si el bloqueo está activo y el número de dispositivos conectados.
Servidor
El servidor es un vps linux que tengo contratado en digitalocean.com, pero podría funcionar con uno propio en casa con los puerto 80, 1976 y 10000 abiertos desde el router.
En este servidor están instalados los siguientes programas:
Si el servicio de websockets está caido el código de la página lo reintenta hasta 10 veces. Así mismo si pasan 5 minutos sin que el usuario haya realizado ninguna acción en la interfaz la página se autodesconectará del servicio de websockets. Si la página web detecta que el navegador del usuario no puede manejar websockets se le informa de ello en la misma página. Los estados de conexión, desconexión y expiración se muestran en la esquina inferior izquierda de la página web.
El script de python crea un servicio de websockets por el puerto 1976 con ayuda de la librería tornado y además crea un socket servidor por el puerto 10000 que espera a la conexión del sistema. Cuando se conecta el sistema el script recibe un byte 0x30 más unos bits que indican el estado actual:
A su vez el script python envía al sistema tantos bytes 0x38 como dispositivos hay conectados y cuando un nuevo dispositivo se conecta mediante websockets. Cuando se desconecta un dispositivo el script envía al sistema un byte 0x39. Tanto en la conexión como en la desconexión del sistema envía un correo electrónico para informar de ese hecho. Cuando el usuario interactua con la interfaz, un byte es recibido por los websockets y después se envía inmediatamente al sistema, el sistema responderá con el mismo byte para que sea reenvíado a todos los dispositivos que en este momento estén conectados (esto es así porque también sirve para cuando se pulsan los botones físicos y se envía el estado de las lámparas)
Aquí dejo el código fuente de la web y del script de python: http://sistemasorp.homelinux.com/servidor.zip
Sistema
El sistema está formado por:
El script nada más comenzar apaga las lámparas si estas estuvieran encendidas. Intenta conectarse al servidor por el puerto 10000 hasta que lo consigue. Recibe tantos 0x38 como dispositivos haya conectados al servidor y muestra en el display el estado actual:
Si el operador pulsa el botón superior se enciende o apaga la lámpara 1. Si el usuario pulsa el botón inferior se enciende o apaga la lámpara 2. Si el usuario pulsa el botón derecho se activa o desactiva el bloqueo de comandos. Si el usuario pulsa el botón select entonces comienza el apagado de la Raspberry Pi. En todos los casos se muestra en el display la información correspondiente.
Aquí dejo el código fuente del script de python: http://sistemasorp.homelinux.com/sistema.py
Como colofón, si os preguntais por qué uso los bytes del 0x30 al 0x39 es porque representan los ASCII del 0 al 9, por lo que para hacer pruebas con un telnet me bastaba con pulsar los números en el teclado.
Y creo que no me dejo nada, pero si teneis alguna duda, critica constructiva o comentario, podeis ponerlo en este mismo hilo.
Gracias.
La idea general es poder controlar dos lámparas de 220V a través de internet o localmente.
Cómo hay distintos dispositivos (móviles, tablets, pc, portátiles) con distintos sistemas operativos, la interfaz para controlar esas lámparas tiene que ser web para que desde cualquier navegador moderno se pueda manejar sin tener que instalar ninguna aplicación. También es necesario que varias personas puedan interactuar con las lámparas al mismo tiempo y que los resultados se vean en todos los dispositivos a la vez en tiempo real.
El usuario se conecta a un servidor web en internet y el sistema también se conecta a este mismo servidor para que coordine todo el funcionamiento entre los usuarios y el sistema. La opción de que todo estuviese en el sistema no era posible porque por un lado no sabía si había wifi en el local de la Maker Faire y por otro esta no iba a tener los puertos abiertos para su correcto funcionamiento.
En local el operador puede enceder o apagar las lámparas, bloquear o no las acciones de los usuarios o apagar el sistema pulsando los botones correspondientes. También el operador puede visualizar en el display el estado de las lámparas, si el bloqueo está activo y el número de dispositivos conectados.
Servidor
El servidor es un vps linux que tengo contratado en digitalocean.com, pero podría funcionar con uno propio en casa con los puerto 80, 1976 y 10000 abiertos desde el router.
En este servidor están instalados los siguientes programas:
- apache: Para servir las páginas html, los estilos css y el código javascript.
- python: Para ejecutar un script que use tornado para los websockets y otro servicio para comunicarse con el sistema.
- tornado: Librería de python para proveer el funcionamiento de websockets.
- screen: Para poder ejecutar un script en una sesión virtual que siempre esté activa.
Si el servicio de websockets está caido el código de la página lo reintenta hasta 10 veces. Así mismo si pasan 5 minutos sin que el usuario haya realizado ninguna acción en la interfaz la página se autodesconectará del servicio de websockets. Si la página web detecta que el navegador del usuario no puede manejar websockets se le informa de ello en la misma página. Los estados de conexión, desconexión y expiración se muestran en la esquina inferior izquierda de la página web.
El script de python crea un servicio de websockets por el puerto 1976 con ayuda de la librería tornado y además crea un socket servidor por el puerto 10000 que espera a la conexión del sistema. Cuando se conecta el sistema el script recibe un byte 0x30 más unos bits que indican el estado actual:
- bit 0: indica el estado de la lámpara 1
- bit 1: indica el estado de la lámpara 2
- bit 2: indica el estado del bloqueo
A su vez el script python envía al sistema tantos bytes 0x38 como dispositivos hay conectados y cuando un nuevo dispositivo se conecta mediante websockets. Cuando se desconecta un dispositivo el script envía al sistema un byte 0x39. Tanto en la conexión como en la desconexión del sistema envía un correo electrónico para informar de ese hecho. Cuando el usuario interactua con la interfaz, un byte es recibido por los websockets y después se envía inmediatamente al sistema, el sistema responderá con el mismo byte para que sea reenvíado a todos los dispositivos que en este momento estén conectados (esto es así porque también sirve para cuando se pulsan los botones físicos y se envía el estado de las lámparas)
Aquí dejo el código fuente de la web y del script de python: http://sistemasorp.homelinux.com/servidor.zip
Sistema
El sistema está formado por:
- Raspberry Pi modelo A
- Display HD44780 con botones para visualizar los datos y manejar las lámparas en local https://www.adafruit.com/products/1109
- Placa de relés para manejar tensiones de 220V http://www.sainsmart.com/arduino-pro-mini.html
- Conversor de niveles para convertir los 3,3V de la Rasperry Pi a los 5V de los relés https://www.sparkfun.com/products/12009
- Modem 3G USB
- Hub USB para poder usar y dar suficiente alimentación al modem USB y alimentar la Raspberry Pi, la placa de relés y el conversor de niveles. http://www.amazon.es/Belkin-F4U040qeb-Hu...B006DYNU3G
- Lámparas 220V
- python para ejecutar un script que maneje la conexión al servidor y los GPIOs para los relés.
- AdaFruit CharLCDPLate Librería de python para poder manejar el display y los botones.
- usb_modeswitch para poder usar un modem 3G USB sin que moleste la función ZeroCD
- wvdial para poder conectarse a Internet con el modem 3G USB.
El script nada más comenzar apaga las lámparas si estas estuvieran encendidas. Intenta conectarse al servidor por el puerto 10000 hasta que lo consigue. Recibe tantos 0x38 como dispositivos haya conectados al servidor y muestra en el display el estado actual:
- L1 y L2: 1 si la lámpara está encendida, 0 si no lo está.
- B: 1 si los comandos de los usuarios están bloqueados, 0 si no lo están.
- C: Número de dispositivos conectados al servidor actualmente.
- 0x30: Lámaparas apagadas.
- 0x31: Lámpara 1 encendida.
- 0x32: Lámpara 2 encendida.
- 0x33: Lámaparas encendidas.
Si el operador pulsa el botón superior se enciende o apaga la lámpara 1. Si el usuario pulsa el botón inferior se enciende o apaga la lámpara 2. Si el usuario pulsa el botón derecho se activa o desactiva el bloqueo de comandos. Si el usuario pulsa el botón select entonces comienza el apagado de la Raspberry Pi. En todos los casos se muestra en el display la información correspondiente.
Aquí dejo el código fuente del script de python: http://sistemasorp.homelinux.com/sistema.py
Como colofón, si os preguntais por qué uso los bytes del 0x30 al 0x39 es porque representan los ASCII del 0 al 9, por lo que para hacer pruebas con un telnet me bastaba con pulsar los números en el teclado.
Y creo que no me dejo nada, pero si teneis alguna duda, critica constructiva o comentario, podeis ponerlo en este mismo hilo.
Gracias.