DocumentaciónManual de usuario finalConectar dispositivos IoT a Abior — guía técnica para makers

Conectar dispositivos IoT a Abior — guía técnica para makers

Host MQTT, autenticación, registro de dispositivos, topics, payloads y ejemplo ESP32.

Visión general y arquitectura

Cómo se conecta un dispositivo físico a Abior: drivers disponibles y cuándo usar cada uno.

Cómo se conecta un dispositivo a Abior

   ┌──────────────┐         MQTT 8883 TLS         ┌──────────────┐
   │  Tu device   │ ──────────────────────────► │   Abior.art  │
   │ (ESP32 etc.) │ ◄────────────────────────── │ Mosquitto +  │
   └──────────────┘   topics abior/{id}/...      │   Django API │
                                                 └──────────────┘

Un dispositivo físico (ESP32, Raspberry Pi, Arduino con WiFi, etc.) se autentica con un ApiToken propio y publica/recibe via MQTT estándar. Abior:

  • Ingiere las lecturas y las guarda como Lectura para gráficas y reglas reactivas.
  • Despacha comandos a actuadores cuando se dispara una Regla o un ProcedPaso automático.
  • Mantiene Dispositivo.online y last_seen_at actualizados.

Drivers disponibles

DriverCuándo usarloVentaja
mqtt_nativeDIY: ESP32, Raspberry, Arduino, MicroPythonBidireccional + push real-time
rest_webhookDevices que solo pueden hacer HTTP POSTNo necesita conexión persistente
rest_pollingShelly, Hue, Tasmota (devices con API REST propia)Abior pollea cada N segundos
tuya_cloudDevices Tuya / Smart LifeIntegración via cloud externa

Recomendado para DIY: mqtt_native. Es el más eficiente y soporta reglas reactivas con latencia mínima.

Lo que necesitas

  1. Una cuenta en Abior (/register) — gratis.
  2. Crear un Disp_modelo (plantilla) con sus sensores y actuadores.
  3. Crear un Dispositivo físico desde el modelo. Abior te genera un ApiToken único.
  4. Flashear tu device con las credenciales y los topics MQTT correctos.

Todo el flujo está en las siguientes hojas.

Permalink a esta hoja →

Conexión MQTT y autenticación

Host, puerto, TLS y cómo autenticarse con tu ApiToken.

Conexión al broker MQTT público

ParámetroValor producciónValor dev local
Hostabior.artmosquitto (dentro del docker network)
Puerto8883 (TLS)1883 (plaintext)
TLSSí, certificado de Let's EncryptNo
Keep-alive60 s recomendado60 s

Autenticación

Abior usa el plugin mosquitto-go-auth que valida usuario/contraseña contra Django via HTTP.

  • Usuario MQTT = <ApiToken.key> del dispositivo (lo obtienes al crearlo, ver siguiente hoja).
  • Contraseña MQTT = token (literal, hoy; será dinámico en futuras versiones).

El plugin valida cada CONNECT contra:

POST /api/auth/mqtt/check_user/
POST /api/auth/mqtt/check_acl/

Si el token está activo y tiene permiso sobre el topic, el broker acepta la conexión.

Variables de entorno relevantes (settings Django)

MQTT_BROKER_PUBLIC_HOST = 'abior.art'        # Host público para devices
MQTT_BROKER_PUBLIC_PORT = 8883               # TLS
MQTT_BROKER_HOST = 'mosquitto'               # Host interno (Docker)
MQTT_BROKER_PORT = 1883                      # Plaintext interno

ACL (qué puede publicar/suscribir cada device)

Cada ApiToken solo tiene permiso sobre topics de su propio device:

  • abior/{tu_device_id}/sensors/+ (publicar lecturas)
  • abior/{tu_device_id}/state (publicar online/offline)
  • abior/{tu_device_id}/ack/+ (confirmar comandos recibidos)
  • abior/{tu_device_id}/commands/+ (suscribirse a comandos del servidor)
  • abior/{otro_device_id}/... (rechazado)

