Skip to main content

OPC UA Module

OPC Unified Architecture (OPC UA) is a machine to machine communication protocol for industrial automation developed by the OPC Foundation. It provides a robust, secure, and scalable framework for communications and data exchange in the industrial automation space.

OPC UA is platform-independent, ensuring the seamless flow of information among devices from multiple vendors. It supports robust, reliable, and secure communications, providing both encryption and authentication, making it a leading choice for Industrial Internet of Things (IIoT) applications.

The OPC UA module in the context of Azure IoT Edge is a container that you deploy on your IoT Edge devices. This module is able to communicate with OPC UA servers in your industrial environment, extract data from them, and send this data to the cloud for further analysis or storage.

The OPC UA module can read data from many types of industrial equipment like PLCs, DCS, SCADA systems, and more. This is crucial because it allows for a wide variety of data to be pulled into Azure IoT Edge from industrial systems that traditionally have been difficult to integrate with modern cloud-based solutions.

In Azure IoT Edge, the OPC UA module communicates with other modules using the IoT Edge Hub, enabling complex processing and filtering of data at the edge before it's sent to the cloud. This can reduce the amount of data that needs to be sent to the cloud, lowering bandwidth requirements and improving responsiveness.

OPC UA manifest

Creating a manifest for an OPC/UA Module and configuring a template for it in Azure IoT Central involves defining the Modbus module in the manifest, setting up its Docker image and settings, and routing its messages. Then, in IoT Central, a template reflecting the Modbus module's capabilities is created and linked with the IoT Edge device. Finally, the manifest is applied to start deployment.

Step 1: Create an OPC/UA Module Manifest

The manifest is a JSON document that describes which modules to deploy to your IoT Edge device and how to configure them.

Below is a sample manifest that deploys an OPC/UA module:

{
"modulesContent": {
"$edgeAgent": {
"properties.desired": {
"modules": {
"OpcPublisher": {
"settings": {
"image": "mcr.microsoft.com/iotedge/opc-publisher:2.8.3",
"createOptions": "{\"HostName\":\"OpcPublisher\",\"Cmd\":[\"OpcPublisher\",\"--autoaccept\",\"--trustowncert\",\"--publishfile=/iot/pn.json\",\"--diagnosticsinterval=30\",\"--iothubsendinterval=1\"],\"HostConfig\":{\"Binds\":[\"/iot:/iot\"],\"LogConfig\":{\"Config\":{\"max-size\":\"5m\",\"max-file\":\"20\"},\"Type\":\"json-file\"}}}"
},
"type": "docker",
"status": "running",
"restartPolicy": "always",
"version": "1.0"
},
// Additional modules go here
},
// Additional configuration goes here
}
},
// Additional module configurations go here
}
}
  • "image": "mcr.microsoft.com/iotedge/opc-publisher:2.8.3": This specifies the Docker image to use for the module. In this case, it's version 2.8.3 of the OPC Publisher module from Microsoft's container registry.

  • "createOptions": This field contains a JSON string that specifies additional options for creating the Docker container. It includes several sub-fields:

    • "HostName":"OpcPublisher": This sets the hostname of the Docker container to "OpcPublisher".

    • "Cmd":["OpcPublisher","--autoaccept","--trustowncert","--publishfile=/iot/pn.json","--diagnosticsinterval=30","--iothubsendinterval=1"]: This is the command that will be run when the Docker container starts. It starts the OPC Publisher and includes several command-line arguments:

      • "--autoaccept": This option makes the OPC Publisher automatically accept all server certificates.
      • "--trustowncert": This option makes the OPC Publisher trust its own certificate.
      • "--publishfile=/iot/pn.json": This specifies the path to the publish nodes file, which contains the list of OPC UA nodes to publish.
      • "--diagnosticsinterval=30": This sets the interval in seconds at which diagnostic information should be sent.
      • "--iothubsendinterval=1": This sets the interval in seconds at which data should be sent to the IoT Hub.
    • "HostConfig": This field contains additional configuration for the Docker host:

      • "Binds":["/iot:/iot"]: This binds the "/iot" directory on the host to the "/iot" directory in the Docker container.
      • "LogConfig": This field contains configuration for the Docker logs:
        • "Config":{"max-size":"5m","max-file":"20"}: This sets the maximum size of the log file to 5 megabytes and the maximum number of log files to 20.
        • "Type":"json-file": This sets the format of the log files to JSON.
  • "type": "docker": This specifies that the module is a Docker module.

  • "status": "running": This sets the desired status of the module to "running", meaning that it should be started as soon as it's deployed.

  • "restartPolicy": "always": This sets the restart policy for the module to "always", meaning that it should be restarted whenever it stops, regardless of the reason for stopping.

