Dirigido a desarrolladores de firmware y arquitectos de sistemas con experiencia intermedia en redes.
1. ¿Qué es MQTT y por qué importa en IoT?
MQTT (Message Queuing Telemetry Transport) es un protocolo de mensajería ligero basado en el patrón publish/subscribe, diseñado para entornos con ancho de banda limitado, alta latencia o dispositivos con recursos restringidos. Fue creado por IBM en 1999 y estandarizado por OASIS en 2014 (v3.1.1) y 2019 (v5.0).
Opera sobre TCP/IP y su overhead es mínimo: la cabecera fija tiene solo 2 bytes, lo que lo hace ideal para redes celulares (LTE/4G), conexiones satelitales o enlaces serie.
2. Arquitectura MQTT: Componentes Clave
La arquitectura MQTT se basa en tres actores principales:

Componentes:
- Broker: servidor central que recibe, filtra y distribuye mensajes. Nunca procesa el contenido.
- Publisher: cliente que publica mensajes en un topic.
- Subscriber: cliente que se suscribe a uno o más topics y recibe los mensajes.
- Topic: cadena jerárquica que actúa como canal de enrutamiento (ej.
factory/line1/temperature).
3. Conceptos Fundamentales
3.1 Topics y Wildcards
Los topics son cadenas UTF-8 separadas por /. Los suscriptores pueden usar comodines:
+→ un nivel (ej.factory/+/tempcapturafactory/line1/tempyfactory/line2/temp)#→ todos los niveles restantes (ej.factory/#)
3.2 Quality of Service (QoS)
| Nivel | Nombre | Garantía | Uso típico |
|---|---|---|---|
| QoS 0 | At most once | Sin confirmación, puede perderse | Telemetría no crítica |
| QoS 1 | At least once | Confirmado, puede duplicarse | Alarmas, eventos |
| QoS 2 | Exactly once | Entrega exacta, mayor overhead | Transacciones críticas |
3.3 Retain y Clean Session
- Retain flag: el broker almacena el último mensaje de un topic. Un nuevo suscriptor lo recibe inmediatamente al conectarse.
- Clean Session = false: el broker persiste las suscripciones y mensajes QoS 1/2 pendientes entre reconexiones. Esencial para dispositivos móviles o con conectividad intermitente.
- Last Will and Testament (LWT): mensaje que el broker publica automáticamente si el cliente se desconecta de forma inesperada.
4. Ejemplos de Código Python
4.1 Publisher básico con paho-mqtt
import paho.mqtt.client as mqtt
import json
import time
BROKER = "broker.hivemq.com"
PORT = 1883
TOPIC = "factory/line1/temperature"
client = mqtt.Client(client_id="teltonika-rut955-01", clean_session=False)
client.username_pw_set("user", "password")
# Last Will Testament: notifica desconexión inesperada
client.will_set(
topic="factory/line1/status",
payload=json.dumps({"status": "offline", "device": "RUT955-01"}),
qos=1,
retain=True
)
client.connect(BROKER, PORT, keepalive=60)
client.loop_start()
payload = {
"device_id": "RUT955-01",
"timestamp": int(time.time()),
"temperature": 72.4,
"unit": "celsius",
"location": "factory/line1"
}
# Publicar con QoS 1 y retain=True
result = client.publish(
topic=TOPIC,
payload=json.dumps(payload),
qos=1,
retain=True
)
result.wait_for_publish()
print(f"[OK] Publicado en {TOPIC}: {json.dumps(payload, indent=2)}")
client.loop_stop()
client.disconnect()
4.2 Subscriber con callback y wildcards
import paho.mqtt.client as mqtt
import json
def on_connect(client, userdata, flags, rc):
codes = {0: "Conectado", 1: "Versión incorrecta", 5: "No autorizado"}
print(f"Conexión: {codes.get(rc, f'Error {rc}')}")
# Suscribirse a todos los sensores de la fábrica
client.subscribe("factory/#", qos=1)
def on_message(client, userdata, msg):
try:
data = json.loads(msg.payload.decode())
print(f"[{msg.topic}] QoS={msg.qos} Retain={msg.retain}")
print(f" device_id : {data.get('device_id')}")
print(f" timestamp : {data.get('timestamp')}")
print(f" value : {data.get('temperature')} {data.get('unit','')}")
except json.JSONDecodeError:
print(f"Payload no JSON: {msg.payload}")
client = mqtt.Client(client_id="dashboard-subscriber-01", clean_session=False)
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.hivemq.com", 1883, keepalive=60)
client.loop_forever() # Bloquea y procesa mensajes indefinidamente
4.3 Publicación con TLS/SSL y QoS 2
import paho.mqtt.client as mqtt
import ssl, json, time
client = mqtt.Client(client_id="rubustel-r2000-secure")
# Configurar TLS con certificados de cliente
client.tls_set(
ca_certs="/etc/mqtt/ca.crt",
certfile="/etc/mqtt/client.crt",
keyfile="/etc/mqtt/client.key",
tls_version=ssl.PROTOCOL_TLSv1_2
)
client.tls_insecure_set(False)
client.connect("mqtt.empresa.com", 8883, keepalive=30)
payload = {
"device": "R2000-EDGE-07",
"ts": int(time.time()),
"gps": {"lat": 40.4168, "lon": -3.7038},
"signal": {"rssi": -78, "technology": "LTE"},
"io": {"din1": True, "dout1": False, "analog1": 3.3}
}
# QoS 2: entrega exactamente una vez (crítico para comandos)
client.publish(
topic="fleet/truck007/telemetry",
payload=json.dumps(payload),
qos=2
)
client.loop(timeout=5.0)
client.disconnect()
print("Publicado con QoS 2 sobre TLS")
5. Escenarios de Uso en IoT
A continuación se presentan tres escenarios reales con arquitectura MQTT:
6. Implementaciones Gratuitas de MQTT
| Implementación | Versión MQTT | Licencia | Conexiones máx. | Clustering | Persistencia | Ideal para |
|---|---|---|---|---|---|---|
| Eclipse Mosquitto | 3.1.1 / 5.0 | EPL 2.0 (Open Source) | ~100k (single node) | ❌ No nativo | Archivos planos | Desarrollo, edge, Raspberry Pi |
| EMQ X (EMQX) CE | 3.1.1 / 5.0 | Apache 2.0 | 1M+ por nodo | ✅ Sí (Erlang) | PostgreSQL/MySQL | Producción, alta escala |
| HiveMQ CE | 3.1.1 | Apache 2.0 | ~25k | ❌ Limitado | En memoria | Pruebas, desarrollo Java |
| VerneMQ | 3.1.1 / 5.0 | Apache 2.0 | 1M+ | ✅ Sí (Erlang) | LevelDB | Alternativa a EMQX |
| NanoMQ | 3.1.1 / 5.0 | MIT | ~100k | ❌ No | SQLite | Edge computing, IoT embebido |
Recomendación práctica: Para entornos de producción con >10k dispositivos, usa EMQX CE. Para desarrollo local y edge, Mosquitto es la opción más ligera y documentada.
7. Configuración en Routers Teltonika y Rubustel
7.1 Teltonika RUT955 — Configuración vía UCI (OpenWrt)
El RUT955 incluye un cliente MQTT nativo basado en mosquitto_pub. La configuración se realiza desde la WebUI o por SSH:
# Acceso SSH al router
ssh root@192.168.1.1
# Instalar cliente MQTT si no está disponible
opkg update && opkg install mosquitto-client-ssl
# Publicar telemetría manualmente (prueba)
mosquitto_pub \
-h "mqtt.empresa.com" \
-p 8883 \
--cafile /etc/ssl/ca.crt \
-u "rut955-user" \
-P "secretpassword" \
-t "factory/line1/rut955/telemetry" \
-m '{"device":"RUT955-01","ts":1700000000,"temp":72.4}' \
-q 1 \
--retain
Configuración persistente en /etc/config/mqtt (UCI):
uci set mqtt.@mqtt[0].enabled='1'
uci set mqtt.@mqtt[0].broker='mqtt.empresa.com'
uci set mqtt.@mqtt[0].port='8883'
uci set mqtt.@mqtt[0].topic='factory/line1/rut955/telemetry'
uci set mqtt.@mqtt[0].qos='1'
uci set mqtt.@mqtt[0].tls='1'
uci set mqtt.@mqtt[0].cafile='/etc/ssl/ca.crt'
uci set mqtt.@mqtt[0].interval='30' # segundos entre publicaciones
uci commit mqtt
/etc/init.d/mqtt restart
7.2 Rubustel R2000 — Configuración vía WebUI / CLI
El R2000 soporta MQTT nativo desde el firmware 3.x. Configuración por CLI:
# Conectar por SSH
ssh admin@192.168.1.1
# Configurar cliente MQTT
set mqtt broker_address mqtt.empresa.com
set mqtt broker_port 8883
set mqtt client_id R2000-EDGE-07
set mqtt username rubustel-user
set mqtt password secretpassword
set mqtt tls enable
set mqtt ca_cert /etc/ssl/ca.crt
set mqtt publish_topic fleet/truck007/telemetry
set mqtt publish_interval 30
set mqtt qos 1
set mqtt retain enable
commit
7.3 Payload JSON de Ejemplo — Teltonika RUT955
{
"device_id": "RUT955-01",
"firmware": "RUT9_R_00.07.04.5",
"timestamp": 1700000000,
"uptime_sec": 86400,
"network": {
"wan_ip": "203.0.113.45",
"technology": "LTE",
"operator": "Vodafone ES",
"rssi_dbm": -78,
"rsrp_dbm": -95,
"signal_bars": 3
},
"system": {
"cpu_load_pct": 12,
"ram_free_mb": 48,
"temperature_c": 42
},
"io": {
"din1": false,
"din2": true,
"dout1": false,
"analog_in_v": 12.4
},
"gps": {
"lat": 40.4168,
"lon": -3.7038,
"alt_m": 667,
"speed_kmh": 0,
"fix": true
}
}
7.4 Payload JSON de Ejemplo — Rubustel R2000
{
"device": "R2000-EDGE-07",
"model": "Rubustel R2000-4L",
"ts": 1700000000,
"connection": {
"type": "4G",
"apn": "internet.empresa.com",
"rssi": -82,
"lac": "1A2B",
"cell_id": "3C4D5E"
},
"serial_data": {
"port": "RS485",
"protocol": "Modbus RTU",
"register_40001": 724,
"register_40002": 1013
},
"alarms": {
"power_loss": false,
"high_temp": false,
"link_down": false
}
}
8. Flujo de Conexión MQTT — Diagrama de Secuencia

