Fabricación inteligente

Monitorización del estado de máquinas con MQTT: en marcha, en espera y parada en tiempo real

Define un modelo de estados de máquina limpio, deduce marcha, espera y parada a partir de balizas luminosas o señales del PLC, y publica mensajes MQTT retenidos para que cada dashboard muestre el estado actual en cuanto se conecta.

Panel de monitorización del estado de máquinas que muestra los estados en marcha, en espera y parada de varias máquinas actualizados en vivo mediante mensajes MQTT retenidos
Pruébalo en tu propio broker MQTTConsigue un broker MQTT privado y gestionado con el plan Free y empieza con ejemplos de código listos para usar.
Pruébalo gratis Ejemplos de código Sin tarjeta

La monitorización del estado de máquinas responde a la pregunta más básica del taller, "¿está funcionando ahora mismo?", para todas las máquinas a la vez. En este tutorial definirás un modelo de estados sencillo, deducirás en una Raspberry Pi los estados de marcha, espera y parada a partir de balizas luminosas o señales del PLC, y publicarás el estado como mensajes MQTT retenidos para que cualquier dashboard muestre el estado actual en el instante en que se conecta.

Por qué empezar por el estado de la máquina

El estado de la máquina es la base de casi todos los KPI de producción. La disponibilidad del OEE, el análisis de paradas, las estadísticas de tiempo de ciclo y la energía por hora en espera dependen de saber cuándo estaba funcionando una máquina y cuándo no. También es el dato más barato de obtener: muchas máquinas ya muestran su estado en una baliza luminosa, y casi todos los PLC tienen un bit de "ciclo activo" y otro de "fallo".

La dificultad no es la señal, sino la coherencia. Si una máquina informa "auto", otra "RUN" y una tercera solo enciende una lámpara verde, compararlas es un suplicio. Por eso el modelo de estados va primero.

Un modelo de estados práctico

Mantén pocos estados y definiciones sin ambigüedad. Este modelo de cinco estados cubre la mayor parte de la fabricación discreta:

Estado Definición Señal típica
running La máquina produce; un ciclo terminó dentro del tiempo esperado Pulso de ciclo, luz verde, "en ciclo" del PLC
idle La máquina está sana y disponible pero no produce (espera material, operario, proceso anterior) Sin fallo, sin ciclo reciente
down La máquina no puede producir por un fallo o alarma Luz roja, bit de fallo del PLC
setup Cambio de formato planificado, cambio de herramienta o mantenimiento Entrada del operario, modo del PLC, estado de la orden en el MES
offline No hay datos del dispositivo edge Last Will de MQTT

Dos reglas hacen que el modelo funcione:

  1. Prioridad: si se cumplen varias condiciones, gana la de mayor prioridad. Un orden sensato es offline, down, setup, running, idle.
  2. Antirrebote temporal: una máquina que completa un ciclo cada 40 segundos no debería parpadear a espera entre ciclos. Trátala como en marcha hasta que no se haya visto ningún ciclo durante, por ejemplo, el doble del tiempo de ciclo nominal.

Los motivos de parada y espera (sin material, rotura de herramienta, retención de calidad) son una dimensión aparte. Recógelos más adelante en un campo reason en lugar de multiplicar los estados.

Diseño de topics con mensajes retenidos

Cada máquina tiene un topic state que guarda su estado actual como mensaje retenido. El broker almacena el último mensaje retenido de cada topic y lo envía de inmediato a cada nuevo suscriptor. Un dashboard abierto a las 10:15 no tiene que esperar al siguiente cambio; ve al instante "parada desde las 09:52". Lee mensajes retenidos en MQTT para conocer todo el mecanismo.

connectmq/plant1/machining/line1/cnc-01/state     retained  current state
connectmq/plant1/machining/line1/cnc-01/events    not retained, one message per transition
connectmq/plant1/machining/line1/cnc-01/status    retained  online / offline (Last Will)

Payload de estado:

{
  "state": "down",
  "since": 1760599920,
  "previous": "running",
  "reason": null,
  "source": "edge-cnc-01"
}

Incluir since permite a un dashboard mostrar la duración sin ninguna base de datos histórica. El topic events es al que se suscribe un historian para los informes de paradas y disponibilidad.

Cableado de las señales

En máquinas sin acceso de red al PLC, toma las señales de la baliza luminosa o de salidas libres del PLC mediante módulos de entrada con optoacoplador de 24 V hacia los GPIO de la Raspberry Pi. Nunca conectes señales de 24 V directamente a la Pi; sus pines GPIO solo admiten 3,3 V. Los trabajos eléctricos en armarios de máquina deben realizarlos profesionales cualificados.

