Hace ya algunos años, cuando aún vivíamos en Irlanda, desarrollé un sistema de telemetría casero para el Mercedes C180 Sportcoupe que teníamos allí, basado en una Raspberry Pi y un receptor GPS, junto con un conector OBD-II por Bluetooth para leer datos de la centralita del coche. Fue un sistema que estuvo funcionando estupendamente bien, pero que dejé de utilizar, por razones que no vienen al caso.
En fechas recientes me he decidido a revivirlo (también por razones que no vienen al caso), pero quería darle una vuelta de tuerca al sistema, para cambiar algunas características que -estando bien- no se amoldaban del todo a mis necesidades. La principal de ella es que el sistema original dependía de una conexión Bluetooth con un teléfono móvil que hiciera de módem sobre este medio, a fin de proporcionar conectividad al exterior. Buscaba que la nueva versión del entorno tuviera conectividad independiente, a fin de poder hacer seguimiento del coche de manera más sencilla. Mi primera idea fue conectar un modem USB a la Raspberry Pi, pero se trata de un modelo 2 de la RPi, que sólo dispone de 2 conexiones USB, y ambas estaban en uso: una para el receptor GPS, y otra para el dongle Bluetooth que se necesita para conectar con la centralita del coche. Pensé en portar todo a una RPi más moderna, pero fue aquí cuando entró en danza el siguiente artilugio:
Se trata de un dispositivo LilyGO TTGO T-A7670G. Se trata de un ESP-32 que proporciona, de manera simultánea, conectividad Bluetooth, zócalo para tarjetas de telefonía 4G, receptor GPS, e incluso un zócalo para conectar una batería 18650, todo ello en una sola placa. Ya tenía experiencia trabajando con ESP-32 en Arduino, lo cual era una gran ventaja para mí, además de trabajar con estos componentes por separado, pero nunca lo había hecho con una placa de fabricante que proporcionara todos estos elementos de manera integrada. Mucho mejor que tener que ir montando componentes por separado.
El fabricante, además, proporciona un repositorio en GitHub donde acceder a librerías, ejemplos de código, documentación, e incluso esquemáticos de carcasas, lo que ha hecho que haya podido imprimir una caja para el dispositivo:
Con todo esto, he podido realizar una nueva versión del sistema de telemetría, con las siguientes características:
Además, la placa viene con una antena GPS pasiva. Esto está bien si el dispositivo se encuentra directamente al aire libre, pero era problemático si estaba dentro de una casa o de un coche, ya que apenas tenía cobertura. Para solucionar este inconveniente tuve que hacer uso de una antena GPS activa con conector SMA, y hacer uso de un pigtail UFL/U.FL/IPX a RP-SMA/SMA. Nada grave, pero sí un poco molesto. Ahora bien, en cuanto dispuse de esta antena activa el sistema pasó a ser capaz de detectar señal GPS incluso en interiores. Todo una diferencia, y sin necesidad de reprogramar.
En estos días he estado haciendo algunas pruebas, y al margen de la captura de datos de la centralita, el resultado es bastante bueno. Espero poder seguir haciendo mejor al respecto en las próximas semanas.
Etiquetas: a7670, arduino, bluetooth, esp32, gps, impresora 3d, lilygo, mqtt, obd-ii, telemetría
En fechas recientes he implementado un elemento adicional de interacción con la domótica. No es algo especialmente nuevo (de hecho, ya en Irlanda empecé a trastear con ellos), pero sí es algo que he recuperado recientemente: el uso de tags NFC para interactuar con la domótica, usando teléfonos inteligentes. La idea es bastante sencilla: desplegar una serie de tags desplegados por la casa, allí donde quiera que se dispare una acción concreta, para escanearlo con el teléfono, y ejecutar la acción. Y el elemento más obvio para ello es el control de luces inteligentes.
En mi caso, tengo desplegadas dos tecnologías diferentes para el control de luces inteligentes: interruptores WiFi (básicamente, diversas variedades de Sonoff) y luces Zigbee, que controlo mediante sendas plataformas zigbee2MQTT que tengo tanto en Santiponce como en Forcarey. Todo ello integrado en mi servidor MQTT, que se utiliza también con la plataforma HomeAssistant. La gracia del asunto es que toda la interacción con ellas se realiza desde el propio HomeAssistant, independientemente de la tecnología subyacente. Y siempre usando MQTT como elemento de mensajería.
Para poner en marcha el sistema de interacción basado con NFC he optado por lo siguiente: codificar en los NFC el envío de un datagrama UDP. La razón de hacerlo así es que es que de esta manera se evita, como es el caso de conexiones HTTP o similar, el tener que hacer uso de un programa específico en el teléfono, ya que mediante el envío del datagrama se evita que el usuario tenga que interactuar con ninguna aplicación, haciéndose el envío siempre en segundo plano. Esto implica que es preciso tener abierto en algún lugar un puerto UDP al que enviar los mensajes. Y la opción obvia en mi caso es hacer uso de Node-Red.
Así pues, he hecho un flujo bastante simple, que lo que hace es exponer un puerto UDP, a donde el teléfono envía la mensaje del datagrama. Este mensaje, en líneas generales, es un alfanumérico que me permite identificar qué luz quiero encender (por ejemplo, santiponceSalon1, para identificar la luz principal del salón de Santiponce). Una vez recibido el mensaje, se procesa en un switch, con tantas entradas como luces a controlar (en mi caso, de momento, 4), y se incluye en el payload el mensaje de encendido/apagado. Aquí hay dos opciones:
Una vez publicado el flujo, el servidor donde tengamos desplegado Node-Red abrirá un puerto UDP para escuchar conexiones (aconsejo hacer uso de un puerto alto, para evitar tener que asignar permisos de root). En mi caso, dado que publico Node-Red mediante un contenedor docker, es por lo que tenía que realizar una publicación de puertos del contenedor, de lo que hablaba en el artículo anterior. Y con esto, estaremos listos para controlar las luces con un móvil NFC.
Un par de comentarios adicionales:
Etiquetas: android, domótica, homeassistant, mqtt, nfc, node-red, sonoff, tasmota, udp, wifi, zigbee, zigbee2mqtt
Una de las gracias de ejecutar servicios en un contenedor docker es que, si cambian las necesidades del contenedor (como por ejemplo publicar en un nuevo puerto), es bastante sencillo aprovisionar uno nuevo sin mayores consecuencias. Pero a veces pasa que no puedes destruir y aprovisionar un nuevo contenedor, bien porque tienes determinada información persistente en el mismo (cosa que no debe hacerse, ya que en teoría los contenedores han de poder ser sin estado, pero esa es otra historia) o por cualquier otro motivo, y precisas de mantener el mismo contenedor, pero modificando (bien añadiendo, quitando o reemplazando puertos) el contenedor existente. Aunque no es una buena práctica, es posible realizarlo, siguiendo los siguientes pasos (por supuesto, recomiendo hacer primero una copia de seguridad de los ficheros modificados):
“PortBindings”:{“18332/tcp”:[{"HostIp":"","HostPort":"18332"}],”18334/tcp”:[{"HostIp":"","HostPort":"18334"}]}
“ExposedPorts”:{“18332/tcp”:{},”18334/tcp”:{}},
Referencias:
Etiquetas: contenedor, docker, microservicios, puertos
Desde hace algunos días vengo experimentando problemas con mi conexión doméstica a Internet. Esto es un problema bastante molesto para mí, porque hago uso de una serie de servicios en un servidor casero que publico hacia el exterior. El principal de ellos es este sitio web, pero hay algunos adicionales, como algunos servicios de domótica y una conexión VPN para acceder de manera segura desde el exterior. Hasta ahora, venía publicándolo todo de manera directa, ya que disponía de una IPv4 con mi conexión, pero desde la semana pasada han pasado a darme acceso a Internet detrás de un CG-NAT. Esto implica que ya no dispongo de una IPv4 propia, sino que salgo a través de una NAT del operador, por lo que no es posible acceder de manera remota a dichos servicios.
Mientras me lo solucionan, he optado por poner en pie un mecanismo para poder seguir publicando servicios, basado en el uso de un pequeño servidor público que se encarga de redireccionar los servicios hacia mi sistema detrás del CG-NAT. Y para ello, hago uso de una plataforma que permite establecer redes securizadas mediante una combinación de SG-NAT y VPN, llamada ZeroTier. La gracia de ZeroTier es que el entorno funciona como un concentrador de VPNs, de tal manera que entre los clientes que necesitemos conectar se establece una red privada, con lo que es posible dotar de conectividad entre ellos a los mismos, tan sólo instalando un agente del propio ZeroTier entre ellos, y establecer la visibilidad oportuna entre nodos. Haciendo que el servidor publicado en Internet sea uno de los nodos, puedo proporcionar servicios utilizándolo de pasarela pública.
La segunda pata del asunto es conseguir este servidor frontal público, y hacer que funcione de pasarela. En mi caso, he optado por hacer uso de Oracle Cloud Infrastructure, donde se puede desplegar de manera gratuita un servidor basado en Linux. Y una vez que me he hecho con este servidor, he montado la pasarela con un servidor NGINX, debido a que me permite redireccionar tanto servicios publicados por TCP (mi servidor web y mi servidor MQTT) como UDP (mi servidor VPN), con lo que me ahorro tener que andar instalando y gestionando servicios duplicados en este frontal. Sencillo y eficiente. El diagrama general de cómo ha quedado el entorno es el siguiente:
La configuración a nivel interno sí que tiene algunos puntos a tener en cuenta:
stream {
upstream web_server {
server IP_PRIVADA_REMOTA_ZEROTIER:443;
}server {
listen 443;
ssl_preread on;
proxy_pass web_server;
}upstream mqtt_server {
server IP_PRIVADA_REMOTA_ZEROTIER:1883;
}
server {
listen 1883;
proxy_pass mqtt_server;
proxy_connect_timeout 1s;
}upstream vpn_server {
server IP_PRIVADA_REMOTA_ZEROTIER:1194;
}
server {
listen 1194 udp;
proxy_pass vpn_server;
}}
stream {
upstream vpn_server {
server IP_SERVIDOR_LOCAL_VPN:1194;
}
server {
listen 1194 udp;
proxy_pass vpn_server;
}}
En realidad, me gusta tanto cómo ha quedado configurado, que es posible que lo deje así incluso cuando se solucione el tema del CG-NAT, ya que añade una capa extra de seguridad y disponibilidad a mis sistemas.
Referencias:
How to bypass CGNAT and expose your server to the internet using ZeroTier, a VPS and NGINX
Bypassing a CGNAT with Wireguard (Especialmente útil para la parte de configuración del entorno en Oracle Cloud)
How to set nginx reverse proxy to an SSL site without certificate?
Etiquetas: cg-nat, iot, mqtt, nginx, oracle cloud, vpn, vps, wordpress, zerotier
Con el nivel tan disparatado de precios que están alcanzando los combustibles en estas fechas, es interesante tener una manera rápida de consultar los precios en diferentes estaciones de servicio, a fin de poder reposar en la que más nos convenga. Por razones de trabajo y sus subsecuentes desplazamientos, hay varias gasolineras que nos interesa a Ana y a mí tener monitorizadas. Existe una página del Ministerio para la Transición Ecológica (Geoportal de Gasolineras) que permite acceder a los precios de todas las estaciones de servicio de España, pero que no es especialmente usable para hacer consultas rápidas y recurrentes de las mismas estaciones, ya que lo que hace es desplegar un mapa y un buscador, pero que no proporciona URLs de acceso directo ni nada que se le parezca.
Al menos, no lo hace a la vista del usuario. Pero si trasteas un poco con el funcionamiento de la página, es posible ver que sí se hace uso a nivel interno de URLs únicas que proporcionan en el mapa los valores de cada una de las gasolineras en formato XML, para poder reflejar dichos valores al pulsar sobre las gasolineras, con un aspecto como este:
Y ya teniendo esta información, haciendo uso de Node Red es sencillo procesar los parámetros, jugar un poco con ellos, e insertarlos en topics MQTT. En mi caso, me quedo con el valor de la gasolina sin plomo 95, de tres estaciones de servicio determinadas, realizando consultas una vez a la hora para cada una de ellas.
Por último, al existir esta información en un topic MQTT, es sencillo consumirla desde Home Assistant. En mi caso, he optado por mostrarla en tres diales, para que sea sencillo comparar los precios entre estaciones. Además, como valor añadido, me guarda el histórico de cotizaciones y cuándo se produjeron cambios en las mismas.
Con todo esto, es sencillo comprobar el precio de los combustibles en nuestro Home Assistant, al que accedemos desde nuestro móvil, de un solo vistazo, y escoger el sitio óptimo para repostar. Estoy pensando en darle una vuelta de tuerca, e integrar un sistema de consulta en los sistemas de infoentretenimiento de los coches, pero eso quedará para otra ocasión.
Etiquetas: home assistant, mqtt, node-red