Introduction
OPC UA integration follows the standard device protocols principle in Cumulocity IoT. This helps you to connect and map your OPC UA Server data to Cumulocity IoT easily without coding. The Device Management application supports you to create and manage your device protocols. However, there are some advanced features which are not supported by the OPC UA protocols UI yet. Via REST API you can go beyond the UI capabilities. In this article, I will show additional important features you should know as advanced user.
Device Protocols
The most important features are offered by the Device protocols UI and will be sufficient in most cases. See OPC UA - Cumulocity IoT Guides
However, some features are not available from the UI but only via the API. In this article I will show you how the following advanced features can be used:
- Configure MEA* Processing Mode
- Configure MEA* custom static fragment
- Advanced Custom Actions (retryEnabled, noRetryHttpCodes)
- UAEvents (UAEventCreation/UAAlarmCreation)
- Troubleshooting Operations
*MEA = Measurement, Event and Alarm
Device protocols for OPC UA can be created via REST API:
POST
/service/opcua-mgmt-service/device-types
MEA Processing Mode
The processing mode of a MEA in Cumulocity defines how the MEA should be handled. The default mode persistent means that the measurements will be stored in Cumulocity and will be accessible for real-time processing in Streaming Analytics. For more details about processing mode see standard Cumulocity REST API usage
For example, you subscribe to a data point in a low sampling rate, and you do not want to persist this data in Cumulocity but you need to do streaming analytics with Apama. For that you could set the "processingMode"
to: CEP
. This means all mappings will use the processing mode CEP
. With the fragment "overriddenProcessingMode"
you can define even for each MEA* separated which processing mode it should be used!
Following device protocol will show both configurations.
{
"name": "ProSys Simulation",
"processingMode": "CEP",
"referencedNamespaceTable": [
"http://opcfoundation.org/UA/",
"urn:SAG-FVFX12XJHV2H.local:OPCUA:SimulationServer",
"http://www.prosysopc.com/OPCUA/SampleAddressSpace",
"http://www.prosysopc.com/OPCUA/ComplianceNodes",
"http://www.prosysopc.com/OPCUA/ComplianceNonUaNodes",
"http://www.prosysopc.com/OPCUA/SimulationNodes",
"http://www.prosysopc.com/OPCUA/SampleBigAddressSpace"
],
"enabled": true,
"applyConstraints": {
"matchesNodeIds": [
"ns=5;s=85/0:Simulation"
]
},
"mappings": [{
"browsePath": [
"5:Counter1"
],
"measurementCreation": {
"series": "Counter",
"unit": "I",
"type": "Counter",
"overriddenProcessingMode": "PERSISTENT"
}
},
{
"browsePath": [
"5:Sinusoid1"
],
"measurementCreation": {
"series": "Sinus",
"unit": "S",
"type": "Sinus"
}
}
],
"subscriptionType": {
"type": "Subscription",
"subscriptionParameters": {
"samplingRate": 500,
"queueSize": 10,
"attrs": {}
}
}
}
That protocol above used in general for all mappings the processing mode CEP
, except for the mapping of β5:Counter1β which will use PERSISTENT
.
MEA Static fragment
Sometimes you want to mark MEA with a specific fragment. You can do this by including a staticFragment
in the device protocol.
{
"name": "ProSys Simulation",
"referencedNamespaceTable": [
"http://opcfoundation.org/UA/",
"urn:SAG-FVFX12XJHV2H.local:OPCUA:SimulationServer",
"http://www.prosysopc.com/OPCUA/SampleAddressSpace",
"http://www.prosysopc.com/OPCUA/ComplianceNodes",
"http://www.prosysopc.com/OPCUA/ComplianceNonUaNodes",
"http://www.prosysopc.com/OPCUA/SimulationNodes",
"http://www.prosysopc.com/OPCUA/SampleBigAddressSpace"
],
"enabled": true,
"applyConstraints": {
"matchesNodeIds": [
"ns=5;s=85/0:Simulation"
]
},
"mappings": [{
"browsePath": [
"5:Counter1"
],
"measurementCreation": {
"series": "Counter",
"unit": "I",
"type": "Counter",
"staticFragments": [
"myFragment1",
"myFragment2"
],
}
},
{
"browsePath": [
"5:Sinusoid1"
],
"measurementCreation": {
"series": "Sinus",
"unit": "S",
"type": "Sinus"
}
}
],
"subscriptionType": {
"type": "Subscription",
"subscriptionParameters": {
"samplingRate": 500,
"queueSize": 10,
"attrs": {}
}
}
}
The staticFragments
can be defined for measurement, event, alarm, and custom action mappings. The above protocol would produces following measurement:
{
"Counter": {
"Counter": {
"unit": "I",
"value": 7
}
},
"id": "27653182",
"myFragment1": {},
"myFragment2": {},
"source": {
"id": "1127504039"
},
"time": "2024-07-16T13:45:59.000+02:00",
"type": "Counter"
}
Custom action retry mechanism
With custom actions you can directly connect and map to another REST API. It makes sense to have a retry option to handle connections issues. With these two specific configurations you can define your retry feature on a single custom action mapping and overwrite global gateway configuration.
retryEnabled
- Whether a failed HTTP POST should be retried or not. This overrides the configuration in the gateway. If this is not provided, the configuration in the gateway will be taken.
noRetryHttpCodes
- Array of HTTP POST status exceptions by which the failed HTTP POST should not be retried if enabled. Example: [400, 500]. Note that, if this is null or missing, the exceptions will be taken from the gateway configuration. If this is provided, even with an empty array, the configuration in the gateway is disregarded.
The retry configuration can also be configured globally, which will be applied to all custom actions if not explicit defined in the protocol as mentioned here. For more details see Custom Actions retry
Example:
{
"name": "MySimulator",
"referencedRootNodeId": "ns=2;s=MyDevice",
"referencedNamespaceTable": [
"http://opcfoundation.org/UA/",
"urn:SAG-FVFX12XJHV2H.local:OPCUA:SimulationServer",
"http://www.prosysopc.com/OPCUA/SampleAddressSpace",
"http://www.prosysopc.com/OPCUA/ComplianceNodes",
"http://www.prosysopc.com/OPCUA/ComplianceNonUaNodes",
"http://www.prosysopc.com/OPCUA/SimulationNodes",
"http://www.prosysopc.com/OPCUA/SampleBigAddressSpace"
],
"enabled": true,
"applyConstraints": {
"matchesNodeIds": [
"ns=2;s=MyDevice"
]
},
"mappings": [{
"browsePath": [
"2:MyLevel"
],
"customAction": {
"type": "HttpPost",
"endpoint": "http://localhost:8080/hello",
"bodyTemplate": "{\"hello\": \"Custom action ${value} \" }",
"headers": {
"Content-Type": "application/json"
},
"retryEnabled": true,
"noRetryHttpCodes": [500, 400]
}
}
],
"subscriptionType": {
"type": "CyclicRead",
"cyclicReadParameters": {
"rate": 1000
}
}
}
UA Events
It is also possible to map UA events of a monitored item to Cumulocity events and alarms. The example shows how to do that. See more information OPC UA - Cumulocity IoT documentation
{
"name": "ProSys MyDevice",
"referencedNamespaceTable": [
"http://opcfoundation.org/UA/",
"urn:SAG-FVFX12XJHV2H.local:OPCUA:SimulationServer",
"http://www.prosysopc.com/OPCUA/SampleAddressSpace",
"http://www.prosysopc.com/OPCUA/ComplianceNodes",
"http://www.prosysopc.com/OPCUA/ComplianceNonUaNodes",
"http://www.prosysopc.com/OPCUA/SimulationNodes",
"http://www.prosysopc.com/OPCUA/SampleBigAddressSpace"
],
"enabled": true,
"applyConstraints": {
"matchesNodeIds": [
"ns=0;i=85"
]
},
"uaEventMappings": [{
"browsePath": [
"0:Server"
],
"eventTypeId": "i=9482",
"attributes": [
"Severity",
"Time",
"EventId",
"Message",
"SourceNode"
],
"alarmCreation": {
"text": "MyLevel Alaram! severity: ${0}, time: ${1}, evntId: ${2}, message: ${3}, nodeId: ${4}",
"status": "ACTIVE",
"type": "c8y_myLevel_alarm_${0}_${4}"
},
"eventCreation": {
"text": "MyLevel sent an event: severity: ${0}, time: ${1}, evntId: ${2}, message: ${3}, nodeId: ${4}",
"type": "c8y_myLevel_event_${4}"
}
}
],
"subscriptionType": {
"type": "Subscription",
"subscriptionParameters": {
"samplingRate": 500,
"queueSize": 10,
"attrs": {}
}
}
}
In the example above the UA Events from type βi=9482β will be monitored of the OPC UA server β0:Serverβ. If the gateway receives an UA Event it will create an alarm and event.
Troubleshooting Operations
Sometimes you run into the problem that device protocols are not applied at all. In that case no device is created for your protocol. To help you in these situations, operations are available, which help you to find the issue with the protocol and check against a certain OPC UA server.
Testing a device type against a node on an OPC UA server
As a first step you can test if the defined device type in Cumulocity should match against a node on a connected OPC-UA server. This allows you to see if the problem is in your device type definition in Cumulocity or elsewhere. More details can be found here: OPC UA Operation documentation
Example: Test if device type 18608327 matches OPC UA Server 6819231401
{
"description": "Test device type matching",
"deviceId": "6819231401",
"c8y_ua_command_TestDeviceTypeMatching": {
"deviceTypeId": "18608327",
"rootNodeId": "ns=3;s=85/0:Simulation"
}
}
Postive:
Negative:
Analyzing the set of nodes to which a device type can be applied (dry run)
If you do not know what exact nodes a device type should match or if you want to avoid it matching against unexpected nodes you can do a dry run to see to which nodes a device type in Cumulocity would be applied. For more details see OPC UA Operation documentation
Example: Dry run if device type 18608327 matches OPC UA Server 6819231401
{
"description": "Dry run device type matching",
"deviceId": "6819231401",
"c8y_ua_command_DryRunDeviceTypeMatching": {
"deviceTypeId": "18608327"
}
}
Positive:
Negative:
Get the current application state of a device type
To test what nodes Cumulocity device type is currently applied to you can use this operation. You provide it with a list of nodes and for each node it will provide information if the device type is currently applied or not. For more details see OPC UA Operation documentation
Example: Test if device type 18608327 matches OPC UA Server 6819231401
{
"description": "Get device type application state",
"deviceId": "6819231401",
"c8y_ua_command_GetDeviceTypeApplicationState": {
"deviceTypeId": "7519251726",
"matchingRootNodes": ["ns=3;s=85/0:Simulation"]
}
}
Positive:
Negative:
Summary
This article introduced advanced features of the Cumulocity OPC UA integration that are not yet available through the UI. It covered the processing modes and the inclusion of custom fragments for device protocols. You also learned how to set up retries for custom actions in the event of connectivity problems. Additionally, the article discussed UA Events, which you have the option to subscribe to. Finally, it explored various operations that assist in troubleshooting device protocol issues.