OPC UA

Open Platform Communications - Unified Architecture, or OPC UA for short, describes a machine-to-machine (M2M) communication protocol developed by the OPC Foundation. It is widely used for communication with industrial equipment and systems for data collection and control.

This page describes how the Connectware can act as an OPC UA client. The Connectware can also act as a OPC UA server.

Subscription Strategies

OPC UA distinguishes between subscriptions and monitors. A subscription carries parameters like publishInterval and maxNotificationsPerPublish so that it controls the data flow between server and client. Multiple monitors can be added to each subscription, with parameters like nodeId, attributeId, samplingInterval, so monitors control the gathering of the data by the server.

The Connectware tries to abstract this complexity away and automatically combines monitors to as few subscriptions as possible. Important: As of today, subscriptions are combined only by the publishInterval parameter. Other subscription parameters such as maxNotificationsPerPublish will be taken only from the first mapping, and subsequently ignored.

Security Settings

For production use, the connection to the OPC UA server should only be established using the security profile SignAndEncrypt. Any other security profile bears the risk that the communication between client and server can easily get manipulated or compromised. Per default, the built-in OPC UA server only allows connections with SignAndEncrypt security setting enabled (in the property securityModes). Please use your Connectware credentials when authenticating to the OPC UA server by Connectware username and password user token.

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
resources:
  spindleSpeed:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      subscribe:
        nodeId: "ns=1;s=spindleSpeed"
        publishInterval: 1000
        samplingInterval: 100
        maxNotificationsPerPublish: 100
  powerConsumption:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      subscribe:
        nodeId: "ns=1;s=powerConsumption"
        publishInterval: 1000
        maxNotificationsPerPublish: 50
        samplingInterval: 1000
  temperature:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      subscribe:
        nodeId: "ns=1;s=temperature"
        publishInterval: 15000
        samplingInterval: 15000

In the above example, two subscriptions will be created, one with publishInterval set to 1000ms and maxNotificationsPerPublish set to 100, the other one with publishInterval set to 15.000ms. The sampling of the individual source values will be set as expected, but remember that OPC UA does not offer a fixed data sampling but rather applies a change-of-value filter to each particular data point automatically.

Connection Properties

host (string, required)

Hostname or IP of the OPC UA device

port (integer, required)

Port of the OPC UA device

Default: 4840

resourcePath (string)

Path of the OPC UA server

Default: ""

username (string)

Username for OPC UA server

password (string)

Password for OPC UA server

timeout (integer)

Timeout, in milliseconds

Default: 1000

certificateFile (string)

Absolute path to the client certificate file

privateKeyFile (string)

Absolute path to the client private key file

checkHostReachable (boolean)

Checks if a low level TCP connection can be made to the configured host and port

Default: false

maxMonitoredItemsPerCall (integer)

If non-zero, multiple monitoredItems (i.e. multiple endpoints) will be registered in groups of maximum size of this given number. This is a server configuration property that can be queried on the server at nodeId: ns=0;i=11714. If this value is zero, no maximum value is assumed and all endpoints will be registered in one call.

Default: 0

options (object)

Properties of the options object:

defaultSecureTokenLifetime (integer)

Lifetime of the secure token. Specified in milliseconds.

Default: 3600000

requestedSessionTimeout (integer)

OPC UA sessions may survive TCP connection breaks and are only deleted if no message from a client is received within the timeout period. Specified in milliseconds.

Default: 3600000

endpointMustExist (boolean)

Specifies if the connection is strictly meant for the given endpoint. If false and the endpoint doesn’t exist, a reasonable default endpoint is automatically chosen.

Default: false

messageSecurityMode (string, enum)

This element must be one of the following enum values:

  • None

  • Sign

  • SignAndEncrypt

Default: "None"

securityPolicy (string, enum)

This element must be one of the following enum values:

  • Aes128_Sha256_RsaOaep

  • Basic128

  • Basic128Rsa15

  • Basic192

  • Basic192Rsa15

  • Basic256

  • Basic256Rsa15

  • Basic256Sha256

  • None

  • PubSub_Aes128_CTR

  • PubSub_Aes256_CTR

