O monitoramento da cadeia de frio consiste em provar que alimentos resfriados, vacinas ou biológicos nunca saíram da sua faixa de temperatura entre o frigorífico ou o depósito e o cliente, e em reagir rápido quando saem. Neste artigo você vai projetar um sistema de monitoramento para caminhões e contêineres refrigerados que envia dados de temperatura via MQTT celular, sobrevive a zonas sem sinal sem perder leituras e dispara alertas de excursão com base em quanto tempo um limite foi ultrapassado, e não a cada pico isolado.
O Que o Monitoramento da Cadeia de Frio Precisa Provar
O registro de temperatura no transporte tem dois públicos. A equipe de operações precisa de informação ao vivo para que o motorista possa corrigir uma porta entreaberta ou um equipamento de refrigeração com defeito antes que a carga se perca. A equipe de qualidade precisa de um registro completo após a viagem, muitas vezes para atender clientes e requisitos de boas práticas de distribuição, mostrando cada leitura com seu horário e localização.
Essas duas necessidades guiam todo o projeto:
| Requisito | Por que importa | Consequência no projeto |
|---|---|---|
| Visibilidade ao vivo | Intervir antes que o produto seja danificado | Conectividade celular, telemetria MQTT a cada poucos minutos |
| Nenhuma lacuna no registro | Uma hora faltando pode invalidar um embarque | Buffer store-and-forward no dispositivo |
| Timestamps confiáveis | A ordem e a duração das excursões precisam ser comprováveis | Timestamp no momento da medição, não da chegada |
| Contexto | A porta estava aberta? Onde estava o caminhão? | Sensores de porta e GPS junto com a temperatura |
| Alertas significativos | Ciclos de degelo e aberturas de porta causam picos breves | Regras de excursão baseadas em duração |
Hardware no Veículo
Uma configuração típica tem três partes:
- Sondas de temperatura no compartimento de carga, normalmente duas ou mais: uma perto do evaporador e uma no fundo, perto das portas, por onde entra o ar quente. Registradores BLE sem fio são comuns para rastreamento por palete; sondas cabeadas atendem instalações fixas de equipamentos reefer.
- Um gateway de telemática com modem LTE-M, NB-IoT ou LTE e GPS. Pode ser uma unidade comercial ou uma pequena placa Linux com um HAT celular. Ele lê as sondas, armazena os dados em buffer e publica via MQTT.
- Sensores de contato nas portas para que cada aumento de temperatura possa ser correlacionado a uma abertura.
O gateway é o único dispositivo que fala com o broker. Até uma carreta longa cheia de registradores BLE de palete vira uma única conexão MQTT.
Design de Topics para o Monitoramento da Cadeia de Frio
Organize por ativo da frota, e não por viagem; as viagens são metadados no payload:
coldchain/<fleet>/<asset-id>/telemetry {"ts":1760600000,"t_front":3.8,"t_rear":4.6,"door":"closed","lat":41.01,"lon":28.97,"trip":"TR-8812"}
coldchain/<fleet>/<asset-id>/status retained {"online":true,"fw":"1.4.2","battery_v":12.6}
coldchain/<fleet>/<asset-id>/alarm {"type":"excursion","probe":"t_rear","max":9.4,"duration_s":1260,"trip":"TR-8812"}
coldchain/<fleet>/<asset-id>/config retained {"min":2.0,"max":8.0,"grace_s":900}
Reter o topic config é um truque elegante. O gateway o assina ao se conectar, então mudar uma carga de resfriada para congelada é uma única publicação retida a partir do sistema de despacho, e um gateway que reinicia recupera seus limites imediatamente.
Código do Gateway com Store-and-Forward
A cobertura celular em rodovias do interior, túneis e portos como o de Santos é irregular. O gateway precisa continuar amostrando enquanto está offline e enviar tudo quando o link voltar. O esboço em Python abaixo usa paho-mqtt 2.x, MQTT 5 e uma fila SQLite no gateway. Ele aponta para o servidor MQTT público, para que você possa testá-lo em qualquer computador; substitua read_probes() pelo código real dos seus sensores.
import json
import random
import sqlite3
import time
import paho.mqtt.client as mqtt
PREFIX = "connectmq/demo/f2q7b5" # seu próprio prefixo aleatório
ASSET = "TRK-104"
BASE = f"{PREFIX}/coldchain/fleet1/{ASSET}"
SAMPLE_EVERY = 60 # segundos
db = sqlite3.connect("buffer.db")
db.execute("CREATE TABLE IF NOT EXISTS q (id INTEGER PRIMARY KEY, payload TEXT)")
connected = False
limits = {"min": 2.0, "max": 8.0, "grace_s": 900}
def read_probes():
# substitua por sensores reais; os valores aqui simulam uma carga resfriada
return {"t_front": round(random.uniform(3, 5), 1), "t_rear": round(random.uniform(3.5, 6), 1),
"door": "closed"}
def on_connect(client, userdata, flags, reason_code, properties):
global connected
connected = not reason_code.is_failure
if connected:
client.subscribe(f"{BASE}/config", qos=1)
client.publish(f"{BASE}/status", json.dumps({"online": True}), qos=1, retain=True)
def on_disconnect(client, userdata, flags, reason_code, properties):
global connected
connected = False
def on_message(client, userdata, msg):
limits.update(json.loads(msg.payload))
def flush(client, batch=50):
rows = db.execute("SELECT id, payload FROM q ORDER BY id LIMIT ?", (batch,)).fetchall()
for row_id, payload in rows:
info = client.publish(f"{BASE}/telemetry", payload, qos=1)
info.wait_for_publish(timeout=10)
if not info.is_published():
return # link caiu; mantém as linhas restantes
db.execute("DELETE FROM q WHERE id = ?", (row_id,))
db.commit()
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=f"gw-{ASSET}-f2q7b5",
protocol=mqtt.MQTTv5)
client.will_set(f"{BASE}/status", json.dumps({"online": False}), qos=1, retain=True)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_message = on_message
client.reconnect_delay_set(min_delay=2, max_delay=120)
client.connect_async("broker.connectmq.com", 1883, keepalive=120)
client.loop_start()
while True:
reading = {"ts": int(time.time()), "trip": "TR-8812", **read_probes()}
db.execute("INSERT INTO q (payload) VALUES (?)", (json.dumps(reading),))
db.commit()
if connected:
flush(client)
time.sleep(SAMPLE_EVERY)
Cada leitura entra primeiro na fila e só é apagada depois que o broker a confirma com QoS 1. Isso torna o buffer a fonte da verdade: quedas de energia, reinicializações e longas zonas sem sinal não criam lacunas, e o campo ts registra quando a medição foi feita, e não quando chegou. Para saber mais sobre garantias de entrega, veja níveis de QoS do MQTT explicados.
Alertas de Excursão Que Ignoram o Ruído
Uma regra ingênua do tipo "alertar se a temperatura passar de 8 °C" dispara toda vez que as portas abrem em uma parada de entrega ou o evaporador faz o degelo. O alerta real de cadeia de frio olha para a duração: alarma apenas quando uma sonda ficou fora da faixa por mais tempo que um período de tolerância.
import json
import paho.mqtt.client as mqtt
PREFIX = "connectmq/demo/f2q7b5"
LIMITS = {"min": 2.0, "max": 8.0, "grace_s": 900}
state = {} # (asset, probe) -> primeiro timestamp fora da faixa
def check(client, asset, probe, value, ts):
key = (asset, probe)
out = value < LIMITS["min"] or value > LIMITS["max"]
if not out:
state.pop(key, None)
return
start = state.setdefault(key, ts)
if start is not None and ts - start >= LIMITS["grace_s"]:
alarm = {"type": "excursion", "probe": probe, "value": value, "since": start,
"duration_s": ts - start}
client.publish(f"{PREFIX}/coldchain/fleet1/{asset}/alarm", json.dumps(alarm), qos=1)
state[key] = None # um alarme por excursão; zera quando volta à faixa
def on_connect(client, userdata, flags, reason_code, properties):
client.subscribe(f"{PREFIX}/coldchain/fleet1/+/telemetry", qos=1)
def on_message(client, userdata, msg):
asset = msg.topic.split("/")[-2]
r = json.loads(msg.payload)
for probe in ("t_front", "t_rear"):
if probe in r:
check(client, asset, probe, r[probe], r["ts"])
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="excursion-f2q7b5")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_forever()
Como usa o timestamp da medição, o detector lida corretamente com dados em buffer: uma excursão de vinte minutos ocorrida em um túnel continua sendo reconhecida como vinte minutos quando o acúmulo chega. Para limites fixos simples sobre um valor ao vivo, as regras de alerta por limite no portal são um começo rápido; uma lógica de duração como esta pertence ao seu próprio subscriber ou ao Node-RED.
Acompanhando a Frota
Assine tudo durante os testes:
mosquitto_sub -h broker.connectmq.com -p 1883 -i ops-f2q7b5 -t "connectmq/demo/f2q7b5/coldchain/#" -v
O servidor MQTT público serve para este protótipo e para testes, mas dados de embarques, localizações de clientes e outros dados de produção não devem trafegar por um servidor legível publicamente. Gateways em produção devem usar TLS na porta 8883 e credenciais geradas no portal.
Dicas de Conectividade Celular
- Mantenha os payloads pequenos. Chaves curtas e amostras a cada minuto mantêm os planos de dados modestos; agrupe várias leituras por mensagem se o seu plano cobrar por mensagem.
- Defina um keep-alive generoso. Valores de dois a cinco minutos reduzem os despertares do rádio sem atrasar demais a detecção de desconexão.
- Use o session expiry do MQTT 5 para que as assinaturas sobrevivam a quedas curtas; veja recursos do MQTT 5.
- Use backoff na reconexão. Atrasos exponenciais evitam sobrecarregar a rede após uma troca de torre.
- Monitore o modem. Publique a intensidade do sinal e o tipo de rede em
statuspara diagnosticar zonas sem sinal.
Armadilhas Comuns
Sonda apenas ao lado do evaporador. Essa sonda mostra o ar mais frio do compartimento e pode esconder uma zona quente perto das portas. Meça onde o produto corre mais risco.
Timestamps no servidor. Se você carimba as leituras quando elas chegam, um acúmulo em buffer colapsa em um único minuto e as durações das excursões perdem o sentido. Sempre carimbe no momento da medição.
Tempestade de alarmes após a reconexão. Um gateway descarregando uma hora de dados pode disparar muitos alertas de uma vez. Alarme uma vez por excursão, como faz o detector acima, e marque alarmes atrasados como "históricos" para que os despachantes saibam que o evento já terminou.
Credenciais compartilhadas em toda a frota. Um único login vazado expõe todos os caminhões. Dê a cada gateway suas próprias credenciais e seu próprio client ID.
Checklist de Implantação
- Sondas posicionadas nos pontos mais quentes e mais frios do compartimento de carga, e calibradas.
- Sensores de porta instalados e reportados em todas as mensagens de telemetria.
- O gateway armazena em memória não volátil e só apaga após a confirmação.
- Timestamps de um relógio sincronizado (GPS ou NTP).
- Limites entregues como configuração retida por ativo.
- Regras de excursão baseadas em duração por categoria de produto.
- Um subscriber de arquivamento durável que grava cada leitura em um banco de dados para relatórios de viagem.
- TLS e credenciais únicas por gateway.
Padrões Relacionados
O monitoramento de frotas tem muito em comum com outros sistemas IoT distribuídos. A ideia de um gateway por ativo espelha os gateways de campo em uma arquitetura IoT de cidade inteligente, e agregar muitos ativos em visões de status ao vivo é o mesmo problema resolvido no estacionamento inteligente IoT. Para construir um modelo durável de estado retido, nosso projeto de detecção de vazamento de água mostra alarmes retidos em um cenário menor, e o guia de automação IoT traz mais exemplos.
Rode Sua Telemetria de Cadeia de Frio no ConnectMQ
A telemetria de frotas precisa de um broker acessível a partir de qualquer rede celular, protegido com TLS e mantido 24 horas por dia. O ConnectMQ oferece um broker MQTT gerenciado com MQTT 5, TLS, credenciais geradas e um explorador de topics ao vivo para ver cada caminhão reportando. Comece com um broker Serverless gratuito em app.connectmq.com, sem cartão de crédito, e escale para um plano pago ou dedicado conforme a frota cresce. Para contexto sobre hospedagem, leia sobre a abordagem de broker MQTT na nuvem.
Perguntas frequentes
Com que frequência um caminhão refrigerado deve reportar a temperatura?
Amostrar a cada um a cinco minutos é o típico. Amostre localmente nessa taxa mesmo offline e envie as leituras armazenadas quando a cobertura voltar.
O que acontece se o caminhão ficar sem sinal?
O gateway armazena as leituras com seus timestamps de medição no armazenamento local e as publica em ordem assim que se conecta, apagando cada uma somente depois que o broker a confirma.
Por que alertar pela duração em vez de uma única leitura alta?
Aberturas de porta e ciclos de degelo causam picos breves que não prejudicam o produto. Um período de tolerância filtra esses picos e ainda detecta as excursões reais.
O ConnectMQ armazena o histórico de temperatura?
Não. O ConnectMQ entrega mensagens em tempo real. Execute um subscriber que grave cada leitura no seu próprio banco de dados para relatórios de viagem e auditorias.



