Inicio » Blog » MQTT: Protocolo de Mensagens para IoT — Guia Técnico Completo

MQTT: Protocolo de Mensagens para IoT — Guia Técnico Completo

Destinado a desenvolvedores de firmware e arquitetos de sistemas com experiência intermediária em redes.

1. O que é MQTT e por que importa em IoT?

MQTT (Message Queuing Telemetry Transport) é um protocolo de mensagens leve baseado no padrão publish/subscribe, projetado para ambientes com largura de banda limitada, alta latência ou dispositivos com recursos restritos. Foi criado pela IBM em 1999 e padronizado pela OASIS em 2014 (v3.1.1) e 2019 (v5.0).

Opera sobre TCP/IP e seu overhead é mínimo: o cabeçalho fixo tem apenas 2 bytes, o que o torna ideal para redes celulares (LTE/4G), conexões via satélite ou links seriais.

2. Arquitetura MQTT: Componentes Chave

A arquitetura MQTT baseia-se em três atores principais:

Componentes:

  • Broker: servidor central que recebe, filtra e distribui mensagens. Nunca processa o conteúdo.
  • Publisher: cliente que publica mensagens em um topic.
  • Subscriber: cliente que se inscreve em um ou mais topics e recebe as mensagens.
  • Topic: cadeia hierárquica que atua como canal de roteamento (ex. factory/line1/temperature).

3. Conceitos Fundamentais

3.1 Topics e Wildcards

Os topics são cadeias UTF-8 separadas por /. Os assinantes podem usar curingas:

  • + → um nível (ex. factory/+/temp captura factory/line1/temp e factory/line2/temp)
  • # → todos os níveis restantes (ex. factory/#)

3.2 Quality of Service (QoS)

NívelNomeGarantiaUso típico
QoS 0At most onceSem confirmação, pode perderTelemetria não crítica
QoS 1At least onceConfirmado, pode duplicarAlarmes, eventos
QoS 2Exactly onceEntrega exata, maior overheadTransações críticas

3.3 Retain e Clean Session

  • Retain flag: o broker armazena a última mensagem de um topic. Um novo assinante a recebe imediatamente ao conectar-se.
  • Clean Session = false: o broker persiste as inscrições e mensagens QoS 1/2 pendentes entre reconexões. Essencial para dispositivos móveis ou com conectividade intermitente.
  • Last Will and Testament (LWT): mensagem que o broker publica automaticamente se o cliente se desconectar de forma inesperada.

4. Exemplos de Código Python

4.1 Publisher básico com 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 desconexão 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 com QoS 1 e retain=True
result = client.publish(
    topic=TOPIC,
    payload=json.dumps(payload),
    qos=1,
    retain=True
)
result.wait_for_publish()
print(f"[OK] Publicado em {TOPIC}: {json.dumps(payload, indent=2)}")

client.loop_stop()
client.disconnect()

4.2 Subscriber com callback e wildcards

import paho.mqtt.client as mqtt
import json

def on_connect(client, userdata, flags, rc):
    codes = {0: "Conectado", 1: "Versão incorreta", 5: "Não autorizado"}
    print(f"Conexão: {codes.get(rc, f'Erro {rc}')}")
    # Inscrever-se em todos os sensores da 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 não 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()  # Bloqueia e processa mensagens indefinidamente

4.3 Publicação com TLS/SSL e QoS 2

import paho.mqtt.client as mqtt
import ssl, json, time

client = mqtt.Client(client_id="rubustel-r2000-secure")

# Configurar TLS com 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 exatamente uma 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 com QoS 2 sobre TLS")

5. Cenários de Uso em IoT

A seguir, apresentam-se três cenários reais com arquitetura MQTT:

6. Implementações Gratuitas de MQTT

ImplementaçãoVersão MQTTLicençaConexões máx.ClusteringPersistênciaIdeal para
Eclipse Mosquitto3.1.1 / 5.0EPL 2.0 (Open Source)~100k (single node)❌ Não nativoArquivos planosDesenvolvimento, edge, Raspberry Pi
EMQ X (EMQX) CE3.1.1 / 5.0Apache 2.01M+ por nó✅ Sim (Erlang)PostgreSQL/MySQLProdução, alta escala
HiveMQ CE3.1.1Apache 2.0~25k❌ LimitadoEm memóriaTestes, desenvolvimento Java
VerneMQ3.1.1 / 5.0Apache 2.01M+✅ Sim (Erlang)LevelDBAlternativa ao EMQX
NanoMQ3.1.1 / 5.0MIT~100k❌ NãoSQLiteEdge computing, IoT embarcado

Recomendação prática: Para ambientes de produção com >10k dispositivos, use EMQX CE. Para desenvolvimento local e edge, Mosquitto é a opção mais leve e documentada.

7. Configuração em Routers Teltonika e Rubustel

7.1 Teltonika RUT955 — Configuração via UCI (OpenWrt)

O RUT955 inclui um cliente MQTT nativo baseado em mosquitto_pub. A configuração é feita pela WebUI ou via SSH:

# Acesso SSH ao router
ssh root@192.168.1.1

# Instalar cliente MQTT se não estiver disponível
opkg update && opkg install mosquitto-client-ssl

# Publicar telemetria manualmente (teste)
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

Configuração persistente em /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 publicações
uci commit mqtt
/etc/init.d/mqtt restart

7.2 Rubustel R2000 — Configuração via WebUI / CLI

O R2000 suporta MQTT nativo a partir do firmware 3.x. Configuração via CLI:

# Conectar via 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 Exemplo — 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 Exemplo — 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. Fluxo de Conexão MQTT — Diagrama de Sequência

9. Boas Práticas e Considerações de Segurança

  • Autenticação: use sempre usuário/senha ou certificados X.509. Nunca deixe o broker sem autenticação em produção.
  • TLS obrigatório: porta 8883 para conexões criptografadas. A porta 1883 (sem TLS) só para redes isoladas.
  • Design de topics: use hierarquias claras: {organização}/{local}/{dispositivo}/{tipo_dado}. Evite topics genéricos como data ou sensor.
  • QoS adequado: não use QoS 2 por padrão; o overhead de 4 mensagens por publicação pode saturar redes lentas.
  • ACLs no broker: restrinja quais clientes podem publicar/assinar quais topics. Um sensor não deve poder assinar comandos de outros dispositivos.
  • Monitoramento: assine $SYS/# no Mosquitto para métricas do broker (conexões ativas, mensagens/segundo, bytes transferidos).

10. Resumo

MQTT é o protocolo de fato para IoT industrial graças à sua eficiência, flexibilidade e suporte a padrões assíncronos. A combinação de routers industriais (Teltonika RUT955, Rubustel R2000) como publishers de telemetria, brokers robustos (EMQX, Mosquitto) e payloads JSON estruturados permite construir arquiteturas escaláveis, resilientes e seguras para qualquer caso de uso: desde monitoramento de planta até frotas veiculares e smart grids.