Automação IoT

Automação de Estufa com MQTT e Node-RED: Ventilação, Aquecimento e Nebulização

Automatize uma estufa com MQTT: sensores publicam dados de clima, um fluxo Node-RED decide quando ventilar, aquecer ou nebulizar usando histerese, e nós de relé atuam com proteções locais.

Montagem de automação de estufa com sensores de temperatura e umidade, exaustor, aquecedor e bicos de nebulização controlados via MQTT
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 automação de estufa mantém a temperatura e a umidade na faixa de que suas plantas precisam, acionando ventiladores, aquecedores e nebulização automaticamente, em vez de depender de alguém para abrir as janelas na hora certa, seja numa estufa de hortaliças ou numa produção de flores no interior paulista. Neste tutorial você vai projetar os tópicos MQTT, escrever um fluxo Node-RED que controla três atuadores com histerese e intertravamentos, adicionar um watchdog para dados desatualizados e tornar os nós de relé seguros por conta própria caso a rede caia.

A arquitetura

O sistema tem três partes que só se comunicam por meio de um broker MQTT:

 Climate sensor (ESP32 + SHT31/BME280)
        |  publishes telemetry every 30 s
        v
   MQTT broker  <---->  Node-RED (decision logic)
        ^                     |
        |  publishes /set     |
        +---------------------+
        |
 Relay node (ESP32 + 3 relays): fan, heater, mister
        publishes /state after acting

Separar sensoriamento, lógica e atuação traz benefícios reais. Você pode trocar o sensor sem mexer na lógica, alterar setpoints pelo celular sem regravar firmware e, mais tarde, adicionar um painel ou um registrador de dados como mais um assinante. Se precisar relembrar o papel dos brokers, leia antes sobre o que faz um broker MQTT.

Projeto de tópicos para automação de estufa

Use o servidor MQTT público (gratuito) durante o desenvolvimento. Substitua g2w6n3 por uma sequência aleatória sua, pois o servidor MQTT público é compartilhado, pode ser lido por qualquer pessoa e serve apenas para testes e protótipos.

Tópico Direção Payload Retido
connectmq/demo/g2w6n3/greenhouse/climate sensor para todos {"temp":27.4,"hum":58.2} sim
connectmq/demo/g2w6n3/greenhouse/setpoints celular/painel para o Node-RED {"heat_on":12,"vent_on":28,"mist_on":45} sim
connectmq/demo/g2w6n3/greenhouse/fan/set Node-RED para o relé ON / OFF não
connectmq/demo/g2w6n3/greenhouse/heater/set Node-RED para o relé ON / OFF não
connectmq/demo/g2w6n3/greenhouse/mister/set Node-RED para o relé ON / OFF não
connectmq/demo/g2w6n3/greenhouse/<actuator>/state relé para todos ON / OFF sim
connectmq/demo/g2w6n3/greenhouse/alarm Node-RED para todos {"type":"stale_sensor"} não

Os setpoints são retidos para que o Node-RED receba os valores atuais logo após reiniciar. Os comandos não são retidos, para que um relé que reinicia não execute de novo uma instrução antiga.

Construindo o fluxo no Node-RED

Crie o fluxo com estes nós. Se você está começando no Node-RED, o tutorial de Node-RED com MQTT cobre o básico da configuração do broker.

Nó Configuração
config mqtt-broker Servidor broker.connectmq.com, porta 1883, client ID nodered-gh-g2w6n3, protocolo MQTT 3.1.1
mqtt in "climate" Tópico connectmq/demo/g2w6n3/greenhouse/climate, saída "a parsed JSON object"
mqtt in "setpoints" Tópico connectmq/demo/g2w6n3/greenhouse/setpoints, saída "a parsed JSON object"
function "climate logic" Código abaixo, 1 saída, ligado aos dois nós mqtt in
mqtt out "actuators" Tópico vazio (vem de msg.topic), QoS 1, retain false
inject "watchdog tick" Repetir a cada 60 segundos
function "watchdog" Código abaixo, ligado ao mesmo mqtt out

A função de lógica de clima

const BASE = "connectmq/demo/g2w6n3/greenhouse";

// Valores padrão, substituídos pela mensagem retida de setpoints
const sp = flow.get("sp") || { heat_on: 12, heat_off: 14, vent_on: 28, vent_off: 25, mist_on: 45, mist_off: 55, mist_max_temp: 35 };

if (msg.topic.endsWith("/setpoints")) {
    const p = msg.payload || {};
    if (p.heat_on !== undefined) { sp.heat_on = p.heat_on; sp.heat_off = p.heat_on + 2; }
    if (p.vent_on !== undefined) { sp.vent_on = p.vent_on; sp.vent_off = p.vent_on - 3; }
    if (p.mist_on !== undefined) { sp.mist_on = p.mist_on; sp.mist_off = p.mist_on + 10; }
    flow.set("sp", sp);
    node.status({ fill: "blue", shape: "ring", text: "setpoints " + JSON.stringify(p) });
    return null;
}