Step 2: Upload the Manifest to Azure IoT Central

Now, you can upload this manifest to Azure IoT Central:

  1. In your Azure IoT Central application, go to Device Templates, and select the appropriate template for your IoT Edge device.
  2. Go to Edge Manifests.
  3. Click + New to add a new manifest.
  4. Enter a name for the manifest, and paste the manifest JSON in the Manifest field.
  5. Click Create.

Step 3: Deploy the OPC/UA Module

Finally, you can deploy your OPC/UA module to your IoT Edge device:

  1. In your Azure IoT Central application, go to Devices, and select your IoT Edge device.
  2. Go to Configuration.
  3. In the Configuration Manifests section, select the manifest you created in the previous step.
  4. Click Save.
info

An Azure IoT Edge device can host multiple modules, each serving a distinct function or process. It's important to understand that we don't deploy these modules individually; rather, we deploy a complete manifest. This manifest is a comprehensive description of all the modules to be installed, their configurations, and the inter-module communication routes. When the manifest is deployed, all of the outlined modules are deployed and configured together on the IoT Edge device.

Your IoT Edge device will now start deploying the OPC/UA module according to the manifest. This might take a few minutes. After the deployment is complete, the OPC/UA module will start running on your IoT Edge device, and you can start interacting with it through Azure IoT Central.

Step 4: Create OPC UA module configuration

  1. Create a JSON file that will contain all the necessary configuration information required by the OPC UA module. For example, you can create a file named configuration.json.

  2. Populate the configuration file with the basic settings, including the OPC UA server endpoint URL, whether to use security, and the OPC UA nodes to be published.

  {
"EndpointUrl": "opc.tcp://testserver:62541/Quickstarts/ReferenceServer",
"UseSecurity": true,
"OpcNodes": [
{
"Id": "i=2258",
"OpcSamplingInterval": 2000,
"OpcPublishingInterval": 5000,
"DisplayName": "Current time"
}
]
}
note

Please note that an individual object {} should be used for the final configuration file, not an array [].

  1. If required, add additional paramaters to the configuration file. These parameters can relate to data set writing, messaging mode, batching, and details of the OPC nodes. A typical configuration schema with both the file-based and API-based configuration could look like this:
{
"EndpointUrl": "string",
"UseSecurity": "bool",
"EndpointSecurityMode": "string",
"EndpointSecurityPolicy": "string",
"OpcAuthenticationMode": "string",
"OpcAuthenticationUsername": "string",
"OpcAuthenticationPassword": "string",
"UseReverseConnect": "bool",
"DataSetWriterId": "string",
"DataSetClassId": "guid",
"DataSetName": "string",
"DataSetDescription": "string",
"DataSetPublishingInterval": "integer",
"DataSetPublishingIntervalTimespan": "string",
"DataSetKeyFrameCount": "integer",
"DataSetExtensionFields": "object",
"MetaDataUpdateTime": "integer",
"MetaDataUpdateTimeTimespan": "string",
"SendKeepAliveDataSetMessages": "boolean",
"DataSetWriterGroup": "string",
"MessageEncoding": "string",
"MessagingMode": "string",
"WriterGroupTransport": "string",
"BatchSize": "integer",
"BatchTriggerInterval": "integer",
"BatchTriggerIntervalTimespan": "string",
"OpcNodes":
[
{
"Id": "string",
"ExpandedNodeId": "string",
"AttributeId": "string",
"IndexRange": "string",
"UseCyclicRead": "boolean",
"RegisterNode": "boolean",
"FetchDisplayName": "boolean",
"OpcSamplingInterval": "integer",
"OpcSamplingIntervalTimespan": "string",
"OpcPublishingInterval": "integer",
"OpcPublishingIntervalTimespan": "string",
"DataSetFieldId ": "string",
"DataSetClassFieldId ": "Guid",
"DisplayName": "string",
"SkipFirst": "boolean",
"DiscardNew": "boolean",
"HeartbeatInterval": "integer",
"HeartbeatIntervalTimespan": "string",
"QueueSize": "integer",
"DataChangeTrigger": "string",
"DeadbandType": "string",
"DeadbandValue": "decimal",
"EventFilter": {
(*)
}
}
],
"Version": "integer",
"LastChangeTimespan": "string",
}

