Overview

This document presents how to connect to MQTT brokers and integrate external UNS data into FrameworX solutions. Two approaches are available:

  1. TagProvider (UNS Module) — Auto-discovery, direct namespace integration
  2. Device Module — Explicit mapping with Points, traditional SCADA approach


Approach 1: TagProvider (Recommended for large datasets with frequent definition updates)

TagProvider creates a direct connection to an external data source and integrates it into the Unified Namespace. Tags are auto-discovered and accessible under the provider's namespace.

JSON Structure (UnsTagProviders)

json

{
  "ObjectIdentification": {
    "TableType": "UnsTagProviders"
  },
  "Data": [
    {
      "Name": "MQTT",
      "Protocol": "MQTT",
      "PrimaryStation": "localhost;1883;ClientID;;;;;None;False;;AtLeastOnce;10;False;False;",
      "BackupStation": "",
      "Interface": "Custom",
      "Separators": "BranchSeparator=/;AttributeSeparator=/;",
      "Access": 0,
      "ReadTime": 500,
      "WriteTime": 500,
      "Description": "MQTT Broker Connection"
    }
  ]
}

JSON Structure (UnsTagProviders) with mandatory fields only


son


{
  "ObjectIdentification": {
    "TableType": "UnsTagProviders"
  },
  "Data": [
    {
      "Name": "MQTT",
      "Protocol": "MQTT",
      "PrimaryStation": "localhost;1883;",
    }
  ]
}
PrimaryStation Format (MQTT)
{Host};{Port};{ClientID};{Username};{Password};{CertFile};{KeyFile};{TLS};{CleanSession};{WillTopic};{QoS};{KeepAlive};{RetainPublish};{UseWebSocket};


PositionFieldExampleDescription
1HostlocalhostBroker hostname or IP
2Port1883Broker port (1883=TCP, 8883=TLS)
3ClientIDMyClientUnique client identifier
4Username(empty)Authentication username
5Password(empty)Authentication password
6CertFile(empty)TLS certificate file path
7KeyFile(empty)TLS key file path
8TLSNoneTLS mode: None, TLS, mTLS
9CleanSessionFalseClean session flag
10WillTopic(empty)Last Will topic
11QoSAtLeastOnceQoS: AtMostOnce, AtLeastOnce, ExactlyOnce
12KeepAlive10Keep-alive interval (seconds)
13RetainPublishFalseRetain published messages
14UseWebSocketFalseUse WebSocket transport


Special Placeholders:

  • _SolutionName_ — Replaced with solution name at runtime
  • _Guid_ — Replaced with unique GUID at runtime

Separators Configuration

BranchSeparator=/;AttributeSeparator=/;

Maps MQTT topic hierarchy to UNS path:

  • Topic plant/line1/tank1/temperature → Tag path plant/line1/tank1/temperature

Accessing TagProvider Data

Once connected, topics appear under the provider namespace:


MQTT TopicUNS Access
plant/line1/tempTag.MQTT.plant.line1.temp
spBv1.0/Group/Node/tempTag.MQTT.("spBv1.0/Group/Node/temp")


Note: Topics with special characters use quoted syntax: Tag.ProviderName.("topic/path")


Approach 2: Device Module

The Device Module provides explicit control over tag-to-topic mapping using Channels, Nodes, and Points.

Available MQTT Protocols


ProtocolDescriptionUse Case
MQTTStandard MQTT 3.1.1/5.0Generic MQTT brokers
MQTTspBSparkplug B specificationIndustrial IoT, auto-discovery

Channel JSON (DevicesChannels)

Standard MQTT:

json

{
  "ObjectIdentification": {
    "TableType": "DevicesChannels"
  },
  "Data": [
    {
      "Name": "MQTT1",
      "Protocol": "MQTT",
      "ProtocolOptions": "TimePublishRate=500;StoreAndForward=false",
      "Interface": "Custom",
      "Description": "MQTT Client Connector"
    }
  ]
}

Sparkplug B:

json

{
  "ObjectIdentification": {
    "TableType": "DevicesChannels"
  },
  "Data": [
    {
      "Name": "SparkplugCollector",
      "Protocol": "MQTTspB",
      "ProtocolOptions": "Type=Collector;TimePublishRate=500;StoreAndForward=false;PublishDBIRTHAfterNBIRTH=true;UseParenthesesForArray=false;PublishUDTsAsSimpleTags=false",
      "Interface": "TCPIP",
      "Description": "Sparkplug B Collector"
    }
  ]
}

