Tutoriais

Guia de configuração MQTT no ESPHome: discovery, birth/will e brokers externos

Configure o componente mqtt: do ESPHome: broker e credenciais, topic_prefix, discovery do Home Assistant, mensagens birth e will, TLS, on_message e testes.

Atualizado · 9 min de leitura

Guia de configuração MQTT no ESPHome: discovery, birth/will e brokers externos

O ESPHome fala MQTT com um único bloco de YAML. Adicione mqtt: com o endereço de um broker e cada sensor, switch e luz do dispositivo passa a publicar seu estado e aceitar comandos em topics previsíveis, sem escrever C++. Funciona com o Home Assistant via MQTT discovery, e funciona igualmente bem sem Home Assistant, alimentando Node-RED, Grafana ou o seu próprio backend a partir de qualquer broker.

Este guia cobre uma configuração completa com um broker externo, a estrutura de topics que o ESPHome gera, discovery, mensagens birth e will, TLS, assinaturas personalizadas e como verificar cada parte pelo navegador.

Uma configuração mínima que funciona

livingroom.yaml
esphome:
  name: livingroom

esp32:
  board: esp32dev
  framework:
    type: esp-idf

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

logger:

ota:
  - platform: esphome
    password: !secret ota_password

mqtt:
  broker: broker.connectmq.com
  port: 1883
  username: !secret mqtt_user
  password: !secret mqtt_password
  client_id: esphome-livingroom
  topic_prefix: testmqtt/esphome/livingroom
  discovery: false

sensor:
  - platform: wifi_signal
    name: "WiFi Signal"
    update_interval: 30s
  - platform: uptime
    name: "Uptime"

switch:
  - platform: gpio
    pin: GPIO2
    name: "Relay"
    id: relay
secrets.yaml
wifi_ssid: "your-ssid"
wifi_password: "your-wifi-password"
ota_password: "change-me"
mqtt_user: "username"
mqtt_password: "password"

Grave com esphome run livingroom.yaml. No log você deve ver Connecting to MQTT... seguido de MQTT Connected!.

Três configurações valem ser definidas explicitamente em vez de confiar nos padrões:

  • topic_prefix usa por padrão o nome do nó (livingroom). Em um broker compartilhado, isso colide com a sala de estar de todo mundo. Um prefixo único como testmqtt/esphome/livingroom mantém seus topics só seus.
  • client_id precisa ser único por dispositivo. Dois dispositivos com o mesmo ID se desconectam em loop. Se você omitir, o ESPHome gera um a partir do nome e do MAC, o que é ótimo; só nunca copie um ID fixo entre arquivos YAML.
  • discovery: false enquanto testa em um broker público ou compartilhado, para não publicar mensagens de configuração do Home Assistant em um namespace que outras pessoas leem. Ative quando usar o seu próprio broker.

Os topics que o ESPHome gera

Cada entidade ganha um topic de estado, e as entidades controláveis um topic de comando. O object ID é o nome da entidade em minúsculas, com espaços trocados por underscores:

EntidadeTopicDireção
Disponibilidadetestmqtt/esphome/livingroom/statusdispositivo → broker (online / offline)
Sensor WiFi Signaltestmqtt/esphome/livingroom/sensor/wifi_signal/statedispositivo → broker
Sensor Uptimetestmqtt/esphome/livingroom/sensor/uptime/statedispositivo → broker
Estado do switch Relaytestmqtt/esphome/livingroom/switch/relay/statedispositivo → broker (ON / OFF)
Comando do switch Relaytestmqtt/esphome/livingroom/switch/relay/commandbroker → dispositivo (ON / OFF / TOGGLE)
Logstestmqtt/esphome/livingroom/debugdispositivo → broker

Sobrescreva qualquer um deles por entidade com state_topic: e command_topic: quando precisar se encaixar em um design de topics existente. A opção log_topic: controla o topic de debug; defina como null para parar de publicar logs via MQTT, economizando banda em dispositivos movimentados.

Mensagens birth, will e shutdown

O ESPHome envia uma mensagem birth depois de conectar e registra um Last Will no broker. Por padrão as duas vão para <topic_prefix>/status, retained, com os payloads online e offline. É isso que o Home Assistant usa para a disponibilidade das entidades. Você pode personalizá-las:

Custom availability
mqtt:
  # ...
  birth_message:
    topic: testmqtt/esphome/livingroom/availability
    payload: "connected"
    retain: true
  will_message:
    topic: testmqtt/esphome/livingroom/availability
    payload: "lost"
    retain: true
  shutdown_message:
    topic: testmqtt/esphome/livingroom/availability
    payload: "shutdown"
    retain: true
  keepalive: 30s

O will é publicado pelo broker, não pelo dispositivo, cerca de 1,5 × keepalive depois que o dispositivo silencia. A mensagem shutdown é enviada pelo próprio dispositivo antes de um reboot planejado ou de uma atualização OTA, para você distinguir "reiniciando de propósito" de "ficou sem energia". Os tempos estão explicados em MQTT Last Will, e o flag retained em mensagens retidas.

Discovery do Home Assistant

Com discovery: true (o padrão), o ESPHome publica uma mensagem de configuração retained por entidade em <discovery_prefix>/<component>/<node>/<object_id>/config. A integração MQTT do Home Assistant assina esse prefixo e cria as entidades automaticamente.