Señal GPIO (BCM) Significado cuando está activa
Pulso de ciclo completado o luz verde 17 Ha terminado un ciclo / máquina en ciclo
Luz roja o salida de fallo 27 Máquina en fallo
Llave de setup o luz amarilla 22 Setup o cambio de formato planificado

Donde el PLC sea accesible por red, lee los mismos bits por Modbus TCP, OPC UA o S7; solo cambia la función de entrada.

El script edge de monitorización del estado de máquinas

Instala las librerías en un entorno virtual (pip install gpiozero lgpio paho-mqtt). El script siguiente evalúa las entradas dos veces por segundo, aplica las reglas de prioridad y tiempo, y publica solo en las transiciones.

#!/usr/bin/env python3
"""Machine status monitoring edge script: GPIO signals -> retained MQTT state."""
import json
import time

import paho.mqtt.client as mqtt
from gpiozero import DigitalInputDevice

BROKER = "broker.connectmq.com"
MACHINE = "cnc-01"
BASE = f"connectmq/demo/msm-5t2r/line1/{MACHINE}"
NOMINAL_CYCLE_S = 40
RUN_TIMEOUT_S = 2 * NOMINAL_CYCLE_S

cycle_in = DigitalInputDevice(17, pull_up=True, bounce_time=0.02)
fault_in = DigitalInputDevice(27, pull_up=True, bounce_time=0.05)
setup_in = DigitalInputDevice(22, pull_up=True, bounce_time=0.05)

last_cycle = 0.0
state, since = None, 0


def on_cycle():
    global last_cycle
    last_cycle = time.time()


cycle_in.when_activated = on_cycle


def derive_state(now):
    if fault_in.is_active:
        return "down"
    if setup_in.is_active:
        return "setup"
    if cycle_in.is_active or now - last_cycle < RUN_TIMEOUT_S:
        return "running"
    return "idle"


def on_connect(client, userdata, flags, reason_code, properties):
    print("Connected:", reason_code)
    client.publish(f"{BASE}/status", "online", qos=1, retain=True)
    if state is not None:                           # restore after reconnect
        publish_state(client, state, state, since, event=False)


def publish_state(client, new, previous, ts, event=True):
    payload = {"state": new, "since": ts, "previous": previous,
               "reason": None, "source": f"edge-{MACHINE}"}
    client.publish(f"{BASE}/state", json.dumps(payload), qos=1, retain=True)
    if event:
        client.publish(f"{BASE}/events", json.dumps(payload), qos=1)
    print(payload)


client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=f"msm-5t2r-{MACHINE}")
client.will_set(f"{BASE}/status", "offline", qos=1, retain=True)
client.on_connect = on_connect
client.connect(BROKER, 1883, keepalive=30)
client.loop_start()

while True:
    now = time.time()
    new = derive_state(now)
    if new != state:
        previous, state, since = state, new, int(now)
        publish_state(client, state, previous, since)
    time.sleep(0.5)

Algunas decisiones de diseño que merece la pena destacar:

  • El Last Will en status convierte un script caído, una red perdida o un corte de corriente en un estado "offline" visible, en lugar de un "running" congelado.
  • Al reconectarse, el script vuelve a publicar el estado retenido, de modo que el broker siempre conserva la última verdad aunque haya habido una transición mientras la conexión estaba caída.
  • Las entradas usan pull_up=True porque los módulos de optoacoplador típicos llevan la línea a nivel bajo cuando están activos. Inviértelo si tu módulo se comporta de otra forma.

Ejecútalo como servicio de systemd para que arranque al iniciar. Para un broker de producción, añade client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD"), client.tls_set(), usa el client ID que se te haya emitido y conéctate al puerto 8883.

Ver el panel de estado

Cualquier cliente MQTT puede mostrar ya el estado en vivo. Desde un terminal:

mosquitto_sub -h broker.connectmq.com -p 1883 -i msm-board-$RANDOM \
  -t "connectmq/demo/msm-5t2r/line1/+/state" -v

Los estados retenidos aparecen de inmediato, una línea por máquina. En un dashboard de navegador, MQTT.js se conecta por WebSocket seguro y hace lo mismo:

import mqtt from "mqtt";

const client = mqtt.connect("wss://broker.connectmq.com:8084/mqtt", {
  clientId: "msm-board-" + Math.random().toString(16).slice(2, 8),
  protocolVersion: 5,
});
const board = {};