ProtocolOptions Reference

MQTT Protocol:

OptionValuesDefaultDescription
TimePublishRatems500Publish interval
StoreAndForwardtrue/falsefalseBuffer on disconnect


MQTTspB Protocol:

OptionValuesDefaultDescription
TypeCollector/EdgeCollectorNode type
TimePublishRatems500Publish interval
StoreAndForwardtrue/falsefalseBuffer on disconnect
PublishDBIRTHAfterNBIRTHtrue/falsetrueBirth certificate behavior
UseParenthesesForArraytrue/falsefalseArray notation style
PublishUDTsAsSimpleTagstrue/falsefalseUDT handling


Node JSON (DevicesNodes)

json

{
  "ObjectIdentification": {
    "TableType": "DevicesNodes"
  },
  "Data": [
    {
      "Name": "MQTTBroker1",
      "Channel": "Channel.MQTT1",
      "PrimaryStation": "broker.example.com;1883;MyClient;;;None;;AtLeastOnce;10;",
      "BackupStation": "",
      "Description": "Production MQTT Broker"
    }
  ]
}

Node PrimaryStation Format

Same format as TagProvider PrimaryStation (see above).

Point Address Format

For Device Module Points, the Address field contains the MQTT topic:

json

{
  "ObjectIdentification": {
    "TableType": "DevicesPoints"
  },
  "Data": [
    {
      "TagName": "Tag.Line1.Temperature",
      "Node": "Node.MQTTBroker1",
      "Address": "plant/line1/temperature",
      "AccessType": "Read"
    }
  ]
}

AssetTree (UNS Folder Organization)

The AssetTree defines the hierarchical folder structure in the Unified Namespace.

JSON Structure (UnsAssetTree)

json

{
  "ObjectIdentification": {
    "TableType": "UnsAssetTree"
  },
  "Data": [
    {
      "Name": "Plant",
      "Parent": -1,
      "Children": "",
      "Description": "Root folder"
    },
    {
      "Name": "Line1",
      "Parent": 0,
      "Children": "",
      "Description": "Production Line 1"
    },
    {
      "Name": "Tank1",
      "Parent": 1,
      "Children": "",
      "Description": "Fermentation Tank"
    }
  ]
}

Fields


FieldTypeDescription
NamestringFolder name
ParentintParent folder ID (-1 for root)
ChildrenstringChild mappings (TagProvider topics)
DescriptionstringOptional description

Mapping TagProvider Topics to Folders

The Children field can map TagProvider topics into the folder:

@ProviderName.("topic/path")\t\tDisplayName\tProtected\r\n

Example:

@MQTT.("spBv1.0/Cities")\t\tCities\tProtected

This maps the MQTT topic spBv1.0/Cities into the folder with display name "Cities".


Demo Workflows

Demo 1: TagProvider Approach (Simplest)

Scenario: Connect to MQTT broker and auto-discover all topics.

Steps:

  1. Create TagProvider with MQTT connection
  2. Topics auto-appear under Tag.{ProviderName}.{topic.path}
  3. Create AssetTree folders for organization
  4. Map provider topics to folders
  5. Add historian logging for selected tags
  6. Create alarms for critical values

JSON to Import:

json

{
  "ObjectIdentification": {"TableType": "UnsTagProviders"},
  "Data": [{
    "Name": "ProductionMQTT",
    "Protocol": "MQTT",
    "PrimaryStation": "mqtt.factory.local;1883;FrameworX-001;;;;;None;False;;AtLeastOnce;10;False;False;",
    "Separators": "BranchSeparator=/;AttributeSeparator=/;",
    "Description": "Production floor MQTT broker"
  }]
}

Access pattern: Tag.ProductionMQTT.line1.tank1.temperature


Demo 2: Device Module Approach (Explicit Mapping)

Scenario: Map specific MQTT topics to local Tags with full control.

Steps:

  1. Create local Tags for data points
  2. Create MQTT Channel
  3. Create Node with broker connection
  4. Create Points mapping Tags to topics
  5. Add historian and alarms

JSON to Import (in order):

1. Tags:

json

