Digital Thread — The «Same Name» Across Systems
A digital thread is not about collecting data in one place. It enables distributed systems to refer to the same objects by the same names and trace the relationships and history of those objects. Simply collecting data creates a data swamp. When names remain connected, the data forms a thread even when it is distributed.
This article divides the thread into three strands—identity, relationships, and time—and explains where each strand breaks and how to reconnect it. The examples come from actual implementations in the PlantPulse platform, but the principles apply to any factory and any technology stack.
Engineers responsible for integrating MES, ERP, historians, and CMMS; architects designing factory data models; and anyone who has wondered, “We have all the data, so why can’t we get an answer?” For related reading, see Manufacturing AI — What Factory Data Demands of Models.
1. What It Is—and What It Is Not
A product is designed, its process is defined, it is turned into a work order, it undergoes inspection, and the equipment fails and receives maintenance. Each stage is recorded by a different system. A digital thread is the line that lets you trace those records backward.
Using the thread to answer “Why did the defect rate for this lot increase?” looks like this:
불량 로트 ─(어느 작업지시?)─▶ 워크오더 ─(어느 설비, 언제?)─▶ 설비 · 시간 구간
─(그때 그 설비의 신호는?)─▶ 태그 시계열 ─(상류는?)─▶ 공급 설비 · 유틸리티
─(그 설비의 정비 이력 · 절차서는?)─▶ 문서
Each arrow represents one join across a system boundary. If even one join breaks, the investigation stops there and someone starts opening multiple spreadsheets to match the records manually.
| Commonly confused term | Difference |
|---|---|
| Digital twin | A twin is a state model of one object: What condition is this pump in now? A thread is a reference connecting objects and time: What does this pump feed, which work order used it, and what happened at that time? Even with multiple twins, without a thread they remain isolated islands that know nothing about one another |
| Data lake | A lake provides storage. Even if all data is placed in one location, it cannot be joined when the IDs do not match |
| Integrated platform | One product providing every function is different from multiple systems using the same names. A thread is the latter |
2. Where the Thread Breaks
In the field, threads usually break in one of four ways.
| Break type | Example |
|---|---|
| Different names | SCADA calls the same pump P-101A, CMMS calls it PUMP_101_A, and ERP identifies it by asset number 400123 |
| Missing relationships | The hierarchy shows which line the equipment belongs to, but nowhere records the flow—what it feeds—or the dependencies—which utilities it relies on |
| Misaligned time | Equipment clocks, server clocks, and record timestamps differ. When a disconnected link is restored, delayed data arrives all at once |
| Diverging copies | The equipment master was copied into multiple systems. Equipment was moved in one system, but the other systems were not updated |
The fourth case is the most subtle. The copies are identical at first, so the problem is invisible. After they diverge, there is no basis for deciding which copy is correct.
3. First Strand—Identity: One Authoritative Source, Everything Else Derived
There is one principle: maintain a single source of truth (SSOT) for master data, and derive every other representation from it. A derived artifact can always be rebuilt, so if it diverges, the conflict has a clear resolution—the authoritative source wins.
In PlantPulse, the PostgreSQL metastore is that authoritative source. It contains the enterprise, site, asset tree, tags, alarm settings, and command definitions. The graph, topic paths, and structures exposed to AI described below are all derived by reading this source.
Store External IDs in «Mapping Columns»
Do not replace your IDs with IDs from another system. The two systems generate IDs according to different rules. Instead, retain your own IDs under your own rules and store the other system’s IDs in separate columns.
| Entity | Internal ID | External system ID |
|---|---|---|
| Customer | customer_id — letters, numbers, and _ only | external_customer_id (MES · ERP) |
| Product | Product ID | External product ID |
This approach means that even if ERP changes its code system, none of your internal joins break. Only the mapping column needs to be updated.
Resolve Human Terms to IDs
“Line 3 compressor” is not an ID. There must be a separate step that resolves a human-readable name to an ID in the authoritative source. This is the first thing PlantPulse AI does when it receives a question (search_domains). If this step is wrong, no matter how accurate the subsequent analysis is, it produces an accurate answer about the wrong equipment.
4. Second Strand—Relationships: Hierarchy Alone Is Not Enough
Hierarchy Answers «Where Is It?»
The ISA-95 hierarchy forms the backbone of the thread.
Enterprise ─ Site ─ Area ─ Line ─ Equipment ─ Tag ─ 값
With this tree, you can answer questions such as “all equipment on Line 3” or calculate an “OEE rollup by site.” PlantPulse KPI rollups are also aggregated by line, area, site, and enterprise by following this tree.
Messaging addresses are also derived from this tree. UNS (Unified Namespace) MQTT topics use the hierarchy path directly.
pp/{site_id}/{area_id}/{line_id}/{equipment_id}/{tag_id}/point
The topic name alone reveals where the value came from. Context accompanies the value, so subscribers do not need to perform a separate lookup—the thread is effectively embedded in the message.
Moving a tag to different equipment changes that tag’s MQTT topic. External systems subscribed to the old topic will silently stop receiving values without an error. Before changing the hierarchy, check whether any consumers subscribe to that path. For this reason, design the hierarchy carefully at first and change it rarely afterward. PlantPulse lets you preview and copy topic paths on the UNS screen.
Directed Relationships Answer «What Does It Affect?»
The question “If this equipment stops, how far does the shutdown propagate?” cannot be answered from the hierarchy. Equipment on the same line does not necessarily feed one another, while an air compressor in another area might stop the entire line. Directed relationships must therefore be modeled separately from the hierarchy.
| Relationship | Meaning | What traversal reveals |
|---|---|---|
FEEDS | The upstream node flows into the downstream node | Downstream: scope of shutdown impact · Upstream: candidate causes of quality anomalies |
DEPENDS_ON | The equipment depends on a utility such as power, air, or cooling | Which equipment will stop together if one utility stops |
PRODUCES | What the equipment produces | From equipment to product |
The same chain is modeled from the product side: product route (the sequence of unit processes a product passes through) → unit process (the process definition and associated equipment) → connection topology (flows and dependencies between equipment). On the process screen, “Products Using This Process” is read-only because it is derived from product routes. If it were entered separately in two places, the copies would diverge—the fourth break type in Section 2.
The Graph Is a Derived Artifact
Graphs are convenient for questions that require traversing relationships. However, making a graph database a second authoritative source violates the principle in Section 3. The equipment master would then exist in two places, and the synchronization pipeline would become the weakest link in the thread.
PlantPulse takes the opposite approach.
- The graph is an in-memory RDF model (Apache Jena) within the platform and is rebuilt in full from the metastore. There is no synchronized graph store
- It is rebuilt when a query arrives after the TTL has expired (10 minutes by default) (
semantic.graph.refresh.minutes). Even if multiple queries arrive concurrently, only one rebuild runs; the others receive the previous model - The trade-off is explicit: newly registered equipment may not appear in the graph until the next refresh. In exchange, the graph cannot structurally remain permanently diverged from the authoritative source
When a synchronized copy is wrong, you do not know how long it will remain wrong. A derived artifact rebuilt periodically can remain stale for at most one refresh interval. This distinction matters in thread design: delay resolves itself by waiting, but divergence requires someone to find and correct it.
5. Third Strand—Time: The Work Order as a Join Key
Identity and relationships connect what and where. Factory questions, however, almost always include when—“while that lot was being produced” or “during the two weeks before the failure.”
The Work Order Is the Join Key for the Time Axis
A work order has a special role in the thread. A single work order simultaneously references equipment, product, customer, and assignee, while also carrying planned start and end times and a target quantity. In other words, one work order provides the join condition:
“The time series from this equipment during this time interval belongs to this product and this customer.”
This join enables OEE calculations by work order and allows users to drill down from an equipment screen to “work orders for this equipment only.” Conversely, if there is time series data but no work order, values may be abundant, but there is no way to determine what was being produced when those values were recorded.
Separate Stored States from Derived States
Once time is involved, states fall into two categories.
| Example | Where it exists | |
|---|---|---|
| Stored state | Pending · In progress · Paused · Completed · Abnormally terminated | Database |
| Derived state | Delayed (planned start has passed but work has not started) · Canceled (planned end has passed without work starting) | Calculated by the screen using the current time—not stored in the data |
There is a reason derived states are not stored. If “Delayed” is stored, who or what will clear it, and when? becomes a new problem. If that update is missed even once, the data becomes false. The trade-off is that you will not find DELAY through the API or in the database. When passing state to an external system through the thread, the derivation rules must be passed along with it.
Event Time and Arrival Time Are Different
When a connection is lost, Edge buffers values locally and uploads them all at once after the connection is restored. No values are lost, but values from several hours ago arrive now. Always use event time for time-based joins in the thread. If arrival time is used, old values are incorrectly attached to the work order active immediately after recovery, while the work order active during the outage remains empty.
6. Do Not Put Values in the Graph—Put Pointers in It
When representing a thread as a graph, it can be tempting to place time series values in the graph as well. Do not. Time series data grows without limit and is read by tag over a time range, so it belongs in a purpose-built store—a time series database.
Instead, a tag node in the graph indicates where its values are stored and how to read them.
| Property | Meaning | Example |
|---|---|---|
seriesKey | Time series query key | Tag ID |
seriesStore | Store and table location | Time series store identifier |
seriesTool | Which tool to use for reading | get_tag_history |
lastValue · lastTimestamp | Latest-value snapshot | Provides the «current» value without a query |
seriesTool has an interesting role. Because the graph contains not only the data reference but also «how to read it», a consumer traversing the graph—whether a person or an AI agent—can obtain the next tool to call directly from the graph. The equipment timeline is referenced in the same way (timelineKey · timelineStore).
This is also a general principle of the thread: a thread does not move data; it connects the paths leading to the data.
7. Use Standards at the «Boundary»
Standards such as UNS, Sparkplug B, OPC-UA, and AAS (Asset Administration Shell) provide the language used to expose the thread outside the system.
| Standard | What it standardizes | In PlantPulse |
|---|---|---|
| UNS (MQTT) | Hierarchy paths as topic addresses | Generate and preview topics from the hierarchy |
| Sparkplug B | MQTT payloads and state (birth · death) | Enabled on Edge when needed (disabled by default) |
| OPC-UA | Equipment information models and access | Driver · standards UI (:12780) |
| AAS V3 | An asset’s «digital nameplate»—technical information organized into submodels | Standards UI (:8091) |
Using a standard as the internal model usually creates more problems than it solves. Standards represent the broadest common denominator agreed upon by multiple companies, so they cannot capture every factory-specific relationship, such as what feeds what. They also make the internal model vulnerable to changes whenever the standard is revised. Use your own authoritative source internally and standards externally. Translating at the boundary makes the thread less likely to break.
8. AI Is Accurate Only When Built on the Thread
When asked, “How has the Line 3 compressor been doing lately?”, a language model ultimately answers by following the thread.
① 「3라인 압축기」 → 설비 ID 식별
② 이 설비의 상류 · 하류 · 의존 관계 (그래프)
③ 태그 노드의 seriesTool 로 이력 조회 시간 (포인터)
④ 해당 기간의 워크오더 · 알람 · 문서 시간 + 식별
If the thread is broken, the model fills the gap with plausible language. If the name cannot be resolved, it selects similar equipment. If relationships are missing, it infers an impact merely because the equipment belongs to the same line. Manufacturing AI accuracy therefore depends on thread completeness before it depends on model size. For the same reason, when a graph query tool reaches its depth limit, it displays truncated, and when a total cannot be counted, it uses total_tag_count_unknown to report «unknown». A gap must be reported as a gap so that the model does not fill it in. The tool list is available under Ontology.
Design Checklist
When building or inspecting a thread, ask these questions regardless of the technology stack.
| Question | What a good answer looks like |
|---|---|
| Where is the authoritative source for the equipment master? | One place. Everything else is derived from it and can be rebuilt |
| How are IDs from external systems handled? | They are stored in mapping columns without changing internal IDs |
| Is there a step that resolves human language to an ID? | Yes, and it occurs before analysis |
| Are there directed relationships in addition to the hierarchy? | Flow (FEEDS) and dependency (DEPENDS_ON) are modeled separately |
| Is the graph authoritative or derived? | Derived. It is rebuilt without a synchronized store, and its maximum staleness is known |
| Are time series values copied into the graph? | No. Store only pointers and instructions for reading the data |
| What is used for time-based joins? | Event time. Work-order start and end times define the join condition |
| Are derived states stored? | No. When exported, the derivation rules are passed along with them |
| What breaks when the hierarchy changes? | Topic addresses change, so subscribers are identified first |
| Where are standards used? | At the boundary. Internally, use your own authoritative source; externally, use standards |
See Also
Manufacturing AI — What Factory Data Demands of Models · How a Single Value Reaches the Screen — from Edge to the screen · UNS — topics generated from the hierarchy · Ontology — tools for traversing relationships · Database Model — tables in the authoritative source · Overall Architecture