La telemetría MQTT para empresas de agua reúne estaciones de bombeo, depósitos, estaciones de rebombeo y bombeos de aguas residuales dispersos en una única capa de datos en vivo a la que pueden suscribirse operadores, ingenieros y herramientas de planificación. Esta guía muestra cómo estructurar esa telemetría, qué señales publicar y cómo hacerlo, y cómo generar alertas por umbral sobre niveles y presiones antes de que un depósito se vacíe o un pozo de bombeo desborde. Además ejecutarás un pequeño simulador de estación y un ayudante de alarmas que puedes adaptar a equipos reales.
El problema de la telemetría en las redes de agua
Una empresa de agua típica opera desde decenas hasta cientos de emplazamientos remotos repartidos por su zona de servicio. Muchos se conectaron a lo largo de décadas con distintas RTU, radios y protocolos, y los sondea un maestro SCADA central. Ese esquema funciona, pero genera problemas conocidos:
- Escaneos lentos en radio compartida. Sondear cada emplazamiento por turnos significa que una alarma de nivel puede esperar al siguiente escaneo.
- Datos encerrados en el SCADA. Los equipos de gestión de activos, modelado hidráulico y energía piden exportaciones o construyen frágiles interfaces punto a punto.
- Generaciones de equipos mezcladas. Cada nuevo tipo de emplazamiento añade otro driver y otro mapa de registros.
- Emplazamientos celulares por todas partes. Los emplazamientos más recientes usan módems celulares, que favorecen conexiones salientes iniciadas por el dispositivo en lugar del sondeo entrante.
MQTT invierte el sentido: cada estación publica sus propios cambios en un broker, y todos los consumidores, incluido el SCADA, se suscriben. Si estás planificando el lado SCADA de este cambio, lee MQTT en sistemas SCADA junto con esta guía.
Qué publicar desde cada emplazamiento
Parte de las preguntas operativas, no de la lista de registros de la RTU. La tabla siguiente es una base práctica para instalaciones de agua potable y residual.
| Tipo de emplazamiento | Señal | Unidad | Regla de publicación | Idea de alerta |
|---|---|---|---|---|
| Depósito / tanque | Nivel | m | Banda muerta de 2 a 5 cm, latido de 15 min | Nivel bajo y alto |
| Depósito / tanque | Posición de la válvula de entrada | % | Al cambiar un 2 % | Válvula atascada mientras baja el nivel |
| Estación de rebombeo o de bombeo | Presión de impulsión | bar | Banda muerta de 0,05 a 0,1 bar | Presión alta y baja |
| Estación de rebombeo o de bombeo | Caudal | m3/h | Banda muerta del 2 al 5 % del rango | Caudal con la bomba parada |
| Estación de rebombeo o de bombeo | Estado de marcha de la bomba | bool | En cada cambio | Demasiados arranques por hora |
| Bombeo de aguas residuales | Nivel del pozo húmedo | m | Banda muerta de 2 cm, latido más rápido | Nivel alto, riesgo de desbordamiento |
| Todos los emplazamientos | Alimentación de red, intrusión, comunicaciones | bool | En cada cambio, retained | Cualquier cambio |
| Puntos de tratamiento | Cloro residual | mg/L | Banda muerta de 0,02 mg/L | Por debajo o por encima del rango objetivo |
Dos reglas hacen que esta tabla funcione. Publica los valores analógicos por excepción con una banda muerta dimensionada según la precisión del instrumento, y publica cada cambio de estado de inmediato. La guía de report by exception explica cómo dimensionar la banda muerta y por qué sigue siendo necesario un latido.
Diseñar topics para una red de agua
Los topics deben reflejar cómo piensan los operadores en la red: región, emplazamiento, activo, medida. Una jerarquía en la línea de ISA-95 lo mantiene coherente:
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
Pautas que compensan más adelante:
- Mantén estables y en minúsculas los nombres de emplazamientos y activos; se convierten en identificadores en todos los sistemas posteriores.
- Pon una medida por topic, o un pequeño objeto JSON por activo, y elige un único enfoque para toda la empresa.
- Da a cada emplazamiento un topic
site/statusretained con un Last Will, para que una conexión celular perdida aparezca comoofflineen lugar de como valores congelados. - No codifiques números de registro de la RTU en los topics. Guárdalos en un campo
sourcesi los ingenieros los necesitan.
Cuando los nombres de tags del SCADA existente ya siguen una convención, asígnalos a la nueva jerarquía en el gateway en lugar de renombrar puntos en el SCADA. Los operadores conservan los nombres que conocen, mientras que cada nuevo consumidor obtiene topics limpios y predecibles. Documenta el mapeo una vez y revísalo cada vez que se añada un emplazamiento, porque las incoherencias son mucho más baratas de corregir en el segundo emplazamiento que en el quincuagésimo.
Ejemplo: simulador de estación de bombeo
El script siguiente simula una estación de rebombeo con el depósito al que alimenta: dos bombas, presión de impulsión y nivel del depósito. Publica por excepción con latidos y un Last Will, lo que lo convierte en un buen sustituto mientras diseñas dashboards y alertas. Usa el servidor MQTT público gratuito, así que solo envía valores simulados bajo un prefijo aleatorio.
import json
import random
import time
import uuid
import paho.mqtt.client as mqtt
BROKER, PORT = "broker.connectmq.com", 1883 # production: your broker, port 8883 + TLS
CLIENT_ID = f"booster-sim-{uuid.uuid4().hex[:6]}" # production: "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)
# Simple level control: start pumps when the reservoir falls, stop when full
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)
Observa la estación desde otro terminal:
mosquitto_sub -h broker.connectmq.com -p 1883 -i booster-watch-01 \
-t 'connectmq/demo/+/north/booster-ridge/#' -v
Verás cómo el depósito baja lentamente, arrancan las bombas, salta la presión de impulsión y el nivel se recupera, con solo unos pocos mensajes por minuto a pesar de un bucle de cinco segundos.
Alertas por umbral sobre niveles y presiones
La telemetría demuestra su valor cuando avisa a alguien de un problema con antelación. En un broker privado de ConnectMQ puedes añadir reglas de alerta por umbral en el portal, como un nivel de depósito por debajo de 1,5 m o una presión de impulsión por encima de 6 bar, y revisar cada alerta disparada en el registro de alertas. Eso da a los ingenieros una visión rápida e independiente de los límites críticos durante un piloto o junto al SCADA.
Algunas condiciones no son un simple umbral. Los arranques demasiado frecuentes de una bomba (short-cycling), por ejemplo, son un recuento de arranques a lo largo del tiempo. El patrón honesto para una lógica así es un pequeño servicio suscriptor conectado al broker como un cliente MQTT corriente:
import json
import time
from collections import deque
import paho.mqtt.client as mqtt
MAX_STARTS_PER_HOUR = 6
starts = {} # topic -> deque of start timestamps
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")
# Forward to your paging, SMS or ticketing tool here.
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()
El mismo enfoque funciona con Node-RED o con cualquier otra herramienta compatible con MQTT. El envío de notificaciones se queda en la herramienta que tu equipo de operaciones ya utiliza.
Lista de comprobación de seguridad y fiabilidad
Las empresas de agua son infraestructura crítica, así que el listón está más alto que en un proyecto IoT típico.
- TLS en el puerto 8883 para cada estación; nunca envíes telemetría en texto claro por redes celulares o públicas.
- Usuario, contraseña y client ID únicos por estación, revocables de forma individual.
- Conexiones solo salientes desde las estaciones; ningún puerto entrante abierto en los módems.
- Monitorización separada del control. Los comandos a bombas y válvulas se quedan en el SCADA con sus enclavamientos, salvo que un diseño revisado diga lo contrario.
- Estado del emplazamiento retained con Last Will, y alertas ante un
offlineinesperado. - Buffer local en las estaciones para que los cortes breves no dejen huecos en los datos relevantes para el cumplimiento normativo.
- Sincronización horaria en origen para obtener secuencias de eventos precisas.
- Un estándar de topics documentado, del que se responsabilice un único equipo, aplicado a cada nuevo emplazamiento.
Dónde ejecutar el broker
Las empresas con conectividad mixta, algunos emplazamientos en radio privada y otros en red celular, se benefician de un broker accesible desde cualquier lugar con TLS. Un broker MQTT gestionado elimina el parcheado y la renovación de certificados de la carga de trabajo de la empresa. ConnectMQ ofrece MQTT 3.1.1 y 5.0, una vista de dispositivos ISA-95 que agrupa emplazamientos y activos, y opciones Dedicated o BYOC para empresas que necesitan un clúster aislado o un despliegue en su propia cuenta cloud. Para elegir la arquitectura entre PLC de estación, gateways y reenvío desde SCADA, consulta conectividad de PLC a la nube; para el comportamiento de los módems celulares, MQTT sobre red celular. La guía de IoT industrial con MQTT une todas estas piezas.
Empieza un piloto de telemetría de agua con ConnectMQ
Elige un depósito y una estación de bombeo, conéctalos a un broker MQTT en la nube y configura alertas sobre los niveles y presiones que más importan. Crea un broker Serverless gratuito en app.connectmq.com, sin tarjeta de crédito, y ten hoy mismo datos de estación en vivo en el explorador de topics.
Preguntas frecuentes
¿Puede MQTT sustituir nuestro sistema SCADA de agua?
MQTT suele sustituir el transporte de la telemetría, no las funciones del SCADA. El SCADA se suscribe al broker para la operación, mientras otros equipos consumen los mismos datos de forma independiente.
¿Cómo sabemos que una estación de bombeo ha perdido las comunicaciones?
Da a cada estación un Last Will en un topic de estado retained. Cuando expira su keep alive, el broker publica offline, y los suscriptores o las reglas de alerta reaccionan de inmediato.
¿Qué banda muerta deberíamos usar para los niveles de depósito?
Lo habitual son unos pocos centímetros, según la precisión del instrumento y la rapidez con que se mueve el nivel. Combínala con un latido periódico para que un nivel estable siga demostrando que la estación está viva.
¿Es MQTT lo bastante seguro para infraestructura crítica de agua?
MQTT con TLS, credenciales por estación, conexiones solo salientes y separación entre monitorización y control es una base sólida. Combínalo con el programa general de ciberseguridad de tu empresa.