Published Nodes Entry Models have the following attributes:

AttributeMandatoryTypeDefaultDescription
VersionNoIntegernullA monotonically increasing number identifying the change version. NOTE: At this point the version number is informational only, but should be provided in API requests if available. It is not used inside file based configuration.
LastChangeTimespanNoStringnullThe time the Publisher configuration was last updated. Read only and informational only.
EndpointUrlYesStringN/AThe OPC UA server endpoint URL
UseReverseConnectNoBooleanfalseControls whether to use OPC UA reverse connect to connect to the OPC UA server. A publisher wide default value can be set using the command line.
UseSecurityNoBooleanfalseControls whether to use a secure OPC UA mode to establish a session to the OPC UA server endpoint. true corresponds to EndpointSecurityMode = SignAndEncrypt, false to EndpointSecurityMode = None
EndpointSecurityModeNoEnumnullEnum to specify a requested security mode of the chosen session endpoint. Overrides UseSecurity value.Options: Sign, SignAndEncrypt, None, and Best (security mode possible which might include None)
EndpointSecurityPolicyNoStringnullString to specify a security policy the chosen endpoint must meet. Refines the endpoint chosen through EndpointSecurityMode and overrides UseSecurity value.
OpcAuthenticationModeNoEnumAnonymousEnum to specify the session authentication. Options: Anonymous, UsernamePassword
OpcAuthenticationUsernameNoStringnullThe username for the session authentication if OpcAuthentication mode is UsernamePassword.
OpcAuthenticationPasswordNoStringnullThe password for the session authentication if OpcAuthentication mode is UsernamePassword.
DataSetWriterGroupNoString"<<UnknownWriterGroup>>"The data set writer group collecting datasets defined for a certain endpoint uniquely identified by the above attributes. This attribute is used to identify the session opened into the server. The default value consists of the EndpointUrl string, followed by a deterministic hash composed of the EndpointUrl, UseSecurity, OpcAuthenticationMode, UserName and Password attributes.
DataSetWriterIdNoString"<<UnknownDataSet>>"The unique identifier for a data set writer used to collect OPC UA nodes to be semantically grouped and published with the same publishing interval. When not specified a string representing the common publishing interval of the nodes in the data set collection. This attribute uniquely identifies a data set within a DataSetWriterGroup. The uniqueness is determined using the provided DataSetWriterId and the publishing interval of the grouped OpcNodes. An individual subscription is created for each DataSetWriterId.
DataSetNameNoStringnullThe optional name of the data set as it will appear in the dataset metadata.
DataSetDescriptionNoStringnullThe optional description for the data set as it will appear in the dataset metadata.
DataSetClassIdNoGuidGuid.EmptyThe optional dataset class id as it shall appear in dataset messages and dataset metadata.
DataSetExtensionFieldsNoObjectnullAn optional JSON object with key value pairs where the value is a Variant in JSON encoding. This can be used to contextualize data set messages produced by the writer. Each item is added to key frame and meta data messages in the same data set, or in the extension section of samples messages (in samples messages the value is stringified).
DataSetPublishingIntervalNoIntegernullThe publishing interval used for a grouped set of nodes under a certain DataSetWriter. Value expressed in milliseconds. Ignored when DataSetPublishingIntervalTimespan is present. Note: When a specific node underneath DataSetWriter defines OpcPublishingInterval (or Timespan), its value will overwrite publishing interval for the specified node.
DataSetPublishingIntervalTimespanNoStringnullThe publishing interval used for a grouped set of nodes under a certain DataSetWriter.>Value expressed as a Timespan string ({d.hh:mm:dd.fff}). When both Intervals are specified, the Timespan will win and be used for the configuration. Note: When a specific node underneath DataSetWriter defines OpcPublishingInterval (or Timespan), its value will overwrite publishing interval for the specified node.
DataSetKeyFrameCountNoIntegernullThe optional number of messages until a key frame is inserted. Only valid if messaging mode supports key frames
MetaDataUpdateTimeNoIntegernullThe optional interval at which meta data messages should be sent even if the meta data has not chnaged. Only valid if messaging mode supports metadata or metadata is explicitly enabled.
MetaDataUpdateTimeTimespanNoStringnullSame as MetaDataUpdateTime but expressed as duration string. Takes precedence over the Integer value.
SendKeepAliveDataSetMessagesNoBooleanfalseWhether to send keep alive data set messages for this data set when a subscription keep alive notification is received. Only valid if messaging mode supports keep alive messages.
MessageEncodingNoStringnullThe message encoding to use when publishing the data sets.
MessagingModeNoStringnullThe messaging mode to use when publishing the data sets.
WriterGroupTransportNoStringnullThe transport technology to use when publishing messages.
BatchSizeNoIntegernullThe optional number of notifications that are queued before a network message is generated. For historic reasons the default value is 50 unless otherwise configured via --bs command line option.
BatchTriggerIntervalNoIntegernullThe network message publishing interval. Network and meta data messages are published cyclically from the notification queue when the specified duration has passed (or when the batch size configuration triggered a network message). For historic reasons the default value is 10 seconds unless otherwise configured via the --bi command line option.
BatchTriggerIntervalTimespanNoStringnullSame as BatchTriggerInterval but expressed as duration string. Takes precedence over the Integer value.
OpcNodesNoList<OpcNode>emptyThe DataSet collection grouping the nodes to be published for the specific DataSetWriter defined above.

