Skip to content

Commit 1ef9f70

Browse files
dominicbettswilliam_harding
andauthored
HMI demo updates (#187)
# Fabrikam HMI-26 Demo This folder is a demo overlay on the base `explore-iot-operations` quickstart, showing an end-to-end industrial IoT solution for the Fabrikam rHDPE post-consumer plastics recycling facility — a 100 m × 40 m, 18-stage production line that uses Azure IoT Operations to stream live plant telemetry from the edge, Foundry Local (on-cluster) for real-time AI quality ops, Microsoft Fabric for analytics and dashboards, and NVIDIA Omniverse for a live digital twin of the plant floor. ## Does this introduce a breaking change? ``` [] Yes [x] No ``` ## Pull Request Type What kind of change does this Pull Request introduce? <!-- Please check the one that applies to this PR using "x". --> ``` [ ] Bugfix [ ] Feature [ ] Code style update (formatting, local variables) [ ] Refactoring (no functional changes, no api changes) [x] Documentation content changes [ ] Other... Please describe: ``` ## How to Test The code in this repository is purely an example. The main `explore-iot-operations` will give you a more complete understanding of the tools and infrastructure. --------- Co-authored-by: william_harding <wharding@microsoft.com>
1 parent f2c28a4 commit 1ef9f70

15 files changed

Lines changed: 1354 additions & 0 deletions
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Fabrikam HMI-26 Demo
2+
3+
This folder is a demo overlay on the base `explore-iot-operations` quickstart, showing an end-to-end industrial IoT solution for the Fabrikam rHDPE post-consumer plastics recycling facility — a 100 m × 40 m, 18-stage production line that uses Azure IoT Operations to stream live plant telemetry from the edge, Foundry Local (on-cluster) for real-time AI quality ops, Microsoft Fabric for analytics and dashboards, and NVIDIA Omniverse for a live digital twin of the plant floor.
4+
5+
## Architecture Overview
6+
7+
```
8+
Edge Device (K8s cluster)
9+
└── Azure IoT Operations
10+
├── edgemqttsim (recycling plant telemetry → MQTT broker)
11+
├── MQTT Broker (aio-broker)
12+
├── Dataflow pipelines → Azure
13+
└── Foundry Local (on-cluster AI inference, deployed via Helm)
14+
15+
Workstation
16+
└── NVIDIA Omniverse (digital twin / visualization)
17+
18+
Azure
19+
└── Microsoft Fabric (data pipelines & analytics)
20+
```
21+
22+
## Folder Structure
23+
24+
| Folder | Contents |
25+
|--------|----------|
26+
| [factory-model/](factory-model/) | Recycling plant simulation spec and edgemqttsim customizations |
27+
| [foundry-local/](foundry-local/) | Foundry Local setup, model configuration, and agent prompts |
28+
| [fabric-connectors/](fabric-connectors/) | Fabric Real-Time Intelligence connector docs and dataflow references |
29+
| [omniverse/](omniverse/) | Omniverse USD stage spec, connector config, and setup scripts |
30+
| [scripts/](scripts/) | Fix-it scripts and one-offs that solve HMI-26-specific issues |
31+
32+
## Prerequisites
33+
34+
This demo builds on the base quickstart. Complete the base install before applying HMI-26 customizations:
35+
36+
- [Base quickstart README](../readme.md)
37+
- [Advanced config](../README_ADVANCED.md)
38+
- Config file: `../config/aio_config.json` (resource group `<your-resource-group>`, cluster `<your-cluster-name>`)
39+
40+
## Getting Started
41+
42+
1. Complete the base Azure IoT Operations install (Path A or Path B from the base readme).
43+
2. Deploy the edgemqttsim module — see [factory-model/README.md](factory-model/README.md).
44+
3. Set up Foundry Local — see [foundry-local/README.md](foundry-local/README.md).
45+
4. Configure Fabric connectors — see [fabric-connectors/README.md](fabric-connectors/README.md).
46+
5. Connect Omniverse — see [omniverse/README.md](omniverse/README.md).
47+
6. Any environment-specific fixes are in [scripts/](scripts/).
48+
49+
---
50+
51+
## References
52+
53+
### Azure IoT Operations
54+
55+
- [Deploy Azure IoT Operations](https://learn.microsoft.com/azure/iot-operations/deploy-iot-ops/howto-deploy-iot-operations) — full install guide for the base platform
56+
- [Azure IoT Operations overview](https://learn.microsoft.com/azure/iot-operations/overview-iot-operations)
57+
- [Arc-enable a Kubernetes cluster](https://learn.microsoft.com/azure/azure-arc/kubernetes/quickstart-connect-cluster) — prerequisite for IoT Operations deployment
58+
- [Connect to an Arc-enabled cluster (proxy)](https://learn.microsoft.com/azure/azure-arc/kubernetes/cluster-connect) — how to use `az connectedk8s proxy` for kubectl access
59+
60+
### Foundry Local
61+
62+
- [Foundry Local overview](https://learn.microsoft.com/azure/ai-foundry/foundry-local/overview)
63+
- [Microsoft Agent Framework](https://learn.microsoft.com/azure/ai-foundry/agents/overview)
64+
65+
### Microsoft Fabric
66+
67+
- [Fabric Real-Time Intelligence overview](https://learn.microsoft.com/fabric/real-time-intelligence/overview)
68+
69+
### NVIDIA Omniverse
70+
71+
- [NVIDIA Omniverse documentation](https://docs.omniverse.nvidia.com/)
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
# Fabric Connectors — Fabrikam HMI-26
2+
3+
This folder documents how Azure IoT Operations dataflow pipelines deliver recycling plant telemetry into **Microsoft Fabric** for analytics, dashboards, and AI enrichment.
4+
5+
No ARM templates are stored here — those live in the base quickstart [`arm_templates/`](../../arm_templates/). This doc records the HMI-26-specific dataflow topology and what to configure in each Fabric service.
6+
7+
---
8+
9+
## Architecture
10+
11+
```
12+
IoT Operations MQTT Broker (edge)
13+
└── IoT Operations Dataflow Pipeline
14+
├── → Event Hub (ingestion)
15+
│ └── Fabric Eventstream → Eventhouse (KQL)
16+
│ └── Power BI Real-Time Dashboard
17+
└── → Fabric Lakehouse (batch / cold path)
18+
└── Notebooks → ML / OEE reports
19+
```
20+
21+
---
22+
23+
## Dataflow Pipelines
24+
25+
### Pipeline 1 - Recycling Plant Telemetry -> Event Hub
26+
27+
Forwards all `fabrikam/#` MQTT messages to Azure Event Hubs in near-real-time.
28+
29+
| Setting | Value |
30+
|---------|-------|
31+
| Source | MQTT topic `fabrikam/#` |
32+
| Destination | Event Hub namespace in `<your-resource-group>` |
33+
| Auth | Managed Identity (no secrets) |
34+
| Serialization | JSON passthrough |
35+
36+
The Event Hub name and namespace are configured in `aio_config.json`. The dataflow is deployed by `External-Configurator.ps1`.
37+
38+
### Pipeline 2 - Quality-enriched stream -> Eventhouse
39+
40+
After Foundry Local enrichment (colour quality classification, contamination scores), a second dataflow writes enriched records to the Fabric Eventhouse.
41+
42+
| Setting | Value |
43+
|---------|-------|
44+
| Source | Internal MQTT topic `fabrikam/enriched/#` |
45+
| Destination | Fabric Eventhouse via Eventstream |
46+
| KQL table | `plant_telemetry` |
47+
48+
---
49+
50+
## Microsoft Fabric Setup
51+
52+
### 1. Create a Fabric workspace
53+
54+
In the Fabric portal, create a workspace named `fabrikam-hmi26` (or link to an existing one).
55+
56+
### 2. Eventstream — connect Event Hub
57+
58+
1. In the workspace, create a new **Eventstream**.
59+
2. Add a source: **Azure Event Hub** → select the hub from `<your-resource-group>`.
60+
3. Add a destination: **Eventhouse** → create or select a KQL database.
61+
62+
### 3. KQL Database (Eventhouse)
63+
64+
Suggested table schema for `plant_telemetry`:
65+
66+
```kusto
67+
.create table plant_telemetry (
68+
timestamp: datetime,
69+
machine_id: string,
70+
process_stage: string,
71+
lot_id: string,
72+
source_zone: string,
73+
source_bin_id: string,
74+
throughput_kg_hr: real,
75+
oee_availability: real,
76+
oee_performance: real,
77+
oee_quality: real,
78+
contamination_ppm: real,
79+
separation_purity_pct: real,
80+
pellet_size_p50_mm: real,
81+
colour_r: int,
82+
colour_g: int,
83+
colour_b: int,
84+
quality_classification: string
85+
)
86+
```
87+
88+
Ingestion mapping (JSON -> columns):
89+
90+
```kusto
91+
.create table plant_telemetry ingestion json mapping 'plant_telemetry_mapping'
92+
'['
93+
' {"column":"timestamp","path":"$.timestamp","datatype":"datetime"},'
94+
' {"column":"machine_id","path":"$.machine_id","datatype":"string"},'
95+
' {"column":"process_stage","path":"$.process_stage","datatype":"string"},'
96+
' {"column":"lot_id","path":"$.lot_id","datatype":"string"},'
97+
' {"column":"source_zone","path":"$.source_zone","datatype":"string"},'
98+
' {"column":"throughput_kg_hr","path":"$.throughput_kg_hr","datatype":"real"},'
99+
' {"column":"contamination_ppm","path":"$.contamination_ppm","datatype":"real"},'
100+
' {"column":"quality_classification","path":"$.quality_classification","datatype":"string"}'
101+
']'
102+
```
103+
104+
### 4. Power BI Real-Time Dashboard
105+
106+
Connect a Power BI report directly to the KQL database. Recommended visuals:
107+
108+
- **OEE Gauge** - overall plant OEE (last 1 hour)
109+
- **Machine Status Grid** - colour-coded by `process_stage` and machine status
110+
- **Throughput Trend** - kg/hr across the production line over time
111+
- **Contamination Rate** - contamination_ppm trend per sorting/wash stage
112+
- **Pellet Quality Trend** - colour scan RGB readings at PKG-01; highlight blue-tint events
113+
- **Lot Lineage View** - trace `lot_id` from source bin/zone through all 18 stages to packaged output
114+
115+
---
116+
117+
## Managed Identity Permissions
118+
119+
The IoT Operations cluster's managed identity needs the following roles:
120+
121+
| Role | Scope |
122+
|------|-------|
123+
| `Azure Event Hubs Data Sender` | Event Hub namespace |
124+
| `Storage Blob Data Contributor` | Storage account (for Lakehouse cold path) |
125+
126+
These are granted by `grant_entra_id_roles.ps1` in the base quickstart. Confirm with:
127+
128+
```powershell
129+
az role assignment list --assignee <cluster-managed-identity-object-id> --output table
130+
```
131+
132+
---
133+
134+
## Troubleshooting
135+
136+
| Symptom | Check |
137+
|---------|-------|
138+
| No data in Eventhouse | Verify dataflow is `Running` in the IoT Operations portal; check Event Hub metrics |
139+
| Auth errors in dataflow | Re-run `grant_entra_id_roles.ps1`; confirm managed identity object ID |
140+
| Timestamps wrong in KQL | Ensure `timestamp` field is ISO 8601 UTC in the MQTT payload |
141+
| Eventstream lag > 30 s | Check Event Hub partition count; scale up if needed |
142+
143+
---
144+
145+
## References
146+
147+
### How to do this yourself
148+
149+
- [IoT Operations Dataflow overview](https://learn.microsoft.com/azure/iot-operations/connect-to-cloud/overview-dataflow) — how dataflow pipelines work
150+
- [Configure an Event Hubs dataflow destination](https://learn.microsoft.com/azure/iot-operations/connect-to-cloud/howto-configure-destination-event-hubs) — step-by-step for the MQTT → Event Hub pipeline
151+
- [Fabric Eventstream overview](https://learn.microsoft.com/fabric/real-time-intelligence/eventstream/overview)
152+
- [Add Azure Event Hubs as an Eventstream source](https://learn.microsoft.com/fabric/real-time-intelligence/eventstream/add-source-azure-event-hubs) — wire Event Hub output into Fabric
153+
- [Fabric Eventhouse overview](https://learn.microsoft.com/fabric/real-time-intelligence/eventhouse) — the KQL database that stores `plant_telemetry`
154+
- [Fabric Real-Time Intelligence overview](https://learn.microsoft.com/fabric/real-time-intelligence/overview)
155+
- [KQL quick reference](https://learn.microsoft.com/azure/data-explorer/kql-quick-reference)
156+
- [Grant managed identity RBAC for Event Hubs](https://learn.microsoft.com/azure/event-hubs/authenticate-managed-identity) — required for the dataflow managed identity auth
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# Plant Simulation Model — Fabrikam HMI-26
2+
3+
This folder documents the **recycling plant simulation model** for the HMI-26 demo and the customizations applied to the `edgemqttsim` module.
4+
5+
The simulator itself lives in the [shared module](../../modules/edgemqttsim/).
6+
7+
This folder does **not** copy those files. Instead it records:
8+
- What the plant model represents (Fabrikam rHDPE recycling)
9+
- What was changed from the default simulator configuration
10+
- How to build and deploy the module for this environment
11+
- The MQTT topic layout and asset definitions
12+
13+
---
14+
15+
## Plant Model: Fabrikam rHDPE Recycling Facility
16+
17+
The simulated plant represents the Fabrikam post-consumer plastics recycling facility — a 100 m × 40 m operation that processes collected plastic waste into production-ready recycled HDPE (rHDPE) pellets. It is modeled in the [`message_structure.yaml`](../../modules/edgemqttsim/message_structure.yaml) config and documented in [`HMI-fabrikam-data-spec.md`](../../modules/edgemqttsim/HMI-fabrikam-data-spec.md).
18+
19+
### Production Line and Equipment
20+
21+
Material flows through 18 stages from collection to finished pellet packaging:
22+
23+
| Stage | Equipment | MQTT topic |
24+
|-------|-----------|------------|
25+
| Collection | Smart bins, trucks | `fabrikam/collection`, `fabrikam/collection_transport` |
26+
| Inbound identification | Feed scanner | `fabrikam/inbound_identification` |
27+
| Feeding | Feed conveyor (FC-01) | `fabrikam/feeding` |
28+
| Sorting | NIR optical sorters (NIR-01, NIR-02) | `fabrikam/sorting` |
29+
| Primary size reduction | Shredder (SHR-01) | `fabrikam/primary_size_reduction` |
30+
| Secondary size reduction | Granulator (GRN-01) | `fabrikam/secondary_size_reduction` |
31+
| Pre-wash | Pre-wash tank (PW-01) | `fabrikam/pre_wash` |
32+
| Friction wash | Friction washers (FW-01, FW-02) | `fabrikam/friction_wash` |
33+
| Hot wash | Hot wash tank (HW-01) | `fabrikam/hot_wash` |
34+
| Rinsing | Rinse tank (RW-01) | `fabrikam/rinsing` |
35+
| Density separation | Float-sink separator (FS-01) | `fabrikam/density_separation` |
36+
| Mechanical drying | Centrifugal dryer (CD-01) | `fabrikam/mechanical_drying` |
37+
| Thermal drying | Thermal dryer (TD-01) | `fabrikam/thermal_drying` |
38+
| Post-dry buffering | Collection bin (CB-EXTR-01) | `fabrikam/post_dry_buffering` |
39+
| Extrusion | Extruders (EXT-01, EXT-02) | `fabrikam/extrusion` |
40+
| Melt filtration | Screen changers (SC-01, SC-02) | `fabrikam/melt_filtration` |
41+
| Pelletizing | Pelletizer (PEL-01) | `fabrikam/pelletizing` |
42+
| Pellet screening | Pellet screener (PS-01) | `fabrikam/pellet_screening` |
43+
| Packaging | Bagging station (PKG-01) | `fabrikam/packaging` |
44+
45+
### Key Design Decisions
46+
47+
- One simulated lot travels end-to-end in ~900 seconds (configurable in `message_structure.yaml`).
48+
- Machine IDs follow `<TYPE>-<NN>` (e.g., `NIR-02`, `EXT-01`).
49+
- All messages carry `lot_id` and `source_zone` to support full lineage tracing from collection bin to finished pellet.
50+
- OEE (Availability, Performance, Quality) is derivable from raw telemetry — no pre-aggregation.
51+
- The PKG station emits colour scan readings (RGB) used by the Colour Quality Ops Agent to detect blue-tint contamination.
52+
53+
---
54+
55+
## edgemqttsim Module Reference
56+
57+
Source: [`quickstart/modules/edgemqttsim/`](../../modules/edgemqttsim/)
58+
59+
Key files:
60+
61+
| File | Purpose |
62+
|------|---------|
63+
| `app.py` | Main MQTT client — connects to `aio-broker`, drives message loop |
64+
| `messages.py` | Message generation logic per equipment type |
65+
| `message_structure.yaml` | Tune frequencies, machine counts, quality distributions |
66+
| `deployment.yaml` | K8s deployment — update `image:` field to your ACR |
67+
| `Dockerfile` | Build image for ACR push |
68+
| `mqtt-asset-endpoint.yaml` | Azure IoT Operations Asset Endpoint Profile for the simulator |
69+
| `mqtt-asset-example.yaml` | Example Azure IoT Operations Asset definition |
70+
| `arm_asset_creation.py` | Helper to create Azure IoT Operations assets via ARM API |
71+
| `deploy-mqtt-assets.sh` | Shell wrapper for asset creation |
72+
| `HMI-fabrikam-data-spec.md` | Full payload schema for all machine types and stages |
73+
74+
---
75+
76+
## HMI-26 Customizations
77+
78+
Record changes made to the default `edgemqttsim` config for this environment below.
79+
80+
### `message_structure.yaml` changes
81+
82+
<!--
83+
Document any tweaks to stage weights, machine counts, lot duration, or anomaly seed.
84+
Example:
85+
- Reduced total_duration_sec from 900 to 600 for faster demo cycles
86+
- Increased contamination probability at sorting stage to make blue-tint events more frequent
87+
-->
88+
89+
_No customizations recorded yet. Update this section as changes are made._
90+
91+
### `deployment.yaml` changes
92+
93+
| Setting | Value | Notes |
94+
|---------|-------|-------|
95+
| `image` | `<your-acr-name>.azurecr.io/edgemqttsim:latest` | HMI-26 ACR |
96+
| `MQTT_BROKER` | `aio-broker.azure-iot-operations.svc.cluster.local` | Do not change |
97+
| `MQTT_PORT` | `18883` | MQTTS |
98+
99+
---
100+
101+
## Building and Deploying
102+
103+
### 1. Build and push the image
104+
105+
```bash
106+
# From quickstart/modules/edgemqttsim/
107+
docker build -t <your-acr-name>.azurecr.io/edgemqttsim:latest .
108+
az acr login --name <your-acr-name>
109+
docker push <your-acr-name>.azurecr.io/edgemqttsim:latest
110+
```
111+
112+
### 2. Deploy to cluster
113+
114+
```bash
115+
# From quickstart/modules/edgemqttsim/
116+
kubectl apply -f deployment.yaml
117+
```
118+
119+
The [`Deploy-EdgeModules.ps1`](../../external_configuration/Deploy-EdgeModules.ps1) script automates ACR credential setup and deployment. Run it from the Windows management machine after the base Azure IoT Operations install.
120+
121+
### 3. Verify
122+
123+
```bash
124+
kubectl logs -l app=edgemqttsim -f
125+
# Expect: "Published: factory/cnc ..." messages every second
126+
```
127+
128+
---
129+
130+
## MQTT Asset Definitions
131+
132+
Azure IoT Operations Asset resources map the simulator's MQTT streams into the IoT Operations asset model. The base templates are in the [shared module](../../modules/edgemqttsim/):
133+
134+
- [`mqtt-asset-endpoint.yaml`](../../modules/edgemqttsim/mqtt-asset-endpoint.yaml) — defines the MQTT source endpoint
135+
- [`mqtt-asset-example.yaml`](../../modules/edgemqttsim/mqtt-asset-example.yaml) — example asset for a single machine type
136+
137+
HMI-26-specific asset YAML files should be added to this folder when created.
138+
139+
---
140+
141+
## References
142+
143+
### In this repo
144+
145+
- [HMI-fabrikam-data-spec.md](../../modules/edgemqttsim/HMI-fabrikam-data-spec.md) — full payload schema for all stages
146+
- [Foundry Local](../foundry-local/README.md) — on-cluster AI for quality ops and contamination detection
147+
- [Omniverse](../omniverse/README.md) — digital twin visualization of this plant
148+
149+
### How to do this yourself
150+
151+
- [IoT Operations MQTT Broker overview](https://learn.microsoft.com/azure/iot-operations/manage-mqtt-broker/overview-broker) — understand the broker that edgemqttsim publishes to
152+
- [Manage assets in IoT Operations](https://learn.microsoft.com/azure/iot-operations/discover-manage-assets/overview-manage-assets) — map MQTT streams to IoT Operations Asset resources
153+
- [Push a Docker image to Azure Container Registry](https://learn.microsoft.com/azure/container-registry/container-registry-get-started-docker-cli) — build and push the edgemqttsim image
154+
- [Pull from ACR in Kubernetes](https://learn.microsoft.com/azure/container-registry/container-registry-auth-kubernetes) — configure the ACR pull secret used by the deployment
155+
- [Configure MQTT broker authentication](https://learn.microsoft.com/azure/iot-operations/manage-mqtt-broker/howto-configure-authentication) — SAT-based auth used by the simulator pod

0 commit comments

Comments
 (0)