Gemelo digital

Guía de gemelo digital con MQTT: transmite el estado en tiempo real a tu gemelo

Por qué MQTT es el transporte natural para los gemelos digitales y cómo diseñar topics, estado retenido, presencia y comandos para que un gemelo se mantenga sincronizado con los activos reales, con código Python y JavaScript listo para ejecutar.

Flujo de datos de un gemelo digital MQTT con máquinas que publican su estado en vivo a través de un broker hacia un modelo 3D de fábrica en el navegador
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

Combinar un gemelo digital con MQTT es la forma más directa de mantener un modelo virtual al compás de los equipos reales. En esta guía aprenderás por qué el modelo publish/subscribe de MQTT encaja tan bien con los gemelos, cómo diseñar topics, estado retenido, presencia y comandos, y cómo transmitir el estado en vivo a un gemelo en el navegador con código Python y JavaScript listo para ejecutar.

Si el concepto de gemelo es nuevo para ti, empieza por la guía de tecnología de gemelo digital.

Por qué MQTT encaja con los gemelos digitales

Un gemelo necesita tres cosas de su transporte: actualizaciones de baja latencia, una forma de que quienes llegan tarde obtengan el estado actual y un acoplamiento débil para poder añadir nuevos consumidores sin tocar los dispositivos. MQTT ofrece las tres en el propio protocolo.

Requisito del gemelo Función de MQTT Por qué ayuda
Actualizaciones en vivo Conexiones persistentes, entrega push Los valores llegan en milisegundos, sin polling
Estado actual al cargar Retained messages Un nuevo visor recibe al instante el último valor de cada topic
Jerarquía de activos Topics jerárquicos y comodines plant1/line2/# te da una línea entera con una sola suscripción
Estado online/offline Last Will and Testament El broker anuncia cuándo se cae un dispositivo
Control de fiabilidad QoS 0, 1, 2 Telemetría rápida con QoS 0, eventos importantes con QoS 1
Muchos consumidores Desacoplamiento publish/subscribe Dashboards, vistas 3D y analítica comparten un mismo flujo
Visores en el navegador MQTT sobre WebSocket Las escenas 3D se conectan directamente sin gateway adicional

El polling HTTP, en cambio, obliga a cada visor a bombardear una API y aun así deja huecos entre consultas. Las colas de mensajes diseñadas para el procesamiento en backend a menudo carecen de estado retenido y de conectividad desde el navegador. Por eso tantas plataformas de gemelos ponen un broker MQTT en el centro.

Diseño de topics para un gemelo digital con MQTT

El árbol de topics es el esquema de direcciones de tu gemelo. Refleja la jerarquía física y termina con una clase de mensaje:

connectmq/demo/<id>/factory1/line1/cnc1/telemetry   stream, not retained
connectmq/demo/<id>/factory1/line1/cnc1/state       current state, retained
connectmq/demo/<id>/factory1/line1/cnc1/status      online/offline, retained + last will
connectmq/demo/<id>/factory1/line1/cnc1/cmd         commands, never retained
connectmq/demo/<id>/factory1/line1/cnc1/cmd/ack     command results

Reglas que ahorran problemas más adelante:

  • Usa identificadores estables como niveles de topic, no nombres visibles. Los nombres cambian; los IDs no.
  • Pon las unidades y las marcas de tiempo en el payload, no en el topic.
  • Mantén cada payload pequeño y centrado en un solo activo.
  • Nunca retengas comandos. Un cmd retenido se volvería a ejecutar cada vez que un dispositivo se reconecta.

Para profundizar en cómo se corresponden los topics con el modelo de activos, consulta arquitectura de gemelo digital.

Los retained messages como memoria del gemelo

Cuando un visor abre el gemelo, no debería esperar al siguiente ciclo de telemetría para mostrar cada máquina. Publicar el estado con el flag retain hace que el broker guarde el último mensaje de cada topic y lo entregue de inmediato al suscribirse. El tutorial de estado MQTT retenido construye un gemelo completo de esta forma; esta es la idea central en Python con paho-mqtt 2.x:

import json
import random
import time
import paho.mqtt.client as mqtt