Esto evita que un device comprometido escuche o envíe a otros.

Permalink a esta hoja →

Registrar tu dispositivo (provisioning)

Crear Disp_modelo + Dispositivo + obtener ApiToken via API REST.

Flow completo de provisioning

1. Crear Disp_modelo (plantilla)        → Define sensores+actuadores
2. Crear Dispositivo desde el modelo    → Signal materializa Sensor/Actuador
                                         + crea Gafete propio del device
                                         + crea ApiToken único
3. GET /dispositivos/{id}/api-tokens/    → Te devuelve el token.key
4. Flashear firmware con esas creds      → Listo

1. Crear el Disp_modelo (plantilla)

Define qué sensores y actuadores tiene tu hardware. Reusable para clones.

curl -X POST https://abior.art/api/desar/disp-modelos/ \
  -H "Authorization: Token <TU_USER_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "alias": "ESP32 + DHT22 + Relay",
    "desc": "Modelo casero: lee temp+humedad y controla un relay",
    "driver_key": "mqtt_native",
    "emprendimiento": "<TU_EMPRENDIMIENTO_UUID>",
    "sensor_templates": [
      {"code": "temp", "name": "Temperatura", "unit": "C"},
      {"code": "hum",  "name": "Humedad",     "unit": "%"}
    ],
    "actuador_templates": [
      {"code": "ventilador", "name": "Ventilador", "tipo": "on_off"}
    ]
  }'

2. Crear el Dispositivo físico

curl -X POST https://abior.art/api/desar/dispositivos/ \
  -H "Authorization: Token <TU_USER_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "alias": "Granja - sector A",
    "modelo": "<DISP_MODELO_UUID>",
    "driver_key": "mqtt_native",
    "emprendimiento": "<TU_EMPRENDIMIENTO_UUID>"
  }'

Al crearse, un signal post_save corre automáticamente:

  • Materializa los Sensor y Actuador desde los templates del modelo.
  • Crea un Gafete para que el device tenga identidad en el emprendimiento.
  • Crea un ApiToken único asociado a ese gafete.

3. Obtener el ApiToken

curl -X GET https://abior.art/api/desar/dispositivos/<DEVICE_UUID>/api-tokens/ \
  -H "Authorization: Token <TU_USER_TOKEN>"

Respuesta:

[
  {
    "key": "abc123def456...",
    "created": "2026-04-29T05:30:00Z",
    "expires_at": null
  }
]

Guarda ese key en tu firmware. Es el usuario MQTT y la credencial para los webhooks HTTP.

4. (Opcional) Listar sensores y actuadores del device

curl https://abior.art/api/desar/sensores/?dispositivo=<DEVICE_UUID> \
  -H "Authorization: Token <TU_USER_TOKEN>"

curl https://abior.art/api/desar/actuadores/?dispositivo=<DEVICE_UUID> \
  -H "Authorization: Token <TU_USER_TOKEN>"

Cada sensor y actuador tiene su code (slug que aparece en los topics MQTT).

Permalink a esta hoja →

Topics MQTT, payloads y ejemplo ESP32

Convención de topics + JSON payloads + código MicroPython funcional + fallback HTTP.

Convención de topics MQTT

Reemplaza {device_id} por el UUID de tu dispositivo y {code} por el code de tu sensor o actuador.

DirecciónTopicQuién publica
Device → Abiorabior/{device_id}/sensors/{code}Tu firmware (lectura de sensor)
Device → Abiorabior/{device_id}/stateTu firmware (heartbeat online/offline)
Device → Abiorabior/{device_id}/ack/{cmd_id}Tu firmware (confirmar comando recibido)
Abior → Deviceabior/{device_id}/commands/{code}Servidor (al disparar regla/quehacer/procedpaso)

Payloads JSON

Lectura de sensor (sensors/<code>):

