msgbartop
Me encanta el olor del napalm por la mañana
msgbarbottom

03 feb 20 Dash button doméstico con ESP-01

Uno de los proyectos de mejora que tenía para la domótica de la casa era el añadirle un dash button para controlar alguno de los sistemas. ¿Y qué es un dash button? En pocas palabras, es un pequeño pulsador que permite comprar de manera completamente automatizada un producto en concreto a Amazon, con la idea de facilitar la compra sencilla de bienes consumibles.

Ejemplo de dash button

Ejemplo de dash button

El caso es que aunque el producto fue exitoso, tuvo que enfrentarse a una serie de problemas legales, y Amazon acabó retirándolos de la venta. Pero el concepto detrás de ellos seguía siendo interesante. No tardé en encontrar un proyecto en Thingiverse sobre cómo implementar un dash button software libre, y no tardé demasiado tiempo en preparar mi propia versión, con algunas modificaciones sobre el diseño original.

Dash button doméstico

Dash button doméstico

En mi caso, en vez de hacer uso de un ESP8266, opté por usar un ESP-01, más compacto, y un botón rojo externo en vez de un pulsador interno. Por lo demás, el diseño es el mismo. En lo referente a la lógica del sistema, se basa en el modo deep sleep de los ESP. En este caso, el sistema queda durmiendo de manera permanente hasta que el botón es pulsado, lo que despierta al sistema, ya que el botón puentea el puerto RST del ESP-01 con el GND. Combinado con el uso de la batería CR2 de 3V, en teoría hay alimentación para varios años. ¿Y en cuanto a la acción en sí? Sencillo: el sistema despierta, conecta a mi WiFi doméstica, y actualiza un topic MQTT. Después de eso, vuelve a dormir hasta una nueva pulsación.

Parece poca cosa, pero con esa actualización del topic MQTT se puede programar cualquier acción que deseemos en el sistema de domótica. Eso ya queda para una segunda fase. :mrgreen:

VN:F [1.9.20_1166]
Rating: 10.0/10 (1 vote cast)

Etiquetas: , , , , ,

25 ene 20 Integración de una estación meteorológica doméstica en el sistema de domótica

Estas Navidades me han regalado una estación meteorológica casera, de las que tienen capacidad para mostrar temperatura y humedad tanto en interior como en exterior, esto último mediante un módulo externo que se deja a la intemperie, y que transmite la información a la estación mediante señal de radio a 433 MHz. Aparte de por el regalo en sí, este tipo de estaciones me venía interesando desde hace bastante tiempo por el hecho de enviar la información utilizando la banda antes mencionada, de la que dispongo unos cuantos receptores. Así que en cuanto abrí el regalo supe que iba a invertir algo de tiempo en intentar integrar el sensor externo en mi sistema de domótica.

Mi nueva estación meteorológica

Mi nueva estación meteorológica

Tras investigar un poco sobre este tipo de estaciones, encontré que la mayoría de ellas hacen uso de protocolos de comunicación bien definidos y relativamente estandarizados, lo que hace que sea razonablemente sencillo encontrar información sobre las mismas, e incluso implementaciones de dichos protocolos para entornos linux o arduino. Dicho lo cual, empecé a hacer algunas pruebas de implementación de un sistema que permitiera recibir la información del emisor externo. Las primeras pruebas las hice con un receptor basado en arduino y un módulo 433 MHz, más la librería rc-switch que tan buenos resultados me había dado en el pasado. No fue este el caso, ya que al intentar capturar paquetes enviados por la estación el programa de captura de paquetes basados en esta librería producía un error de desbordamiento, siendo incapaz de recibir correctamente el datagrama. Hice algunas pruebas en bruto con otras librerías, entre las que se incluían algunas diseñadas específicamente para alguno de los protocolos de envío antes mencionados, con resultados igualmente infructuosos.

NodeMCU con receptor a 433 MHz y módulo externo de la estación

NodeMCU con receptor a 433 MHz y módulo externo de la estación

