Sistemas de estacionamento inteligente IoT mostram aos motoristas onde estão as vagas livres antes que eles comecem a dar voltas, e mostram aos operadores como seus estacionamentos são realmente usados, de um shopping em Campinas ao pátio de caminhões de um centro logístico. Este artigo apresenta um projeto completo: escolha dos sensores de vaga, estruturação dos topics MQTT, agregação das vagas livres por zona e um mapa ao vivo no navegador que se atualiza no instante em que um carro sai.
O Que um Sistema de Estacionamento Inteligente Precisa Fazer
Tirando o marketing, um sistema de guiamento de vagas tem quatro tarefas:
- Detectar se cada vaga está ocupada.
- Transportar essas mudanças de estado de forma confiável do campo até o back-end.
- Agregar vagas individuais em números que importam para as pessoas: vagas livres por andar, por zona, por estacionamento.
- Exibir o resultado em painéis, apps e mapas, quase em tempo real.
O MQTT se encaixa naturalmente nas camadas de transporte e exibição. Cada vaga é um topic de estado retido, os agregadores assinam com wildcards e os navegadores assinam via WebSocket para receber atualizações ao vivo. O restante do artigo acompanha os dados do asfalto até a tela.
Escolhendo os Sensores de Vaga
| Tipo de sensor | Como funciona | Pontos fortes | Cuidados |
|---|---|---|---|
| Magnetômetro (embutido no piso ou disco de superfície) | Detecta a alteração no campo magnético da Terra causada por um carro | Bateria de longa duração, não é afetado por luz ou clima | Interferência de vagas vizinhas, exige calibração |
| Radar (combinado com magnetômetro) | Reflexão de curto alcance na parte inferior do veículo | Menos falsos positivos que o magnetômetro sozinho | Custo e consumo maiores |
| Ultrassônico (montado no teto) | Mede a distância até o teto do carro | Simples, comum em garagens cobertas, muitas vezes com indicador LED | Requer alimentação da rede e instalação em ambiente interno |
| Câmera com modelo de visão | Uma câmera cobre muitas vagas | Baixo custo por vaga, pode ler placas | Regras de privacidade, iluminação, processamento na borda |
Para estacionamentos ao ar livre e vagas na rua, discos magnetômetros ou de radar alimentados por bateria em LoRaWAN ou NB-IoT são a escolha habitual. Garagens cobertas costumam usar sensores ultrassônicos no teto em um barramento cabeado com um gateway local. Sistemas de câmera publicam resultados, não vídeo: o dispositivo de borda faz a detecção e publica apenas occupied ou free por vaga.
Caminhos de Conectividade até o Broker
A forma como os sensores chegam ao broker molda a arquitetura mais do que o tipo de sensor:
- LoRaWAN: os sensores falam com gateways, os gateways encaminham para um network server como o The Things Stack ou o ChirpStack, e o network server, ou um pequeno serviço de bridge, publica os dados decodificados no seu broker. Centenas de vagas viram uma única conexão MQTT. Veja The Things Network com MQTT para a etapa de bridge.
- NB-IoT ou LTE-M: cada sensor pode se conectar diretamente via MQTT ou reportar pela plataforma da operadora, que você então conecta via bridge.
- Barramento cabeado com gateway: um gateway interno consulta os sensores ultrassônicos e publica as mudanças.
- Câmera de borda: um pequeno computador faz a detecção e publica resultados por vaga.
A abordagem com gateway é atraente além do custo. Ela mantém baixo o número de conexões, então até um plano de broker pequeno dá conta de um estacionamento grande, e o estado da vaga continua sendo um topic MQTT limpo quando chega às suas aplicações.
Design de Topics para Estacionamento Inteligente IoT
Uma hierarquia que espelha o layout físico transforma qualquer consulta em um wildcard:
parking/<site>/<level>/<bay>/state retained: {"occupied":true,"ts":1760600000}
parking/<site>/<level>/<bay>/battery retained: 3.41
parking/<site>/<level>/summary retained: {"free":37,"total":120}
parking/<site>/summary retained: {"free":112,"total":420}
parking/<site>/<level>/<bay>/availability retained online/offline (gateway-reported)
parking/central/+/+/statesão todas as vagas do estacionamento central.parking/+/summaryé o número principal de cada local, que é tudo de que um painel municipal precisa.
Reter tanto os estados das vagas quanto os resumos significa que um novo app ou painel mostra os números corretos imediatamente ao se conectar. Inclua um timestamp no payload, porque uma vaga que não reporta há um dia é "desconhecida", não "livre".
Agregando Vagas Livres por Andar
Um agregador assina todos os estados de vaga, mantém-nos em memória e republica os resumos sempre que algo muda. Esta versão em Python usa paho-mqtt 2.x e o servidor MQTT público (gratuito), adequado para testes e protótipos, não para dados de produção:
import json
import time
from collections import defaultdict
import paho.mqtt.client as mqtt
PREFIX = "connectmq/demo/p3v6z8" # seu próprio prefixo aleatório
SITE = "central"
STALE_AFTER = 6 * 3600 # segundos sem reporte = desconhecido
bays = {} # (level, bay) -> {"occupied": bool, "ts": float}
def publish_summaries(client):
now = time.time()
per_level = defaultdict(lambda: {"free": 0, "occupied": 0, "unknown": 0, "total": 0})
for (level, _), s in bays.items():
bucket = per_level[level]
bucket["total"] += 1
if now - s["ts"] > STALE_AFTER:
bucket["unknown"] += 1
elif s["occupied"]:
bucket["occupied"] += 1
else:
bucket["free"] += 1
site = {"free": 0, "occupied": 0, "unknown": 0, "total": 0}
for level, b in per_level.items():
client.publish(f"{PREFIX}/parking/{SITE}/{level}/summary", json.dumps(b), qos=1, retain=True)
for k in site:
site[k] += b[k]
client.publish(f"{PREFIX}/parking/{SITE}/summary", json.dumps(site), qos=1, retain=True)
def on_connect(client, userdata, flags, reason_code, properties):
client.subscribe(f"{PREFIX}/parking/{SITE}/+/+/state", qos=1)
def on_message(client, userdata, msg):
parts = msg.topic.split("/")
level, bay = parts[-3], parts[-2]
try:
data = json.loads(msg.payload)
bays[(level, bay)] = {"occupied": bool(data["occupied"]), "ts": float(data.get("ts", time.time()))}
except (ValueError, KeyError):
return
publish_summaries(client)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="parking-agg-p3v6z8")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_forever()
Simule algumas vagas pelo terminal:
P=connectmq/demo/p3v6z8/parking/central
mosquitto_pub -h broker.connectmq.com -p 1883 -i sim-p3v6z8 -r -q 1 -t $P/l1/b001/state -m "{\"occupied\":true,\"ts\":$(date +%s)}"
mosquitto_pub -h broker.connectmq.com -p 1883 -i sim-p3v6z8 -r -q 1 -t $P/l1/b002/state -m "{\"occupied\":false,\"ts\":$(date +%s)}"
mosquitto_sub -h broker.connectmq.com -p 1883 -i view-p3v6z8 -t "$P/+/summary" -t "$P/summary" -v
Observe que o prefixo de demonstração adiciona níveis: o topic de estado da vaga acima tem oito níveis de profundidade, o máximo permitido pelo broker público. Em um broker privado, você descartaria o prefixo e começaria em parking/.
Em uma implantação grande, publicar todos os resumos a cada mudança é desperdício. Agrupe as atualizações a cada um ou dois segundos e, se um agregador não bastar, as shared subscriptions do MQTT 5 em um plano pago permitem que várias instâncias dividam a carga.
O Mapa de Disponibilidade ao Vivo
O navegador se conecta via WebSocket seguro e assina apenas os resumos, ou os estados das vagas para uma visão detalhada de um andar. Com MQTT.js:
import mqtt from "mqtt";
const PREFIX = "connectmq/demo/p3v6z8/parking/central";
const client = mqtt.connect("wss://broker.connectmq.com:8084/mqtt", {
clientId: "parking-map-" + Math.random().toString(16).slice(2, 8),
protocolVersion: 5,
});
client.on("connect", () => {
client.subscribe(`${PREFIX}/+/summary`, { qos: 1 });
client.subscribe(`${PREFIX}/l1/+/state`, { qos: 0 });
});
client.on("message", (topic, payload) => {
const data = JSON.parse(payload.toString());
const parts = topic.split("/");
if (topic.endsWith("/summary")) {
const level = parts[parts.length - 2];
const el = document.querySelector(`[data-level="${level}"] .free`);
if (el) el.textContent = `${data.free} free of ${data.total}`;
} else {
const bay = parts[parts.length - 2];
const cell = document.querySelector(`[data-bay="${bay}"]`);
if (cell) cell.className = data.occupied ? "bay occupied" : "bay free";
}
});
Em uma biblioteca de mapas como o Leaflet, o mesmo handler recoloriria um marcador por local. Como os resumos são retidos, o mapa desenha a situação atual no instante em que a página carrega. Nosso guia de MQTT sobre WebSocket cobre os detalhes de conexão no navegador e o tratamento de credenciais, o que é importante: uma página web pública nunca deve embutir credenciais capazes de publicar nos topics das vagas.
Checklist de Implantação
- Escolha os sensores por ambiente: discos ao ar livre, ultrassônicos em áreas cobertas, câmeras onde as regras de privacidade permitirem.
- Conecte redes LoRaWAN ou cabeadas por meio de gateways para manter baixo o número de conexões.
- Retenha os estados das vagas e os resumos; inclua timestamps.
- Trate sensores silenciosos como desconhecidos e gere alertas de bateria fraca.
- Nunca entregue credenciais com permissão de publicação a clientes de mapa públicos; sirva os resumos pelo seu próprio back-end.
- Use TLS na porta 8883 para gateways e 8084 para navegadores.
- Registre as mudanças de estado em um banco de dados com um subscriber separado para análises de ocupação.
Armadilhas Comuns em Projetos de Estacionamento
Interferência de vagas vizinhas. Uma van grande pode perturbar o magnetômetro da vaga ao lado. Calibre os sensores após a instalação e prefira unidades combinadas de magnetômetro e radar em layouts apertados.
Ocupação fantasma. Neve, água empoçada ou um objeto metálico caído podem fazer uma vaga parecer ocupada por dias. Sinalize vagas que não mudam de estado por um tempo anormalmente longo e revise-as.
Desvio de relógio. Se os timestamps vêm dos sensores, um relógio desregulado faz dados recentes parecerem antigos. Deixe o gateway ou o network server carimbar as mensagens na chegada.
Excesso de publicação de resumos. Centenas de painéis e apps recebendo um resumo a cada mudança de vaga desperdiçam banda. Limite a taxa dos resumos e publique apenas quando os números realmente mudarem.
Escalando Além de um Único Estacionamento
Quando vários locais publicam sob parking/<site>/..., um painel de guiamento municipal assina parking/+/summary e nada mais. É o mesmo padrão de mensageria usado na arquitetura IoT de cidade inteligente mais ampla, em que estacionamento, iluminação e qualidade do ar compartilham um broker, mas ficam em subárvores separadas, e onde os mesmos resumos podem alimentar um gêmeo digital da cidade. A logística sensível à temperatura usa um padrão de frota semelhante, como descrito em monitoramento da cadeia de frio.
Operar o broker por conta própria significa aplicar patches, gerenciar certificados e monitorar um sistema do qual os motoristas dependem todos os dias. Um broker MQTT gerenciado como o ConnectMQ cuida do TLS, dos endpoints WebSocket e do gerenciamento de conexões, enquanto o explorador de topics ao vivo no portal permite acompanhar a chegada dos estados das vagas. Se você está comparando modelos de hospedagem, nossa visão geral da abordagem de broker MQTT na nuvem ajuda, e o guia de automação IoT reúne projetos relacionados.
Comece Seu Piloto de Estacionamento Inteligente no ConnectMQ
Faça o piloto de um andar com alguns sensores e um gateway, publique no ConnectMQ e coloque o mapa ao vivo em uma tela de teste. Crie um broker Serverless gratuito em app.connectmq.com, sem cartão de crédito, e migre para um plano pago ou dedicado quando o número de vagas crescer.
Perguntas frequentes
Quantas conexões MQTT um sistema de estacionamento inteligente precisa?
Normalmente bem menos do que o número de vagas. Network servers LoRaWAN e gateways internos publicam por muitos sensores em uma única conexão, então o número de conexões cresce com os gateways e apps, não com as vagas.
Qual sensor é melhor para vagas ao ar livre?
Discos magnetômetros alimentados por bateria, de preferência combinados com radar para reduzir leituras falsas, são a escolha comum ao ar livre porque resistem ao clima e duram anos com uma bateria.
Como evito que o mapa público seja usado de forma abusiva?
Faça o proxy dos dados pelo seu próprio back-end, por exemplo um pequeno servidor que assina os resumos e os envia para a página. Nunca embuta em uma página pública credenciais que possam publicar nos topics de vaga ou de resumo.
Posso usar câmeras em vez de sensores de vaga?
Sim. Um dispositivo de borda faz a detecção e publica apenas a ocupação por vaga, nunca vídeo, o que mantém o uso de banda baixo e ajuda no cumprimento das regras de privacidade, como a LGPD quando placas ou imagens identificam pessoas.



