Using OpcCmd Utility as OPC UA PubSub Sniffer: Difference between revisions
No edit summary |
|||
(11 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
[[Category:OPC UA PubSub]] [[Category:OPC UA PubSub Sniffing]] [[Category:OpcCmd Utility]] [[Category:Sniffing]] [[Category:Troubleshooting]] | |||
This article assumes that you have basic knowledge of the [[OPC UA PubSub Sniffing concepts]]; please read the corresponding article first. | This article assumes that you have basic knowledge of the [[OPC UA PubSub Sniffing concepts]]; please read the corresponding article first. | ||
= Accessing the OPC UA PubSub Sniffer = | = Accessing the OPC UA PubSub Sniffer = | ||
Line 21: | Line 21: | ||
Binary data (UADP) are shown in hexadecimal format, textual data (JSON) are decoded first, and shown as strings. | Binary data (UADP) are shown in hexadecimal format, textual data (JSON) are decoded first, and shown as strings. | ||
== Aggregates == | |||
The '''subscribeCapture''' command can calculate aggregated information out of the notifications received, and display it at the end of command execution. By default, it displays a statistics of capture headers (count of each distinct header received, and the rate at which it was received). You can use the '''--Aggregates''' ('''-a''') option to choose the aggregate (or aggregates) that will be calculated and displayed. Available aggregates are currently '''CaptureHeaderStatistics''', '''CaptureTypeStatistics''', '''DataSetWriterStatistics''', '''GroupByOrigin''', '''HierarchizeByObjectId''', '''HierarchizeByOriginPath''', '''OriginStatistics''', and '''PublisherStatistics'''. | |||
Multiple aggregates can be specified, and separated by comma. The reserved name '''None''' represents no aggregates, and the reserved word '''All''' represents all available aggregates. | |||
= Typical usage scenarios = | = Typical usage scenarios = | ||
Line 103: | Line 108: | ||
== Discover who communicates what == | == Discover who communicates what == | ||
This scenario is useful when you want to get an overview of the actors (publishers) that are communicating on a given PubSub connection, what types of messages they exchange, and which PubSub objects are involved (e.g. writer groups, dataset writers). | This scenario is useful when you want to get an overview of the actors (publishers) that are communicating on a given PubSub connection, what types of messages they exchange, and which PubSub objects are involved (e.g. writer groups, dataset writers). | ||
The <code>!wait Infinite</code> subcommand is used so that the information can be collected over an extended period of time. A new entry is displayed each time a message with distinct capture header is received. Repeated occurrences of the same capture header are hidden, so that they do not clutter the output. After some time, when you believe you have collected enough data (new entries do not appear any longer), you can press 'X' to end the capture. Obviously, you can also instruct the capture to be run for specific amount of time, by omitting the <code>!wait</code> subcommand, or specifying the desired time period with it. | |||
Discover who communicates what with UDP transport mapping: | Discover who communicates what with UDP transport mapping: | ||
Line 170: | Line 177: | ||
* The 'writer' field tells us the dataset writer Id(s) the publishers are configured to publish. | * The 'writer' field tells us the dataset writer Id(s) the publishers are configured to publish. | ||
* We can see that some publishers, but not all, are also using delta frames. Some are also sending events, or keep-alive messages. | * We can see that some publishers, but not all, are also using delta frames. Some are also sending events, or keep-alive messages. | ||
== Discover publisher Ids, writer group Ids and dataset writer Ids == | |||
subscribeCapture opc.udp://239.0.0.1:4840 --CaptureTypes AllDataSetMessages --Aggregates HierarchizeByObjectIds | |||
== Capture and show message data == | == Capture and show message data == | ||
Line 188: | Line 198: | ||
... | ... | ||
</pre></small> | </pre></small> | ||
== Find message origins == | |||
subscribeCapture mqtt://opcua-pubsub.demo-this.com # --Aggregates GroupByOrigin | |||
{{Note|Use command-line option for sequence viewing like <code>-!vs::K64V100</code> if the automatically determined column sizes are not appropriate.}} | |||
subscribeCapture mqtt://opcua-pubsub.demo-this.com # --Aggregates HierarchizeByOriginPath | |||
subscribeCapture mqtt://opcua-pubsub.demo-this.com # --CaptureTypes TransportMessage --Aggregates HierarchizeByOriginPath | |||
{{Note|Use command-line option for tree viewing like <code>-!vt::D99N9999T100</code> if the automatically determined column size, maximum depth or maximum number of nodes are not appropriate.}} | |||
= See also = | = See also = |
Latest revision as of 17:32, 4 September 2024
This article assumes that you have basic knowledge of the OPC UA PubSub Sniffing concepts; please read the corresponding article first.
Accessing the OPC UA PubSub Sniffer
In the OpcCmd utility, the OPC UA PubSub Sniffer is accessible as a service under the uaSubscriber command. For interactive usage, you can access it as follows:
uaSubscriber getService uaPubSubSniffer
(shortened: uas gs uapss
). You can also use the above command text as a prefix, and append the desired uaPubSubSniffer command at the end, for a "one-shot" execution of the OPC UA PubSub Sniffer.
uaPubSubSniffer subscribeCapture command
The subscribeCapture
command (shortened: sc
) subscribes to traffic captures and displays them. Its arguments, and vast majority of its options, are identical with the uaSubscriber subscribeDataSet
command, so we are not going to repeat them here.
At the end of its execution, the command displays a table, where each distinct capture header is represented by a row, and it shows the fields of the capture header, and a number of times such header has been encountered. The table is ordered first by the capture type, and then by the remaining fields of the capture header.
The events?
command (shortened: ev?
) can be used to display the captured events in form of a table, and/or to extract a particular numbered event and show its details.
Limiting the capture types
If you are not interested in all messages that appear on the specified PubSub connection, but only in some message types, use the --CaptureTypes
(shortened: -ct
) command option. With it, you can specify the capture type either as an individual capture type, a specific combination of them, or a predefined capture type grouping.
Selecting distinct headers
If you are not interested in every message, but only in knowing what kinds of messages appear on the network (PubSub connection), use the --DistinctHeadersOnly
option (shortened: -dho
). With this option, the capture header of every new incoming capture notification is compared with the already recorder headers, and the notification is displayed only if the capture header has not been encountered before.
Capturing message data
In order to display the data captured with each transport message, use the --ShowCaptureData
option (shortened: -scd
). More information: Data capture with sniffing.
Binary data (UADP) are shown in hexadecimal format, textual data (JSON) are decoded first, and shown as strings.
Aggregates
The subscribeCapture command can calculate aggregated information out of the notifications received, and display it at the end of command execution. By default, it displays a statistics of capture headers (count of each distinct header received, and the rate at which it was received). You can use the --Aggregates (-a) option to choose the aggregate (or aggregates) that will be calculated and displayed. Available aggregates are currently CaptureHeaderStatistics, CaptureTypeStatistics, DataSetWriterStatistics, GroupByOrigin, HierarchizeByObjectId, HierarchizeByOriginPath, OriginStatistics, and PublisherStatistics.
Multiple aggregates can be specified, and separated by comma. The reserved name None represents no aggregates, and the reserved word All represents all available aggregates.
Typical usage scenarios
Show all communication
You do not need any additional options in order to show all communication with the subscribeCapture
command. In the simplest case, you just enter the connection URI as the first command argument, and if you are using MQTT, the topic filter as the second argument.
Show all communication with UDP transport mapping:
subscribeCapture opc.udp://239.0.0.1:4840
Show all communication with MQTT transport mapping:
subscribeCapture mqtt://opcua-pubsub.demo-this.com #
Example output:
Executing for 00:01:00 (press 'X' to stop)... Subscribing capture... [0] IUAPubSubSniffer.Capture: None Capture handle: 13000003 [1] IUAPubSubSniffer.Capture: TransportMessage; origin=opcuademo/uadp/none, mapping=Uadp [2] IUAPubSubSniffer.Capture: NetworkMessage; publisher=[String]32, class=eae79794-1af7-4f96-8401-4096cd1d8908, origin=opcuademo/uadp/none, mapping=Uadp [3] IUAPubSubSniffer.Capture: DataSetKeyFrame; publisher=[String]32, writer=1, class=eae79794-1af7-4f96-8401-4096cd1d8908, origin=opcuademo/uadp/none, mapping=Uadp [4] IUAPubSubSniffer.Capture: TransportMessage; origin=opcuademo/uadp/none, mapping=Uadp [5] IUAPubSubSniffer.Capture: NetworkMessage; publisher=[String]32, class=96976b7b-0db7-46c3-a715-0979884b55ae, origin=opcuademo/uadp/none, mapping=Uadp [6] IUAPubSubSniffer.Capture: DataSetKeyFrame; publisher=[String]32, writer=3, class=96976b7b-0db7-46c3-a715-0979884b55ae, origin=opcuademo/uadp/none, mapping=Uadp [7] IUAPubSubSniffer.Capture: TransportMessage; origin=opcuademo/uadp/none, mapping=Uadp [8] IUAPubSubSniffer.Capture: NetworkMessage; publisher=[String]32, class=cc7cb5f4-4272-45c2-9a4d-f85a8b331f6a, origin=opcuademo/uadp/none, mapping=Uadp [9] IUAPubSubSniffer.Capture: DataSetKeyFrame; publisher=[String]32, writer=4, class=cc7cb5f4-4272-45c2-9a4d-f85a8b331f6a, origin=opcuademo/uadp/none, mapping=Uadp [10] IUAPubSubSniffer.Capture: TransportMessage; origin=opcuademo/uadp/none, mapping=Uadp [11] IUAPubSubSniffer.Capture: NetworkMessage; publisher=[UInt64]31, origin=opcuademo/uadp/none, mapping=Uadp [12] IUAPubSubSniffer.Capture: DataSetDeltaFrame; publisher=[UInt64]31, writer=1, origin=opcuademo/uadp/none, mapping=Uadp [13] IUAPubSubSniffer.Capture: DataSetDeltaFrame; publisher=[UInt64]31, writer=3, origin=opcuademo/uadp/none, mapping=Uadp [14] IUAPubSubSniffer.Capture: DataSetDeltaFrame; publisher=[UInt64]31, writer=4, origin=opcuademo/uadp/none, mapping=Uadp [15] IUAPubSubSniffer.Capture: DataSetEvent; publisher=[UInt64]31, writer=51, origin=opcuademo/uadp/none, mapping=Uadp [16] IUAPubSubSniffer.Capture: TransportMessage; origin=opcuademo/json, mapping=Json [17] IUAPubSubSniffer.Capture: NetworkMessage; publisher=[String]31, class=eae79794-1af7-4f96-8401-4096cd1d8908, origin=opcuademo/json, mapping=Json [18] IUAPubSubSniffer.Capture: DataSetKeyFrame; publisher=[String]31, class=eae79794-1af7-4f96-8401-4096cd1d8908, origin=opcuademo/json, mapping=Json [19] IUAPubSubSniffer.Capture: TransportMessage; origin=opcuademo/json, mapping=Json [20] IUAPubSubSniffer.Capture: NetworkMessage; publisher=[String]32, origin=opcuademo/json, mapping=Json ... Unsubscribing capture (capture handle 13000003)... PubSub header counts (sequence): 35 element(s) ╒═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╤═════╕ │[] │Value│ ╞═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╪═════╡ │None │1 │ │TransportMessage; origin=opcuademo/json, mapping=Json │150 │ │TransportMessage; origin=opcuademo/uadp/none, mapping=Uadp │150 │ │NetworkMessage; publisher=[UInt16]30, origin=opcuademo/uadp/none, mapping=Uadp │30 │ │NetworkMessage; publisher=[UInt64]31, origin=opcuademo/uadp/none, mapping=Uadp │30 │ │NetworkMessage; publisher=[String]30, origin=opcuademo/json, mapping=Json │30 │ │NetworkMessage; publisher=[String]31, class=96976b7b-0db7-46c3-a715-0979884b55ae, origin=opcuademo/json, mapping=Json │30 │ │NetworkMessage; publisher=[String]31, class=cc7cb5f4-4272-45c2-9a4d-f85a8b331f6a, origin=opcuademo/json, mapping=Json │30 │ │NetworkMessage; publisher=[String]31, class=eae79794-1af7-4f96-8401-4096cd1d8908, origin=opcuademo/json, mapping=Json │30 │ │NetworkMessage; publisher=[String]32, origin=opcuademo/json, mapping=Json │30 │ │NetworkMessage; publisher=[String]32, class=96976b7b-0db7-46c3-a715-0979884b55ae, origin=opcuademo/uadp/none, mapping=Uadp │30 │ │NetworkMessage; publisher=[String]32, class=cc7cb5f4-4272-45c2-9a4d-f85a8b331f6a, origin=opcuademo/uadp/none, mapping=Uadp │30 │ │NetworkMessage; publisher=[String]32, class=eae79794-1af7-4f96-8401-4096cd1d8908, origin=opcuademo/uadp/none, mapping=Uadp │30 │ │DataSetKeyFrame; publisher=[UInt16]30, group=101, origin=opcuademo/uadp/none, mapping=Uadp │20 │ │DataSetKeyFrame; publisher=[UInt64]31, writer=1, origin=opcuademo/uadp/none, mapping=Uadp │1 │ │DataSetKeyFrame; publisher=[UInt64]31, writer=3, origin=opcuademo/uadp/none, mapping=Uadp │1 │ │DataSetKeyFrame; publisher=[UInt64]31, writer=4, origin=opcuademo/uadp/none, mapping=Uadp │1 │ │DataSetKeyFrame; publisher=[String]30, writer=1, origin=opcuademo/json, mapping=Json │1 │ │DataSetKeyFrame; publisher=[String]30, writer=2, origin=opcuademo/json, mapping=Json │1 │ │DataSetKeyFrame; publisher=[String]30, writer=3, origin=opcuademo/json, mapping=Json │1 │ │DataSetKeyFrame; publisher=[String]31, class=96976b7b-0db7-46c3-a715-0979884b55ae, origin=opcuademo/json, mapping=Json │30 │ │DataSetKeyFrame; publisher=[String]31, class=cc7cb5f4-4272-45c2-9a4d-f85a8b331f6a, origin=opcuademo/json, mapping=Json │30 │ │DataSetKeyFrame; publisher=[String]31, class=eae79794-1af7-4f96-8401-4096cd1d8908, origin=opcuademo/json, mapping=Json │30 │ │DataSetKeyFrame; publisher=[String]32, origin=opcuademo/json, mapping=Json │90 │ │DataSetKeyFrame; publisher=[String]32, writer=1, class=eae79794-1af7-4f96-8401-4096cd1d8908, origin=opcuademo/uadp/none, mapping=Uadp│30 │ │DataSetKeyFrame; publisher=[String]32, writer=3, class=96976b7b-0db7-46c3-a715-0979884b55ae, origin=opcuademo/uadp/none, mapping=Uadp│30 │ │DataSetKeyFrame; publisher=[String]32, writer=4, class=cc7cb5f4-4272-45c2-9a4d-f85a8b331f6a, origin=opcuademo/uadp/none, mapping=Uadp│30 │ │DataSetDeltaFrame; publisher=[UInt64]31, writer=1, origin=opcuademo/uadp/none, mapping=Uadp │19 │ │DataSetDeltaFrame; publisher=[UInt64]31, writer=3, origin=opcuademo/uadp/none, mapping=Uadp │19 │ │DataSetDeltaFrame; publisher=[UInt64]31, writer=4, origin=opcuademo/uadp/none, mapping=Uadp │19 │ │DataSetDeltaFrame; publisher=[String]30, writer=1, origin=opcuademo/json, mapping=Json │29 │ │DataSetDeltaFrame; publisher=[String]30, writer=2, origin=opcuademo/json, mapping=Json │29 │ │DataSetDeltaFrame; publisher=[String]30, writer=3, origin=opcuademo/json, mapping=Json │29 │ │DataSetEvent; publisher=[UInt64]31, writer=51, origin=opcuademo/uadp/none, mapping=Uadp │7 │ │DataSetKeepAlive; publisher=[UInt64]31, writer=51, origin=opcuademo/uadp/none, mapping=Uadp │18 │ ╘═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╧═════╛ Command finished: subscribeCapture|sc (60.3 seconds). Observed 1066 event(s), start index 0. You can use the "events?" ("ev?") command to view their details.
Discover who communicates what
This scenario is useful when you want to get an overview of the actors (publishers) that are communicating on a given PubSub connection, what types of messages they exchange, and which PubSub objects are involved (e.g. writer groups, dataset writers).
The !wait Infinite
subcommand is used so that the information can be collected over an extended period of time. A new entry is displayed each time a message with distinct capture header is received. Repeated occurrences of the same capture header are hidden, so that they do not clutter the output. After some time, when you believe you have collected enough data (new entries do not appear any longer), you can press 'X' to end the capture. Obviously, you can also instruct the capture to be run for specific amount of time, by omitting the !wait
subcommand, or specifying the desired time period with it.
Discover who communicates what with UDP transport mapping:
subscribeCapture opc.udp://239.0.0.1:4840 --CaptureTypes AllPubSubMessages --DistinctHeadersOnly !wait Infinite
Discover who communicates what with MQTT transport mapping:
subscribeCapture mqtt://opcua-pubsub.demo-this.com # --CaptureTypes AllPubSubMessages --DistinctHeadersOnly !wait Infinite
Example output:
Executing for Infinite (press 'X' to stop)... Subscribing capture... 8/15/2022 1:03:30 PM Distinct header: None Capture handle: 13000002 8/15/2022 1:03:32 PM Distinct header: DataSetKeyFrame; publisher=[String]32, writer=1, class=eae79794-1af7-4f96-8401-4096cd1d8908, origin=opcuademo/uadp/none, mapping=Uadp 8/15/2022 1:03:32 PM Distinct header: DataSetKeyFrame; publisher=[String]32, writer=3, class=96976b7b-0db7-46c3-a715-0979884b55ae, origin=opcuademo/uadp/none, mapping=Uadp 8/15/2022 1:03:32 PM Distinct header: DataSetKeyFrame; publisher=[String]32, writer=4, class=cc7cb5f4-4272-45c2-9a4d-f85a8b331f6a, origin=opcuademo/uadp/none, mapping=Uadp 8/15/2022 1:03:32 PM Distinct header: DataSetDeltaFrame; publisher=[UInt64]31, writer=1, origin=opcuademo/uadp/none, mapping=Uadp 8/15/2022 1:03:32 PM Distinct header: DataSetDeltaFrame; publisher=[UInt64]31, writer=3, origin=opcuademo/uadp/none, mapping=Uadp 8/15/2022 1:03:32 PM Distinct header: DataSetDeltaFrame; publisher=[UInt64]31, writer=4, origin=opcuademo/uadp/none, mapping=Uadp 8/15/2022 1:03:32 PM Distinct header: DataSetKeepAlive; publisher=[UInt64]31, writer=51, origin=opcuademo/uadp/none, mapping=Uadp 8/15/2022 1:03:32 PM Distinct header: DataSetKeyFrame; publisher=[String]32, origin=opcuademo/json, mapping=Json 8/15/2022 1:03:32 PM Distinct header: DataSetKeyFrame; publisher=[String]31, class=eae79794-1af7-4f96-8401-4096cd1d8908, origin=opcuademo/json, mapping=Json 8/15/2022 1:03:32 PM Distinct header: DataSetKeyFrame; publisher=[String]31, class=96976b7b-0db7-46c3-a715-0979884b55ae, origin=opcuademo/json, mapping=Json 8/15/2022 1:03:32 PM Distinct header: DataSetKeyFrame; publisher=[String]31, class=cc7cb5f4-4272-45c2-9a4d-f85a8b331f6a, origin=opcuademo/json, mapping=Json 8/15/2022 1:03:32 PM Distinct header: DataSetDeltaFrame; publisher=[String]30, writer=1, origin=opcuademo/json, mapping=Json 8/15/2022 1:03:32 PM Distinct header: DataSetDeltaFrame; publisher=[String]30, writer=2, origin=opcuademo/json, mapping=Json 8/15/2022 1:03:32 PM Distinct header: DataSetDeltaFrame; publisher=[String]30, writer=3, origin=opcuademo/json, mapping=Json 8/15/2022 1:03:32 PM Distinct header: DataSetKeyFrame; publisher=[UInt16]30, group=101, origin=opcuademo/uadp/none, mapping=Uadp 8/15/2022 1:03:58 PM Distinct header: DataSetEvent; publisher=[UInt64]31, writer=51, origin=opcuademo/uadp/none, mapping=Uadp 8/15/2022 1:03:58 PM Distinct header: DataSetKeyFrame; publisher=[String]30, writer=1, origin=opcuademo/json, mapping=Json 8/15/2022 1:03:58 PM Distinct header: DataSetKeyFrame; publisher=[String]30, writer=2, origin=opcuademo/json, mapping=Json 8/15/2022 1:03:58 PM Distinct header: DataSetKeyFrame; publisher=[String]30, writer=3, origin=opcuademo/json, mapping=Json The execution has been terminated by the user. Unsubscribing capture (capture handle 13000002)... PubSub header counts (sequence): 20 element(s) ╒═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╤═════╕ │[] │Value│ ╞═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╪═════╡ │None │1 │ │DataSetKeyFrame; publisher=[UInt16]30, group=101, origin=opcuademo/uadp/none, mapping=Uadp │9 │ │DataSetKeyFrame; publisher=[String]30, writer=1, origin=opcuademo/json, mapping=Json │1 │ │DataSetKeyFrame; publisher=[String]30, writer=2, origin=opcuademo/json, mapping=Json │1 │ │DataSetKeyFrame; publisher=[String]30, writer=3, origin=opcuademo/json, mapping=Json │1 │ │DataSetKeyFrame; publisher=[String]31, class=96976b7b-0db7-46c3-a715-0979884b55ae, origin=opcuademo/json, mapping=Json │19 │ │DataSetKeyFrame; publisher=[String]31, class=cc7cb5f4-4272-45c2-9a4d-f85a8b331f6a, origin=opcuademo/json, mapping=Json │19 │ │DataSetKeyFrame; publisher=[String]31, class=eae79794-1af7-4f96-8401-4096cd1d8908, origin=opcuademo/json, mapping=Json │19 │ │DataSetKeyFrame; publisher=[String]32, origin=opcuademo/json, mapping=Json │57 │ │DataSetKeyFrame; publisher=[String]32, writer=1, class=eae79794-1af7-4f96-8401-4096cd1d8908, origin=opcuademo/uadp/none, mapping=Uadp│19 │ │DataSetKeyFrame; publisher=[String]32, writer=3, class=96976b7b-0db7-46c3-a715-0979884b55ae, origin=opcuademo/uadp/none, mapping=Uadp│19 │ │DataSetKeyFrame; publisher=[String]32, writer=4, class=cc7cb5f4-4272-45c2-9a4d-f85a8b331f6a, origin=opcuademo/uadp/none, mapping=Uadp│19 │ │DataSetDeltaFrame; publisher=[UInt64]31, writer=1, origin=opcuademo/uadp/none, mapping=Uadp │9 │ │DataSetDeltaFrame; publisher=[UInt64]31, writer=3, origin=opcuademo/uadp/none, mapping=Uadp │9 │ │DataSetDeltaFrame; publisher=[UInt64]31, writer=4, origin=opcuademo/uadp/none, mapping=Uadp │9 │ │DataSetDeltaFrame; publisher=[String]30, writer=1, origin=opcuademo/json, mapping=Json │18 │ │DataSetDeltaFrame; publisher=[String]30, writer=2, origin=opcuademo/json, mapping=Json │18 │ │DataSetDeltaFrame; publisher=[String]30, writer=3, origin=opcuademo/json, mapping=Json │18 │ │DataSetEvent; publisher=[UInt64]31, writer=51, origin=opcuademo/uadp/none, mapping=Uadp │1 │ │DataSetKeepAlive; publisher=[UInt64]31, writer=51, origin=opcuademo/uadp/none, mapping=Uadp │13 │ ╘═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╧═════╛ Command finished: subscribeCapture|sc (39.8 seconds). Observed 0 event(s), start index 0.
How can the above output be interpreted? It basically tells us, among other things, that
- There are 5 publishers, with publisher Ids [UInt16]30, [UInt64]31, [String]30, [String]31 and [String]32.
- The first two publishers are generating messages in the UADP message mapping, the remaining publishers in JSON.
- The 'origin' field tells us the MQTT topic the publishers are sending messages to.
- The 'writer' field tells us the dataset writer Id(s) the publishers are configured to publish.
- We can see that some publishers, but not all, are also using delta frames. Some are also sending events, or keep-alive messages.
Discover publisher Ids, writer group Ids and dataset writer Ids
subscribeCapture opc.udp://239.0.0.1:4840 --CaptureTypes AllDataSetMessages --Aggregates HierarchizeByObjectIds
Capture and show message data
In order to view the original messages as they are being communicated on the specified PubSub connection, use the --ShowCaptureData
option. In our example, we are not interested in further analysis of the received messages, and we therefore limit the capture to the TransportMessage type, by using the --CaptureTypes
option. By removing this option, you can view the captured data together with their analysis as OPC UA PubSub messages.
Capture and show message data with UDP transport mapping:
subscribeCapture opc.udp://239.0.0.1:4840 --CaptureTypes TransportMessage --ShowCaptureData
Capture and show message data with MQTT transport mapping:
subscribeCapture mqtt://opcua-pubsub.demo-this.com # --CaptureTypes TransportMessage --ShowCaptureData
Example output:
Executing for 00:01:00 (press 'X' to stop)... Subscribing capture... [0] IUAPubSubSniffer.Capture: None Capture handle: 13000001 [1] IUAPubSubSniffer.Capture: TransportMessage; origin=opcuademo/uadp/none, mapping=Uadp Byte[]: D1 0C 02 00 00 00 33 32 94 97 E7 EA F7 1A 96 4F 84 01 40 96 CD 1D 89 08 01 01 00 01 04 00 01 00 06 66 1F 00 00 06 E7 06 00 00 0D C0 FF 94 44 96 B0 D8 01 ...
Find message origins
subscribeCapture mqtt://opcua-pubsub.demo-this.com # --Aggregates GroupByOrigin
Note: Use command-line option for sequence viewing like -!vs::K64V100
if the automatically determined column sizes are not appropriate.
subscribeCapture mqtt://opcua-pubsub.demo-this.com # --Aggregates HierarchizeByOriginPath
subscribeCapture mqtt://opcua-pubsub.demo-this.com # --CaptureTypes TransportMessage --Aggregates HierarchizeByOriginPath
Note: Use command-line option for tree viewing like -!vt::D99N9999T100
if the automatically determined column size, maximum depth or maximum number of nodes are not appropriate.