Modeling Factory Data
Data in your factory, either machine data sending from sensors, or order data exiting in ERP/MES, can all be modeled into understandable tree structure in Tier0.
How the Demo UNS is Structured
Section titled “How the Demo UNS is Structured”Physical Data
Section titled “Physical Data”Industrial data from machines and equipment with physical locations is modeled based on the ISA-95 standard.
Demo Model
Section titled “Demo Model”Enterprise (Level 4)└── Site (Level 3/4) └── Area (Level 3) └── Work Center / Process Cell (Level 2/3) └── Equipment / Unit (Level 1/2) └── Control Module / Device (Level 0/1)DemoFactory└── Site_01 └── Production └── Line_01 └── WorkOrderExecution ├── Metric │ ├── Target_Qty │ ├── Produced_Qty │ ├── Defect_Qty │ └── Completion_Rate └── State ├── CurrentWorkOrder └── WorkOrderStatus{ "namespace": [ { "name": "DemoFactory", "alias": "DemoFactory_9e50bbcd833d", "type": "PATH", "children": [ { "name": "Site_01", "alias": "DemoFactory__6d1fcad14e86", "type": "PATH", "children": [ { "name": "Production", "alias": "__Site_01_Pro_91523d2ad304", "type": "PATH", "children": [ { "name": "Line_01", "alias": "__Production__acd5841c1ada", "type": "PATH", "children": [ { "name": "WorkOrderExecution", "alias": "__Line_01_Wor_54904ff56e91", "type": "PATH", "children": [ { "name": "Metric", "alias": "metric_233fd84305c4", "type": "PATH", "children": [ { "name": "Target_Qty", "alias": "Target_Qty_8646b092e543", "type": "TOPIC", "topicType": "METRIC", "description": "Target quantity for the current Work Order.", "fields": [ { "name": "production_order_id", "type": "STRING" }, { "name": "plan_id", "type": "STRING" }, { "name": "plan_number", "type": "STRING" }, { "name": "work_order_id", "type": "STRING" }, { "name": "value", "type": "DOUBLE" }, { "name": "unit", "type": "STRING" }, { "name": "timestamp", "type": "DATETIME" } ], "enableHistory": "TRUE", "mockData": "FALSE" }, { "name": "Produced_Qty", "alias": "Produced_Qty_1f8cd3e11f77", "type": "TOPIC", "topicType": "METRIC", "description": "Produced quantity for the current Work Order.", "fields": [ { "name": "production_order_id", "type": "STRING" }, { "name": "plan_id", "type": "STRING" }, { "name": "plan_number", "type": "STRING" }, { "name": "work_order_id", "type": "STRING" }, { "name": "value", "type": "DOUBLE" }, { "name": "unit", "type": "STRING" }, { "name": "timestamp", "type": "DATETIME" } ], "enableHistory": "TRUE", "mockData": "FALSE" }, { "name": "Defect_Qty", "alias": "Defect_Qty_b48fb3563ec1", "type": "TOPIC", "topicType": "METRIC", "description": "Defect quantity for the current Work Order.", "fields": [ { "name": "production_order_id", "type": "STRING" }, { "name": "plan_id", "type": "STRING" }, { "name": "plan_number", "type": "STRING" }, { "name": "work_order_id", "type": "STRING" }, { "name": "value", "type": "DOUBLE" }, { "name": "unit", "type": "STRING" }, { "name": "timestamp", "type": "DATETIME" } ], "enableHistory": "TRUE", "mockData": "FALSE" }, { "name": "Completion_Rate", "alias": "Completion_R_7294e38e1530", "type": "TOPIC", "topicType": "METRIC", "description": "Completion percentage for the current Work Order.", "fields": [ { "name": "production_order_id", "type": "STRING" }, { "name": "plan_id", "type": "STRING" }, { "name": "plan_number", "type": "STRING" }, { "name": "work_order_id", "type": "STRING" }, { "name": "value", "type": "DOUBLE" }, { "name": "unit", "type": "STRING" }, { "name": "timestamp", "type": "DATETIME" } ], "enableHistory": "TRUE", "mockData": "FALSE" } ] }, { "name": "State", "alias": "state_539a0f331fe0", "type": "PATH", "children": [ { "name": "CurrentWorkOrder", "alias": "CurrentWorkO_a638320784dd", "type": "TOPIC", "topicType": "STATE", "description": "Current active Work Order on Line_01.", "fields": [ { "name": "production_order_id", "type": "STRING" }, { "name": "plan_id", "type": "STRING" }, { "name": "plan_number", "type": "STRING" }, { "name": "work_order_id", "type": "STRING" }, { "name": "target_line", "type": "STRING" }, { "name": "workstation", "type": "STRING" }, { "name": "product_code", "type": "STRING" }, { "name": "target_qty", "type": "DOUBLE" }, { "name": "unit", "type": "STRING" }, { "name": "started_at", "type": "DATETIME" }, { "name": "updated_at", "type": "DATETIME" } ], "enableHistory": "TRUE", "mockData": "FALSE" }, { "name": "WorkOrderStatus", "alias": "WorkOrderSta_e24e3bf113d1", "type": "TOPIC", "topicType": "STATE", "description": "Execution status of the current Work Order.", "fields": [ { "name": "production_order_id", "type": "STRING" }, { "name": "plan_id", "type": "STRING" }, { "name": "plan_number", "type": "STRING" }, { "name": "work_order_id", "type": "STRING" }, { "name": "status", "type": "STRING" }, { "name": "reason", "type": "STRING" }, { "name": "updated_at", "type": "DATETIME" } ], "enableHistory": "TRUE", "mockData": "FALSE" } ] } ] } ] } ] } ] } ] } ]}Business Data
Section titled “Business Data”For business planning and process objects, such as production orders and work order plans in an ERP, model data according to its business context.
Business Data Modeling Guide
Section titled “Business Data Modeling Guide”Factory / Business Domain / Business Object / Topic Type / Topic-
Business Domain: The business process or system the data belongs to.
Terminal window ERPMESWMSQMSEAMLIMSPlanningInventoryMaintenanceQualityLogistics... -
Business Object: The core managed object in the business domain.
Terminal window ProductionOrdersWorkOrderPlanMaterialInventoryQualityInspectionMaintenanceOrdersPurchaseOrdersShipments... -
Topic Type: Metric, Action, and State.
Topic Type Used for Examples STATE Current status or current facts Work order status, order status, equipment status METRIC Continuously changing numeric values Temperature, speed, output, OEE, energy consumption ACTION Commands for external executors Start equipment, stop equipment, reset alarm, request work order dispatch
Demo Model
Section titled “Demo Model”DemoFactory└── ERP ├── ProductionOrders │ └── State │ ├── UpsertProductionOrder │ └── OrderList └── WorkOrderPlan ├── Metric │ └── SplitCount └── State ├── PlanStatus └── WorkOrderList{ "namespace": [ { "name": "DemoFactory", "alias": "DemoFactory_f925c1ec5041", "type": "PATH", "children": [ { "name": "ERP", "alias": "DemoFactory__e504805b1973", "type": "PATH", "children": [ { "name": "ProductionOrders", "alias": "__ERP_Product_1e7984ac3a1d", "type": "PATH", "children": [ { "name": "State", "alias": "state_c2616c8698fa", "type": "PATH", "children": [ { "name": "UpsertProductionOrder", "alias": "UpsertProduc_d5f166da35c6", "type": "TOPIC", "topicType": "STATE", "description": "Event for creating or updating a Production Order from WOM or ERP simulation.", "fields": [ { "name": "event_id", "type": "STRING" }, { "name": "event_type", "type": "STRING" }, { "name": "source", "type": "STRING" }, { "name": "production_order_id", "type": "STRING" }, { "name": "order_number", "type": "STRING" }, { "name": "product_code", "type": "STRING" }, { "name": "planned_qty", "type": "DOUBLE" }, { "name": "unit", "type": "STRING" }, { "name": "status", "type": "STRING" }, { "name": "due_date", "type": "DATETIME" }, { "name": "updated_at", "type": "DATETIME" } ], "enableHistory": "TRUE", "mockData": "FALSE" }, { "name": "OrderList", "alias": "OrderList_11fbca51a2bd", "type": "TOPIC", "topicType": "STATE", "description": "Retained compatibility snapshot of current Production Orders.", "fields": [ { "name": "orders", "type": "STRING" }, { "name": "updated_at", "type": "DATETIME" } ], "enableHistory": "TRUE", "mockData": "FALSE" } ] } ] }, { "name": "WorkOrderPlan", "alias": "__ERP_WorkOrd_19f04960daf5", "type": "PATH", "children": [ { "name": "Metric", "alias": "metric_17258b809a4f", "type": "PATH", "children": [ { "name": "SplitCount", "alias": "SplitCount_032e86f5fbfc", "type": "TOPIC", "topicType": "METRIC", "description": "Number of executable Work Orders generated from a Work Order Plan.", "fields": [ { "name": "production_order_id", "type": "STRING" }, { "name": "plan_id", "type": "STRING" }, { "name": "plan_number", "type": "STRING" }, { "name": "split_count", "type": "INTEGER" }, { "name": "updated_at", "type": "DATETIME" } ], "enableHistory": "TRUE", "mockData": "FALSE" } ] }, { "name": "State", "alias": "state_884cee548bf7", "type": "PATH", "children": [ { "name": "PlanStatus", "alias": "PlanStatus_2e21c1327c49", "type": "TOPIC", "topicType": "STATE", "description": "Current lifecycle status of a Work Order Plan.", "fields": [ { "name": "production_order_id", "type": "STRING" }, { "name": "plan_id", "type": "STRING" }, { "name": "plan_number", "type": "STRING" }, { "name": "status", "type": "STRING" }, { "name": "updated_at", "type": "DATETIME" } ], "enableHistory": "TRUE", "mockData": "FALSE" }, { "name": "WorkOrderList", "alias": "WorkOrderLis_887b92f26fc2", "type": "TOPIC", "topicType": "STATE", "description": "Split result list generated from a sent Work Order Plan.", "fields": [ { "name": "production_order_id", "type": "STRING" }, { "name": "plan_id", "type": "STRING" }, { "name": "plan_number", "type": "STRING" }, { "name": "split_count", "type": "INTEGER" }, { "name": "lines", "type": "STRING" }, { "name": "updated_at", "type": "DATETIME" } ], "enableHistory": "TRUE", "mockData": "FALSE" } ] } ] } ] } ] } ]}Payload Structure
Section titled “Payload Structure”Data to be consumed and written back must both be considered when structuring the topic payload.
-
Action
Action payloads automatically include
_timestamp, which records when the data is stored in the Tier0 database.Terminal window {"light_turn_on": true,"height_adjust": 12.5,"_timestamp": "2026-07-10T10:00:00Z"}Terminal window {"water_pump_off": true,"window_close": true,"_timestamp": "2026-07-10T10:00:00Z"} -
Metric
Metric payloads automatically include
_timestamp, which records when the data is stored in the Tier0 database, and_quality, which represents data quality.Terminal window {"production_order_id": "PO-20260710-001","plan_id": "PLAN-001","plan_number": "WOP-20260710-001","split_count": 3,"updated_at": "2026-07-10T10:00:00Z","_timestamp": "2026-07-10T10:00:00Z","_quality": "Good"}Terminal window {"production_order_id": "PO-20260710-001","plan_id": "PLAN-001","plan_number": "WOP-20260710-001","work_order_id": "WO-001","value": 1200,"unit": "pcs","timestamp": "2026-07-10T10:00:00Z","_timestamp": "2026-07-10T10:00:00Z","_quality": "Good"} -
State
State payloads automatically include
_timestamp, which records when the data is stored in the Tier0 database.Terminal window {"event_id": "EVT-001","event_type": "UPSERT","source": "ERP","production_order_id": "PO-20260710-001","order_number": "PO-001","product_code": "SKU-1001","planned_qty": 1200,"unit": "pcs","status": "Released","due_date": "2026-07-12T00:00:00Z","updated_at": "2026-07-10T10:00:00Z","_timestamp": "2026-07-10T10:00:00Z"}Terminal window {"production_order_id": "PO-20260710-001","plan_id": "PLAN-001","plan_number": "WOP-20260710-001","work_order_id": "WO-001","status": "Running","reason": "In production","updated_at": "2026-07-10T10:00:00Z","_timestamp": "2026-07-10T10:00:00Z"}
How to Avoid Topic Explosion
Section titled “How to Avoid Topic Explosion”Tier0 uses three fixed topic types, Metric, Action, and State, to avoid topic explosion.
-
Use
Metricfor high-frequency real-time dataPut high-frequency measurements and telemetry under
Metricinstead of expanding the namespace for every signal detail.Terminal window Factory_A└── SMT_Line_1└── Machine_001├── Temperature_Value├── Temperature_Unit├── Temperature_Status└── Speed_ValueTerminal window Factory_A└── SMT_Line_1└── Metric└── Machine_001Topic payload:
Terminal window {"temperature": 80,"temperature_unit": "Celsius","temperature_status": "Normal","speed": 300} -
Use
Statefor low-frequency status dataPut low-frequency status, snapshots, and current business state under
State. Avoid creating a new topic for every changing entity such as jobs, batches, or orders. -
Use
Actionfor low-frequency action dataPut commands, requests, and operator actions under
Action. Keep action inputs as fields on a topic rather than creating one topic per parameter.