OPC UA PubSub over MQTT
You build a setup in which a publisher on the equipment side and a subscriber on the server side share nothing but an MQTT broker:
publisher process Mosquitto subscriber process(publisher_id 100) ──────▶ 127.0.0.1:1883 ──────▶ (Received messages) opcua/uadp/data/100/line1 │ └──▶ mosquitto_sub (observer)- The publisher runs the headless simulator in scenario mode, sends two DataSets and exits.
- The subscriber runs the headless simulator interactively so that you can look at what it received.
mosquitto_subuses a wildcard filter to watch the data of every PublisherId.
OPC UA background explains DataSets, WriterGroups and DataSetWriters.
Before you begin
Section titled “Before you begin”- The
mqtt-labdirectory andlocal.conffrom Run a local Mosquitto broker - The PDComm OPC UA simulator package
- Four terminal windows
-
Save the subscriber input file and the publisher scenario file in the
mqtt-labdirectory.subscriber.jsonl {"action":"configure","config":{"pubsub":{"transport":"mqtt","role":"subscriber","broker":"127.0.0.1:1883","topic":"opcua/uadp/data/100/line1"}}}{"action":"pubsub_start"}The subscriber input holds the JSON commands for the headless simulator, one per line.
publisher-scenario.json [{"command": {"action": "configure","config": {"pubsub": {"transport": "mqtt","role": "publisher","broker": "127.0.0.1:1883","topic": "opcua/uadp/data/100/line1","publisher_id": 100,"writer_group_id": 1,"dataset_writer_id": 1}}}},{ "command": { "action": "pubsub_start" }, "expect": { "running": true, "transport": "mqtt" } },{"command": {"action": "pubsub_publish","fields": [{ "type": "Double", "value": 21.5 },{ "type": "Boolean", "value": true },{ "type": "String", "value": "RUN" }]},"expect": { "sequence": 1 }},{"command": {"action": "pubsub_publish","fields": [{ "type": "Double", "value": 21.75 },{ "type": "Boolean", "value": true },{ "type": "String", "value": "RUN" }]},"expect": { "sequence": 2 }},{ "command": { "action": "pubsub_stop" }, "expect": { "running": false } }]A scenario file is an array of steps. The simulator runs the
commandof each step in order and, when a step hasexpect, compares those values with the result. The publisher uses PublisherId 100, WriterGroupId 1 and DataSetWriterId 1, and publishes toopcua/uadp/data/100/line1, following the OPC UA PubSub topic convention. -
In all four terminals, store the path of the simulator package in a variable and go to
mqtt-lab:터미널 창 PDCOMM_APPS=<simulator package directory>cd mqtt-lab -
In the first terminal, start the broker:
터미널 창 mosquitto -c local.conf -
In the second terminal, watch every OPC UA data topic:
터미널 창 mosquitto_sub -V 5 -t 'opcua/uadp/data/+/#' -F '%t qos=%q retain=%r content-type=%C user-properties=%P %l bytes'+matches the PublisherId level, and#matches every level below it. -
In the third terminal, start the subscriber:
터미널 창 cat subscriber.jsonl - | "$PDCOMM_APPS/bin/pdcomm-opcua-headless"catsends the two lines of the file first and then passes your keyboard input on to the simulator (-). When the second output line contains"role":"subscriber","running":true, the subscription is ready:{"ok":true,"result":{"acknowledged":0,"broker":"127.0.0.1:1883","destination":null,"dropped":0,"error":null,"listen":null,"queued":0,"received":0,"rejected":0,"role":"subscriber","running":true,"sent":0,"topic":"opcua/uadp/data/100/line1","transport":"mqtt"}}In Windows PowerShell, run
bin\pdcomm-opcua-headless.exeand paste the two lines ofsubscriber.jsonl. -
In the fourth terminal, run the publisher scenario:
터미널 창 "$PDCOMM_APPS/bin/pdcomm-opcua-headless" --scenario publisher-scenario.jsonThe simulator prints one result line per step and exits with code 0. The first line, the configuration result, is long and left out here:
{"result":{"acknowledged":0,"broker":"127.0.0.1:1883","destination":null,"dropped":0,"error":null,"listen":null,"queued":0,"received":0,"rejected":0,"role":"publisher","running":true,"sent":0,"topic":"opcua/uadp/data/100/line1","transport":"mqtt"},"step":2}{"result":{"bytes":52,"fields":3,"sequence":1},"step":3}{"result":{"bytes":52,"fields":3,"sequence":2},"step":4}{"result":{"running":false},"step":5}The observer in the second terminal prints two lines:
opcua/uadp/data/100/line1 qos=0 retain=0 content-type=application/opcua+uadp user-properties=UAMessageType:ua-data 52 bytesopcua/uadp/data/100/line1 qos=0 retain=0 content-type=application/opcua+uadp user-properties=UAMessageType:ua-data 52 bytes -
In the third terminal (the subscriber), type:
{"action":"pubsub_received"}{"ok":true,"result":{"messages":[{"bytes":52,"datasets":[{"fields":[{"type":"Double","value":21.5},{"type":"Boolean","value":true},{"type":"String","value":"RUN"}],"major":1,"minor":1,"sequence":1}],"publisher_id":100,"source":"mqtt","writer_group":1,"writer_ids":[1]},{"bytes":52,"datasets":[{"fields":[{"type":"Double","value":21.75},{"type":"Boolean","value":true},{"type":"String","value":"RUN"}],"major":1,"minor":1,"sequence":2}],"publisher_id":100,"source":"mqtt","writer_group":1,"writer_ids":[1]}]}}publisher_id100,writer_ids[1]and sequence numbers 1 and 2 match the publisher’s settings. The subscriber receives by topic, whatever its ownpublisher_id(77 by default) is.
Subscribe from the GUI
Section titled “Subscribe from the GUI”The result is the same when the subscriber is the GUI:
- Open the OPC UA simulator GUI and go to the PubSub tab.
- Set Transport to UADP over MQTT and Role to Subscriber.
- Enter
127.0.0.1:1883in MQTT broker andopcua/uadp/data/100/line1in MQTT topic, then click Start PubSub. - Run the publisher scenario from step 6 again and click Show received. The table shows two rows.
The simulator PubSub tab describes the screen.
Clean up
Section titled “Clean up”- Type
{"action":"shutdown"}in the third terminal to stop the subscriber. - Stop
mosquitto_subin the second terminal and the broker in the first terminal with Ctrl+C.
Common problems
Section titled “Common problems”| Symptom | Cause | Fix |
|---|---|---|
messages from pubsub_received is empty |
You started the subscriber after the publisher. The simulator doesn’t retain data and starts a new session on every connection. | Start the subscriber first, then run the publisher scenario again. |
| The observer sees the messages but the subscriber doesn’t | The subscriber’s topic differs from the publisher’s topic. | Compare topic in the two files. |
The scenario ends with Scenario step 2 failed: MQTT broker connection failed: … |
The publisher couldn’t connect to the broker. | Check the broker from step 3 and the broker address. Look up the rest of the message in Connection problems. |