IoT e IA

Eventos MQTT do Frigate Explicados: Topics, Payloads e Alertas Remotos

Saiba o que o Frigate NVR publica via MQTT, como ler o payload de frigate/events e como encaminhar apenas as detecções relevantes para um broker na nuvem e receber notificações remotas.

Diagrama Frigate MQTT com câmeras de segurança, um NVR detectando uma pessoa e uma mensagem de evento seguindo para um broker MQTT na nuvem
Rode isso no seu próprio broker MQTTTenha um broker MQTT privado e gerenciado no plano Free e comece com exemplos de código prontos.
Teste grátis Exemplos de código Sem cartão de crédito

A integração Frigate MQTT é a forma como o Frigate NVR avisa o resto do seu sistema de que viu uma pessoa, um carro ou um cachorro, e é a maneira mais limpa de criar alertas e automações sobre a detecção de objetos local. Neste guia você vai conhecer cada topic que o Frigate publica, o que o payload do evento realmente contém e como encaminhar apenas as detecções importantes da sua rede local para um broker na nuvem, para recebê-las de qualquer lugar.

Como o Frigate usa o MQTT

O Frigate executa a detecção de objetos localmente nos streams das suas câmeras, geralmente com um detector Coral, Hailo, OpenVINO ou GPU. A gravação e a revisão de clipes acontecem na interface web, mas tudo o que é orientado a eventos sai via MQTT. O Frigate é um cliente MQTT: ele se conecta a um broker que você especifica, publica estado e eventos e assina alguns topics de comando para que você possa ligar e desligar remotamente a detecção, a gravação ou os snapshots.

Esse design faz com que o Frigate não se importe com quem consome os dados. Home Assistant, Node-RED, um script Python ou um aplicativo MQTT no celular podem assinar os mesmos topics ao mesmo tempo. Se você é novo no modelo pub/sub, vale entender o que faz um broker MQTT antes de conectar as peças.

Configurando a seção MQTT no Frigate

O bloco mqtt no config.yml do Frigate aponta para um broker. A maioria das instalações roda um contêiner Mosquitto local ao lado do Frigate:

mqtt:
  enabled: true
  host: mosquitto        # nome do contêiner ou IP do broker local
  port: 1883
  topic_prefix: frigate  # todo topic começa com isto
  client_id: frigate     # deve ser único no broker
  user: frigate
  password: "{FRIGATE_MQTT_PASSWORD}"
  stats_interval: 60     # segundos entre mensagens frigate/stats

cameras:
  driveway:
    mqtt:
      enabled: true      # publica snapshots desta câmera
      timestamp: false
      bounding_box: true
      crop: true
      height: 270
      quality: 70

Duas configurações geram a maioria dos pedidos de suporte. Primeiro, o client_id precisa ser único: se duas instâncias do Frigate compartilharem o ID padrão frigate em um mesmo broker, elas vão derrubar uma à outra em loop. Segundo, se você alterar o topic_prefix, toda automação que escuta em frigate/... também precisa mudar.

Referência de topics MQTT do Frigate

Estes são os topics que você mais vai usar, considerando o prefixo padrão frigate:

Topic Payload Use para
frigate/available online / offline Saúde do NVR; o Frigate define isto como seu Last Will
frigate/events JSON com type, before, after Ciclo de vida do objeto rastreado: new, update, end
frigate/reviews Item de revisão em JSON Alertas e detecções agrupados (versões mais novas)
frigate/<camera>/<object> Contagem inteira Quantos objetos desse tipo estão em cena agora
frigate/<camera>/<object>/snapshot Bytes JPEG Melhor snapshot do objeto atual
frigate/<camera>/motion ON / OFF Estado bruto de movimento
frigate/<camera>/detect/set ON / OFF Comando: ativar ou desativar a detecção
frigate/<camera>/detect/state ON / OFF Estado atual da detecção
frigate/stats JSON Velocidade de inferência do detector, CPU, FPS da câmera

