This document presents how to connect to MQTT brokers and integrate external UNS data into FrameworX solutions. Two approaches are available:
Table of Contents maxLevel 2 minLevel 2 indent 10px exclude Tutorial style none
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
{
"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"
}
]
}
son
{
"ObjectIdentification": {
"TableType": "UnsTagProviders"
},
"Data": [
{
"Name": "MQTT",
"Protocol": "MQTT",
"PrimaryStation": "localhost;1883;ClientID;;;;;None;False;;AtLeastOnce;10;False;False;",
}
]
}
PrimaryStation Format (MQTT){Host};{Port};{ClientID};{Username};{Password};{CertFile};{KeyFile};{TLS};{CleanSession};{WillTopic};{QoS};{KeepAlive};{RetainPublish};{UseWebSocket};| Position | Field | Example | Description |
|---|---|---|---|
| 1 | Host | localhost | Broker hostname or IP |
| 2 | Port | 1883 | Broker port (1883=TCP, 8883=TLS) |
| 3 | ClientID | MyClient | Unique client identifier |
| 4 | Username | (empty) | Authentication username |
| 5 | Password | (empty) | Authentication password |
| 6 | CertFile | (empty) | TLS certificate file path |
| 7 | KeyFile | (empty) | TLS key file path |
| 8 | TLS | None | TLS mode: None, TLS, mTLS |
| 9 | CleanSession | False | Clean session flag |
| 10 | WillTopic | (empty) | Last Will topic |
| 11 | QoS | AtLeastOnce | QoS: AtMostOnce, AtLeastOnce, ExactlyOnce |
| 12 | KeepAlive | 10 | Keep-alive interval (seconds) |
| 13 | RetainPublish | False | Retain published messages |
| 14 | UseWebSocket | False | Use WebSocket transport |
Special Placeholders:
_SolutionName_ — Replaced with solution name at runtime_Guid_ — Replaced with unique GUID at runtimeBranchSeparator=/;AttributeSeparator=/;Maps MQTT topic hierarchy to UNS path:
plant/line1/tank1/temperature → Tag path plant/line1/tank1/temperatureOnce connected, topics appear under the provider namespace:
| MQTT Topic | UNS Access |
|---|---|
plant/line1/temp | Tag.MQTT.plant.line1.temp |
spBv1.0/Group/Node/temp | Tag.MQTT.("spBv1.0/Group/Node/temp") |
Note: Topics with special characters use quoted syntax: Tag.ProviderName.("topic/path")
The Device Module provides explicit control over tag-to-topic mapping using Channels, Nodes, and Points.
| Protocol | Description | Use Case |
|---|---|---|
MQTT | Standard MQTT 3.1.1/5.0 | Generic MQTT brokers |
MQTTspB | Sparkplug B specification | Industrial IoT, auto-discovery |
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"
}
]
}MQTT Protocol:
| Option | Values | Default | Description |
|---|---|---|---|
TimePublishRate | ms | 500 | Publish interval |
StoreAndForward | true/false | false | Buffer on disconnect |
MQTTspB Protocol:
| Option | Values | Default | Description |
|---|---|---|---|
Type | Collector/Edge | Collector | Node type |
TimePublishRate | ms | 500 | Publish interval |
StoreAndForward | true/false | false | Buffer on disconnect |
PublishDBIRTHAfterNBIRTH | true/false | true | Birth certificate behavior |
UseParenthesesForArray | true/false | false | Array notation style |
PublishUDTsAsSimpleTags | true/false | false | UDT handling |
json
{
"ObjectIdentification": {
"TableType": "DevicesNodes"
},
"Data": [
{
"Name": "MQTTBroker1",
"Channel": "Channel.MQTT1",
"PrimaryStation": "broker.example.com;1883;MyClient;;;None;;AtLeastOnce;10;",
"BackupStation": "",
"Description": "Production MQTT Broker"
}
]
}Same format as TagProvider PrimaryStation (see above).
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"
}
]
}The AssetTree defines the hierarchical folder structure in the Unified Namespace.
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"
}
]
}| Field | Type | Description |
|---|---|---|
Name | string | Folder name |
Parent | int | Parent folder ID (-1 for root) |
Children | string | Child mappings (TagProvider topics) |
Description | string | Optional description |
The Children field can map TagProvider topics into the folder:
@ProviderName.("topic/path")\t\tDisplayName\tProtected\r\nExample:
@MQTT.("spBv1.0/Cities")\t\tCities\tProtectedThis maps the MQTT topic spBv1.0/Cities into the folder with display name "Cities".
Scenario: Connect to MQTT broker and auto-discover all topics.
Steps:
Tag.{ProviderName}.{topic.path}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
Scenario: Map specific MQTT topics to local Tags with full control.
Steps:
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"}
]
}Scenario: Auto-discover Sparkplug B edge nodes and metrics.
Steps:
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"
}]
}| Aspect | TagProvider | Device Module |
|---|---|---|
| Setup | Single object | Channel + Node + Points |
| Discovery | Automatic | Manual mapping |
| Tag naming | Provider namespace | Local tags |
| Control | Less (auto) | Full (explicit) |
| Best for | UNS integration, browsing | SCADA, specific tags |
| Access pattern | Tag.Provider.topic.path | Tag.Path.Name |
| TableType | Object Type | Module |
|---|---|---|
UnsTagProviders | TagProvider | UNS |
UnsAssetTree | AssetTree folder | UNS |
UnsTags | Tag | UNS |
DevicesChannels | Channel | Devices |
DevicesNodes | Node | Devices |
DevicesPoints | Point | Devices |
When given MQTT topic documentation:
site/area/equipment/metric)site/area/equipment → \Site\Area\Equipmentadd_tags_to_historian for add_tags_to_alarms for critical measurements