DEV Community

Tech Community for Software AG Tech Community

Posted on • Originally published at tech.forums.softwareag.com on

OPC-UA Integration with Cumulocity, OPC UA Device protocols advanced

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 = M easurement, E vent and A larm

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": {}
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

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": {}
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

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"
}

Enter fullscreen mode Exit fullscreen mode

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
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

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": {}
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

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"
    }
}

Enter fullscreen mode Exit fullscreen mode

Postive:

DeviceTypeMatchesTrue

Negative:

DeviceTypeMatchesFalse

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"
    }
}

Enter fullscreen mode Exit fullscreen mode

Positive:

DeviceTypeDryTrue

Negative:

DeviceTypeDryFalse

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"]
    }
}

Enter fullscreen mode Exit fullscreen mode

Positive:

DeviceTypeApplicationStateTrue

Negative:

DeviceTypeApplicationStateFalse

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.

Read full topic

Top comments (0)