Pares set/state semelhantes existem para gravações, snapshots e detecção de movimento. Consulte a documentação oficial de MQTT do Frigate para a sua versão, porque as versões mais recentes adicionam topics como itens de revisão e atualizações de objetos rastreados.

Lendo o payload de frigate/events

Cada objeto rastreado gera uma sequência de mensagens em frigate/events: uma new, várias mensagens update à medida que o objeto se move ou o índice melhora, e uma end quando ele sai. Cada mensagem traz o estado completo do objeto antes e depois da mudança. Um exemplo resumido:

{
  "type": "new",
  "before": { "id": "1729076512.48-ab12cd", "label": "person", "top_score": 0.0 },
  "after": {
    "id": "1729076512.48-ab12cd",
    "camera": "driveway",
    "label": "person",
    "score": 0.82,
    "top_score": 0.84,
    "false_positive": false,
    "start_time": 1729076512.48,
    "end_time": null,
    "current_zones": ["front_path"],
    "entered_zones": ["front_path"],
    "has_snapshot": true,
    "has_clip": false
  }
}

Os campos que importam para alertas:

  1. after.id é estável durante toda a vida do objeto; use-o para eliminar duplicatas.
  2. after.top_score é a melhor confiança vista até o momento, mais confiável do que o score instantâneo.
  3. after.false_positive passa a false quando o Frigate tem confiança de que o objeto é real. Alertar antes disso gera ruído.
  4. after.entered_zones permite alertar apenas quando alguém realmente entra no caminho, e não quando passa na rua.
  5. type: end com end_time preenchido encerra o evento e é o momento certo de buscar o clipe pela API HTTP do Frigate.

Um erro comum é disparar a cada update. Uma pessoa atravessando o quadro pode gerar muitas atualizações, então uma automação ingênua envia uma rajada de notificações para uma única visita.

Por que encaminhar eventos do Frigate para um broker na nuvem

O broker local é perfeito dentro da casa ou da instalação, mas não é acessível pelo seu celular em dados móveis sem abrir portas, e expor o Mosquitto à internet é um problema de segurança. O padrão mais seguro é somente de saída: um pequeno forwarder na mesma rede assina o broker local, filtra os eventos e publica um JSON compacto em um broker MQTT na nuvem. Seu celular, um dashboard remoto ou uma segunda instalação assinam ali. Nada fica escutando no seu roteador doméstico.

O encaminhamento também permite enxugar o payload. Snapshots podem ter dezenas de kilobytes, e o servidor MQTT público (gratuito) em broker.connectmq.com aceita no máximo 64 KB por mensagem, então o forwarder envia apenas metadados e deixa as imagens no servidor Frigate local.

Você poderia apontar o Frigate diretamente para um broker remoto alterando host e port e definindo o client_id como o client ID emitido com suas credenciais, porque o ConnectMQ vincula client IDs às credenciais. Na prática, um filtro no meio é melhor: o Home Assistant continua funcionando localmente se a internet cair, e apenas eventos relevantes saem da rede.

Forwarder em Python: do Frigate local para o ConnectMQ

O script abaixo usa paho-mqtt 2.x. Ele assina o broker local, encaminha uma mensagem quando uma pessoa ou um carro se torna uma detecção confiável e outra quando ela termina, espelha a disponibilidade do Frigate e repassa ao Frigate um comando remoto de ligar/desligar a detecção.

pip install "paho-mqtt>=2.0"
import json
import os
import uuid

import paho.mqtt.client as mqtt

LOCAL_HOST = os.getenv("LOCAL_HOST", "localhost")
LOCAL_USER = os.getenv("LOCAL_USER")
LOCAL_PASS = os.getenv("LOCAL_PASS")