PREFIX = "connectmq/demo/b72e/factory1/line1/cnc1"

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="cnc1-sim-b72e")
client.will_set(f"{PREFIX}/status", payload="offline", qos=1, retain=True)
client.connect("broker.connectmq.com", 1883)
client.loop_start()

client.publish(f"{PREFIX}/status", "online", qos=1, retain=True)

try:
    while True:
        state = {
            "ts": int(time.time() * 1000),
            "spindle_rpm": random.randint(7800, 8200),
            "feed_mm_min": random.randint(900, 1100),
            "tool": 4,
            "mode": "AUTO",
        }
        client.publish(f"{PREFIX}/state", json.dumps(state), qos=0, retain=True)
        time.sleep(1)
except KeyboardInterrupt:
    client.publish(f"{PREFIX}/status", "offline", qos=1, retain=True)
    client.loop_stop()
    client.disconnect()

El Last Will en el topic status es importante. Si el simulador falla o se cae la red, el broker publica offline por ti y, como está retenido, cualquier visor que se abra más tarde también verá la máquina como desconectada.

Transmitir el gemelo a un navegador

Un gemelo digital 3D o una vista 2D en el navegador se conecta por WebSocket seguro en el puerto 8084 con la ruta /mqtt. Este ejemplo de MQTT.js se suscribe a toda la línea y actualiza un modelo del gemelo en memoria que tu código de renderizado puede leer en cada fotograma:

import mqtt from "mqtt";

const prefix = "connectmq/demo/b72e/factory1/line1";
const twin = new Map();

const client = mqtt.connect("wss://broker.connectmq.com:8084/mqtt", {
  clientId: "twin-viewer-" + Math.random().toString(16).slice(2, 10),
  protocolVersion: 5,
  clean: true,
});

client.on("connect", () => {
  client.subscribe(`${prefix}/+/state`);
  client.subscribe(`${prefix}/+/status`);
});

client.on("message", (topic, payload) => {
  const parts = topic.split("/");
  const asset = parts[parts.length - 2];
  const kind = parts[parts.length - 1];
  const current = twin.get(asset) || {};
  if (kind === "status") {
    current.online = payload.toString() === "online";
  } else {
    Object.assign(current, JSON.parse(payload.toString()));
  }
  twin.set(asset, current);
  console.log(asset, current);
});

Desacopla la gestión de mensajes del renderizado. Los mensajes actualizan el modelo; el bucle de renderizado lee el modelo. Así la tasa de fotogramas se mantiene fluida incluso cuando los mensajes llegan en ráfagas.

Diseño de payloads para los mensajes del gemelo

Los topics indican a los consumidores dónde va un valor; los payloads les dicen qué significa. Unas pocas convenciones mantienen manejable un gemelo que crece:

  • Incluye una marca de tiempo de origen (ts en milisegundos) en cada mensaje de estado y de telemetría. Así los visores pueden mostrar la antigüedad de cada valor e ignorar las actualizaciones desordenadas.
  • Usa nombres de campo y unidades coherentes entre activos del mismo tipo, idealmente documentados en un esquema o en un lenguaje de modelado como DTDL.
  • Envía el estado completo en el topic de estado, no parches parciales. Un parche parcial retenido dejaría a un nuevo visor con media imagen.
  • Mantén los payloads compactos. JSON es fácil de depurar y válido para la mayoría de los gemelos; pasa a una codificación binaria solo cuando el ancho de banda esté realmente limitado.
  • Añade un campo de versión del esquema cuando los payloads puedan evolucionar, para que dispositivos antiguos y nuevos convivan durante los despliegues.

Estas reglas no cuestan nada al principio y ahorran mucho trabajo cuando decenas de tipos de activos y varias aplicaciones consumidoras dependen del mismo flujo.

Comandos: cerrar el lazo

Un gemelo que observa se convierte en un gemelo que opera en cuanto puede enviar comandos. El patrón seguro:

  1. La aplicación publica un comando con un correlation ID en .../cmd con QoS 1, sin retener.
  2. El dispositivo lo valida y lo ejecuta, y después publica el resultado en .../cmd/ack con el mismo ID.
  3. El dispositivo actualiza su state retenido, que ven todos los visores.
  4. La aplicación da un timeout si no llega ninguna confirmación.

