Notas y observaciones sobre desarrollo en Domótica.
1. Homie
Un aspecto importante de la convención Homie es que, más allá de su propio planteamiento, el de establecer un modelo para el uso de MQTT como vía de comunicación de dispositivos y controladores, expresa en sí un modelo genérico de dispositivo ( device ) que puede ser útil más allá del modelo de comunicación de un device con el exterior.
Por otro lado, quizá la especificación debería estar dividida en dos: una definiendo el modelo del objeto device, con sus nodos, las propiedades de éstos, etc. y otra su implementación sobre MQTT. Por ejemplo, más ligera (y menos fiable) sería la implementación sobre UDP multicast, más escalable sobre COAP ...
1.1. El device Homie como paradigma.
El concepto de device con sus nodos y las properties de éstos invita a pensar en cómo utilizarlo no solo para comunicar con broker MQTT, sino como modelo de objeto para su implementación en software.
Tendríamos por un lado la definición de una clase base Device (o, si se quiere, HomieDevice y, por otro, la definición de diferentes modelos de adaptadores para los distintos medios a través de los que un nodo interactúa con el hw al que representa: las capacidades IO del propio hw en el que corre el software, I2C, RS485, Zigbee, RF, ...
Para cada uno de esos medios hay que definir las maneras de obtener/transferir distintos tipos de valores, para lo que cada property de un nodo ha de definir el tipo de su valor. Además, según el medio, hay que definir los parámetros que permitan obtener o transmitir el valor de la propiedad.
Así que como pivotes del sistema que mantiene actualizadas las properties de un nodo y controlado su hw, tendríamos:
- Diversos protocolos de medios.
- Adaptadores que especifican los parámetros que permiten operar con el valor de una propiedad dada en un medio determinado. Cada modelo define los parámetros de sus adaptadores de modo que, dada una instancia de un adaptador, se pueda determinar la propiedad afectada cuando se obtiene un input del hw y generar un output para hw a partir de una propiedad dada.
1.2. Implementaciones Homie en C/C++
1.2.1. Homie for ESP8266.
Es un firmware instalable, en C++ para arduino, concebido como punto de partida para desarrollar customs con soporte Homie, por lo que, por sí mismo es poco útil. Además del soporte Homie implementa algunas funcionalidades básicas para un firmware, como soporte Platformio, configuración por fichero JSON cargable sin reflashear mediante diversas vías, OTA,
Tiene un sistema de Input handlers, pero mirando solo se invoca cuando se recibe algo del broker MQTT: https://github.com/homieiot/homie-esp8266/blob/master/src/Homie/Boot/BootNormal.cpp, handleNodeProperty().
Necesitaría algún modelo de interface de un nodo con su medio, de forma que implementando la gestión necesaria para que el nodo interactúe con su hardware pudiera mantenerse actualizado, preferiblemente mediante sistema de eventos que hicieran innecesario supervidar constantemente si el nodo tiene nuevos datos disponibles en hw.
1.2.2. Implementación parcial para navegador.
Imagino que mediante websockets o algo así. Parece que solo es para discovery, pero aún así podría ser útil para hacer pruebas.
2. Universo ESP
2.1. Documentos espressif
- ESP8266 Technical Reference.
- ESP8266EX Datasheet
- ESP32 Technical Reference Manual
- ESP32-S2Technical Reference Manual
- GPIO register and pin list
2.2. Plataformas de desarrollo
- Espressif ESP8266 NONOS SDK no se desarrolla mas; solo se parchean errores.
- Espressif ESP8266_RTOS_SDK se desarrolla acercandose a ESP-IDF, donde espera confluir. Esta es la plataforma en que se basa nodemcu.
- ESP-IDF por el momento es exclusiva para ESP32.
- Arduino ESP8266, desarrollada en torno a https://www.esp8266.com/. Conocerás el sw basado en esta plataforma por sus extensiones .ino: un penoso modelo de desarrollo. En esto está basado Tasmota.
- Arduino ESP32, de Espressif.
- esp-open-sdk, derivación open de NONOS de Espressif. Open quiere decir que se utilizan elementos abiertos donde es posible y, donde no, las librerías .a de Espressif. Utiliza Crosstools-NG.
- esp-open-rtos, derivación open de RTOS de Espressif. Open quiere decir que se utilizan elementos abiertos donde es posible y, donde no, las librerías .a de Espressif.
- sming, async C++ framework basada en Espressif ESP8266 NONOS SDK >= 3.0.1 para lo que no queda mas remedio. Soporte experimental para ESP32 basado en Espressif ESP-IDF. Necesita GCC >= 8 (buster: 8.3). Tiene un host emulator con el que puedes probar el programa en linux antes de cargarlo al ESP. Tiene todas las features que se pueden esperar, incluyendo HTTPS sin restricciones y es compatible con las librerías de arduino.
- simba, un RTOS: no específico de ESP.
2.3. Herramientas de flasheado.
Es una de las utilidades mas utilizadas en todo el ámbito ESP para flashear, pero resulta que no es una, sino varias, y bien diferentes entre sí algunas:
- esptool-ck y esptool-ck, en C, son forks, probablemente el segundo del primero, pero el segundo parece congelado hace 6 años. El primero es una de las utilidades mencionadas en el Getting Started de Tasmota, mientras que el segundo es mencionado en repositorio ESP2866 de Olimex.
- esptool versión python está en Debian y se llama así, esptool. Fue iniciada por un particular, pero ahora lo lleva la propia espressif.
2.4. esp-open-sdk
ESP2866 SDK, incluyendo los blobs de espressif, parece que listo para usar a la vieja usanza (sin platformio, ni arduino, solo ejecutar make, como siempre, y tienes tu bin (en ese ejemplo compilan nodemcu-firmware con el make que trae él mismo, paise).
Incluye librerías libres que también utiliza espressif en su propio SDK, como lwip, wpa_supplicant, o la wifi de freebsd. Lo que interesaría es saber cómo añadir mas librerías ahí.
Importante es que hay dos formas de construir la tool-chain: de forma separada las herramientas y el SDK de espressif (que contiene los binary blobs) o conjuntamente standalone: la primera es más fácil de gestionar pq se pueden actualizar independientemente las herramientas y el SDK de expressif, además de facilitar la gestión de licencias; a cambio, hay que añadir -I$(THISDIR)/sdk/include -L$(THISDIR)/sdk/lib a la invocación de xtensa-lx106-elf-gcc. Para construir la versión separada, hay que hacerlo con make STANDALONE=n.
Incluye instrucciones específicas para instalarlo en debian. Como nota, en debian hay soporte build para la arquitectura xtensa (a la que pertenece el procesador del ESP8266), con los paquetes gcc-xtensa-lx106 y binutils-xtensa-lx106. Otra cosa son las librerías: newlib está en debian para ARM, pero no para xtensa. lwip sí que está, ... pero no se usan, pq no aparecen en la lista de paquetes que hay que instalar antes de construir esp-open-sdk.
Las librerías que incluye estan bastante obsoletas, contando con esp-open-rtos, mas abajo, se podría pasar de ellas.
2.5. esp-open-rtos
esp-open-rtos es complementario a esp-open-sdk, porque aquí no incluye toolchain: si no se usa esp-open-sdk, hay que preparar alguna otra cross toolchain para xtensa: aunque como queda dicho arriba debian cuenta con compilador y binutils para xtensa, no quiero ahora meterme en preparar el asunto, que desconozco, así que mejor utilizar esp-open-sdk, btm. Cuando tenga algo de tiempo, quizá con ayuda del cross-wiki de debian podamos pasar de esp-open-sdk.
Tiene wiki. Se habla, p.e., del storage en flash y otras diferencias con el sdk de espressif
No dejarse engañar: la parte rtos es una minucia, no se come la memoria ni nada de eso. Incluye tb el sdk de espressif, peeerooo como tras la v0.9.9 cambió a una licencia no compatible con BSD, ésa es la versión que incluyen. Por defecto, en lugar de las librerías binarias de espressif. se usan las del dir open_esplibs, que son librerías abiertas equivalentes a las de espressif en lo que se ha podido averiguar mediante reverse engeenering y, de hecho, en esas librerías se usan rutinas de las de espressif que no se han conseguido reproducir; para evitar colisión de símbolos, los de las librerías de espressif se remapean como sdk_<symbol> en tiempo de construcción de forma automática, para que, por defecto, se usen las librerías open. Las cabeceras originales de espressif estan bajo include/espressif.
En general, las librerías que también estan en esp-open-sdk parecen aquí mas actualizadas, p.e. mbedTLS (mas actualizado) en lugar de axtls (que sigue en sourceforge con cvs). En este asunto, antes de dar x bueno lo que pone en el wiki sobre third party libraries, examinar .gitmodules, que dice la verdad sobre qué librerías se usan. En el caso de lwip, que x fuerza necesita ser adaptada, lo que pone en wiki de lwip no es cierto, mientras lo que pone en readme.md sí lo es: la upstream es ésta
En general, las librerías que también estan en esp-open-sdk parecen aquí mas actualizadas, p.e. mbedTLS (mas actualizado) en lugar de axtls (que sigue en sourceforge con cvs). En este asunto, antes de dar x bueno lo que pone en el wiki sobre third party libraries, examinar .gitmodules, que dice la verdad sobre qué librerías se usan. En el caso de lwip, que x fuerza necesita ser adaptada, lo que pone en wiki de lwip no es cierto, mientras lo que pone en readme.md sí lo es: la upstream es ésta
Y en examples hay algunos interesantes, como esphttpd, en el que puede verse que libesphttpd (en extras) incluye sistema de plantillas html: cuando la petición es de un fichero .tpl, se componen los datos y se le adjuntan a la función de librería httpSend() y ya ella realiza las sustituciones. Tb cómo utilizar la utilidad de flasheado vía HTTP que tiene libesphttpd.
Otro ejemplo interesante: fatfs, que puede servir, imagino, para registro de datos en tjtas SD.
Importante common.mk, que hay que incluir en los makefiles de nuestros proyectos (que no tienen por qué estar dentro del tree de esp-open-rtos) y, quizá sobretodo, parameters.mk. En éste último estan las cosas que mas probabilidad tienen de ser candidatas a personalizar.
Para descubrir librerías o utilidades que trabajan con esto: topic esp-open-rtos en github.
También hay herramienta para debug.
2.6. MQTT
2.6.1. broker
broker/bridge en arduino con capacidad de actuar tb como controlador mediante scripting: se pueden establecer reglas que enlacen sensores y actuadores y, actuando como bridge, puede re-enviar y re-escribir mensajes MQTT, con lo que puede ser un mini-controlador controlado a su vez desde un controlador/supervisor maestro. Además, soporta tb operaciones básicas como cliente HTTP, en relación a las GPIO locales, temporizadores, interrupciones, PWM, soporte CLI, ... interesante.
Se basa en esta librería que, aunque arduino family utiliza lwip, que tb anda en la rama espressif-sdk y utiliza código de esp_mqtt, construída para espressif sdk.
3. Otros
Wifi repeater y mas.
He leído en algunos firmwares sobre problemas con TLS (como aquí).
Hay un controller Homie en python.
4. Librerías.
- Librería de componentes que ya, en su mayor parte, estan incluídos en extras de esp-open-rtos, pero algunos de momento no lo estan y otros estan mas actualizados.
- Bounce 2 para arduino: filtra los parpadeos de las GPIO.
- librería TCP asíncrona, en arduino para ESP8266 (y para ESP32).
- HTTP server asíncrono en arduino.
- Modbus master en arduino.
- Librería ESP32 MQTT, versión ESP32 de la habitual MQTT para ESP8266. Preparada para utilizar como submódulo de ESP-IDF|.
- modbus, sobre rtos. Preparada para usar UART0, pero imagino que se podría adaptar a soft uart.
- RF433 sobre rtos.