REMOTE_HOST = os.getenv("REMOTE_HOST", "broker.connectmq.com")
REMOTE_PORT = int(os.getenv("REMOTE_PORT", "1883"))
REMOTE_USER = os.getenv("REMOTE_USER")          # não definido para a área pública de testes
REMOTE_PASS = os.getenv("REMOTE_PASS")
REMOTE_CLIENT_ID = os.getenv("REMOTE_CLIENT_ID", f"frigate-fwd-{uuid.uuid4().hex[:8]}")
PREFIX = os.getenv("REMOTE_PREFIX", f"connectmq/demo/{uuid.uuid4().hex[:8]}/frigate")

LABELS = {"person", "car"}
MIN_SCORE = float(os.getenv("MIN_SCORE", "0.75"))
forwarded = set()   # ids de eventos já anunciados

# ---------- cliente remoto (nuvem) ----------
remote = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=REMOTE_CLIENT_ID)
if REMOTE_USER:
    remote.username_pw_set(REMOTE_USER, REMOTE_PASS)
if REMOTE_PORT == 8883:
    remote.tls_set()
remote.will_set(f"{PREFIX}/forwarder/status", "offline", qos=1, retain=True)


def on_remote_connect(client, userdata, flags, reason_code, properties):
    print("remote connected:", reason_code)
    client.publish(f"{PREFIX}/forwarder/status", "online", qos=1, retain=True)
    client.subscribe(f"{PREFIX}/cmd/+/detect", qos=1)


def on_remote_message(client, userdata, msg):
    camera = msg.topic.split("/")[-2]
    value = msg.payload.decode().upper()
    if value in ("ON", "OFF"):
        local.publish(f"frigate/{camera}/detect/set", value)
        print(f"relayed detect {value} to {camera}")


remote.on_connect = on_remote_connect
remote.on_message = on_remote_message

# ---------- cliente local (Frigate) ----------
local = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=f"frigate-fwd-local-{uuid.uuid4().hex[:6]}")
if LOCAL_USER:
    local.username_pw_set(LOCAL_USER, LOCAL_PASS)


def on_local_connect(client, userdata, flags, reason_code, properties):
    print("local connected:", reason_code)
    client.subscribe([("frigate/events", 0), ("frigate/available", 0)])


def on_local_message(client, userdata, msg):
    if msg.topic == "frigate/available":
        remote.publish(f"{PREFIX}/nvr/status", msg.payload, qos=1, retain=True)
        return

    event = json.loads(msg.payload)
    after = event["after"]
    if after["label"] not in LABELS or after.get("false_positive", True):
        return

    event_id = after["id"]
    if event["type"] in ("new", "update"):
        if event_id in forwarded or after["top_score"] < MIN_SCORE:
            return
        forwarded.add(event_id)
        state = "started"
    elif event["type"] == "end":
        if event_id not in forwarded:
            return
        forwarded.discard(event_id)
        state = "ended"
    else:
        return

    summary = {
        "id": event_id,
        "camera": after["camera"],
        "label": after["label"],
        "score": round(after["top_score"], 2),
        "zones": after.get("entered_zones", []),
        "state": state,
        "start": after["start_time"],
        "end": after.get("end_time"),
    }
    topic = f"{PREFIX}/{after['camera']}/{after['label']}/event"
    remote.publish(topic, json.dumps(summary), qos=1)
    print("forwarded", topic, summary["state"], summary["score"])


local.on_connect = on_local_connect
local.on_message = on_local_message

remote.connect(REMOTE_HOST, REMOTE_PORT, keepalive=60)
remote.loop_start()
local.connect(LOCAL_HOST, 1883, keepalive=60)
print("forwarding to", PREFIX)
local.loop_forever()

Execute-o no host do Frigate e depois acompanhe o lado remoto de qualquer máquina. Use o prefixo que o script imprimiu:

mosquitto_sub -h broker.connectmq.com -p 1883 -i watcher-7f3a2c \
  -t 'connectmq/demo/<your-id>/frigate/#' -v

Passe na frente de uma câmera e você deverá ver exatamente duas mensagens por visita: started e ended. Para testar o caminho de comando, publique OFF em connectmq/demo/<your-id>/frigate/cmd/driveway/detect.