Discovery on your own broker
mqtt:
  broker: broker.connectmq.com
  port: 1883
  username: !secret mqtt_user
  password: !secret mqtt_password
  discovery: true
  discovery_prefix: homeassistant
  discovery_retain: true

O que você precisa saber:

  • O prefixo precisa bater. O Home Assistant escuta em homeassistant, a menos que você tenha mudado nas opções da integração MQTT. Se mudar um, mude os dois.
  • Mensagens de discovery são retained. Se você renomear ou apagar uma entidade, a configuração antiga continua no broker. Limpe-a publicando uma mensagem retained vazia no topic de configuração antigo.
  • Um único broker para os dois. O Home Assistant precisa se conectar ao mesmo broker que o dispositivo. Para o lado do Home Assistant, leia Home Assistant MQTT.

Assinando e publicando a partir do YAML

O ESPHome pode reagir a qualquer topic, não só aos próprios topics de comando, e publicar mensagens arbitrárias:

Custom subscriptions and publishes
mqtt:
  # ...
  on_message:
    - topic: testmqtt/esphome/livingroom/cmd/toggle
      qos: 1
      then:
        - switch.toggle: relay
  on_json_message:
    topic: testmqtt/esphome/livingroom/cmd/json
    then:
      - if:
          condition:
            lambda: 'return x["relay"] == "on";'
          then:
            - switch.turn_on: relay
          else:
            - switch.turn_off: relay

interval:
  - interval: 60s
    then:
      - mqtt.publish:
          topic: testmqtt/esphome/livingroom/heartbeat
          payload: "alive"
          qos: 0
          retain: false

on_json_message faz o parse do payload com ArduinoJson e o expõe como x. Mantenha os payloads pequenos: mensagens muito grandes podem exceder o buffer do cliente em placas com pouca memória.

Usando TLS com um broker externo

No ESP32, adicione o certificado da CA do broker e mude para a porta 8883:

TLS on ESP32
mqtt:
  broker: broker.connectmq.com
  port: 8883
  username: !secret mqtt_user
  password: !secret mqtt_password
  certificate_authority: |
    -----BEGIN CERTIFICATE-----
    ... root CA of your broker's certificate chain ...
    -----END CERTIFICATE-----

Use a CA raiz da cadeia apresentada pelo broker, não o certificado do servidor. O framework ESP-IDF é a escolha recomendada para MQTT sobre TLS no ESP32. O suporte no ESP8266 é bem mais limitado (apenas fingerprints com o framework Arduino), então para dispositivos em que TLS é crítico escolha um ESP32, ou mantenha os ESP8266 em uma rede local confiável. Nosso guia de TLS no ESP32 explica como extrair o certificado certo com openssl s_client.

Teste cada parte pelo navegador

  1. Abra o cliente MQTT online, conecte em broker.connectmq.com na porta 8084 (path /mqtt) e assine testmqtt/esphome/livingroom/#.
  2. Você deve ver status = online (retained) e os estados de wifi_signal e uptime a cada 30 segundos.
  3. Publique ON em testmqtt/esphome/livingroom/switch/relay/command. O relé comuta e switch/relay/state informa ON.
  4. Publique qualquer coisa em testmqtt/esphome/livingroom/cmd/toggle para exercitar o on_message.
  5. Desligue a placa. Depois de cerca de 1,5 × keepalive, o will coloca status em offline. Se em vez disso você reiniciar pelo dashboard, verá primeiro a mensagem shutdown.

Acompanhe seu nó ESPHome no cliente online

Se uma entidade não aparecer no topic esperado, cole o topic e o seu filtro no topic matcher para encontrar um erro de digitação no prefixo.

Referência rápida de problemas

Mensagem de logCausa provável
MQTT Disconnected: TCP disconnected.Host ou porta errados, firewall, porta TLS usada sem certificate_authority
MQTT Disconnected: Not Authorized.Usuário ou senha errados, ou uma ACL nega o cliente
MQTT Disconnected: Identifier Rejected.Client ID rejeitado ou duplicado
O dispositivo reinicia após 15 minutosreboot_timeout atingido porque o broker está inacessível

Para um diagnóstico passo a passo, leia ESPHome MQTT não conecta.

Configurar o ESPHome para MQTT é principalmente uma questão de nomes: prefixo de topic e client ID únicos, discovery ativado só onde o Home Assistant está e topics de disponibilidade confiáveis. Acerte isso, verifique estado, comandos e will pelo cliente online, e o mesmo YAML vai do broker de testes para a produção trocando um hostname e um secret.

Perguntas frequentes

Posso usar o ESPHome com MQTT e a API nativa ao mesmo tempo?

Sim. Os componentes api: e mqtt: são independentes. Muitas instalações mantêm a API nativa para o Home Assistant e adicionam MQTT para que outros sistemas (Node-RED, um data logger, outra unidade) leiam os mesmos sensores.

Por que meu dispositivo ESPHome reinicia a cada 15 minutos?

O componente mqtt: tem reboot_timeout, de 15 minutos por padrão: se o broker ficar inacessível por esse tempo, o dispositivo reinicia. Corrija a conexão ou defina reboot_timeout: 0s para desativar isso em dispositivos que precisam continuar funcionando offline.

Em quais topics o ESPHome publica?

Por padrão em <topic_prefix>/<component_type>/<object_id>/state, onde topic_prefix é o nome do nó e object_id é o nome da entidade em minúsculas com underscores. Entidades controláveis escutam no mesmo caminho terminando em /command.