Bibliotecas cliente IoT para ESP3 en MicroPython. Compatible con el middleware SensorWave Go y ESP-IDF.
- MQTT: Cliente completo con QoS dinámico, suscripciones QoS 2
- HTTP: Soporte SSE (Server-Sent Events), ACKs y retransmisión
- CoAP: Implementación ligera con Observe (suscripciones)
- API Unificada: Misma interfaz que ESP-IDF
- Compatibilidad 100%: Formato JSON, Base64, URL encoding idéntico a Go
nodo-micropython/
├── sensorwave/ # Módulo principal
│ ├── __init__.py # Exports
│ ├── middleware.py # API principal
│ ├── mqtt.py # Cliente MQTT
│ ├── http.py # Cliente HTTP
│ ├── coap.py # Cliente CoAP
│ └── internal/ # Utilidades internas
│ ├── utils.py # Base64, URL encoding
│ └── mensaje.py # JSON
├── ejemplos/ # Ejemplos
│ ├── mqtt_ejemplo.py
│ ├── http_ejemplo.py
│ └── coap_ejemplo.py
└── install_deps.py # Instalador de dependencias
Descargar firmware:
- Versión: MicroPython v1.22.0 o superior (con soporte de red)
- URL: https://micropython.org/download/esp32/
Instalar con esptool:
# Borrar flash
esptool.py --chip esp32 --port /dev/ttyUSB0 erase_flash
# Instalar firmware
esptool.py --chip esp32 --port /dev/ttyUSB0 write_flash -z 0x1000 esp32-20240105-v1.22.1.binReemplazar /dev/ttyUSB0 con tu puerto (Windows: COM3, etc.)
Usando ampy:
# Instalar ampy
pip install adafruit-ampy
# Copiar módulo
ampy --port /dev/ttyUSB0 put sensorwave/
# Copiar ejemplos (opcional)
ampy --port /dev/ttyUSB0 put examples/O usando rshell:
pip install rshell
rshell -p /dev/ttyUSB0
# Dentro de rshell:
cp -r sensorwave /pyboard/
cp -r examples /pyboard/Conectar el ESP32 a WiFi y ejecutar:
# Usando REPL
import network
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect('TU_SSID', 'TU_PASSWORD')
# Esperar conexión
import time
while not wlan.isconnected():
time.sleep(1)
print("Conectado! IP:", wlan.ifconfig()[0])
# Ejecutar instalador
exec(open('install_deps.py').read())O simplemente:
ampy --port /dev/ttyUSB0 run install_deps.pyfrom sensorwave import middleware
import time
# Callback para recibir mensajes
def callback(topico, mensaje):
print(f"Recibido: {topico} = {mensaje}")
# Conectar
middleware.conectar(middleware.MQTT, "broker.hivemq.com", 1883)
# Suscribirse
middleware.suscribir("casa/sensor", callback)
# Publicar (QoS 0 por defecto)
middleware.publicar("casa/sensor", "25.5")
# Publicar con QoS 1
middleware.publicar("casa/sensor", "25.5", qos=1)
# Loop
while True:
time.sleep(1)from sensorwave import middleware
# Callback para notificaciones SSE
def callback(topico, mensaje):
print(f"Notificación: {mensaje}")
# Conectar
middleware.conectar(middleware.HTTP, "192.168.1.100", 8080)
# Suscribirse a notificaciones
middleware.suscribir("alertas", callback)
# Publicar
middleware.publicar("datos/sensor", "humedad:60%", qos=1)from sensorwave import middleware
# Callback
def callback(topico, mensaje):
print(f"Dato CoAP: {mensaje}")
# Conectar
middleware.conectar(middleware.COAP, "192.168.1.100", 5683)
# Suscribirse (Observe)
middleware.suscribir("sensor/temp", callback)
# Publicar (NON si qos=0, CON si qos=1)
middleware.publicar("sensor/temp", "22.5", qos=1)middleware.MQTT # = 0
middleware.HTTP # = 1
middleware.COAP # = 2Inicializa la conexión con el protocolo especificado.
Args:
protocolo:MQTT,HTTPoCOAPhost: Dirección IP o hostnamepuerto: Puerto del servidor
Suscribe a un tópico.
Args:
topico: String con el nombre del tópicocallback: Funcióncallback(topico, mensaje)
QoS por protocolo:
- MQTT: Suscripción con QoS 2 (automático)
- HTTP: SSE (Server-Sent Events)
- CoAP: Observe (RFC 7641)
Publica un mensaje.
Args:
topico: String con el nombre del tópicomensaje: String con el contenidoqos: 0 o 1 (default: 0)
Comportamiento por protocolo:
| Protocolo | QoS 0 | QoS 1 |
|---|---|---|
| MQTT | Fire & forget | ACK del broker |
| HTTP | POST simple | POST + ACK (4 reintentos) |
| CoAP | NON | CON + ACK |
Desuscribe de un tópico.
Cierra la conexión y libera recursos.
# sensorwave/http.py
ACK_TIMEOUT_MS = 2000 # Timeout para ACKs HTTP
ACK_RANDOM_FACTOR = 1.5 # Factor de backoff
MAX_RETRANSMIT = 4 # Máximo de reintentosVer carpeta ejemplos/:
- mqtt_ejemplo.py: Publica temperatura y recibe comandos
- http_ejemplo.py: Envía datos de humedad con notificaciones
- coap_ejemplo.py: Envía presión atmosférica con alarmas
El archivo install_deps.py instala automáticamente:
umqtt.simple- Cliente MQTTumqtt.robust- Cliente MQTT robustourequests- HTTP requests
Incluidos en MicroPython:
ubinascii- Base64ujson- JSONsocket/usocket- Sockets_thread- Threads
El cliente HTTP ahora incluye reconexión automática SSE:
- Hasta 5 intentos de reconexión
- Delay de 2 segundos entre intentos
- Limpieza automática de suscripciones fallidas
Los ACKs de QoS 1 se envían mediante un thread dedicado:
- No bloquean la recepción de mensajes
- Cola interna para manejar múltiples ACKs pendientes
Todas las operaciones de red validan conexión WiFi activa:
- Excepción clara si no hay WiFi
- Timeout de 30 segundos en conexiones
Todas las operaciones de suscripción/desubscripción son thread-safe:
- Locks automáticos con
_thread.allocate_lock() - Protección contra race conditions en callbacks concurrentes
- Fallback sin locks si el firmware no soporta
- Los locks (
_thread.allocate_lock()) requieren MicroPython con soporte de_thread - Si el firmware no soporta locks, se opera sin protección (documentado)
- Recomendado: MicroPython v1.22.0+ con
_threadhabilitado
Solución: Ejecutar install_deps.py para instalar dependencias.
Solución: Conectar a WiFi antes de usar sensorwave:
import network
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect('SSID', 'password')Solución: El ESP32 tiene RAM limitada (~520KB). Intentar:
- Usar solo un protocolo a la vez
- Compilar módulos a bytecode (.mpy)
- Aumentar heap si es posible
MIT License - Ver LICENSE en el repositorio principal.
Versión: 1.0.0
Compatible con: ESP32-WROOM, MicroPython ≥ 1.22.0
Middleware: SensorWave