O servidor MQTT público pode ser lido por qualquer pessoa que adivinhe o topic, então trate-o apenas como sandbox para testes e protótipos, nunca para dados de produção. Para uma casa ou instalação real, como um galpão logístico ou a sede de uma fazenda, crie um broker privado e defina REMOTE_PORT=8883 e os valores de REMOTE_USER, REMOTE_PASS e REMOTE_CLIENT_ID obtidos no portal. Não rode o repasse de comandos em um topic público.

Recebendo alertas no celular

Como o broker na nuvem fala MQTT puro, qualquer coisa capaz de assinar pode alertar você: um aplicativo cliente MQTT no celular, um fluxo Node-RED que envia uma mensagem push por um serviço de notificação de sua escolha ou uma instância remota do Home Assistant. Se você criar um dashboard no navegador, conecte-se via WebSocket seguro na porta 8084 com o caminho /mqtt. No portal do ConnectMQ, o explorador de topics em tempo real mostra a chegada dos eventos encaminhados, o que é útil enquanto você ajusta MIN_SCORE e as zonas.

Solução de problemas do Frigate MQTT

  1. O Frigate registra "Unable to connect to MQTT server". Verifique se o host é resolvido dentro do contêiner do Frigate; ali, localhost é o próprio contêiner, e não a máquina host.
  2. A conexão cai a cada poucos segundos. Dois clientes estão usando o mesmo client ID. Dê ao Frigate e a cada forwarder um ID distinto.
  3. Nenhum evento, mas a interface mostra detecções. O objeto pode não estar na lista objects.track da câmera, ou uma configuração required_zones está filtrando-o.
  4. Alertas demais. Alerte com base em top_score e entered_zones, ignore update após o primeiro encaminhamento e adicione cooldowns por câmera, se necessário.
  5. Snapshots rejeitados no broker remoto. Eles excedem o limite de tamanho de mensagem; mantenha as imagens locais e envie links ou metadados.

Para pipelines de detecção mais avançados, veja como funciona a detecção de objetos com YOLO via MQTT ou como construir a detecção de pessoas em uma ESP32-CAM, e consulte o guia de IA e IoT para ter a visão geral.

Receba alertas remotos do Frigate com o ConnectMQ

Um broker privado na nuvem é a peça que faltava entre um NVR local e alertas em que você pode confiar longe de casa. O ConnectMQ é um broker MQTT gerenciado com TLS na porta 8883, credenciais geradas e um explorador de topics para depuração. Comece no plano gratuito Serverless em app.connectmq.com, sem cartão de crédito, e depois aponte o forwarder para o seu novo broker.

Perguntas frequentes

O Frigate precisa de um broker MQTT?

O MQTT é opcional para a gravação e para a interface web, mas a integração com o Home Assistant e todas as automações orientadas a eventos dependem dele. A maioria dos usuários roda o Mosquitto no mesmo host.

Qual a diferença entre frigate/events e frigate/reviews?

frigate/events descreve objetos rastreados individualmente ao longo do seu ciclo de vida. Os itens de revisão agrupam a atividade em alertas e detecções que correspondem ao que você vê na interface de revisão, o que costuma ser melhor para notificações.

Posso enviar snapshots do Frigate para um broker na nuvem?

Somente se couberem no limite de tamanho de mensagem do broker, que é de 64 KB no servidor MQTT público. Enviar metadados e buscar as imagens pela API do Frigate sob demanda costuma ser mais limpo e mais barato.

É seguro expor meu broker Mosquitto local em vez disso?

Não é recomendado. Um forwarder de saída para um broker autenticado com TLS evita abrir portas no seu roteador e mantém o broker local privado.

Artigos relacionados

Todos os artigos →

Seu broker MQTT privado está a poucos cliques de distância

Crie uma conta, receba as credenciais do seu broker e conecte seu primeiro dispositivo — sem servidores para instalar, atualizar ou escalar.