Uma alternativa ao AWS IoT TwinMaker faz sentido quando você quer gêmeos digitais 3D interativos, mas prefere formatos abertos, protocolos padrão e a liberdade de rodar em qualquer lugar. Este guia compara as alternativas realistas, de outras plataformas a stacks web totalmente abertas, e depois mostra a técnica central: vincular dados MQTT ao vivo a nós de um modelo glTF no navegador. Você terminará com um padrão funcional que pode ser expandido para um gêmeo 3D completo.
Para uma base sobre o que é um gêmeo digital em geral, veja o nosso guia de tecnologia.
O Que o TwinMaker Reúne
O AWS IoT TwinMaker combina várias peças de que um gêmeo 3D precisa:
- Entidades e componentes que modelam seus ativos e os ligam a fontes de dados.
- Conectores para outros serviços de dados da AWS, para dados de séries temporais, vídeo e documentos.
- Um compositor de cenas para posicionar modelos 3D e anexar tags e regras de cor orientadas por dados.
- Visualização por meio de um plugin do Grafana ou de um kit de aplicação para apps web personalizados.
Quando seus dados já estão nesses serviços da AWS, isso é conveniente. A contrapartida é que o gêmeo, suas cenas e seus vínculos de dados são expressos em conceitos específicos do serviço. Migrar para outra nuvem, ou para a rede on-premises de uma planta (digamos, em Manaus ou Campinas), significa reconstruí-los. Os roadmaps das plataformas também mudam com o tempo, então verifique o status atual de qualquer serviço gerenciado de gêmeos antes de comprometer com ele um projeto de longo prazo.
Do Que um Gêmeo 3D Portável Precisa
Tirando as marcas, todo gêmeo 3D tem as mesmas cinco camadas:
| Camada | Função | Opções portáveis |
|---|---|---|
| Geometria | O modelo 3D da planta ou da máquina | glTF/GLB exportado de CAD ou do Blender |
| Renderização | Desenhar a cena e interagir com ela no navegador | Three.js, Babylon.js, CesiumJS para dados geoespaciais |
| Dados ao vivo | Entregar os valores atuais à cena | MQTT sobre WebSocket seguro |
| Vínculo | Mapear campos de dados para nós, cores, rótulos, animações | Um pequeno arquivo de mapeamento JSON mais o seu código |
| Histórico | Tendências, reprodução, análises | Banco de dados de séries temporais mais Grafana ou gráficos próprios |
Cada camada tem opções abertas e maduras, e cada uma pode ser substituída sem mexer nas outras. Essa independência é a verdadeira resposta ao lock-in.
As Alternativas Comparadas
| Abordagem | Criação 3D | Caminho dos dados | Lock-in | Esforço |
|---|---|---|---|---|
| Serviços de gêmeos de outras nuvens | Editor de cenas do fornecedor | Serviços de IoT e de dados do fornecedor | Alto | Baixo a médio |
| Motores de jogos (Unity, Unreal) | Editor completo do motor | Plugins ou clientes MQTT personalizados | Médio (licenciamento do motor, runtimes) | Médio a alto |
| Three.js + MQTT | Código, glTF de qualquer ferramenta | MQTT sobre WSS diretamente no navegador | Baixo | Médio |
| Babylon.js + MQTT | Código mais as ferramentas do Babylon | MQTT sobre WSS | Baixo | Médio |
| Grafana + painéis + banco de dados alimentado por MQTT | 3D limitado, gráficos fortes | Telegraf ou um assinante grava em um banco de dados | Baixo | Baixo |
Os motores de jogos se destacam em treinamentos fotorrealistas e VR; veja o guia de gêmeo digital com Unity. Para dashboards operacionais que qualquer pessoa pode abrir em um navegador, as bibliotecas web costumam ser a melhor opção. O guia de gêmeo digital 3D na web compara Three.js e Babylon.js com mais profundidade.
Vinculando Dados MQTT a um Modelo glTF
O coração de qualquer substituto do TwinMaker é a camada de vínculo: "quando este tópico mudar, atualize aquele nó 3D". Mantenha o vínculo em dados, e não em código, para que pessoas que não são desenvolvedoras possam mantê-lo.
Veja um arquivo de mapeamento. Cada entrada liga um tópico e um campo do payload a um nó nomeado da cena glTF e diz o que fazer com o valor:
[
{ "topic": "furnace1/state", "field": "temp_c", "node": "Furnace_Body",
"action": "color", "ranges": [[0, 600, "#4caf50"], [600, 900, "#ff9800"], [900, 2000, "#f44336"]] },
{ "topic": "conveyor1/state", "field": "running", "node": "Conveyor_Belt",
"action": "visible-flag" },
{ "topic": "tank3/state", "field": "level_pct", "node": "Tank3_Liquid",
"action": "scale-y", "max": 100 }
]
E o módulo de navegador que o aplica. Instale three e mqtt com npm e faça o bundle com Vite ou ferramenta semelhante. O modelo plant.glb deve conter nós com os nomes usados no mapeamento.
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import mqtt from "mqtt";
import bindings from "./bindings.json";
const PREFIX = "connectmq/demo/tm-alt-2h7/site1";
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 0.1, 500);
camera.position.set(20, 15, 20);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
new OrbitControls(camera, renderer.domElement);
scene.add(new THREE.HemisphereLight(0xffffff, 0x404040, 3));
const nodes = {};
new GLTFLoader().load("/plant.glb", (gltf) => {
scene.add(gltf.scene);
for (const b of bindings) {
const obj = gltf.scene.getObjectByName(b.node);
if (!obj) { console.warn("Missing node", b.node); continue; }
obj.traverse((o) => { if (o.isMesh) o.material = o.material.clone(); });
nodes[b.node] = obj;
}
});
function apply(b, value) {
const obj = nodes[b.node];
if (!obj) return;
if (b.action === "color") {
const hit = b.ranges.find(([lo, hi]) => value >= lo && value < hi);
if (hit) obj.traverse((o) => o.isMesh && o.material.color.set(hit[2]));
} else if (b.action === "visible-flag") {
obj.traverse((o) => o.isMesh && o.material.emissive?.set(value ? 0x224422 : 0x000000));
} else if (b.action === "scale-y") {
obj.scale.y = Math.max(0.01, value / b.max);
}
}
const client = mqtt.connect("wss://broker.connectmq.com:8084/mqtt", {
clientId: "tm-alt-2h7-view-" + Math.random().toString(16).slice(2, 8),
protocolVersion: 5,
});
client.on("connect", () => client.subscribe(`${PREFIX}/+/state`));
client.on("message", (topic, payload) => {
const rel = topic.slice(PREFIX.length + 1);
const data = JSON.parse(payload.toString());
for (const b of bindings) if (b.topic === rel && b.field in data) apply(b, data[b.field]);
});
renderer.setAnimationLoop(() => renderer.render(scene, camera));
Teste publicando estados retidos no servidor MQTT público (gratuito), que serve para testes e protótipos, não para dados de produção:
mosquitto_pub -h broker.connectmq.com -p 1883 -i tm-alt-2h7-pub -r \
-t "connectmq/demo/tm-alt-2h7/site1/furnace1/state" -m '{"temp_c":935}'
mosquitto_pub -h broker.connectmq.com -p 1883 -i tm-alt-2h7-pub2 -r \
-t "connectmq/demo/tm-alt-2h7/site1/tank3/state" -m '{"level_pct":62}'
Como os estados são retidos, a cena mostra as cores e os níveis corretos no momento em que carrega e depois se atualiza ao vivo. É a mesma experiência que um compositor de cenas gerenciado oferece, construída com peças abertas. O guia para vincular dados IoT a um modelo 3D cobre mais ações, como animações, rótulos e alarmes piscantes, e a documentação do Three.js é a referência para o lado da renderização.
Armadilhas ao Deixar um Serviço Gerenciado de Gêmeos
- Os nomes dos nós mudam. Reexportar um modelo CAD pode renomear nós e quebrar vínculos silenciosamente. Registre os nós ausentes no carregamento, como faz o código acima, e mantenha os nomes estáveis no seu pipeline de exportação.
- Materiais compartilhados. No glTF, muitas malhas costumam compartilhar um único material, então colorir um nó colore todos. Clone os materiais dos nós vinculados.
- Modelos pesados. Exportações de CAD podem ser enormes. Reduza a geometria, mescle malhas estáticas e use glTF comprimido para manter tempos de carregamento razoáveis.
- O histórico é separado. Os dados MQTT ao vivo controlam a cena, mas tendências e reprodução precisam de um banco de dados. Conecte um serviço gravador ou o Telegraf aos mesmos tópicos.
- Credenciais no navegador. Tudo o que é enviado a um navegador pode ser lido pelo usuário. Dê aos visualizadores credenciais voltadas para leitura, separadas das usadas pelos gateways que publicam.
- Estado ausente no primeiro carregamento. Se os gateways publicam apenas mudanças, uma cena recém-aberta fica em branco até que algo mude. Publique mensagens de estado completo com a flag retain para que todo visualizador comece pela situação atual.
- Renderizar a cada mensagem. Telemetria em alta taxa pode disparar mais atualizações de cena do que a tela consegue mostrar. Armazene os valores mais recentes quando as mensagens chegarem e aplique-os uma vez por quadro de animação.
Um Caminho de Migração em Quatro Passos
Se você está substituindo um gêmeo gerenciado existente, em vez de começar do zero, avance em passos pequenos e reversíveis:
- Exporte seus assets 3D para glTF e confirme os nomes de nós de que você precisa para os vínculos.
- Faça os gateways publicarem em um broker MQTT em paralelo com o caminho de dados existente.
- Reconstrua os vínculos da cena como um arquivo de mapeamento e compare o novo visualizador com o antigo lado a lado.
- Migre o histórico para um banco de dados de séries temporais alimentado pelos mesmos tópicos e, então, desative o caminho antigo.
Hospedando a Camada de Dados
A camada de dados ao vivo é a única peça que precisa estar sempre ligada e acessível tanto pela planta quanto pelo navegador. Um broker MQTT gerenciado com suporte a WebSocket seguro resolve isso sem abrir portas na planta: os gateways se conectam de saída via TLS, e os navegadores se conectam via WSS.
A ConnectMQ oferece exatamente isso: TLS na porta 8883 para gateways, WebSocket seguro na porta 8084 no caminho /mqtt para navegadores, suporte a MQTT 5 e um portal com explorador de tópicos ao vivo. A ConnectMQ também mantém uma demo web pública de gêmeo digital 3D, uma fábrica com máquina CNC, braço robótico, forno, tanque, esteira e bomba atualizados ao vivo via WSS, construída com esse mesmo padrão de navegador mais MQTT. Em produção, troque o servidor MQTT público pelas credenciais do seu broker MQTT gerenciado privado, obtidas no portal: YOUR_USERNAME, YOUR_PASSWORD e YOUR_CLIENT_ID.
Construa Seu Gêmeo 3D na ConnectMQ
Bibliotecas web 3D abertas e um broker MQTT padrão dão a você um gêmeo interativo totalmente sob o seu controle. Comece com um broker Serverless gratuito da ConnectMQ, sem cartão de crédito, e conecte hoje mesmo sua primeira cena glTF a dados ao vivo.
Perguntas frequentes
Qual é uma boa alternativa ao AWS IoT TwinMaker para 3D?
Para gêmeos operacionais no navegador, Three.js ou Babylon.js com modelos glTF e MQTT sobre WebSocket seguro é uma escolha flexível e portável. Motores de jogos como o Unity atendem experiências fotorrealistas ou em VR.
Posso reutilizar meus modelos 3D do TwinMaker?
Normalmente sim, se estiverem em formato glTF ou GLB. Você precisará recriar os vínculos de dados e o posicionamento das tags, o que fica mais fácil se você os mantiver em um arquivo de mapeamento, como mostrado acima.
Os navegadores se conectam diretamente ao MQTT?
Sim. O MQTT.js se conecta via WebSocket ou WebSocket seguro, então uma página web pode assinar tópicos sem um relay no backend. Em produção, use TLS e credenciais separadas para os visualizadores.
Para onde vão os dados históricos sem o TwinMaker?
Use um banco de dados de séries temporais alimentado por um assinante MQTT, como o Telegraf ou um pequeno script, e visualize-os no Grafana ou em gráficos dentro da página do seu gêmeo.