Note: OpcNodes field is mandatory for PublishNodes_V1. It is optional for UnpublishNodes_V1 and AddOrUpdateEndpoints_V1. And OpcNodes field shouldn't be specified for the rest of the direct methods.

Each OpcNode has the following attributes:

AttributeMandatoryTypeDefaultDescription
IdYes*StringN/AThe OPC UA NodeId in the OPC UA server whose data value changes should be published. Can be specified as NodeId or ExpandedNodeId as per OPC UA specification, or as ExpandedNodeId IIoT format {NamespaceUi}#{NodeIdentifier}. Note*: Id field may be omitted when ExpandedNodeId is present.
ExpandedNodeIdNoStringnullEnables backwards compatibility. Must be specified as ExpandedNodeId as per OPC UA specification. Note*: when ExpandedNodeId is present Id field may be omitted.
AttributeIdNoStringValueThe node attribute to sample in case the node is a variable value (data item). The allowed values are defined in the OPC UA specification. Ignored when subscribing to events.
IndexRangeNoStringnullThe index range of the value to publish. Value expressed as a numeric range as defined in the OPC UA specification. Ignored when subscribing to events.
OpcSamplingIntervalNoInteger1000The sampling interval for the monitored item to be published. Value expressed in milliseconds. The value is used as defined in the OPC UA specification. Ignored when OpcSamplingIntervalTimespan is present.
OpcSamplingIntervalTimespanNoStringnullThe sampling interval for the monitored item to be published. Value expressed in Timespan string({d.hh:mm:dd.fff}). The value is used as defined in the OPC UA specification.
OpcPublishingIntervalNoIntegernullThe publishing interval for the monitored item to be published. Value expressed in milliseconds. This value will overwrite the publishing interval defined in the DataSetWriter for the specified node. The value is used as defined in the OPC UA specification. Ignored when OpcPublishingIntervalTimespan is present.
OpcPublishingIntervalTimespanNoStringnullThe publishing interval for the monitored item to be published. Value expressed in Timespan string({d.hh:mm:dd.fff}). This value will overwrite the publishing interval defined in the DataSetWriter for the specified node. The value is used as defined in the OPC UA specification.
DataSetFieldIdNoStringnullA user defined tag used to identify the field in the DataSet telemetry message when publisher runs in PubSub message mode.
DataSetClassFieldIdNoGuidGuid.EmptyA user defined Guid that identifies the field in the data set class of the DataSet telemetry message when publisher runs in PubSub message mode. This value is ignored when subscribing to events, in which case a DataSetClassFieldId can be applied to each select clause that select the content of the event dataset.
DisplayNameNoStringnullA user defined tag to be added to the telemetry message when publisher runs in Samples message mode.
HeartbeatIntervalNoInteger0The interval used for the node to publish a value (a publisher cached one) even if the value hasn't been changed at the source. Value expressed in seconds. 0 means the heartbeat mechanism is disabled. This value is ignored when HeartbeatIntervalTimespan is present.
HeartbeatIntervalTimespanNoStringnullThe interval used for the node to publish a value (a publisher cached one) even if the value hasn't been changed at the source. Value expressed in Timespan string({d.hh:mm:dd.fff}).
SkipFirstNoBooleanfalseWhether the first received data change for the monitored item should not be sent. This can avoid large initial messages since all values are sent by a server as the first notification. If an EventFilter is specified, this value is ignored
QueueSizeNoInteger1The desired QueueSize for the monitored item to be published.
FetchDisplayNameNoBooleanfalseWhether the server shall fetch display names of monitored variable nodes and use those inside messages as field names. Default is to use the DisplayName value if provided even if this option is set to true, if not provided or false, and no DisplayName specified, the node id is used.
DiscardNewNoBooleanfalseWhether the server shall discard new values when the queue is full. Default is false, it will discard values that have not been sent yet.
UseCyclicReadNoBooleanfalseRead the value periodically at the sampling rate insteead of subscribing through subscriptions. Ignored when subscribing to events.
RegisterNodeNoBooleanfalseRegister the node to sample using the Register service call before accessing. Some servers then support faster reads, but this is not guaranteed. The service is defined in the OPC UA specification. Ignored when subscribing to events.
DataChangeTriggerNoStringnullThe data change trigger to use. The default is "StatusValue" causing telemetry to be sent when value or statusCode of the DataValue change. "Status" causes messages to be sent only when the status code changes and "StatusValueTimestamp" causes a message to be sent when value, statusCode, or the source timestamp of the value change. A publisher wide default value can be set using the command line. This value is ignored if an EventFilter is configured.
DeadbandTypeNoString1The type of deadband filter to apply. "Percent" means that the DeadbandValue specified is a percentage of the EURange of the value. The value then is clamped to a value between 0.0 and 100.0 "Absolute" means the value is an absolute deadband range. Negative values are interpreted as 0.0. This value is ignored if an EventFilter is present.
DeadbandValueNoDecimal1The deadband value to use. If the DeadbandType is not specified or an EventFilter is specified, this value is ignored.
EventFilterNoEventFilternullAn event filter configuration to use when subscribing to events instead of data changes.

Step 5: Add the configuration to Facts

  1. Log in to Inimco.facts. You will be taken to the Manage Devices screen.
  2. Navigate to Devices.
  3. Select a device that you need to add the configuration to.
  4. Navigate to the Modules tab.
  5. Click the ellipsis (...) next to the module that you need to add the configuration to.
  6. Select Edit configuration.
  7. Add the configuration file to the Configuration OpcPublisher.
note

Please note that an individual object {} should be used for the final configuration file, not an array [].

  1. Click Save.
  2. Click the ellipsis (...) next to the module you added the configuration to.
  3. Select Publish configuration.

Please note that the exact steps and the specifics of the manifest might differ based on your particular use case and the specifics of your OPC/UA module.