const t = Number(msg.payload.temp);
const h = Number(msg.payload.hum);
if (!Number.isFinite(t) || !Number.isFinite(h) || t < -20 || t > 60 || h < 0 || h > 100) {
    node.warn("Implausible reading ignored: " + JSON.stringify(msg.payload));
    return null;
}
flow.set("lastSeen", Date.now());

const st = flow.get("state") || { fan: "OFF", heater: "OFF", mister: "OFF" };
const next = Object.assign({}, st);

// Aquecimento com histerese
if (t <= sp.heat_on) next.heater = "ON";
else if (t >= sp.heat_off) next.heater = "OFF";

// Ventilação com histerese
if (t >= sp.vent_on) next.fan = "ON";
else if (t <= sp.vent_off) next.fan = "OFF";

// Nebulização só quando estiver quente o bastante para evaporar, sem resfriar demais a cultura
if (h <= sp.mist_on && t > 18 && t < sp.mist_max_temp) next.mister = "ON";
else if (h >= sp.mist_off || t <= 18) next.mister = "OFF";

// Intertravamentos: nunca aquecer e ventilar juntos, nunca nebulizar enquanto aquece
if (next.heater === "ON") { next.fan = "OFF"; next.mister = "OFF"; }

flow.set("state", next);

const out = [];
for (const a of ["fan", "heater", "mister"]) {
    if (next[a] !== st[a] || msg.forceSend) {
        out.push({ topic: `${BASE}/${a}/set`, payload: next[a] });
    }
}
node.status({ fill: "green", shape: "dot", text: `${t}°C ${h}% F:${next.fan} H:${next.heater} M:${next.mister}` });
return [out];

Retornar [out] envia cada mensagem do array, uma após a outra, pela única saída até o nó mqtt out. Os comandos só são enviados quando um estado muda, o que mantém o tráfego baixo e os logs do relé legíveis.

A função de watchdog

const BASE = "connectmq/demo/g2w6n3/greenhouse";
const last = flow.get("lastSeen") || 0;
const ageMin = (Date.now() - last) / 60000;

if (last && ageMin > 5 && !flow.get("staleAlarm")) {
    flow.set("staleAlarm", true);
    flow.set("state", { fan: "OFF", heater: "OFF", mister: "OFF" });
    return [[
        { topic: `${BASE}/heater/set`, payload: "OFF" },
        { topic: `${BASE}/mister/set`, payload: "OFF" },
        { topic: `${BASE}/alarm`, payload: JSON.stringify({ type: "stale_sensor", minutes: Math.round(ageMin) }) }
    ]];
}
if (ageMin <= 5) flow.set("staleAlarm", false);
return null;

Se o sensor parar de enviar dados, o watchdog desliga o aquecedor e a nebulização, porque agir com dados antigos é pior do que não fazer nada. O ventilador não é alterado; sem dados, quem decide é a proteção do próprio relé (veja abaixo).

Testando o fluxo

Simule uma tarde quente e seca e, em seguida, uma noite fria:

mosquitto_pub -h broker.connectmq.com -p 1883 -i sim-g2w6n3 -r \
  -t 'connectmq/demo/g2w6n3/greenhouse/climate' -m '{"temp":30.2,"hum":40}'

mosquitto_pub -h broker.connectmq.com -p 1883 -i sim-g2w6n3 -r \
  -t 'connectmq/demo/g2w6n3/greenhouse/climate' -m '{"temp":10.5,"hum":80}'

mosquitto_sub -h broker.connectmq.com -p 1883 -i mon-g2w6n3 \
  -t 'connectmq/demo/g2w6n3/greenhouse/+/set' -v

A primeira mensagem deve ligar o ventilador e a nebulização; a segunda deve desligar os dois e ligar o aquecedor. Altere os setpoints ao vivo publicando {"vent_on":26} no tópico de setpoints.

Tornando o nó de relé seguro por conta própria

O Node-RED decide, mas o nó de relé nunca deve confiar cegamente na rede. Incorpore estas regras ao firmware:

  1. Tempo máximo de funcionamento por atuador. A nebulização se desliga sozinha depois de, digamos, cinco minutos, mesmo que nenhum OFF chegue. Uma válvula travada pode encharcar a cultura.
  2. Corte local por sobretemperatura. Se o nó de relé tiver sua própria sonda de temperatura, ele desliga o aquecedor acima de um limite rígido, independentemente dos comandos.
  3. Estado seguro na desconexão. Quando o MQTT cair por mais de um minuto, aquecedor e nebulização são desligados. Decida se o ventilador deve ligar ou desligar de acordo com o seu clima; em regiões quentes, ventilar costuma ser o padrão mais seguro.
  4. Publicar o estado após agir. Os tópicos /state mostram o que de fato aconteceu, o que permite ao Node-RED e aos painéis detectar um relé que ignora comandos.
  5. Last will. Conecte com uma mensagem will offline retida em um tópico de status, para que um relé ausente fique visível imediatamente.

