Skip to content

Repository files navigation

Microfactory Digital Twin Packages

A collection of Digital Twin (DT) implementations for an automated microfactory system, built on the WLDT (Web-based Laboratory Digital Twin) open-source framework. Each package models a physical machine in the factory as an independent, deployable digital twin.


System Overview

The microfactory consists of four physical machines working in a coordinated production pipeline. Each machine is mirrored by an independent Digital Twin. A fifth Multiprocess Station DT is a composed Digital Twin: it has no physical counterpart, but is built entirely from the digital data published by the four sub-DTs. It aggregates their states and OEE metrics into a unified factory view and coordinates high-level operations such as start, soft-stop, emergency-stop, and reset.

graph TB
    subgraph Physical["Physical World"]
        P1[Oven]
        P2[Vacuum Gripper]
        P3[Turntable]
        P4[Output Conveyor]
    end

    subgraph SubDTs["Sub-Machine Digital Twins"]
        DT1["oven-dt\n─────────────\nMQTT Physical Adapter\nShadowing Function\nMQTT + HTTP Digital Adapter"]
        DT2["vacuum-gripper-dt\n─────────────\nMQTT Physical Adapter\nShadowing Function\nMQTT + HTTP Digital Adapter"]
        DT3["turntable-dt\n─────────────\nMQTT Physical Adapter\nShadowing Function\nMQTT + HTTP Digital Adapter"]
        DT4["output-conveyor-dt\n─────────────\nMQTT Physical Adapter\nShadowing Function\nMQTT + HTTP Digital Adapter"]
    end

    subgraph ComposedDT["Composed Digital Twin"]
        MPS["multiprocess-station-with-oven-dt\n─────────────────────────────\nMQTT Physical Adapter  ←  reads sub-DT topics\nShadowing Function  ←  aggregates state + OEE\nMQTT + WebSocket Digital Adapter"]
    end

    subgraph Clients["External Clients"]
        C1[Dashboard / SCADA]
        C2[Control Application]
    end

    P1 -- MQTT sensors --> DT1
    P2 -- MQTT sensors --> DT2
    P3 -- MQTT sensors --> DT3
    P4 -- MQTT sensors --> DT4

    DT1 -- "machine-state, oee (MQTT)" --> MPS
    DT2 -- "machine-state, oee (MQTT)" --> MPS
    DT3 -- "machine-state, oee (MQTT)" --> MPS
    DT4 -- "machine-state, oee (MQTT)" --> MPS

    MPS -- "aggregated state, OEE\npickable, placeable (WebSocket + MQTT)" --> C1
    MPS -- "commands: start / stop / reset (MQTT)" --> C2
Loading

Packages

Package Machine DT ID Exposed Port
oven-dt/ Industrial oven 2AC2C63A-... HTTP :1234
vacuum-gripper-dt/ Vacuum gripper arm 62552ADA-... HTTP :1234
turntable-dt/ Rotating turntable with saw C3866359-... HTTP :1234
output-conveyor-dt/ Output conveyor belt 3606225E-... HTTP :1234
multiprocess-station-with-oven-dt/ Composed DT (aggregates sub-DTs) 8ea609a9-... WebSocket :8123

Architecture

WLDT Digital Twin Model

Every DT in this project follows the standard WLDT three-layer architecture:

Physical World
      │
      ▼
┌─────────────────────┐
│   Physical Adapter  │  ← Receives sensor data / actuator feedback (MQTT)
├─────────────────────┤
│ Shadowing Function  │  ← Core DT logic: state sync, OEE, anomaly detection
├─────────────────────┤
│   Digital Adapter   │  ← Exposes DT to external clients (MQTT, HTTP, WebSocket)
└─────────────────────┘
      │
      ▼
External Clients / Composed DT

Physical Adapters subscribe to MQTT topics published by the real hardware (for single-machine DTs) or to topics published by sub-DTs (for the Multiprocess Station). Each incoming message is parsed as a PhysicalPayloadMessage<T> and forwarded to the Shadowing Function as a physical property change event.

Shadowing Functions implement the synchronization logic: they maintain a replica of every physical property, run the state machine, count produced pieces, compute OEE, detect motor anomalies, and log all changes to CSV. In the Multiprocess Station, the Shadowing Function aggregates the states of all four sub-DTs instead of reading hardware directly.