client.on("connect", () => client.subscribe("connectmq/demo/msm-5t2r/line1/+/state"));
client.on("message", (topic, payload) => {
  const machine = topic.split("/").at(-2);
  board[machine] = JSON.parse(payload.toString());
  const lines = Object.entries(board).map(([m, s]) => {
    const minutes = Math.round((Date.now() / 1000 - s.since) / 60);
    return `${m}: ${s.state} for ${minutes} min`;
  });
  console.clear();
  console.log(lines.join("\n"));
});

Recuerda que los topics del servidor MQTT público gratuito son visibles para todos; es para pruebas, y los nombres y estados de máquina de una planta real deben ir a un broker privado. El mismo flujo de estados también puede colorear cada máquina en un gemelo digital 3D de la planta.

Del estado a las métricas

Una vez que existe el flujo events, el resto de la monitorización de la línea se construye sobre él:

  1. Disponibilidad: tiempo en marcha dividido entre el tiempo de producción planificado, a partir del historial de eventos.
  2. Registro de paradas: cada transición de marcha a parada abre un registro de parada; los operarios añaden los motivos en una tableta.
  3. Tiempo de ciclo: la misma entrada de ciclo, con marca de tiempo, da la duración ciclo a ciclo, explicada en monitorización del tiempo de ciclo.
  4. Recuento de piezas: un contador sobre el mismo pulso alimenta el conteo de producción con sensores IoT.
  5. Escalado: una máquina parada más tiempo que un umbral dispara un aviso en un sistema andon digital.

Solución de problemas

Síntoma Causa Solución
El estado parpadea entre running e idle El timeout de marcha es menor que la variación real del ciclo Aumenta RUN_TIMEOUT_S
El dashboard muestra un "running" obsoleto tras un corte de corriente Sin Last Will, o el dashboard ignora status Usa Last Will y muestra offline con prioridad
Siguen apareciendo máquinas antiguas en el panel Los mensajes retenidos permanecen tras darlas de baja Publica un mensaje retenido vacío para limpiar el topic
La entrada de fallo siempre está activa Lógica invertida del módulo de optoacoplador Cambia pull_up o usa active_state

Funcionamiento a escala

Docenas de máquinas, cada una con un estado retenido y un cliente edge que debe reconectarse de forma fiable, es exactamente la carga de trabajo para la que está pensado un broker MQTT gestionado. ConnectMQ expone además el estado de conexión de cada cliente en $SYS/broker/connection/{clientId}/state, lo que ayuda a detectar dispositivos edge que se desconectan una y otra vez. La guía de fabricación inteligente muestra cómo encaja el estado de máquina en una hoja de ruta completa de monitorización.

Empieza con ConnectMQ

ConnectMQ te ofrece un broker MQTT 5 protegido con TLS, con mensajes retenidos, un explorador de topics en vivo y una vista de dispositivos ISA-95 que agrupa las máquinas por área y línea. Crea un broker Serverless gratuito sin tarjeta de crédito y pasa tu monitorización del estado de máquinas del servidor de pruebas a producción.

Preguntas frecuentes

¿Por qué usar mensajes retenidos para el estado de las máquinas?

Un mensaje retenido se entrega de inmediato a cada nuevo suscriptor, así que dashboards, tabletas y servicios empiezan siempre con el estado actual de cada máquina en lugar de esperar al siguiente cambio.

¿Cómo detecto que el dispositivo edge de una máquina está offline?

Configura un mensaje Last Will en un topic de estado retenido cuando el cliente se conecte. Si el dispositivo se desconecta de forma inesperada, el broker publica el Will y los dashboards pueden mostrar la máquina como offline.

¿Puedo obtener el estado de la máquina directamente del PLC en lugar de las balizas?

Sí. Lee los bits de ciclo y fallo del PLC por Modbus TCP, OPC UA o un protocolo del fabricante y pásalos a la misma lógica de estados. Las señales del PLC suelen ser más precisas que las balizas luminosas.

¿Cuántos estados debe tener un modelo de estado de máquina?

Los menos posibles que sigan respondiendo a tus preguntas. Running, idle, down, setup y offline cubren la mayoría de las necesidades; usa códigos de motivo para los detalles en lugar de añadir estados.

Artículos relacionados

OEE vs TEEP vs OOE: ¿qué indicador deberías usar?

OEE, OOE y TEEP comparten los mismos factores de rendimiento y calidad, pero se miden frente a bases de tiempo distintas. Esta comparativa resuelve un único ejemplo y enumera las señales MQTT que necesita cada indicador.

8 min de lectura

Todos los artículos →

Tu broker MQTT privado, a unos pocos clics

Crea una cuenta, obtén las credenciales de tu broker y conecta tu primer dispositivo, sin servidores que instalar, parchear ni escalar.