{
  "ObjectIdentification": {"TableType": "UnsTags"},
  "Data": [
    {"Name": "Temperature", "Type": 153, "Path": "\\Line1\\Tank1", "Description": "Tank temperature", "Units": "°C"},
    {"Name": "Pressure", "Type": 153, "Path": "\\Line1\\Tank1", "Description": "Tank pressure", "Units": "bar"},
    {"Name": "Level", "Type": 153, "Path": "\\Line1\\Tank1", "Description": "Tank level", "Units": "%"}
  ]
}

2. Channel:

json

{
  "ObjectIdentification": {"TableType": "DevicesChannels"},
  "Data": [{
    "Name": "MQTTBroker",
    "Protocol": "MQTT",
    "ProtocolOptions": "TimePublishRate=500;StoreAndForward=false",
    "Description": "Factory MQTT connection"
  }]
}

3. Node:

json

{
  "ObjectIdentification": {"TableType": "DevicesNodes"},
  "Data": [{
    "Name": "FactoryBroker",
    "Channel": "Channel.MQTTBroker",
    "PrimaryStation": "mqtt.factory.local;1883;FrameworX-001;;;None;;AtLeastOnce;10;",
    "Description": "Production MQTT broker"
  }]
}

4. Points:

json

{
  "ObjectIdentification": {"TableType": "DevicesPoints"},
  "Data": [
    {"TagName": "Tag.Line1.Tank1.Temperature", "Node": "Node.FactoryBroker", "Address": "line1/tank1/temperature", "AccessType": "Read"},
    {"TagName": "Tag.Line1.Tank1.Pressure", "Node": "Node.FactoryBroker", "Address": "line1/tank1/pressure", "AccessType": "Read"},
    {"TagName": "Tag.Line1.Tank1.Level", "Node": "Node.FactoryBroker", "Address": "line1/tank1/level", "AccessType": "Read"}
  ]
}

Demo 3: Sparkplug B Collector

Scenario: Auto-discover Sparkplug B edge nodes and metrics.

Steps:

  1. Create MQTTspB Channel (Collector mode)
  2. Create Node with broker connection
  3. Sparkplug metrics auto-discovered as Tags
  4. Configure historian for discovered tags

JSON to Import:

json

{
  "ObjectIdentification": {"TableType": "DevicesChannels"},
  "Data": [{
    "Name": "SparkplugCollector",
    "Protocol": "MQTTspB",
    "ProtocolOptions": "Type=Collector;TimePublishRate=500;PublishDBIRTHAfterNBIRTH=true",
    "Description": "Sparkplug B edge node collector"
  }]
}

json

{
  "ObjectIdentification": {"TableType": "DevicesNodes"},
  "Data": [{
    "Name": "SparkplugBroker",
    "Channel": "Channel.SparkplugCollector",
    "PrimaryStation": "mqtt.factory.local;1883;FrameworX-Collector;;;;;None;False;;AtLeastOnce;10;False;",
    "Description": "Sparkplug B broker connection"
  }]
}

Comparison: TagProvider vs Device Module


AspectTagProviderDevice Module
SetupSingle objectChannel + Node + Points
DiscoveryAutomaticManual mapping
Tag namingProvider namespaceLocal tags
ControlLess (auto)Full (explicit)
Best forUNS integration, browsingSCADA, specific tags
Access patternTag.Provider.topic.pathTag.Path.Name

TableType Reference (Updated)


TableTypeObject TypeModule
UnsTagProvidersTagProviderUNS
UnsAssetTreeAssetTree folderUNS
UnsTagsTagUNS
DevicesChannelsChannelDevices
DevicesNodesNodeDevices
DevicesPointsPointDevices

MCP Context Hints for AI

When given MQTT topic documentation:

  1. Analyze topic structure
    • Identify hierarchy pattern (e.g., site/area/equipment/metric)
    • Note data types if documented
    • Identify which topics are critical (need alarms)
  2. Choose approach
    • TagProvider if: Auto-discovery wanted, UNS integration focus
    • Device Module if: Specific tags needed, traditional SCADA
  3. Create Tag hierarchy (Device Module approach)
    • Map topic hierarchy to folder path: site/area/equipment\Site\Area\Equipment
    • Create Tags matching metrics
  4. Configure connection
    • Use broker address, port, credentials from documentation
    • Set appropriate QoS level
  5. Add historian logging
    • Use add_tags_to_historian for numeric tags
    • Default to Table1 unless specific retention needed
  6. Add alarms
    • Use add_tags_to_alarms for critical measurements
    • Choose appropriate condition (HiHi, LoLo, etc.)
    • Set setpoints from process documentation