IoT industrial

MQTT para Telemetria em Saneamento de Água e Esgoto

Como empresas de saneamento de água e esgoto usam MQTT para levar estações elevatórias, reservatórios e elevatórias de esgoto a uma única camada de telemetria, com design de topics, report by exception, alertas por limite e um simulador de estação pronto para rodar.

Estação elevatória e reservatório no alto de um morro enviando dados de nível e pressão a um broker na nuvem com ícones de alerta, ilustrando a telemetria MQTT em saneamento
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 telemetria MQTT em saneamento reúne estações elevatórias, reservatórios, boosters e elevatórias de esgoto espalhados em uma única camada de dados ao vivo que operadores, engenheiros e ferramentas de planejamento podem assinar. Este guia mostra como estruturar essa telemetria, quais sinais publicar e de que forma, e como gerar alertas por limite em níveis e pressões antes que um reservatório fique baixo ou um poço úmido transborde. Você também vai rodar um pequeno simulador de estação e um auxiliar de alarmes que pode adaptar a equipamentos reais.

O problema da telemetria em redes de água

Uma empresa de saneamento típica, seja uma companhia estadual ou um serviço municipal como um SAAE, opera de dezenas a centenas de sites remotos espalhados pela sua área de atendimento. Muitos foram conectados ao longo de décadas com RTUs, rádios e protocolos diferentes, e consultados por polling por um mestre SCADA central. Esse arranjo funciona, mas cria problemas conhecidos:

  • Varreduras lentas em rádio compartilhado. Consultar cada site em sequência significa que um alarme de nível pode esperar a próxima varredura.
  • Dados presos no SCADA. As equipes de gestão de ativos, modelagem hidráulica e energia pedem exportações ou constroem interfaces ponto a ponto frágeis.
  • Gerações misturadas de equipamentos. Cada novo tipo de site adiciona mais um driver e mais um mapa de registradores.
  • Sites celulares por toda parte. Os sites mais novos usam modems celulares, que favorecem conexões de saída iniciadas pelo dispositivo, e não polling de entrada.

O MQTT inverte a direção: cada estação publica as próprias mudanças em um broker, e todo consumidor, incluindo o SCADA, o modelo hidráulico ou um gêmeo digital da rede, assina. Se você está planejando o lado SCADA dessa mudança, leia MQTT em sistemas SCADA junto com este guia.

O que publicar em cada site

Parta das perguntas operacionais, não da lista de registradores da RTU. A tabela abaixo é uma base prática para sites de água e esgoto.

Tipo de site Sinal Unidade Regra de publicação Ideia de alerta
Reservatório / tanque Nível m Banda morta de 2 a 5 cm, heartbeat de 15 min Nível baixo e alto
Reservatório / tanque Posição da válvula de entrada % Na mudança de 2 % Válvula travada enquanto o nível cai
Booster ou estação elevatória Pressão de recalque bar Banda morta de 0,05 a 0,1 bar Pressão alta e baixa
Booster ou estação elevatória Vazão m3/h Banda morta de 2 a 5 % da faixa Vazão com bomba parada
Booster ou estação elevatória Status de operação da bomba bool A cada mudança Partidas demais por hora
Elevatória de esgoto Nível do poço úmido m Banda morta de 2 cm, heartbeat mais rápido Nível alto, risco de extravasamento
Todos os sites Energia da rede, intrusão, comunicação bool A cada mudança, retido Qualquer mudança
Pontos de tratamento Cloro residual mg/L Banda morta de 0,02 mg/L Abaixo ou acima da faixa alvo

Duas regras fazem esta tabela funcionar. Publique valores analógicos por exceção com uma banda morta dimensionada pela precisão do instrumento e publique toda mudança de estado imediatamente. O guia de report by exception explica o dimensionamento da banda morta e por que um heartbeat continua necessário.

Projetando topics para uma rede de água

Os topics devem refletir como os operadores pensam a rede: região, site, ativo, medição. Uma hierarquia no espírito do ISA-95 mantém tudo consistente:

waterco/north/reservoir-hilltop/tank1/level
waterco/north/booster-ridge/pump2/running
waterco/north/booster-ridge/discharge/pressure
waterco/south/lift-station-07/wetwell/level
waterco/south/lift-station-07/site/status

Diretrizes que compensam depois:

  • Mantenha os nomes de sites e ativos estáveis e em minúsculas; eles viram identificadores em todo sistema consumidor.
  • Coloque uma medição por topic, ou um pequeno objeto JSON por ativo, e escolha uma única abordagem para toda a empresa.
  • Dê a cada site um topic site/status retido com Last Will, para que uma conexão celular perdida apareça como offline em vez de valores congelados.
  • Não codifique números de registradores da RTU nos topics. Guarde-os em um campo source se os engenheiros precisarem deles.

