Integrar um carregador de veículo elétrico via MQTT permite que o seu wallbox participe do restante do sistema de energia da casa, por exemplo em uma residência com geração solar distribuída: carregar quando o sol brilha, pausar quando o forno e a bomba de calor estão ligados e mostrar seu status no mesmo painel que todo o resto. Este guia explica como OCPP e MQTT diferem, as três formas práticas de colocar um carregador no MQTT, um projeto de tópicos organizado e um controlador funcional de excedente solar em Python. Ao final, você saberá qual caminho combina com o seu carregador e como construir sobre ele com segurança.
OCPP e MQTT resolvem problemas diferentes
Muita gente pergunta se um carregador deve usar OCPP ou MQTT. Na prática, eles atendem relações diferentes, e uma boa instalação residencial frequentemente usa os dois.
OCPP (Open Charge Point Protocol) é a linguagem padrão entre um carregador e um Charging Station Management System (CSMS), o back-office que cuida de autorização, sessões e cobrança. O OCPP 1.6J e o 2.0.1 trafegam mensagens JSON sobre um WebSocket que o carregador abre até o CSMS. As mensagens incluem BootNotification, StatusNotification, MeterValues, início e fim de transação e SetChargingProfile para recarga inteligente. Cada carregador se conecta a um CSMS por vez.
MQTT é um protocolo publish/subscribe de uso geral. Um carregador ou uma bridge publica seu estado em um broker, e qualquer número de consumidores (painel, Home Assistant, gerenciador de energia, app de celular) assina sem que o carregador precise saber deles. Se o padrão é novo para você, a explicação sobre o que faz um broker MQTT cobre o básico.
| Aspecto | OCPP | MQTT |
|---|---|---|
| Finalidade | Carregador para back-office: sessões, autorização, cobrança, recarga inteligente | Qualquer dispositivo para qualquer número de consumidores |
| Transporte | WebSocket, o carregador se conecta a um CSMS | TCP ou WebSocket até um broker, muitos assinantes |
| Esquema de mensagens | Definido rigidamente por versão do OCPP | Você projeta tópicos e payloads |
| Usuário típico | Operadores de pontos de recarga, frotas, recarga no trabalho | Automação residencial, gestão de energia, painéis |
| Controle | Início/parada remotos, perfis de recarga | O que o dispositivo ou a bridge expuser |
| Múltiplos consumidores | Não, um CSMS por conexão | Sim, nativamente |
Se você opera carregadores públicos ou corporativos, OCPP até um CSMS é o núcleo certo. Se quer que um carregador residencial coopere com painéis solares, baterias e cargas da casa, o MQTT é a camada de integração prática, às vezes alimentada por OCPP nos bastidores.
Três formas de colocar um carregador de veículo elétrico no MQTT
1. MQTT nativo no carregador. Alguns carregadores, especialmente modelos de hardware aberto e voltados a entusiastas, publicam status e aceitam comandos diretamente via MQTT. Você informa host, porta e credenciais do broker na interface web do carregador. É o caminho mais simples quando disponível, mas os nomes de tópicos e os payloads variam de fabricante para fabricante.
2. Um servidor OCPP local que faz bridge para o MQTT. Muitos wallboxes comerciais falam apenas OCPP (além da nuvem do fabricante). Aponte a URL OCPP do carregador para um servidor OCPP local, por exemplo a integração OCPP do Home Assistant ou um CSMS de código aberto, e deixe esse servidor republicar status e medições em MQTT. Você mantém a semântica padrão do OCPP e ganha MQTT para todo o resto. A contrapartida é que os recursos da nuvem do fabricante podem deixar de funcionar enquanto o carregador conversa com o seu servidor.
3. Um gerenciador de energia no meio. Gerenciadores de energia de código aberto, como o evcc, conversam com muitos carregadores por seus protocolos nativos e publicam seu próprio estado em MQTT, incluindo potência da rede, potência fotovoltaica e potência de recarga por ponto de carga, além de aceitar mudanças de modo por tópicos MQTT. Esse costuma ser o caminho mais rápido para a recarga guiada pela energia solar, porque a lógica de controle já está pronta e testada.
Seja qual for o caminho, busque o mesmo resultado no broker: uma árvore de tópicos estável, que não muda se você trocar o carregador.
Projetando a árvore de tópicos MQTT do carregador
Separe estado de comandos, retenha o estado e nunca retenha comandos:
home/ev/charger1/state retained {"status":"charging","power_w":7210,"current_a":10.4,"phases":3,"session_kwh":12.8}
home/ev/charger1/status retained online / offline (Last Will)
home/ev/charger1/set/current_a command 6..16
home/ev/charger1/set/enabled command true / false
home/energy/grid/telemetry retained {"net_w": -2350, ...}
Use valores de status no estilo OCPP (available, preparing, charging, suspended_ev, suspended_evse, finishing, faulted) mesmo quando a origem não for OCPP. Eles são bem conhecidos e distinguem "o carro está cheio" (suspended_ev) de "o carregador pausou" (suspended_evse), o que importa para as automações.
Reter um comando como set/current_a é um erro clássico: depois de uma queda de energia, o carregador ou a bridge se reconecta e executa de novo um valor antigo. Os comandos não devem ser retidos; a bridge publica o valor efetivo de volta no tópico de estado retido.
Um controlador de excedente solar em Python
O controlador abaixo assina o net_w do medidor da rede (negativo significa exportação, como publicado no tutorial de monitor de energia residencial) e o estado do carregador, e publica uma corrente de recarga que acompanha o excedente. Ele funciona com qualquer carregador ou bridge que aceite um setpoint de corrente em um tópico. Teste-o no servidor MQTT público com mensagens simuladas antes de conectar qualquer equipamento real.
pip install "paho-mqtt>=2.0"
import json
import time
import paho.mqtt.client as mqtt
PREFIX = "connectmq/demo/ev7k2" # use seu próprio prefixo aleatório durante os testes
GRID_TOPIC = f"{PREFIX}/energy/grid/telemetry"
STATE_TOPIC = f"{PREFIX}/ev/charger1/state"
SET_CURRENT = f"{PREFIX}/ev/charger1/set/current_a"
SET_ENABLED = f"{PREFIX}/ev/charger1/set/enabled"
VOLTAGE = 230
PHASES = 1 # defina 3 para um carregador trifásico
MIN_A, MAX_A = 6, 16 # 6 A é a menor corrente na sinalização IEC 61851
START_MARGIN_W = 300 # exportação extra exigida antes de iniciar
UPDATE_EVERY = 30 # segundos entre mudanças de setpoint
STOP_AFTER = 300 # segundos abaixo do mínimo antes de pausar
state = {"net_w": None, "charger_current_a": 0.0, "status": "unknown"}
current_set = 0
below_since = None
last_update = 0.0
def on_connect(client, userdata, flags, reason_code, properties):
print("Connected:", reason_code)
client.subscribe(GRID_TOPIC, qos=1)
client.subscribe(STATE_TOPIC, qos=1)
def on_message(client, userdata, msg):
data = json.loads(msg.payload)
if msg.topic == GRID_TOPIC:
state["net_w"] = data.get("net_w")
elif msg.topic == STATE_TOPIC:
state["charger_current_a"] = data.get("current_a", 0.0)
state["status"] = data.get("status", "unknown")
def control(client):
global current_set, below_since, last_update
if state["net_w"] is None or state["status"] in ("available", "faulted", "unknown"):
return
if time.time() - last_update < UPDATE_EVERY:
return
charger_w = state["charger_current_a"] * VOLTAGE * PHASES
surplus_w = charger_w - state["net_w"] # o que poderíamos usar sem importar da rede
if current_set == 0:
surplus_w -= START_MARGIN_W
target = int(surplus_w // (VOLTAGE * PHASES))
if target >= MIN_A:
below_since = None
target = min(target, MAX_A)
if current_set == 0:
client.publish(SET_ENABLED, "true", qos=1)
if target != current_set:
client.publish(SET_CURRENT, str(target), qos=1)
print(f"surplus {surplus_w:.0f} W -> {target} A")
current_set = target
elif current_set > 0:
below_since = below_since or time.time()
if time.time() - below_since > STOP_AFTER:
client.publish(SET_ENABLED, "false", qos=1)
print("Not enough surplus, pausing")
current_set = 0
elif current_set != MIN_A:
client.publish(SET_CURRENT, str(MIN_A), qos=1)
current_set = MIN_A
last_update = time.time()
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="ev-surplus-6619")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_start()
while True:
control(client)
time.sleep(1)
Simule uma tarde ensolarada em outro terminal e veja o controlador reagir:
mosquitto_pub -h broker.connectmq.com -p 1883 -i ev-sim-1 -t "connectmq/demo/ev7k2/ev/charger1/state" -m '{"status":"suspended_evse","current_a":0}'
mosquitto_pub -h broker.connectmq.com -p 1883 -i ev-sim-2 -t "connectmq/demo/ev7k2/energy/grid/telemetry" -m '{"net_w":-2600}'
Com 2.600 W de exportação em uma única fase, o controlador começa em 10 A depois de descontar a margem de partida.
Regras de projeto para controlar o carregador com segurança
O hardware de recarga lida com correntes altas por horas, então seja conservador:
- Deixe o carregador impor seus próprios limites. Seu controlador apenas solicita um setpoint; o máximo configurado no carregador e as proteções da instalação devem continuar sendo a autoridade final.
- Mude os setpoints devagar. Mudanças frequentes de corrente e ciclos de liga/desliga castigam os contatores e alguns veículos. Um intervalo de atualização de 30 segundos e um atraso de parada de 5 minutos são bons pontos de partida.
- Respeite o mínimo de 6 A. Abaixo disso, pause a recarga em vez de solicitar uma corrente inválida.
- Trate a troca de fases com cuidado. Alternar entre monofásico e trifásico exige suporte do carregador e nunca deve acontecer com corrente fluindo.
- Falhe com segurança. Se o medidor da rede parar de enviar dados, pare de ajustar e volte para um estado fixo ou pausado. Use o status retido do Last Will do medidor para detectar isso.
- Nunca controle carregadores por um servidor MQTT público. Qualquer pessoa poderia publicar no seu tópico de comando. A área pública serve apenas para simulação.
Migrando para um broker privado
Quando a simulação se comportar bem, conecte o carregador real ou a bridge e o controlador a um broker privado com TLS e credenciais por cliente. Um broker MQTT gerenciado como a ConnectMQ mantém esse broker no ar sem um servidor para administrar e, como o carregador, o leitor do medidor e o controlador só fazem conexões de saída, nada precisa ser exposto no seu roteador. No portal da ConnectMQ, crie um broker, emita credenciais para cada cliente e conecte na porta 8883:
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="YOUR_CLIENT_ID")
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set()
client.connect("broker.connectmq.com", 8883, keepalive=60)
Em seguida, traga os dados de produção do monitoramento de inversor solar e de armazenamento do monitoramento de bateria residencial para decidir se o carro ou a bateria fica com o excedente primeiro. Com todos esses fluxos no mesmo broker, você tem a base para um gêmeo digital simples da instalação de energia. O guia de automação IoT mostra como esses fluxos de energia se encaixam em uma instalação residencial mais ampla, e o guia de broker MQTT na nuvem ajuda você a escolher onde hospedá-lo.
Conecte seu carregador à ConnectMQ
A ConnectMQ oferece à bridge do seu carregador, ao gerenciador de energia e aos painéis um broker privado com TLS, acesso via WebSocket para apps no navegador e um explorador de tópicos ao vivo para verificar cada mudança de estado. Crie um broker Serverless gratuito em app.connectmq.com, sem cartão de crédito.
Perguntas frequentes
Meu carregador residencial deve usar OCPP ou MQTT?
Use o que o carregador suporta nativamente para a conexão principal e use o MQTT como camada de integração para a automação residencial. Muitas instalações rodam OCPP até um servidor local e republicam em MQTT.
Posso usar OCPP e a nuvem do fabricante ao mesmo tempo?
Normalmente não, porque um carregador se conecta a um único backend OCPP. Apontá-lo para o seu próprio servidor costuma substituir o backend do fabricante, então verifique quais recursos você perderia.
Qual é a corrente mínima de recarga?
A sinalização de control pilot IEC 61851, usada pelos carregadores AC, tem mínimo de 6 A. Abaixo disso, o controlador deve pausar a recarga em vez de reduzir ainda mais a corrente.
Com que rapidez um controlador de excedente deve reagir?
A cada 30 a 60 segundos é um padrão sensato. Reações mais rápidas basicamente perseguem nuvens passageiras e causam acionamentos desnecessários.