Default: "None"

watchInterval (integer)

For observing connection breaks, a connection watchdog runs regularly. Short intervals guarantee short notice on break but lead to higher load. Specified in milliseconds

Default: 30000

connectionStrategy (object)

If a connection attempt fails, retries will be performed with increasing delay (waiting time) in between. The following parameters control how these delays behave.

Properties of the connectionStrategy object:

maxRetry (integer)

Maximum number of connection retries in case of failure.

Default: 1000000000

initialDelay (integer)

Delay (waiting time) of the first connection retry (in milliseconds). For subsequent retries, the delay will be increased by a factor of 2, and also by a potential random increase according to the parameter randomisationFactor.

Default: 1000

maxDelay (integer)

Maximum delay (waiting time) to wait until the next retry (in milliseconds). The delay (waiting time) for any subsequent connection retry will not be larger than this value. Must be strictly greater than initialDelay.

Default: 30000

randomisationFactor (number)

This parameter controls added randomisation to the retry attempts. Must be a number between 0 and 1. If set to 0, retries will be performed with exponentially growing delay until maxDelay. If set to 1, a maximum noise will be added to the retry delays.

Default: 0

Additional restrictions:

  • Maximum: 1

Endpoint Properties

nodeId (string)

String of the exact location of the endpoint. Either nodeId or browsePath are required. A nodeId value is encoded as an xs:string with the syntax ns=<namespaceIndex>;<type>=<value>. The fields have the following meaning: <namespaceIndex> is an integer number such as 0 or 10, denoting the namespace. <type> is a flag that specifies the identifier type and can be: i for numeric (integer), s for string, g for guid, or b for opaque (byte string). <value> is the identifier itself, encoded as a string and in the format according to the identifierType. Examples of nodeIds: i=13 , ns=10;i=-1 , ns=10;s=Hello:World . See also https://reference.opcfoundation.org/v104/Core/docs/Part6/5.3.1 section 5.3.1.10

browsePath (string)

String containing the relative path to the endpoint. Either nodeId or browsePath are required.

browsePathPrefix (string)

Optional, can be used to set a prefix for the browsePath. Both strings will be concatenated using a forward slash /.

publishInterval (integer)

Optional, sets the interval in which values are sent to their appropriate publish methods.

Default: 1000

samplingInterval (integer)

Integer, that sets the interval in which values are read from the server.

Default: 1000

maxNotificationsPerPublish (integer)

Sets the maximum number of monitor notifications that are in a single publish message of the OPC UA subscription. Setting this to a lower value will lead to more network traffic.

Default: 100

priority (integer)

Default: 10

requestedLifetimeCount (integer)

Default: 30

requestedMaxKeepAliveCount (integer)

Default: 10

retryMonitorTimeout (integer)

Default: 300000

Additional restrictions:

  • Minimum: 10000

Example Commissioning Files

Simple example

This is a simple OPC UA connectivity example that only subscribes to the “Server Status” node of an OPC UA server. The proposed node (endpoint) can also be used if the server would otherwise close the connection, which has been observed for some specific versions of OPC UA servers on a S7 PLC.

The example will need some OPC UA server available in your network:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
---
description: >

  Simple OPC UA connectivity example

metadata:

  name: Simple OPC UA connectivity
  version: 1.0.0
  icon: https://www.cybus.io/wp-content/uploads/2019/03/Cybus-logo-Claim-lang.svg
  provider: cybus
  homepage: https://www.cybus.io

parameters:

  opcuaHost:
    type: string
    description: OPC-UA Host
    default: 172.17.0.1

  opcuaPort:
    type: integer
    default: 4840

  opcuaUser:
    type: string
    default: ''

  opcuaPass:
    type: string
    default: ''

resources:

  opcuaConnection:
    type: Cybus::Connection
    properties:
      protocol: Opcua
      connection:
        host: !ref opcuaHost
        port: !ref opcuaPort
        username: !ref opcuaUser
        password: !ref opcuaPass

  serverStatusEndpoint:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      subscribe:
        nodeId: ns=0;i=2259
        samplingInterval: 2000