Digital Adapters expose the digital state to external consumers. Single-machine DTs use an MQTT Digital Adapter (for state/OEE publishing) and an HTTP Digital Adapter (for REST queries). The Multiprocess Station uses MQTT and WebSocket adapters.

MQTT Topic Convention

multiprocess-station/machines/<machine>/<property>        # physical → DT
multiprocess-station/digital-twin/<machine>/<property>    # DT → clients

Where <machine> is one of: oven, vacuum-gripper, turntable, output-conveyor.

Machine State Machine

All DTs share the same state enum:

START → UNKNOWN → RESETTING → READY → WORKING → STOPPING → STOPPED
                                  ↕          ↕
                                BUSY       ANOMALY / INHERITED_ANOMALY

State is derived by combining multiple boolean signals published by the physical hardware (e.g. oven-state-working, oven-state-anomaly).

OEE Calculation

OEE (Overall Equipment Effectiveness) is computed per machine:

OEE = (pieces_counted × ideal_piece_time_ms) / elapsed_time_ms
Machine Ideal Piece Time
Oven 21 700 ms
Vacuum Gripper 20 000 ms
Turntable 5 500 ms
Output Conveyor 1 500 ms

The Multiprocess Station computes a combined OEE as the product of all four individual OEE values.

Anomaly Detection

Each single-machine DT uses a MotorAnomalyDetection utility: a timer is started when a motor actuator turns ON; if the motor has not turned OFF within the configured timeout, an anomaly callback fires and the DT transitions to the ANOMALY state.

Machine Motor Anomaly Timeout
Oven 4 000 ms
Turntable 3 000 ms
Vacuum Gripper 10 000 ms
Output Conveyor 3 000 ms

Common File Structure

Each package follows the same layout:

<package>/
├── pom.xml                             # Maven build (Java 24, WLDT deps)
├── Dockerfile                          # Multi-stage build → OpenJDK 24 image
├── config.yaml                         # Runtime configuration
└── src/main/java/it/barboneantonello/<pkg>/
    ├── DtXxxxProcess.java              # Entry point: wires adapters + engine
    ├── config/
    │   └── DigitalTwinConfig.java      # YAML-mapped configuration beans
    ├── models/
    │   └── PhysicalPayloadMessage.java # Generic sensor payload wrapper
    └── utils/
        ├── XxxxDtShadowingFunction.java # State sync, OEE, piece counting
        ├── MachineState.java            # State enum
        ├── MotorAnomalyDetection.java   # Timer-based stall detection
        └── CSVLogger.java               # Append-only state change log

Technology Stack

Component Technology
Language Java 24
Build Maven 3.9.9
DT Framework WLDT Core 0.4.0
Communication MQTT (physical ↔ DT ↔ clients), HTTP REST, WebSocket
Serialization GSON 2.8.9 (JSON), SnakeYAML 2.3 (config)
Data Logging OpenCSV 5.9
Deployment Docker (multi-stage, OpenJDK 24 base)

Configuration

All runtime parameters are defined in each package's config.yaml. The MQTT broker IP is set to 192.168.1.100 by default and must be updated to match your network:

dt_id: "<uuid>"
dt_name: "<name>"
mqtt_adapters:
  physical:
    broker: "192.168.1.100"   # ← update this
    port: 1883
    base_topic: "multiprocess-station/machines/<machine>/"
    adapter_id: "mqtt_pa"
  digital:
    broker: "192.168.1.100"   # ← update this
    port: 1883
    base_topic: "multiprocess-station/digital-twin/<machine>/"
    adapter_id: "mqtt_da"
http_digital_adapter:
  host: "0.0.0.0"
  port: 1234
  adapter_id: "http_da"

Building and Running

Local Build (per package)

cd <package-name>/
mvn clean install
java -jar target/<package-name>-*.jar

Docker

cd <package-name>/
docker build -t <package-name>:latest .
docker run --network host <package-name>:latest

--network host is recommended so the container can reach the MQTT broker on the local network without extra port mapping.


References

About

Industrial Microfactory - Digital Twin Packages

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages