Cómo crear desde cero un multisensor de viento, lluvia y luminosidad para eedomus (Parte III)
- Último capítulo de nuestro tutorial sobre la creación de un multisensor de viento, lluvia y luminosidad. Hoy toca hablar de programación en Python.
Tercera y última entrega de nuestro tutorial paso a paso sobre cómo construir desde cero un multisensor de viento, lluvia y luminosidad preparado para el controlador domótico eedomus.
En la primera parte del tutorial hablamos de los elementos necesarios para la construcción del sensor, y en la segunda parte del funcionamiento del anemómetro y la conexión de los distintos sensores a la Raspberry Pi. Por consiguiente, ha llegado el momento de hablar de programación.
Programación
En esta última sección vamos a describir los programas que hemos escrito para tomar lecturas básicas de los tres sensores, procesarlas y enviar los resultados a periféricos virtuales del controlador eedomus, para que éste, mediante su estructura de reglas, permita tomar las acciones oportunas.
Estos programas en Python son tres y podéis descargarlos en este enlace.
Cabe destacar que con estos programas tenemos absoluto control sobre la frecuencia con la que queremos que la Raspberry Pi informe a eedomus. Los programas que he escrito son muy básicos en este sentido, pero pueden modificarse a voluntad del usuario según sus necesidades.
Supondré que ya tenéis instalado en vuestra Raspberry Pi el sistema operativo Raspbian y hecha la configuración básica de red (WiFi), de modo que se pueda entrar de forma remota (ssh). Podéis encontrar ayuda para todas estas actuaciones a partir de este enlace.
Siempre conviene tener actualizado el software. Ejecutaremos sucesivamente:
pi@rpimeteo:~ $ sudo apt-get update pi@rpimeteo:~ $ sudo apt-get upgrade
Tenemos también que activar el uso del bus I²C:
pi@rpimeteo:~ $ sudo raspi-config
y en el menú que se nos presenta seleccionar “5 Interfacing Options”. Dentro de esta opción elegiremos “P5 I2C“, y a continuación elegiremos “Sí”.
Necesitaremos también que estén instalados algunos paquetes, aunque es muy posible que la mayoría ya lo estén. Lanzaremos el comando siguiente:
pi@rpimeteo:~ $ sudo apt-get install python3 python3-requests > python3-gpiozero python3-rpi.gpio python3-smbus
Confirmaremos la selección y tras una breve espera tendremos instaladas las herramientas y las librerías que necesitaremos para trabajar con el lenguaje Python.
Antes de cargar, configurar y ejecutar los programas, vamos a preparar tres periféricos en eedomus. Entramos en Configuración, y pulsamos sucesivamente Añadir o eliminar un periférico, Añadir otro tipo de periférico, Estado y Crear. En el formulario de creación del periférico rellenamos los campos siguientes:
Periférico para reflejar la velocidad del viento:
– Nombre: toldos.viento
– Uso: Otro indicador (sensor)
– Tipo de datos: Decimal
– Unidad: km/h
Periférico para reflejar la luminosidad:
– Nombre: toldos.luminosidad
– Uso: Otro indicador (sensor)
– Tipo de datos: Decimal
– Unidad: lux
Periférico para reflejar la lluvia:
– Nombre: toldos.lluvia
– Uso: Otro indicador (sensor)
– Tipo de datos: Lista de valores
En este periférico, entraremos en la pestaña Valores y crearemos dos valores:
– Descripción: No ha llovido, valor bruto: 0.
– Descripción: Ha llovido, valor bruto: 100.
En cada uno de estos tres periféricos, después de cumplimentar estos valores y antes de pulsar el botón
Guardar, desplegaremos la sección Parámetros experto para anotar el código API del periférico, ya que lo necesitaremos incluir en los programas. Opcionalmente, los podemos asignar a una “habitación” de
eedomus. Las figuras siguientes ilustran el proceso para el periférico toldos.lluvia:
Estos tres periféricos actúan como sensores, aunque no se comportan como los sensores virtuales estándar de eedomus ya que no hacen llamadas URL cada cierto tiempo para obtener el valor: es la Raspberry Pi la que se encargará directamente de poner los valores cada vez que se considere en el programa.
Los programas tienen incluidos bastantes comentarios que ayudan a comprender su funcionamiento detallado para aquellos que tengan unas nociones mínimas de programación. Aun así, mencionaré aquí las líneas principales que los estructuran.
El programa para la gestión del anemómetro (windsensor.py) consta de un bucle infinito, que no termina nunca, en el que simplemente inicia un contador de pulsos a 0, espera un tiempo programado (por defecto diez segundos), tras el cual mira el valor del contador y a partir de él calcula la velocidad del viento (con la fórmula indicada anteriormente), que envía inmediatamente a eedomus.
Además, hace algunas funciones administrativas, para dejar rastro en un “log” de lo que va haciendo. Os podríais preguntar cómo se incrementa el contador de pulsos, ya que con lo dicho parece que nunca sería distinto de cero. Pues bien, antes de iniciarse el bucle, el programa prepara, con la librería GPIO, el sistema de entrada/salida de la Raspberry Pi, de modo que cada vez que en el pin CHANNEL, en el que tenemos conectado el anemómetro, se produzca una transición de 1 a 0 (lo que ocurre en cada pulso, dos veces cada vuelta de las cazoletas) se produzca una interrupción en el programa principal (que estará esperando a que pase el tiempo programado de diez segundos) y llame a la función pulse_detect, que incrementa el contador en uno.
El programa para la gestión del sensor de lluvia (rainsensor.py) también consta de un bucle infinito. En él, tras esperar un tiempo predeterminado (1 segundo) lee el valor del pin en el que está conectado el anemómetro, y cuenta las veces en que se detecta lluvia. Tras un número predeterminado de lecturas (10), el programa indica lluvia si en la mayoría de ellas la ha detectado. Esto es así para poder configurar la sensibilidad del sensor y evitar que informe lluvia cuando, por ejemplo, solamente ha caído una gota. Todo esto puede cambiarse con facilidad por los criterios que cada cual considere mejores. El programa, al igual que el anterior, también realiza las funciones administrativas ya mencionadas.
El programa para la gestión del sensor de luminosidad (lightsensor.py) también consta de un bucle infinito. En él, en cada iteración, tras la espera de un cierto tiempo (10 segundos en este caso), se realiza la lectura de los dos sensores de luz que tiene el chip TSL2561 accediendo al bus I²C mediante las funciones proporcionadas por la librería smbfs de Python. Los dos sensores, como ya hemos mencionado, proporcionan un valor que es leído en dos bloques de 8 bits y convertido al valor de 16 bits. Tras ello, el programa convierte los valores de ambas lecturas en un único valor de luminosidad mediante un algoritmo proporcionado en las especificaciones del chip. Esta lectura se repite un número predefinido de veces (18) y se envía a eedomus el promedio de los 18 valores calculados (por tanto, cada 3 minutos).
Una vez configurados los sensores virtuales en eedomus, instalaremos los tres programas lightsensor.py, windsensor.py y rainsensor.py, en el directorio bin de la cuenta pi: /home/pi/bin, (o en otro cualquiera, aunque utilizaré éste en lo sucesivo). Utilizando el editor de texto que más nos guste (editor, vi, emacs, ed, etc.), abriremos cada uno de los programas y editaremos las líneas siguientes de modo que reflejen los valores reales de nuestro controlador eedomus:
API_USER = ‘APIUserEedomus’
API_SECRET = ‘APISecretEedomus’
PERIPH_ID = 1001003
EEDOMUS _URL = ‘http://192.168.1.69/api/set’
Como valor de API_USERy API_SECRET sustituiremos los valores ficticios proporcionados por los correspondientes para autenticación en nuestro eedomus (dentro de las comillas simples, que hay que conservar). Si no sabes cómo obtener estas credenciales, puedes consultar este artículo, en el que está muy bien explicada la API de eedomus . En la cadena EEDOMUS_URL tienes que sustituir la dirección IP 192.168.1.69 por la real de tu eedomus. Si el tuyo no está configurado con una dirección IP fija, es el momento de hacerlo con este tutorial.
Finalmente, en PERIPH_ID tienes que sustituir el código que está por el que has anotado al crear el periférico correspondiente al programa que estés editando:
– En lightsensor.py el código API correspondiente al sensor toldos.luminosidad.
– En windsensor.py el código API correspondiente al sensor toldos.viento.
– En rainsensor.py el código API correspondiente al sensor toldos.lluvia.
Estos cambios son los mismos para los tres programas.
Una vez instalados y configurados, basta ejecutar los tres para que comiencen a funcionar y a actualizar los sensores instalados en eedomus con la frecuencia que traen por defecto (3 minutos el sensor de luminosidad, y 10 segundos los de viento y de lluvia). Para que los programas se inicien automáticamente al iniciarse la Raspberry Pi, y para que si, por el motivo que sea, fallan y dejan de correr (cosa que hacen, por ejemplo, si se cae la red WiFi), se reinicien automáticamente, vamos a indicar cómo se configuran tres servicios de systemd en el sistema operativo Raspbian:
– En el directorio /lib/systemd/system creamos tres ficheros, con los siguientes nombres y contenidos:
-> Fichero/lib/systemd/system/rainsensor.service
[Unit] Description=RPI rain sensor service After=multi-user.target [Service] Type=idle ExecStart=/usr/bin/python /home/pi/bin/rainsensor.py Restart=always [Install] WantedBy=multi-user.target
-> Fichero /lib/systemd/system/windsensor.service
[Unit] Description=RPI wind sensor service After=multi-user.target [Service] Type=idle ExecStart=/usr/bin/python /home/pi/bin/windsensor.py Restart=always [Install] WantedBy=multi-user.target
-> Fichero /lib/systemd/system/lightsensor.service
[Unit] Description=RPI light sensor service After=multi-user.target [Service] Type=idle ExecStart=/usr/bin/python /home/pi/bin/lightsensor.py Restart=always [Install] WantedBy=multi-user.target
– Nos aseguramos de que esos ficheros tienen los permisos adecuados:
pi@rpimeteo:~ $ sudo chown root:root /lib/system/system/lightsensor.service pi@rpimeteo:~ $ sudo chmod 644 /lib/system/system/lightsensor.service pi@rpimeteo:~ $ sudo chown root:root /lib/system/system/rainsensor.service pi@rpimeteo:~ $ sudo chmod 644 /lib/system/system/rainsensor.service pi@rpimeteo:~ $ sudo chown root:root /lib/system/system/windsensor.service pi@rpimeteo:~ $ sudo chmod 644 /lib/system/system/windsensor.service
– Después informamos al proceso de estos cambios y preparamos los servicios para su inicio automático al arrancar la Raspberry Pi:
pi@rpimeteo:~ $ sudo systemctl daemon-reload pi@rpimeteo:~ $ sudo systemctl enable lightsensor.service pi@rpimeteo:~ $ sudo systemctl enable windsensor.service pi@rpimeteo:~ $ sudo systemctl enable rainsensor.service
– Finalmente, iniciamos los servicios manualmente si no queremos reiniciar en este momento:
pi@rpimeteo:~ $ sudo systemctl start lightsensor.service pi@rpimeteo:~ $ sudo systemctl start windsensor.service pi@rpimeteo:~ $ sudo systemctl start rainsensor.service
– Podemos comprobar que los programas están en ejecución con el comando ps:
pi@rpimeteo:~ $ ps -ef | grep python
y obtendremos una salida como ésta, que indica la ejecución de los tres programas y datos de los procesos asociados:
root 2003 1 0 17:34 ? 00:00:15 /usr/bin/python /home/pi/bin/windsensor.py root 2015 1 0 17:34 ? 00:00:15 /usr/bin/python /home/pi/bin/rainsensor.py root 2113 1 0 17:39 ? 00:00:03 /usr/bin/python /home/pi/bin/lightsensor.py
– También podemos acceder al log de cada programa con el comando journalctl con las opciones adecuadas:
pi@rpimeteo:~ $ journalctl -efu windsensor.service
y obtendremos algo similar (aunque mucho más largo con el tiempo de ejecución) a:
ago 11 17:34:36 rpimeteo systemd[1]: Started RPI wind sensor service. ago 11 17:34:49 rpimeteo python[2003]: Sat Aug 11 17:34:49 2018: windspeed=1.2 ago 11 17:34:59 rpimeteo python[2003]: Sat Aug 11 17:34:59 2018: windspeed=0.0
Ya hemos acabado. Ahora sólo os queda crear en eedomus las reglas que necesitéis para controlar vuestros toldos.
Hola buenas tardes, despues de recolectar todo el material y realizar las conexiones electricas oportunas, ahora toca programar, lo que peor llevo la verdad ya que nunca antes habia realizado.
No se si prefieres tener esta conversacion por el foro o aqui ya esta bien, la question es que me surgen algunas dudas:
¿como instalo los 3 ficheros descargados, es question de copiarlos en el directorio y ya esta? porque yo los he copiado y he substituido los parametros como decias por los mios.
Luego, para que se reinicien automaticamente, intento crear un archivo en el directorio pero me dice que no tengo permiso, lo hago haciendo clic derecho en el directorio y crear archivo nuevo.
Mil gracias
Sí. Basta copiarlos. Se pueden editar antes o después. La parte de crear los ficheros necesarios en /lib/systemd requiere tener los privilegios adecuados. Pueden instalarse como el usuario “root” o utilizando el programa “sudo”. Para esta parte es mejor utilizar la línea de comandos que haciendo click con el ratón, ya que esto último solo te funcionará si eres el superusuario (usuario “root”).
Hola buenas.
Para realizar este paso:
Una vez configurados los sensores virtuales en eedomus, instalaremos los tres programas lightsensor.py, windsensor.py y rainsensor.py, en el directorio bin de la cuenta pi: /home/pi/bin, (o en otro cualquiera, aunque utilizaré éste en lo sucesivo). Utilizando el editor de texto que más nos guste (editor, vi, emacs, ed, etc.), abriremos cada uno de los programas y editaremos las líneas siguientes de modo que reflejen los valores reales de nuestro controlador eedomus.
Simplemente tenemos que copiar los archivos en el directorio, con eso ya quedan instalados? soy nuevo con Raspbian.
Gracias.
Sí. Pueden copiarse en el directorio una vez “editados”.
Hola, estoy intentando hacerlo funcionar y no lo consigo. me da los siguientes errores cuando le doy a “run” para que se ejecute uno de los archivos.
Traceback (most recent call last):
File “/usr/lib/python3.5/tkinter/__init__.py”, line 1562, in __call__
return self.func(*args)
File “/usr/lib/python3/dist-packages/thonny/running.py”, line 317, in _cmd_run_current_script
self.execute_current(“Run”)
File “/usr/lib/python3/dist-packages/thonny/running.py”, line 295, in execute_current
self.execute_script(filename, args, working_directory, command_name)
File “/usr/lib/python3/dist-packages/thonny/running.py”, line 266, in execute_script
get_shell().submit_magic_command(cd_cmd_line + exe_cmd_line)
File “/usr/lib/python3/dist-packages/thonny/shell.py”, line 98, in submit_magic_command
self.text.submit_command(cmd_line, (“magic”,))
File “/usr/lib/python3/dist-packages/thonny/shell.py”, line 201, in submit_command
assert get_runner().is_waiting_toplevel_command()
AssertionError
¿Sería mucho pedir una rápida explicación de como integrarlo en home assistan en vez de eemodus?
mil gracias