--- alias: operation-guide-uns-topic-mapping tags: - data platform - UNS - MQTT - CDM - ISA-95 summary: "Understand the UNS topic hierarchy, how CDM entities map to MQTT topics, and how to customize the topic construction logic" --- # UNS Topic Mapping and Customization This guide explains how the UNS Export Integration constructs MQTT topics from CDM event data, how ISA-95 entities map to the topic hierarchy, and how to customize the mapping logic for your organization's needs. ## Default Topic Structure All CDM events published through the UNS Export Integration follow this hierarchical topic pattern: ```log Enterprise/Site/Area/Resource/Event ``` Each level represents a node in the manufacturing hierarchy, derived from the ISA-95-aligned CDM model. This structure enables consumers to subscribe at any level of granularity. **Examples:** | Scenario | Topic | | --- | --- | | Resource state change for Baker-01 | `DefaultEnterprise/DefaultSite/Cookie-Manufacturing/Baker-01/ResourceStateChange` | | Material operation at Oven-02 | `Acme-Corp/Austin-Fab/Packaging/Oven-02/MaterialOperations` | | Area-level event (no resource) | `Acme-Corp/Austin-Fab/Assembly/PostDataCollection` | ## CDM-to-UNS Entity Mapping Although ISA-95 terminology is used as the foundation, it is important to understand how Critical Manufacturing MES entities map to the UNS structure. MES nomenclature does not always match ISA-95 one-to-one. | UNS Level | CDM / MES Source | Default Value | Notes | | --- | --- | --- | --- | | **Enterprise** | Enterprise entity | `DefaultEnterprise` | If no Enterprise is associated with the event data, the default value is used. | | **Site** | Site entity | `DefaultSite` | If no Site is associated, the default is used. | | **Area** | Area entity | `DefaultArea` | Represents the logical production area. | | **Resource** | Resource entity | `DefaultResource` | Typically maps to what ISA-95 refers to as a Work Center, depending on how resources are modeled in the MES. This level is included only if a resource is present in the event. | | **Event** | CDM Event Type | — | The event definition name (for example, `ResourceStateChange`, `MaterialOperations`). Derived from the IoT Event Definition's `EventDefinition` application property. | Table: CDM Entity to UNS Level Mapping !!! note The **Resource** level is conditionally included. If the CDM event does not contain a resource reference (for example, area-level events), the topic omits this level and follows the pattern `Enterprise/Site/Area/Event`. ## Topic Construction Logic The automation controller workflow includes a **Code Execution** task that transforms raw CDM event data into the MQTT topic. The logic performs the following steps: ### 1. Extract Hierarchy Names The code reads entity names from the raw CDM event payload: ```typescript const enterpriseName = rawData?.Enterprise?.Name?.trim() || "DefaultEnterprise"; const siteName = rawData?.Site?.Name?.trim() || "DefaultSite"; const areaName = rawData?.Area?.Name?.trim() || "DefaultArea"; ``` If any level is missing or has an empty name, the corresponding default value is used. ### 2. Construct Base Topic The base topic is built from the first three hierarchy levels: ```typescript let topic = `${enterpriseName}/${siteName}/${areaName}`; ``` ### 3. Conditionally Add Resource If the event payload includes a `Resource` object, the resource name is appended: ```typescript if (rawData?.Resource != null) { const resourceName = rawData?.Resource?.Name?.trim() || "DefaultResource"; topic += `/${resourceName}`; } ``` ### 4. Append Event Type The CDM event definition name is extracted from the IoT event metadata and appended as the final topic level: ```typescript let eventName = inputs?.iotEvent?.value?.AppProperties?.EventDefinition; eventName = eventName.substring(eventName.lastIndexOf("\\") + 1); topic += `/${eventName}`; ``` ### 5. Sanitize Topic Spaces are replaced with hyphens for MQTT topic compatibility: ```typescript topic = topic.replace(/ /g, "-"); ``` ## Customizing the Topic Structure You can modify the topic construction logic to match your organization's UNS namespace design. ### Editing the Workflow Code 1. Navigate to **Data Platform** > **Data Platform Workflows**. 2. Open the automation controller created for UNS Export Integration. 3. Locate the **Code Execution** task in the `Setup` workflow. 4. Modify the TypeScript code in the task settings. ### Common Customizations #### Adding a Facility Level To include the Facility entity between Site and Area: ```typescript const facilityName = rawData?.Facility?.Name?.trim() || "DefaultFacility"; let topic = `${enterpriseName}/${siteName}/${facilityName}/${areaName}`; ``` This produces topics like: ```log Acme-Corp/Austin-Fab/Building-A/Assembly/Oven-02/MaterialOperations ``` #### Using a Custom Topic Prefix To add a fixed prefix for namespace organization: ```typescript const prefix = "cmf/mes"; let topic = `${prefix}/${enterpriseName}/${siteName}/${areaName}`; ``` This produces topics like: ```log cmf/mes/Acme-Corp/Austin-Fab/Assembly/Oven-02/ResourceStateChange ``` #### Alternative Separator Characters While `/` is the standard MQTT topic separator, you can adjust how entity names are formatted. For example, to use underscores instead of hyphens for space replacement: ```typescript topic = topic.replace(/ /g, "_"); ``` #### Filtering Events by Type To publish only specific event types, add a conditional check before the send step: ```typescript const allowedEvents = ["ResourceStateChange", "MaterialOperations"]; if (!allowedEvents.includes(eventName)) { return { dataOut: null }; // Skip this event } return { dataOut: { topic, raw: rawData } }; ``` !!! warning After modifying the workflow code, test the changes by triggering a manufacturing event and verifying the output in the MQTT broker. Syntax errors in the code execution task will cause the entire workflow to fail silently. ## Subscribing to Topics MQTT clients can subscribe to topics using wildcard patterns to consume events at different granularity levels. ### MQTT Wildcard Reference | Wildcard | Meaning | Example | | --- | --- | --- | | `+` | Single level | `+/+/+/+/ResourceStateChange` — all resource state changes across all hierarchies | | `#` | Multi-level (must be last) | `Acme-Corp/Austin-Fab/#` — all events from the Austin Fab site | ### Subscription Examples | Goal | Subscription Pattern | | --- | --- | | All events from all sites | `#` | | All events from a specific site | `Acme-Corp/Austin-Fab/#` | | All resource state changes | `+/+/+/+/ResourceStateChange` | | All events for a specific resource | `+/+/+/Baker-01/#` | | All events in a specific area | `Acme-Corp/Austin-Fab/Assembly/#` | | Area-level events only (no resource) | `+/+/+/PostDataCollection` | Table: MQTT Subscription Patterns ## Event Payload Structure Each MQTT message carries a JSON payload containing the full CDM event data. The payload structure includes: | Section | Description | | --- | --- | | **Header** | Correlation ID, timestamps, CDM version, application and service context. | | **Enterprise** | Enterprise entity UID, name, and additional properties. | | **Site** | Site entity UID, name, and additional properties. | | **Facility** | Facility entity UID, name, and additional properties. | | **Area** | Area entity UID, name, type, and additional properties. | | **Resource** | Resource details including type, model, state information (SEMI-E10 state, system state), control state, and timestamps. Present only for resource-scoped events. | | **Previous** | For state-change events, contains the previous state of the affected entity, enabling consumers to detect transitions without maintaining local state. | Table: CDM Event Payload Sections !!! tip The `Previous` section is a key CDM design feature. It embeds the prior state directly in the event, eliminating the need for downstream systems to maintain state machines or query historical data. For example, a `ResourceStateChange` event includes both the current SEMI-E10 state and the previous state. ## Best Practices ### Topic Design * Start with ISA-95 hierarchies and evolve based on actual consumer patterns. * Keep topics human-readable to simplify debugging and monitoring. * Avoid deep nesting beyond five or six levels, which can complicate wildcard subscriptions. * Use consistent naming conventions across sites and environments. ### Data Volume Management * Subscribe only to the events your consumers need rather than using catch-all wildcards in production. * Consider aggregation or filtering at the workflow level for high-frequency events. * Configure MQTT broker retention and expiry policies based on consumer latency requirements. ### Security * Use TLS encryption (port `8883` by default) for all broker connections. * Configure topic-level ACLs on the MQTT broker to restrict publish and subscribe permissions. * Rotate broker credentials periodically through environment configuration updates. ## Related Topics * [Guides: UNS Integration Customization](https://developer.criticalmanufacturing.com/explore/guides/customizations/integration/uns/) — developer guide for customizing UNS integration * [[operation-guide-configuring-uns-export-integration]] — end-to-end setup guide * [[operation-guide-uns-master-data-package-reference]] — metadata package structure reference * [[tutorials-realtime-insights]] — hands-on tutorial with example scenarios