MQTT 5 lo hace más limpio con las propiedades response topic y correlation data, además de la expiración de mensajes, para que un comando que ha esperado demasiado se descarte en lugar de ejecutarse tarde. Lee funciones de MQTT 5 para más detalles. Para la gestión del estado deseado frente al reportado, consulta sincronización de estado del gemelo digital.

Elegir el QoS para los datos del gemelo

  1. Telemetría rápida para animación: QoS 0. Un fotograma perdido se sustituye por el siguiente.
  2. Cambios de estado y alarmas: QoS 1, para que no se pierdan en desconexiones breves.
  3. Comandos: QoS 1 con tratamiento idempotente y correlation IDs. QoS 2 rara vez es necesario si los comandos son idempotentes.

El artículo niveles de QoS de MQTT explicados analiza en profundidad las ventajas e inconvenientes.

Cómo ConnectMQ impulsa un gemelo digital 3D en vivo

ConnectMQ tiene una demo web de gemelo digital 3D de una pequeña fábrica con una máquina CNC, un brazo robótico, un horno, un depósito, un transportador y una bomba. Los activos simulados publican su estado en el broker y la escena 3D se suscribe por WebSocket seguro, usando exactamente los patrones anteriores: topics jerárquicos, estado retenido para una carga instantánea y actualizaciones en vivo que impulsan la animación.

Para tu propio gemelo, ConnectMQ ofrece un broker MQTT gestionado con MQTT 3.1.1 y 5.0, TLS en el 8883 y WSS en el 8084 con un certificado de Let's Encrypt, para que los visores en el navegador se conecten sin avisos de certificado. El explorador de topics en vivo del portal y la vista de dispositivos por niveles ISA-95 te ayudan a comprobar que cada activo publica donde debe. Empieza a experimentar en el servidor MQTT público gratuito con datos de demostración y después pasa a tus propias credenciales para activos reales.

Resolución de problemas en gemelos digitales con MQTT

  • El visor no muestra nada hasta la primera actualización. El estado no se está publicando con el flag retain.
  • Un dispositivo sigue ejecutando un comando antiguo tras reiniciarse. Se retuvo un comando. Bórralo publicando un payload retenido vacío en ese topic y deja de retener comandos.
  • Los activos siguen "online" tras un corte de alimentación. No hay Last Will configurado o el keepalive es demasiado largo.
  • El navegador no puede conectarse. Comprueba la URL wss://, el puerto 8084 y la ruta /mqtt.
  • Animación a tirones. El renderizado está acoplado a la gestión de mensajes, o la frecuencia de telemetría es demasiado baja para un movimiento fluido; interpola entre muestras.

Conecta tu gemelo digital a ConnectMQ

Crea un broker con el plan Serverless gratuito en app.connectmq.com, sin tarjeta de crédito, copia el usuario, la contraseña y el client ID generados y apunta tu simulador y tu visor hacia él. En minutos tendrás un gemelo en vivo transmitiendo por MQTT.

Preguntas frecuentes

¿Por qué usar MQTT en lugar de REST para un gemelo digital?

MQTT envía las actualizaciones en el momento en que ocurren por una conexión persistente y guarda el último estado en retained messages, mientras que REST necesita polling y añade latencia y carga.

¿Puede un navegador conectarse directamente a MQTT para un gemelo 3D?

Sí. Los navegadores se conectan mediante MQTT sobre WebSocket, por ejemplo wss://broker.connectmq.com:8084/mqtt, usando una biblioteca como MQTT.js.

¿Debo retener la telemetría o solo el estado?

Retén el topic de estado actual para que los visores carguen al instante; deja sin retener los flujos de telemetría de alta frecuencia para evitar confusiones entre el flujo y la instantánea.

¿Cómo muestro en el gemelo que un dispositivo se ha desconectado?

Configura un mensaje Last Will en un topic de estado retenido. El broker lo publica automáticamente cuando el dispositivo se desconecta de forma inesperada.

Artículos relacionados

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.