Quando os nomes de tags do SCADA existente já seguem uma convenção, mapeie-os para a nova hierarquia no gateway em vez de renomear pontos no SCADA. Os operadores mantêm os nomes que conhecem, enquanto cada novo consumidor recebe topics limpos e previsíveis. Documente o mapeamento uma vez e revise-o sempre que um site for adicionado, porque inconsistências são muito mais baratas de corrigir no segundo site do que no quinquagésimo.

Exemplo: simulador de estação elevatória

O script abaixo simula uma estação booster com o reservatório que ela abastece: duas bombas, pressão de recalque e nível do reservatório. Ele publica por exceção com heartbeats e um Last Will, o que o torna um bom substituto enquanto você projeta dashboards e alertas. Ele usa o servidor MQTT público (gratuito), feito para testes, então envia apenas valores simulados sob um prefixo aleatório.

import json
import random
import time
import uuid

import paho.mqtt.client as mqtt

BROKER, PORT = "broker.connectmq.com", 1883          # produção: seu broker, porta 8883 + TLS
CLIENT_ID = f"booster-sim-{uuid.uuid4().hex[:6]}"   # produção: "YOUR_CLIENT_ID"
BASE = f"connectmq/demo/{uuid.uuid4().hex[:6]}/north/booster-ridge"
HEARTBEAT = 300


def on_connect(client, userdata, flags, reason_code, properties):
    print("Connected:", reason_code, "- publishing under", BASE)
    client.publish(f"{BASE}/site/status", "online", qos=1, retain=True)


client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID)
client.will_set(f"{BASE}/site/status", "offline", qos=1, retain=True)
client.on_connect = on_connect
client.connect(BROKER, PORT, keepalive=60)
client.loop_start()

level, pumps = 3.2, [False, False]
last = {}
last_full = 0.0


def publish(name, value, deadband=None, unit=None, retain=False):
    prev = last.get(name)
    if prev is not None and not force:
        if deadband is None and value == prev:
            return
        if deadband is not None and abs(value - prev) < deadband:
            return
    payload = {"value": value, "ts": int(time.time())}
    if unit:
        payload["unit"] = unit
    client.publish(f"{BASE}/{name}", json.dumps(payload), qos=1, retain=retain)
    last[name] = value


while True:
    force = time.time() - last_full >= HEARTBEAT
    demand = random.uniform(0.010, 0.020)
    supply = 0.018 * sum(pumps)
    level = round(max(0.0, level + supply - demand), 3)

    # Controle de nível simples: liga as bombas quando o reservatório baixa, desliga quando enche
    if level < 2.8:
        pumps = [True, level < 2.4]
    elif level > 3.6:
        pumps = [False, False]

    pressure = round(1.2 + 2.1 * sum(pumps) + random.uniform(-0.03, 0.03), 2)

    publish("reservoir/level", level, deadband=0.03, unit="m")
    publish("discharge/pressure", pressure, deadband=0.08, unit="bar")
    publish("pump1/running", pumps[0], retain=True)
    publish("pump2/running", pumps[1], retain=True)

    if force:
        last_full = time.time()
    time.sleep(5)

Acompanhe a estação em outro terminal:

mosquitto_sub -h broker.connectmq.com -p 1883 -i booster-watch-01 \
  -t 'connectmq/demo/+/north/booster-ridge/#' -v

Você verá o reservatório baixar devagar, as bombas partirem, a pressão de recalque subir e o nível se recuperar, com apenas algumas mensagens por minuto apesar de um loop de cinco segundos.

Alertas por limite em níveis e pressões

A telemetria se paga quando avisa alguém sobre um problema cedo. Em um broker privado do ConnectMQ, você pode adicionar regras de alerta por limite no portal, como nível de reservatório abaixo de 1,5 m ou pressão de recalque acima de 6 bar, e revisar cada alerta disparado no log de alertas. Isso dá aos engenheiros uma visão rápida e independente dos limites críticos durante um piloto ou ao lado do SCADA.

Algumas condições não são um único limite. A ciclagem curta de bombas, por exemplo, é uma contagem de partidas ao longo do tempo. O padrão honesto para uma lógica assim é um pequeno serviço assinante conectado ao broker como um cliente MQTT comum:

import json
import time
from collections import deque

import paho.mqtt.client as mqtt