{"value": 25.5, "ts": "2026-04-29T14:30:00Z"}

ts es opcional — si se omite, Abior usa la hora de recepción.

Estado del device (state):

{"online": true, "fw_version": "1.0.3"}

Comando del servidor (commands/<code>):

{"cmd_id": "uuid-del-comando", "ts": "2026-04-29T14:30:00Z", "accion": "on", "valor": 80}

ACK del device (ack/<cmd_id>):

{"ok": true, "result": {"estado_final": "on"}}

Ejemplo completo MicroPython (ESP32)

import network, ssl, ujson, time
from umqtt.simple import MQTTClient

WIFI_SSID = "MiRed"
WIFI_PASS = "supersecreto"
DEVICE_ID = "uuid-de-tu-dispositivo-en-abior"
API_TOKEN = "tu-api-token-key"  # GET /api/desar/dispositivos/{id}/api-tokens/

# 1. WiFi
wlan = network.WLAN(network.STA_IF); wlan.active(True)
wlan.connect(WIFI_SSID, WIFI_PASS)
while not wlan.isconnected(): time.sleep(0.5)

# 2. MQTT con TLS al broker publico Abior
client = MQTTClient(
    client_id=DEVICE_ID,
    server="abior.art",
    port=8883,
    user=API_TOKEN,
    password="token",
    keepalive=60,
    ssl=True,
    ssl_params={"server_hostname": "abior.art"},
)

# 3. Suscribirse a comandos
def on_command(topic, msg):
    cmd = ujson.loads(msg)
    cmd_id = cmd.get("cmd_id")
    code = topic.decode().split("/")[-1]
    print("Comando recibido:", code, cmd)
    # ... ejecutar (p.ej. encender relay) ...
    client.publish(
        f"abior/{DEVICE_ID}/ack/{cmd_id}",
        ujson.dumps({"ok": True}),
    )

client.set_callback(on_command)
client.connect()
client.subscribe(f"abior/{DEVICE_ID}/commands/+")

# 4. Heartbeat
client.publish(f"abior/{DEVICE_ID}/state", ujson.dumps({"online": True}))

# 5. Loop: leer sensor cada 30s + escuchar comandos
while True:
    temperatura = leer_dht22()  # tu funcion
    client.publish(
        f"abior/{DEVICE_ID}/sensors/temp",
        ujson.dumps({"value": temperatura}),
    )
    for _ in range(30):
        client.check_msg()  # non-blocking
        time.sleep(1)

Fallback HTTP (sin MQTT)

Si tu device no soporta MQTT pero sí HTTP, usa los webhooks REST:

curl -X POST https://abior.art/api/iot/webhook/<DEVICE_ID>/sensor/temp/ \
  -H "Authorization: Token <API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"value": 25.5}'

Endpoints disponibles:

EndpointMétodoUso
/api/iot/webhook/{device_id}/sensor/{code}/POSTReportar lectura
/api/iot/webhook/{device_id}/state/POSTHeartbeat
/api/iot/webhook/{device_id}/ack/{cmd_id}/POSTConfirmar comando

Comandos del servidor en modo HTTP: Abior los encola y tu device los pollea con GET /api/iot/webhook/{device_id}/comandos-pendientes/ (cada N segundos).

Verificar que funciona

Tras publicar tu primera lectura, deberías verla en:

curl https://abior.art/api/desar/lecturas/?sensor=<SENSOR_UUID> \
  -H "Authorization: Token <TU_USER_TOKEN>"

O en la app Android, en el detalle del dispositivo → tab Sensores → gráfica.

Siguiente paso: Reglas reactivas

Una vez que las lecturas llegan, puedes crear Reglas: "si temp > 28 °C entonces encender ventilador". Ver el módulo IoT en /caracteristica-iot o el detalle de tu dispositivo.

Permalink a esta hoja →

Conectar dispositivos IoT a Abior — guía técnica para makers — Abior | Abior