Download: opcua-simple-example.yml

More complex example

More complex example including an OPC UA server container from public docker hub:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
---
description: >

  Simulated OPC UA server

metadata:

  name: Simulated OPC UA
  version: 1.0.1
  icon: https://www.cybus.io/wp-content/uploads/2019/03/Cybus-logo-Claim-lang.svg
  provider: cybus
  homepage: https://www.cybus.io

parameters:

  opcuaHost:
    type: string
    description: OPC-UA Host
    default: 172.17.0.1

  opcuaPort:
    type: integer
    default: 50000

  opcuaUser:
    type: string
    default: user

  opcuaPass:
    type: string
    default: user

definitions:
  CYBUS_MQTT_ROOT: cybus-factory/opcua

resources:

  machineSimulatorContainer:
    type: Cybus::Container
    properties:
      image: mcr.microsoft.com/iotedge/opc-plc
      ports:
        - !sub '${opcuaPort}:50000/tcp'
      command:
        - --unsecuretransport
        - --autoaccept
        - --defaultuser=user
        - --defaultpassword=user


  opcuaConnection:
    type: Cybus::Connection
    properties:
      protocol: Opcua
      connection:
        host: !ref opcuaHost
        port: !ref opcuaPort
        username: !ref opcuaUser
        password: !ref opcuaPass

  currentTime:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      topic: server/status/currenttime
      subscribe:
        nodeId: i=2258

  dipData:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      topic: dip-data
      subscribe:
        nodeId: ns=2;s=DipData

  alternatingBool:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      topic: alternating-bool
      subscribe:
        nodeId: ns=2;s=AlternatingBoolean

  negativeTrendData:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      topic: negative-trend-data
      subscribe:
        nodeId: ns=2;s=NegativeTrendData

  positiveTrendData:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      topic: positive-trend-data
      subscribe:
        nodeId: ns=2;s=PositiveTrendData

  randomSignedInt:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      topic: random-signed-int32
      subscribe:
        nodeId: ns=2;s=RandomSignedInt32

  randomUnsignedInt:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      topic: random-unsigned-int32
      subscribe:
        nodeId: ns=2;s=RandomUnsignedInt32

  spikeData:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      topic: spike-data
      subscribe:
        nodeId: ns=2;s=SpikeData

  stepUp:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      topic: step-up
      subscribe:
        nodeId: ns=2;s=StepUp

Download: opcua-example.yml

Output Format

If data is read from OPC UA the output will be provided as JSON object with value and timestamp.

The given timestamp is the OPC UA “Source Timestamp” which was set on the data source side, see https://reference.opcfoundation.org/v104/Core/docs/Part4/7.7.3/

{
  "timestamp": "<unix timestamp in ms>",
  "value": "value"
}

Note: If 64-bit integers are being used (which are unsupported in JSON, but are supported in Javascript by the BigInt class), the value is returned as a string that contains the decimal number.

Input Format

If data is written to OPC UA it must be provided as JSON object

{
  "value": "<value>"
}

Reconnection Behaviour

In OPC UA connections – just with any network connections – it can happen that the connection is lost. In that case the Connectware’s OpcuaConnection will automatically switch into reconnecting state and repeatedly try to re-establish the connection. The exact behaviour on how often this is tried can be controlled by the optional connectionStrategy properties, see Connection Properties. The important property is maxDelay which sets the maximum waiting time (delay) between consecutive re-tries, in milliseconds. The waiting time will start with the value initialDelay, then be increased step by step, until the maxDelay value.

Example with initially 500ms waiting time, increasing up to 10 seconds:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
resources:
  myConnection:
    type: Cybus::Connection
    properties:
      protocol: Opcua
      connection:
        host: !ref opcuaHost
        port: !ref opcuaPort
        options:
          connectionStrategy:
            initialDelay: 500
            maxDelay: 10000

For further details see also the documentation of the internally used package backoff, https://www.npmjs.com/package/backoff