Eclipse Ditto con MQTT es una de las formas más prácticas de construir gemelos digitales open source: los dispositivos publican en un broker, Ditto mantiene un gemelo JSON de cada dispositivo y las aplicaciones leen el estado del gemelo mediante una API o reciben eventos de cambio. En este tutorial ejecutarás Ditto en local, crearás un thing, conectarás Ditto a un broker MQTT, mapearás el JSON plano de los dispositivos a features del gemelo y publicarás de vuelta en MQTT los eventos del gemelo.
Para entender dónde encaja un servicio de gemelos, consulta la guía de tecnología de gemelo digital.
Qué hace Eclipse Ditto
Eclipse Ditto es un framework open source de la Eclipse Foundation para gestionar gemelos digitales. No habla directamente con los sensores. En su lugar, mantiene un documento de gemelo por dispositivo, llamado thing, y te ofrece:
- Una API REST y WebSocket para leer y modificar gemelos.
- Políticas que controlan quién puede leer o escribir cada parte de un gemelo.
- Un servicio de conectividad que se conecta a brokers externos, incluidos MQTT 3.1.1 y MQTT 5.
- Mapeo de payload para convertir mensajes arbitrarios de dispositivos en actualizaciones del gemelo.
- Eventos de cambio y búsqueda entre todos los things.
Un thing tiene attributes (metadatos mayormente estáticos, como la ubicación o el número de serie) y features (partes funcionales, cada una con properties para los valores reportados y, opcionalmente, desiredProperties para los valores objetivo). Esto encaja perfectamente con el patrón de estado reportado frente a deseado descrito en sincronización de estado del gemelo digital.
Arquitectura de una configuración de Eclipse Ditto con MQTT
devices --publish--> MQTT broker <--subscribe/publish-- Ditto connectivity
| |
| Ditto things (twins)
| |
dashboards <--subscribe--+ REST / WebSocket API for apps
Ditto se conecta al broker como un cliente MQTT normal. Eso significa que el broker puede ser cualquiera que cumpla el estándar: un Mosquitto local, el servidor MQTT público gratuito para experimentos o un broker MQTT gestionado como ConnectMQ en producción.
Paso 1: ejecuta Eclipse Ditto con Docker
El repositorio de Ditto incluye una configuración de Docker Compose. Clónalo y arranca el stack:
git clone https://github.com/eclipse-ditto/ditto.git
cd ditto/deployment/docker
docker compose up -d
Cuando los contenedores estén sanos, la API estará disponible a través de nginx en http://localhost:8080. Las credenciales de desarrollo por defecto son ditto / ditto para la API y devops / foobar para los endpoints administrativos, como las conexiones. Cámbialas antes de exponer Ditto en cualquier lugar. La documentación de Eclipse Ditto describe en detalle las opciones de despliegue.
Paso 2: crea un thing
Crea un gemelo para una bomba. Cuando creas un thing sin una política explícita, Ditto crea una política por defecto que concede acceso completo al sujeto autenticado, que en la configuración con nginx es nginx:ditto.
curl -u ditto:ditto -X PUT -H "Content-Type: application/json" \
http://localhost:8080/api/2/things/acme:pump-01 \
-d '{
"attributes": { "site": "plant1", "line": "water", "model": "CP-200" },
"features": {
"flow": { "properties": { "value": 0, "unit": "l/min" } },
"pressure": { "properties": { "value": 0, "unit": "bar" } },
"motor": { "properties": { "running": false } }
}
}'
Léelo de vuelta con curl -u ditto:ditto http://localhost:8080/api/2/things/acme:pump-01.
Paso 3: añade una conexión MQTT
Ahora indica a Ditto que se conecte al broker. El ejemplo siguiente usa MQTT 5 contra el servidor público, solo apto para pruebas, con un prefijo de topic único. Sustituye e3b9 por tu propia cadena aleatoria.
{
"name": "connectmq-demo",
"connectionType": "mqtt-5",
"connectionStatus": "open",
"uri": "tcp://broker.connectmq.com:1883",
"specificConfig": {
"clientId": "ditto-e3b9",
"separatePublisherClient": "false"
},
"sources": [
{
"addresses": ["connectmq/demo/e3b9/devices/+/telemetry"],
"authorizationContext": ["nginx:ditto"],
"qos": 1,
"payloadMapping": ["telemetry"]
}
],
"targets": [
{
"address": "connectmq/demo/e3b9/twins/{{ thing:name }}/events",
"topics": ["_/_/things/twin/events"],
"authorizationContext": ["nginx:ditto"],
"qos": 0
}
],
"mappingDefinitions": {
"telemetry": {
"mappingEngine": "JavaScript",
"options": {
"incomingScript": "function mapToDittoProtocolMsg(headers, textPayload, bytePayload, contentType) { var name = headers['mqtt.topic'].split('/')[4]; var d = JSON.parse(textPayload); var value = { flow: { properties: { value: d.flow, unit: 'l/min' } }, pressure: { properties: { value: d.pressure, unit: 'bar' } }, motor: { properties: { running: d.running } } }; return Ditto.buildDittoProtocolMsg('acme', name, 'things', 'twin', 'commands', 'merge', '/features', headers, value); }"
}
}
}
}
Guárdalo como connection.json y créalo a través de la API de conexiones con el usuario devops:
curl -u devops:foobar -X POST -H "Content-Type: application/json" \
http://localhost:8080/api/2/connections -d @connection.json
Puntos clave de esta configuración:
separatePublisherClienta false hace que Ditto use un único cliente MQTT en ambas direcciones. Por defecto, Ditto puede abrir un segundo cliente con un client ID derivado, lo que falla en brokers que vinculan los client IDs a las credenciales emitidas, como hace ConnectMQ con los brokers de producción.- El source se suscribe a la telemetría de todos los dispositivos con un comodín de un solo nivel.
- El mapeo en JavaScript extrae el nombre del dispositivo del topic y convierte el JSON plano en un comando
mergede Ditto sobre/features, de modo que los dispositivos nunca necesitan conocer el Ditto Protocol. - El target publica cada evento de cambio del gemelo en un topic de eventos por thing.
En producción, cambia la URI a ssl://YOUR_BROKER_HOST:8883, establece clientId en YOUR_CLIENT_ID y añade las credenciales del portal de ConnectMQ, por ejemplo ssl://YOUR_USERNAME:YOUR_PASSWORD@YOUR_BROKER_HOST:8883.
Paso 4: publica la telemetría del dispositivo
Simula la bomba con mosquitto_pub. El quinto nivel del topic es el nombre del thing que extrae el script de mapeo:
mosquitto_pub -h broker.connectmq.com -p 1883 -i pump-01-e3b9 -q 1 \
-t "connectmq/demo/e3b9/devices/pump-01/telemetry" \
-m '{"flow": 418.5, "pressure": 3.7, "running": true}'
Comprueba el gemelo:
curl -u ditto:ditto http://localhost:8080/api/2/things/acme:pump-01/features
Deberías ver los nuevos valores de caudal, presión y marcha.
Paso 5: consume los eventos del gemelo por MQTT
Ahora cualquier aplicación puede seguir los cambios del gemelo sin llamar a la API de Ditto. Suscríbete al topic de eventos:
mosquitto_sub -h broker.connectmq.com -p 1883 -i events-viewer-e3b9 \
-t "connectmq/demo/e3b9/twins/+/events" -v
Publica otro mensaje de telemetría y aparecerá un evento del Ditto Protocol con el topic acme/pump-01/things/twin/events/merged, la ruta y el valor modificado. Los dashboards y los visores de un gemelo digital 3D pueden suscribirse a estos eventos o conectarse a la API WebSocket de Ditto si necesitan un acceso por gemelo controlado por políticas.
Consideraciones de producción para Eclipse Ditto y MQTT
Pasar de esta configuración local a producción implica algunas decisiones fáciles de pasar por alto:
- Credenciales y políticas. Sustituye los usuarios por defecto de nginx por tu proveedor de identidad y crea políticas explícitas por thing o por grupo de things en lugar de depender de la política por defecto. El contexto de autorización de la conexión debería ser un sujeto dedicado con solo los permisos que necesita.
- Contratos de topics. Documenta la estructura de topics que espera el script de mapeo. Si el firmware del dispositivo cambia la profundidad del topic, la extracción basada en índices del script falla sin avisar, así que valida las entradas y registra los mensajes rechazados.
- Rendimiento. Ditto persiste cada modificación de un gemelo. Alimentarlo con cada muestra de alta frecuencia es un desperdicio; deja que los dispositivos publiquen cuando cambie el valor o a un ritmo moderado, y envía los datos a frecuencia completa a un suscriptor de series temporales independiente.
- Estado deseado. Si las aplicaciones fijan
desiredProperties, añade un target que publique esos cambios en un topic de comandos del dispositivo y haz que los dispositivos informen de vuelta por la misma ruta de telemetría. - Monitorización. Vigila a la vez el estado de la conexión y la actividad de topics del broker, para poder saber si un gemelo desactualizado se debe al dispositivo, al broker o al mapeo.
Resolución de problemas en conexiones de Eclipse Ditto con MQTT
| Síntoma | Causa probable | Solución |
|---|---|---|
| El estado de la conexión sigue en failed | Esquema de URI o puerto incorrectos | Usa tcp:// con 1883 o ssl:// con 8883 |
| La conexión se cae justo después de conectar | Client ID duplicado o no autorizado | Establece un clientId único y desactiva el cliente publicador separado |
| Se reciben mensajes pero el gemelo no se actualiza | El contexto de autorización no está en la política del thing | Haz coincidir authorizationContext con un sujeto de la política |
| Errores de mapeo en los logs | El script falla con un payload inesperado | Protégete frente a campos ausentes y JSON no válido |
| No hay eventos en el topic de destino | Falta el filtro topics del target |
Incluye _/_/things/twin/events |
Obtén el diagnóstico de la conexión con GET /api/2/connections/{connectionId}/status y /logs después de activar el registro mediante el endpoint de comandos de conexión.
Cuándo usar Ditto y cuándo topics retenidos
Ditto añade un servicio de gemelos con APIs, políticas, búsqueda e histórico de cambios. Si solo necesitas que los visores carguen el estado actual, los topics MQTT retenidos pueden bastar y no requieren infraestructura adicional; consulta gemelo digital con retained messages MQTT. Elige Ditto cuando necesites consultas sobre muchos gemelos, control de acceso granular por gemelo, propiedades deseadas o una API REST para aplicaciones de negocio. Para ver dónde encaja cada uno en un stack completo, lee arquitectura de gemelo digital.
Ejecuta Eclipse Ditto sobre ConnectMQ
Ditto se ocupa de los gemelos; ConnectMQ se ocupa de la mensajería. Como broker MQTT en la nube con MQTT 3.1.1 y 5.0, TLS en el 8883 y un explorador de topics en vivo para ver la telemetría y los eventos de Ditto en paralelo, te ahorra el trabajo de operar tu propio broker. Regístrate en app.connectmq.com, crea un broker con el plan Serverless gratuito sin tarjeta de crédito e introduce sus credenciales en tu conexión de Ditto.
Preguntas frecuentes
¿Eclipse Ditto incluye un broker MQTT?
No. Ditto se conecta como cliente a un broker MQTT externo a través de su servicio de conectividad, así que eliges y operas el broker por separado o usas un broker MQTT gestionado.
¿Puede Ditto usar MQTT 5?
Sí. Establece connectionType en mqtt-5 para MQTT 5 o en mqtt para MQTT 3.1.1.
¿Los dispositivos tienen que enviar mensajes del Ditto Protocol?
No. Con un mapeo de payload como el ejemplo en JavaScript anterior, los dispositivos pueden publicar JSON plano y Ditto lo convierte en comandos del gemelo.
¿Cómo envío valores deseados de Ditto a los dispositivos?
Actualiza desiredProperties en una feature y añade un target que publique esos cambios, o envía live messages, a un topic de comandos al que esté suscrito el dispositivo.