9. Buenas Prácticas y Consideraciones de Seguridad
- Autenticación: usa siempre usuario/contraseña o certificados X.509. Nunca dejes el broker sin autenticación en producción.
- TLS obligatorio: puerto 8883 para conexiones cifradas. El puerto 1883 (sin TLS) solo para redes aisladas.
- Diseño de topics: usa jerarquías claras:
{organización}/{sitio}/{dispositivo}/{tipo_dato}. Evita topics genéricos comodataosensor. - QoS adecuado: no uses QoS 2 por defecto; el overhead de 4 mensajes por publicación puede saturar redes lentas.
- ACLs en el broker: restringe qué clientes pueden publicar/suscribirse a qué topics. Un sensor no debería poder suscribirse a comandos de otros dispositivos.
- Monitorización: suscríbete a
$SYS/#en Mosquitto para métricas del broker (conexiones activas, mensajes/segundo, bytes transferidos).
10. Resumen
MQTT es el protocolo de facto para IoT industrial gracias a su eficiencia, flexibilidad y soporte de patrones asíncronos. La combinación de routers industriales (Teltonika RUT955, Rubustel R2000) como publishers de telemetría, brokers robustos (EMQX, Mosquitto) y payloads JSON estructurados permite construir arquitecturas escalables, resilientes y seguras para cualquier caso de uso: desde monitorización de planta hasta flotas vehiculares y smart grids.


