
Part 3 designs an AI-ready data platform over the canonical BIM–ERP–OT model, covering medallion architecture, governance, feature engineering, digital twins and practical cross-domain analytics and AI use cases.
The canonical model and entity resolution logic from Part 2 only deliver value when embedded into a production-grade data platform that supports continuous ingestion, transformation and consumption.
Industrial AI reference architectures show exactly this: ERP and OT data flows via Industrial DataOps/edge into a cloud lakehouse where bronze tables capture raw payloads, silver tables hold harmonised models and gold tables feed BI and AI.
A semantic/graph layer and APIs on top expose BIM–ERP–OT semantics for digital twins and agentic AI.

The ingestion and bronze layers handle raw data capture and persistence.
Bronze remains as close to the source as possible for traceability and reprocessing.
The silver layer is where harmonisation and canonicalization become concrete.
You end up with tables like silver.asset, silver.location, silver.work_package, silver.measurement, silver.event, which are the “source of truth” for cross-domain semantics.
Bitemporal identity as a non‑negotiable AI requirement
In heavy industry, assets are swapped, re-tagged, reconfigured and re-mapped continuously; what you believed an asset was at the time of a failure may differ from what you think it is today.
If your silver.asset is just “latest truth,” any AI model evaluation or root-cause analysis that tries to replay events as-of a failure timestamp will silently use current mappings, not the mappings that were valid at that second. Bitemporal modeling fixes this by tracking both:
That allows exact time-travel queries for identity, not just for raw data.
Define an append-only ledger instead of a replace-in-place table:
Append-only bitemporal identity ledger for assets
Create the asset identity ledger as an append-only Delta table so every mapping between a canonical asset and a source-system identifier is preserved over time.
CREATE TABLE IF NOT EXISTS silver.asset_identity_ledger (
canonical_asset_id STRING NOT NULL,
source_id STRING NOT NULL, -- ERP asset_code or BIM element_id
source_system STRING NOT NULL, -- e.g., 'ERP' or 'BIM'
match_rule STRING NOT NULL,
match_score DOUBLE NOT NULL,
-- Bitemporal columns
asserted_at TIMESTAMP NOT NULL, -- when this mapping was written
valid_from TIMESTAMP NOT NULL, -- when this mapping becomes valid
valid_to TIMESTAMP -- when this mapping stops being valid; NULL means open-ended
)
USING DELTA;
New mappings are appended; when an asset is swapped or reconfigured, you insert a new row with a later valid_from and set valid_to on the previous one, implementing a bitemporal SCD2 pattern over identity.
You can keep a convenience “current view”:
CREATE OR REPLACE VIEW silver.asset_current AS
SELECT *
FROM silver.asset_identity_ledger
WHERE valid_to IS NULL;
Instead of joining telemetry to timeless mappings, join to the ledger with a validity predicate:
-- Silver.Measurement: OT telemetry mapped to assets via bitemporal identity
CREATE OR REPLACE TABLE silver.measurement AS
SELECT
t.telemetry_id,
l.canonical_asset_id AS asset_id,
t.tag_name,
t.timestamp_utc,
t.value_std,
t.measurement_type,
t.unit_std,
t.quality_flag,
-- propagate mapping provenance
l.source_system,
l.source_id,
l.match_rule,
l.match_score,
l.asserted_at,
l.valid_from,
l.valid_to
FROM silver.telemetry_raw AS t
JOIN silver.asset_tag_mappings AS m
ON t.tag_name = m.tag_name
JOIN silver.asset_identity_ledger AS l
ON l.source_id = m.source_id
AND l.source_system = m.source_system
AND t.timestamp_utc >= l.valid_from
AND (l.valid_to IS NULL OR t.timestamp_utc < l.valid_to);
Now each telemetry event is bound to the identity mapping that was actually valid at that instant, not whatever mapping exists today.
You can still present a silver.asset logical model as a view over the ledger and source metadata:
-- Bitemporal silver.asset view enriched with ERP/BIM metadata
CREATE OR REPLACE VIEW silver.asset AS
SELECT
l.canonical_asset_id AS asset_id,
l.source_id,
l.source_system,
COALESCE(e.description, b.description) AS asset_name,
COALESCE(e.asset_class, b.ifc_class) AS asset_class,
COALESCE(e.plant_code, b.project_id) AS site_code,
l.match_rule,
l.match_score,
l.asserted_at,
l.valid_from,
l.valid_to
FROM silver.asset_identity_ledger AS l
LEFT JOIN silver.erp_asset_master AS e
ON l.source_system = 'ERP'
AND l.source_id = e.asset_code
LEFT JOIN silver.bim_equipment AS b
ON l.source_system = 'BIM'
AND l.source_id = b.element_id;
Gold-layer tables are designed around use cases and KPIs, not source systems.
These tables directly feed BI, AI and digital twin experiences.
The rolling vibration features are a good start, but in a heavy-industry setting they must sit inside a Stateful Feature Store Loop with Circuit‑Breaker Logic, not a one‑way “compute and forget” pipeline.
The loop is:
Feature computation (unchanged)
from pyspark.sql import functions as F
from pyspark.sql.window import Window
asset = spark.table("silver.asset")
meas = spark.table("silver.measurement")
events = spark.table("silver.event")
vib = meas.filter(F.col("measurement_type") == "VIBRATION_RMS")
window_spec = (
Window.partitionBy("asset_id")
.orderBy(F.col("timestamp_utc").cast("long"))
.rangeBetween(-30 * 24 * 3600, 0)
)
vib_features = (
vib
.withColumn("vib_mean_30d", F.avg("value_std").over(window_spec))
.withColumn("vib_std_30d", F.stddev("value_std").over(window_spec))
.withColumn("vib_max_30d", F.max("value_std").over(window_spec))
)
failures = events.filter(F.col("event_type") == "FAILURE") \
.select("asset_id", "event_ts")
asset_health_features = (
vib_features.alias("v")
.join(asset.alias("a"), "asset_id")
.join(failures.alias("f"), "asset_id", "left")
.groupBy("asset_id")
.agg(
F.max("v.timestamp_utc").alias("as_of_ts"),
F.last("vib_mean_30d").alias("vib_mean_30d"),
F.last("vib_std_30d").alias("vib_std_30d"),
F.last("vib_max_30d").alias("vib_max_30d"),
F.count("f.event_ts").alias("failure_count_total")
)
)
asset_health_features.write.mode("overwrite").saveAsTable("gold.asset_health_features")
On the consumption side, an agentic workflow might do something like:
Conceptually:
# Pseudo-code for a circuit-breaker check (not full implementation)
health = spark.table("gold.asset_health_features").filter(F.col("asset_id") == some_asset_id).collect()[0]
# proposed_setpoint_vib_rms comes from a model / agent
proposed_setpoint_vib_rms = model_output.setpoint_vib_rms
# Lookup design tolerances via semantic layer / BIM-derived table
design_limits = spark.table("silver.bim_design_tolerances") \
.filter(F.col("asset_id") == some_asset_id) \
.select("max_vibration_rms", "safety_factor") \
.collect()[0]
max_allowed = design_limits["max_vibration_rms"] * design_limits["safety_factor"]
if proposed_setpoint_vib_rms <= max_allowed:
# Recommendation passes semantic guardrail; can be passed to MES with proper controls
execute_mes_setpoint_change(asset_id=some_asset_id,
new_vib_setpoint=proposed_setpoint_vib_rms)
else:
# Circuit breaker trips; log and route to human or reject
log_violation(asset_id=some_asset_id,
proposed_vib=proposed_setpoint_vib_rms,
max_allowed=max_allowed)
raise Exception("Semantic guardrail violation: proposed set-point exceeds BIM design tolerance")
Here:
This is the pattern that turns rolling vibration features from pure analytics into deterministic AI guardrails for autonomous or semi-autonomous MES control, aligning with your broader “Semantic Moat / Stateful Lakehouse Fabrics” narrative.
Once gold tables are stable, you can formalize features and models:
Industrial AI reference architectures describe this as agents orchestrating production control recommendations, field service assistance and machine vision decisions.
Bringing BIM, ERP and OT data together raises governance requirements:
Semantic-CDE and digital-twin research emphasizes that semantic coherence plus governance is key to making integrated BIM–IoT–GIS data trustworthy for real-time decision-making.
With this architecture in place, you can implement analytics that were previously manual or impossible.
These use cases directly impact P&L when embedded into daily operations, not just dashboards.
Digital twins are a natural UX for AI-ready BIM–ERP–OT data:
Multi-layer BIM–IoT digital twin architectures show that ontology-based integration and service-oriented data access enable real-time monitoring, optimization and predictive maintenance.
Regardless of cloud or vendor, the roadmap tends to converge:
1. Strategize
2. Operationalize
3. Industrialize
Reference architectures from industrial AI and edge-to-cloud OT pipelines consistently show that vendor-neutral, AI-ready lakehouse backbones are the sustainable path to cross-domain analytics.
BIM, ERP and shop-floor systems will remain specialized, but their data does not have to remain siloed.
By combining canonical models, rigorous schema harmonisation, robust entity resolution patterns and a governed medallion data platform, you can turn fragmented construction and manufacturing data into an AI-ready backbone that underpins digital twins, advanced analytics and agentic AI.
The heavy lifting is in defining semantics and cleaning and mapping legacy data, but once built, each new AI use case becomes a configuration exercise instead of a bespoke integration project shifting your organization from AI experiments to AI-native operations.