MAX_STARTS_PER_HOUR = 6
starts = {}            # topic -> deque de timestamps de partida
state = {}


def on_connect(client, userdata, flags, reason_code, properties):
    client.subscribe("connectmq/demo/+/north/+/+/running", qos=1)


def on_message(client, userdata, msg):
    running = json.loads(msg.payload)["value"]
    was_running = state.get(msg.topic, running)
    state[msg.topic] = running
    if running and not was_running:
        window = starts.setdefault(msg.topic, deque())
        now = time.time()
        window.append(now)
        while window and now - window[0] > 3600:
            window.popleft()
        if len(window) > MAX_STARTS_PER_HOUR:
            print(f"ALERT short-cycling: {msg.topic} started {len(window)} times in 1 h")
            # Encaminhe aqui para sua ferramenta de paging, SMS ou chamados.


client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=f"shortcycle-{time.time_ns() % 1000000}")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_forever()

A mesma abordagem funciona com Node-RED ou qualquer outra ferramenta compatível com MQTT. O envio de notificações continua na ferramenta que sua equipe de operação já usa.

Checklist de segurança e confiabilidade

Saneamento é infraestrutura crítica, então a exigência é maior do que em um projeto de IoT típico.

  1. TLS na porta 8883 em todas as estações; nunca envie telemetria em texto puro por redes celulares ou públicas.
  2. Usuário, senha e client ID únicos por estação, revogáveis individualmente.
  3. Conexões apenas de saída a partir das estações; nenhuma porta de entrada aberta nos modems.
  4. Monitoramento separado do controle. Comandos para bombas e válvulas ficam no SCADA, com seus intertravamentos, a menos que um design revisado diga o contrário.
  5. Status do site retido com Last Will e alertas para offline inesperado.
  6. Buffer local nas estações para que quedas curtas não criem lacunas em dados relevantes para conformidade regulatória.
  7. Sincronização de horário na origem para sequências de eventos precisas.
  8. Um padrão de topics documentado, sob responsabilidade de uma única equipe, aplicado a todo novo site.

Escolhendo onde o broker roda

Empresas com conectividade mista, alguns sites em rádio privado e outros em rede celular, se beneficiam de um broker acessível de qualquer lugar via TLS. Um broker MQTT gerenciado tira da equipe da empresa a aplicação de patches e a renovação de certificados. O ConnectMQ oferece MQTT 3.1.1 e 5.0, uma visualização de dispositivos ISA-95 que agrupa sites e ativos e opções Dedicated ou BYOC para empresas que precisam de um cluster isolado ou de implantação na própria conta de nuvem. Para escolhas de arquitetura entre CLPs das estações, gateways e encaminhamento via SCADA, veja conectividade de CLP para a nuvem; para o comportamento de modems celulares, MQTT via rede celular. O guia de IoT industrial com MQTT une todas essas peças.

Comece um piloto de telemetria de água com o ConnectMQ

Escolha um reservatório e uma estação elevatória, conecte-os a um broker MQTT na nuvem e configure alertas nos níveis e pressões que mais importam. Crie um broker Serverless gratuito em app.connectmq.com, sem cartão de crédito, e tenha dados ao vivo das estações no explorador de topics hoje mesmo.

Perguntas frequentes

O MQTT pode substituir nosso sistema SCADA de saneamento?

O MQTT geralmente substitui o transporte da telemetria, não as funções do SCADA. O SCADA assina o broker para a operação, enquanto outras equipes consomem os mesmos dados de forma independente.

Como saber que uma estação elevatória perdeu a comunicação?

Dê a cada estação um Last Will em um topic de status retido. Quando o keep alive dela expira, o broker publica offline, e os assinantes ou as regras de alerta reagem imediatamente.

Qual banda morta devemos usar para níveis de reservatório?

Alguns centímetros é o típico, com base na precisão do instrumento e na velocidade com que o nível varia. Combine-a com um heartbeat periódico para que um nível estável continue provando que a estação está viva.

O MQTT é seguro o suficiente para infraestrutura crítica de água?

MQTT com TLS, credenciais por estação, conexões apenas de saída e separação entre monitoramento e controle é uma base sólida. Combine-o com o programa de cibersegurança mais amplo da sua empresa.

Artigos relacionados

Cliente MQTT no CODESYS: Publicando Variáveis do CLP em um Broker

Configure a biblioteca IIoT MQTT Client do CODESYS para publicar variáveis do CLP em JSON, verifique-as no servidor MQTT público broker.connectmq.com e depois migre para um broker privado com credenciais e TLS.

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.