Ante ello, no me quedó más remedio que cambiar el enfoque. Tocaba acometer el problema desde una perspectiva más basica. Así que me tocó desempolvar un receptor RTL SDR que compré hace algún tiempo para un proyecto similar, e intentar hacer una captura del datagrama a nivel de onda enviada, e intentar decodificar la misma (tirando para ello de programas como Gqrx, audacity, y algo de tiempo. Sin embargo, tuve algo de suerte, y tras seguir investigando un poco más, encontré una referencia a un proyecto, rtl_433, que se dedica a decodificar el tráfico de dispositivos que envían información en esta banda.

Captura de pantalla de rtl_433 capturando tráfico

Captura de pantalla de rtl_433 capturando tráfico

Tras una instalación sencilla en mi equipo con Debian (apt install rtl_433), y tras conectar el receptor RTL SDR al mismo, tuve la suerte de que el programa tuviera perfectamente identificado el tipo de protocolo que mi estación estaba utilizando, en concreto el protocolo “Kedsum Temperature & Humidity Sensor, Pearl NC-7415″. Trasteando un poco con el programa, pude tener algo más de información sobre este protocolo, a saber:

Frame structure:
Byte: 0 1 2 3 4
Nibble: 1 2 3 4 5 6 7 8 9 10
Type: 00 IIIIIIII BBCC++++ ttttTTTT hhhhHHHH FFFFXXXX
- I: unique id. changes on powercycle
- B: Battery state 10 = Ok, 01 = weak, 00 = bad
- C: channel, 00 = ch1, 10=ch3
- + low temp nibble
- t: med temp nibble
- T: high temp nibble
- h: humidity low nibble
- H: humidity high nibble
- F: flags
- X: CRC-4 poly 0×3 init 0×0 xor last 4 bits

_Modulation = OOK_PULSE_PPM,
-Short_width = 2000,
-Long_width = 4000,
-Gap_limit = 4400,
-Reset_limit = 9400,

Bien, ya tenía identificado claramente el protocolo, y aquí puede verse una captura de la señal recibida:

root@asustinker:/etc/systemd/system# /usr/local/bin/rtl_433 -R 57
rtl_433 version 19.08-147-g639ab8a branch master at 202001210044 inputs file rtl_tcp RTL-SDR
Use -h for usage help and see https://triq.org/ for documentation.

Consider using “-M newmodel” to transition to new model keys. This will become the default someday.
A table of changes and discussion is at https://github.com/merbanan/rtl_433/pull/986.

Registered 1 out of 145 device decoding protocols [ 57 ]
Found Rafael Micro R820T tuner
Exact sample rate is: 250000.000414 Hz
[R82XX] PLL not locked!
Sample rate set to 250000 S/s.
Tuner gain set to Auto.
Tuned to 433.920MHz.
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
time : 2020-01-25 15:24:00
model : Kedsum Temperature & Humidity Sensor ID : 226
Channel : 1 Battery : OK Flags2 : 129 Temperature: 60.20 F Humidity : 78 % Integrity : CRC
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

Bien, esto me planteaba dos problemas: el primero es que la información recibida de temperatura estaba expresada en grados Fahrenheit, por lo que necesitaba hacer una conversión a Celsius. Y por otro lado, el poder transmitir esta información a mi plataforma de domótica, preferentemente a través de MQTT. Este segundo problema quedó solucionado mediante la capacidad del programa rtl_433 de encapsular la información en un JSON, que puede ser retransmitido posteriormente. En mi caso, lo hice mediante un servicio linux que lanza el programa rtl_433 con las opciones adecuadas (formato JSON, protocolo 57 -Kedsum-, e incrustando la hora UTC), que mediante un pipe es procesado por el cliente MQTT mosquitto y enviado a mi servidor MQTT, a un topic específico:

“/usr/local/bin/rtl_433 -R 57 -F json -M utc | /usr/bin/mosquitto_pub -l -h servidor_mqtt -t topic”

…donde posteriormente es procesado gracias a Node Red, en el que se hace la conversión a Celsius, se obtiene también la sensación térmica, y se inyecta la información resultante en formato JSON en un topic específico:

var data=JSON.parse(msg.payload);
//Datagram example: {“time” : “2020-01-22 19:27:58″, “model” : “Kedsum Temperature & Humidity Sensor”, “id” : 226, “channel” : 1, “battery” : “WEAK”, “flags” : 66, “temperature_F” : 54.600, “humidity” : 79, “mic” : “CRC”}
temp_value=((data.temperature_F-32)*5/9).toFixed(2);
humidity=data.humidity;

HI = 0.5*(data.temperature_F + 61.0 + ((data.temperature_F-68.0)*1.2) + (humidity*0.094))
HIc = (((HI)-32)*5/9).toFixed(2); // converting to Celsius

var thing = {
temp: temp_value,
humidity: humidity,
heatindex: HIc
};
msg.payload=thing;

return msg;

…y el resultado de todo esto fue un… ¡exito! Pasé a conectar el receptor RTL SDR a mi Asus Tinker Board donde tengo implementado el sistema de domótica, con excelentes resultados. El sistema, emplazado en la segunda planta de casa, es capaz de recibir las señales del receptor externo emplazado en el patio.

Asus Tinker Board con receptor RTL SDR

Asus Tinker Board con receptor RTL SDR

Por otro lado, quedaba la integración en el sistema de domótica Home Assistant. En este caso, se trataba de alto tan simple como crear los nuevos sensores en base a la suscripción al topic MQTT de salida definido en el flujo Node Red. El resultado, como no podía ser menos, fue perfecto:

Información mostrada en Home Assistant de la estación meteorológica

Información mostrada en Home Assistant de la estación meteorológica

Gráfica de la información histórica recibida

Gráfica de la información histórica recibida

Este artículo podría haber quedado aquí, pero no me encontraba completamente satisfecho con el resultado, ya que me daba la impresión de que utilizar el receptor RTL SDR solo para este propósito era matar moscas a cañonazos. Mi idea originaria era usar un ESP8266 junto con un módulo RF de 433 Mhz para recibir estas señales, y decodificarlas en el mismo, para inyectar la información directamente en el servidor MQTT, y no tener que dar tantos saltos (RTL SDR -> JSON -> MQTT -> Node Red -> MQTT). No tuve éxito en encontrar una codificación del protocolo bajo el nombre de Kedsum, pero sí la tuve con Pearl NC-7415. Encontré un hilo en un foro de Arduino en alemán, que hablaba precisamente de ello: Dekodieren Temperatursensor von PEARL NC7427(NC7415) 433MHz. Gracias, Google Translate. :mrgreen:

En este hilo pude encontrar alguien que había decodificado exitosamente el protocolo, y que compartía el código. Lo descargué y lo probé y… ¡funcionaba perfectamente! Solo tuve que hacer una modificación menor para realizar la conversión de Fahrenheit a Celsius, calcular la sensación térmica, e inyectarlo en el topic MQTT (el original no hacía nada de esto, se limitaba a mostrar la información por pantalla). Y de nuevo, éxito:

Información recibida en ESP8266 y RF, enviada a servidor MQTT

Información recibida en ESP8266 y RF, enviada a servidor MQTT

Sin embargo, esta vía tiene un problema: el receptor apenas es capaz de recibir la señal cuando se encuentra a unas pocas decenas de centímetros del emisor externo. Así que en la práctica ahora mismo es inusable. He probado con varios formatos de antena acoplados al módulo (173mm de largo, en hilo recto, en espiral…) con resultados bastante pobres. Tengo encargada en aliexpress una antena específica, pero aún tardará algunas semanas en llegar. Espero poder reportar mejoras una vez la reciba. :D

VN:F [1.9.20_1166]
Rating: 10.0/10 (1 vote cast)

Etiquetas: , , , , , , , , , , , , ,

29 ene 17 Sistema de telemetría y geoposicionamiento para vehículos

Escribía en mi entrada anterior que estaba trabajando en un sistema de telemetría para el Mercedes. Durante estas últimas semanas he estado realizando algunas mejoras en el sistema, y si bien aún es posible incorporar algunas más, en este momento ya empieza a tener un desarrollo bastante definido. En pocas palabras, se trata de un sistema de telemetría que recoge datos de dos fuentes, la centralita del coche y un módulo GPS, para transmitirlo a un servidor donde se almacenan los datos para su posterior tratamiento. En este momento, el tratamiento consiste en dos actividades: representación gráfica de velocidad, revoluciones por minuto y consumo del coche, y geoposicionamiento en mapas en tiempo real. Este es un esquema básico de la plataforma:

Esquema del sistema de telemetría

Esquema del sistema de telemetría

El sistema está compuesto por los siguientes elementos:

  • Sonda de captura de datos: La sonda de captura de datos consiste en una Raspberry Pi que se conecta con la centralita del coche mediante un módulo bluetooth. La centralita del coche se ha equipado, a su vez, con un módulo OBD-II con bluetooth. Esta sonda, de igual manera, dispone de un módulo GPS para proporcionar datos relativos a la posición del vehículo.
  • Programa de telemetría: En la sonda de posicionamiento he desplegado un programa que recopila información de las fuentes anteriores, que he desarrollado en Python. Este programa, en líneas generales, comprueba el estado de las fuentes de datos antes mencionados, recopila la información y la prepara para su transmisión. Para ello, se apoya en un broker MQTT instalado en la propia sonda. Por último, se hace un almacenado local en ficheros csv de la información recopilada, junto con una marca de tiempo.
  • Broker MQTT local: Para realizar la transmisión de datos al servidor de almacenamiento y procesado de datos se hace uso de un broker MQTT local. MQTT es un protocolo ligero de mensajería para pequeños sensores y dispositivos móviles ideado por IBM. Está optimizado para realizar la transmisión de datos incluso en redes no confiables y en entornos de alta latencia, por lo que es ideal para delegar en él la capa de transmisión de datos del programa anterior, ya que es presumible que el vehículo pueda encontrarse en situaciones de escasa cobertura o incluso pérdida total de la misma, además de en situaciones en las que la transmisión de datos haya de efectuarse haciendo uso de redes GSM de escasa capacidad. Además, tiene la ventaja de que produce menos sobrecarga que otros protocolos como HTTP, y (en teoría) hace un menor consumo de datos. La idea es la siguiente: el programa anterior delega en el broker MQTT el establecer el envío de paquetes al servidor. El broker MQTT actúa además como buffer local de los paquetes transmitidos, en caso de pérdida o inestabilidad de las comunicaciones. Este buffer local, gracias a una pequeña base de datos interna, es persistente incluso ante reinicios inesperados de la sonda. El broker MQTT local está sincronizado con otro broker MQTT desplegado en el servidor de recepción de datos, y es capaz de garantizar la correcta sincronización, como se ha comentado, incluso en situaciones de pérdida total de conectividad y reinicios en la sonda de datos.
  • Envío de datos mediante tethering bluetooth: El broker local MQTT es dotado de conectividad a Internet mediante tethering bluetooth con un teléfono móvil. Si bien a priori sería más interesante hacer uso de tethering wifi para esto mismo, hay tres buenas razones para optar por bluetooth: La primera es que al hacer uso de MQTT el volumen de información a intercambiar es bastante reducido, por lo que es posible hacer uso de bluetooth para ello, con el consiguiente impacto positivo en el consumo de energía necesario para establecer el canal de datos. La segunda es una limitación física en la sonda. La Raspberry Pi 2 que utilizo tiene sólo dos puertos USB, uno usado con el módulo GPS y otro con el módulo bluetooth para conectar con la centralita, por lo que no queda sitio para un módulo WiFi. Y la tercera, es que todo es mejor con bluetooth. :mrgreen:
  • Servidor de recepción de datos: El segundo bloque del sistema es el servidor de recepción y análisis de datos. Consiste en líneas generales en un servidor Graphite donde se almacenan los datos proporcionados por la sonda de captura de datos, y que permite su posterior utilización, bien para la representación de gráficas de dichos datos mediante Grafana, bien para la el geoposicionamiento del vehículo en tiempo real, con información añadida del resto de parámetros proporcionados por la sonda.
  • Broker MQTT: La comunicación, como se ha comentado, se realiza mediante un broker MQTT que sincroniza con el broker MQTT de la sonda. Este broker recibe los datos proporcionados por la sonda, y los inyecta, mediante una pasarela desarrollada en Python, en el servidor Graphite. Dado que es posible que la información proporcionada por el broker MQTT de la sonda no se reciba en tiempo real debido a posibles cortes en las comunicaciones, se hace uso de la marca de tiempo incluida en cada transmisión de la sonda remota para inyectar los datos en el servidor Graphite con información de tiempo de creación correcta.
  • Servidor Graphite: El servidor Graphite consolida la información proporcionada por la sonda de captura de datos, la almacena en una sistema de base de datos buffer de corta duración (Carbon) y posteriormente la consolida en una base de datos da larga duración (whisper).
  • Servidor Grafana: Los datos consolidados en el servidor Graphite son consumidos por Grafana, software para visualización de métricas. Se han creado una serie de gráficas que permiten acceder a la información relativa a la velocidad, revoluciones por minuto, entrada de aire en el motor, consumo de combustible y altitud con respecto al mar, así como a sus valores medios en un rango de tiempo establecido. Grafana proporciona, además, la capacidad de integrar estas gráficas en una plataforma de terceros.
  • Captura de posicionamiento de vehículo con datos en tiempo real

    Captura de posicionamiento de vehículo con datos en tiempo real

  • Sistema de geoposicionamiento: El broker MQTT permite, además, el procesamiento de la información proporcionada por la sonda para representar en tiempo real la ubicación geográfica del vehículo, así como la traza de las posiciones anteriores mediante una línea de posición. Además, se proporciona información en tiempo real de los parámetros proporcionados por la sonda. Este sistema está basado en Node-RED, una herramienta desarrollada por IBM para permitir una interconexión sencilla de diversas aplicaciones y dispositivos IoT. También hace uso de OpenStreetMap, mediante la librería WorldMap.

Todo este sistema lo he compilado en la siguente web para su visualización: Telemetría (www.eniac2000.com/telemetria)

Dado que la información mostrada en esa URL proporciona datos en tiempo real, he realizado una captura de datos obtenidos en vivo:

Captura del sistema de telemetría

Captura del sistema de telemetría

…así como un vídeo en el que se aprecia la información, si bien realizando la captura de la información desde las dos fuentes de datos separadas, y no desde el mismo portal:

Como comentaba, el sistema está aún en una fase muy temprana, pero el potencial de mejora es grande. Los principales puntos en los que estoy trabajando son los siguientes:

  • Mejora en la seguridad de comunicaciones entre brokers MQTT
  • Mejora en la fiabilidad de la comunicación OBD-II
  • Reemplazo del sistema de base datos de larga duración de Graphite por un sistema NoSQL, presumiblemente un InfluxDB
  • Dotar de redundancia a los elementos de la plataforma
  • Proporcionar un sistema de persistencia de la información
  • Creación de un portal multiusuario con soporte de múltiples dispositivos
  • Otros… :)

Si bien este proyecto empezó como algo personal, con la idea de comprobar cuánto consumía mi coche en los desplazamientos, tengo el convencimiento de que puede convertirse en algo más que en un mero pasatiempo. Esperemos que así sea.

VN:F [1.9.20_1166]
Rating: 10.0/10 (2 votes cast)

Etiquetas: , , , , , , , , , , , ,