Para a ligação dos relés e um sketch de ESP32 que assina tópicos de comando, veja o tutorial de relé com ESP32 e MQTT. Aquecedores e ventiladores ligados à rede elétrica devem ser acionados por contatores devidamente dimensionados e instalados por um profissional qualificado.

Dicas de ajuste

  • Faixas de histerese de 2 a 3 °C evitam ciclos curtos, que desgastam relés e motores.
  • A posição do sensor importa mais do que a sua precisão: proteja o sensor do sol direto, instale-o na altura das plantas e garanta circulação de ar.
  • Setpoints de dia e de noite são fáceis de adicionar: um nó inject no nascer e no pôr do sol pode publicar novos setpoints retidos.
  • Registre tudo. Um fluxo Node-RED ou uma instância do Telegraf assinando greenhouse/# fornece o histórico para ajustar os setpoints ao longo de uma safra.

Para uma visão mais ampla de sensores, conectividade e projeto de tópicos em uma fazenda inteira, leia o guia de agricultura inteligente com IoT e combine esta estufa com o sistema de irrigação automática para a rega.

Acompanhando a estufa remotamente

A automação só é confiável se você consegue ver o que ela está fazendo. Três visões atendem à maioria das necessidades. Uma página do Node-RED Dashboard com medidores de temperatura e umidade, interruptores que mostram os tópicos /state dos atuadores e controles deslizantes que publicam novos setpoints oferece aos produtores um painel de controle simples no celular. Um historiador, como o Telegraf gravando no InfluxDB, permite comparar as noites desta semana com as da semana passada e identificar um aquecedor que funciona mais tempo do que antes. E uma visualização de tópicos ao vivo no lado do broker mostra cada mensagem de comando e de estado no momento em que acontece. Juntos, estado ao vivo e histórico formam a base de um gêmeo digital simples da estufa.

Quando o broker é a ConnectMQ, o explorador de tópicos ao vivo e o painel do portal oferecem essa última visão sem instalar nada, e o cliente MQTT no navegador é útil para publicar um setpoint de teste a partir de um notebook dentro da estufa. Seja qual for a ferramenta, compare /set com /state regularmente: um comando que nunca é confirmado indica um relé com defeito, um fio solto ou um nó que perdeu o Wi-Fi.

Indo para produção

Quando a lógica estiver funcionando, saia do servidor MQTT público. Crie um broker privado, mude o nó mqtt-broker para a porta 8883 com TLS habilitado e informe o usuário, a senha e o client ID emitidos. Cada dispositivo recebe suas próprias credenciais. Um broker MQTT gerenciado mantém o broker no ar mesmo quando o PC da estufa não está, e permite verificar o clima de qualquer lugar. O guia de automação IoT mostra como esse padrão se estende a casas e edifícios.

Rode sua estufa na ConnectMQ

A ConnectMQ oferece à sua estufa um broker MQTT gerenciado e privado com TLS, um explorador de tópicos ao vivo para acompanhar comandos e estados, e regras de alerta por limite como alarme de reserva para geada ou superaquecimento. Crie um broker Serverless gratuito em app.connectmq.com, sem cartão de crédito, e aponte para ele o Node-RED e seus nós ESP32.

Perguntas frequentes

A automação de estufa funciona sem internet?

Sim, se o broker e o Node-RED estiverem na rede local. Com um broker na nuvem você ganha acesso remoto; por isso, coloque as proteções críticas no firmware do relé para que a estufa continue segura durante uma queda.

Qual sensor de temperatura é o melhor para estufa?

Um SHT31 ou SHT4x lida melhor com umidade alta do que um DHT22. Seja qual for a escolha, proteja-o do sol direto com um abrigo de radiação ventilado.

Por que meu ventilador liga e desliga o tempo todo?

A diferença entre os limites de ligar e desligar é pequena demais, ou o sensor está no fluxo de ar do ventilador. Aumente a histerese e mude o sensor de lugar.

O Node-RED ou o ESP32 deve tomar as decisões de controle?

Use o Node-RED para a lógica flexível e os setpoints, e mantenha limites de segurança simples no ESP32 para que os atuadores entrem em estado seguro se a conexão cair.

Artigos relacionados

Guia de Configuração do Zigbee2MQTT: do Coordenador ao Painel

Instale o Zigbee2MQTT com Docker, configure o coordenador e a conexão MQTT, pareie e renomeie dispositivos, controle-os via MQTT e veja seus estados em um painel, testando primeiro no servidor MQTT público (gratuito).

8 min de leitura

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.