ezvpn-gw-opcua is a service (provided as Docker container image) acting as a server OPC-UA.

OPC-UA Gateway Schema

Using ezvpn-gw-opcua, allows you to:

  • write data to IOhubTM using OPC-UA protocol.

  • read data from IOhubTM using OPC-UA protocol.

  • exchange data between OPC-UA and other containers using the EXCH language.

We support communication with and without password authentication. Authentication using certificates is not supported.

How to use it

ezvpn-gw-opcua is a Docker container image to communicate with OPC-UA protocol.

It listens by default on port 4840 and responds to OPC-UA client requests. To read and write values from the IOhubTM environment, you can use the OPC-UA field container.

You can use it directly in IOhubTM for final production, or on your PC for testing purposes.

Only one environment variable must be provided: OPCUA_CFG.

OPCUA_CFG is a string representing a JSON object, describing the OPC-UA configuration addresses.

Below is a working example representing an oversimplified case with authentication and same address type.

    "port": 4840,
    "authentication": {
        "username": "testusername",
        "password": "testpassword"
    "addresses": [
            "name": "variable1",
            "nodeId": 23,
            "dataType": "Double",
            "readOnly": false,
            "value": 123
            "name": "variable2",
            "dataType": "Int16"
            "name": "variable3",
            "dataType": "String",
            "nodeId": "var3"
            "name": "variable4",
            "dataType": "String",
            "value": "var4 value"
            "name": "variable5",
            "nodeId": 33,
            "dataType": "Boolean",
            "value": true
            "name": "variable6",
            "dataType": "Boolean"

If your IOhubTM hardware is configured in router mode, by default, access to any network port from WAN is denied. Please read the section "Access from WAN" to unlock it.

Mapping configuration (OPCUA_CFG)

The JSON represented by the following objects:

    "port": <OPC-UA server port>,
    "resourcePath": <resource path>,
    "deviceName": <device name>,
    "ns": <namespace>,
    "authentication": { "username": "<username>", "password": "<password>"},
    "namespaceMode": <see below>,
    "directWrite": <see below>,
    "addresses": [],
    "enableDuplicates": <true/false>
  • port: OPC-UA server port. Required
  • resourcePath: (optional) e.g. /UA/MyOPCUAServer. This path will be added to the endpoint resource name (e.g. opc.tcp://localhost:4840/UA/MyOPCUAServer)
  • deviceName: (optional) the device name, defaults to IOhubOPCUA
  • ns: (optional) the namespace number, valid values are 1-255, defaults to 1
  • authentication: (optional) username and password for OPC-UA authentication.
  • enableDuplicates: (optional). If false, addresses with the same name are not allowed. If true, you can define addresses with the same name, as long as their nodeId is different. Defaults to false.


namespaceMode is an convenient extension to the OPC-UA addresses definition. If configured as dynamic, it allows dynamic creation of OPC-UA addresses from an mqtt subscription. Using dynamic mode you have the ability to create on the fly OPC-UA addresses through MQTT messages.

namespaceMode is configured as one of the modes below:

static mode
"namespaceMode": {
    "type": "static"
dynamic mode
"namespaceMode": {
    "type": "dynamic",
    "mqttHost": "<mqtt broker IP address>",
    "mqttPort": "<mqtt broker port>",
    "mqttTopic": "<mqtt broker subscribed topic>",
    "defaultDataType": "<optional opcua default data type>"

If not defined, namespaceMode default to static mode.

When dynamic mode is defined, the container subscribes to mqttTopic on the mqtt broker defined. To define a new address, a JSON paylod, in the format below, must be sent to mqttTopic.

    "name": "<variable name>",
    "dataType": "<variable data type>",
    "readOnly": true/false,
    "value": "<variable initial value>",
    "nodeId": "<variable node id, as string or number>",

Upon receiving such a payload, an address is created on the OPC-UA gateway. Field definition is below:

  • name: mandatory. The variable name. String
  • dataType: mandatory if defaultDataType is not defined. Otherwise optional. It is the data type on the new OPC-UA address. if missing, defaultDataType is used. dataType can also be defined to override defaultDataType. String containing one of the allowed OPC-UA types as defined below (Boolean, Byte, Double, Float, Int16, Int32, Int64, SByte, String, UInt16, UInt32, UInt64).
  • readOnly: optional, defaults to false. If true the new address is not writable. Boolean.
  • value: optional. The initial value assigned during the address creation. If not defined, it is initialized following the same default rules for the statically defined addresses. The value type must be compatible with the dataType.
  • nodeId: optional. The internal OPC-UA node id. If passed as a string, the node id will be set using the string format (e.g. ns=1;s=myNodeId) If passed as an integer, the node id will be set using the integer format (e.g. ns=4;i=23)


If directWrite is defined, gw-opcua accepts writes also through the MQTT protocol.

directWrite is configured as one of the modes below:

"directWrite": {
    "mqttHost": "<mqtt broker IP address>",
    "mqttPort": "<mqtt broker port>",
    "mqttTopic": "<mqtt broker subscribed topic>",
    "autoCreateDataType": "<optional opcua default data type>"


"directWrite": {
    "mqttHost": "ezvpn-mqtt",
    "mqttTopic": "opcua-gw-write/#",
    "autoCreateDataType": "String"
How it works
  1. gw-opcua subscribes to mqttTopic (e.g. opcua-gw-write/#), for incoming value updates.
  2. When a message is received on the topic mqttTopic, the address name is extracted from the topic as the last part of the topic name following the last /, e.g. if a value is received on opcua-gw-write/some/topic/somewhere/newVar while subscribing to opcua-gw-write/#, newVar is considered the OPC-UA address name.
  3. If at least one address having name newVar is defined, each address value is updated using the incoming MQTT payload value
  4. If no address having name newVar exists and autoCreateDataType is not defined, the message is silently dropped
  5. If no address having name newVar exists and autoCreateDataType is set, a new OPC-UA address with name newVar is created, with initial value set to the incoming value, and data type set to the value of autoCreateDataType.


addresses is an array of objects representing the available OPC-UA variables. The addresses array cannot be empty.

The variables are exposed under

+ RootFolder
    + Objects
        + <deviceName>
            + Variable1
            + Variable2
            + AnotherVariable

Each address is represented by the following object:

    "name": "<symbolic address name>",
    "nodeId": <nodeId> | "<nodeId>",
    "datatype": "<data type>",
    "readOnly": <true/false>,
    "value": <initial value>
  • name: measurement name Required
  • nodeId: (optional) OPC-UA NodeID address. If not specified it will be assigned automatically. It can be a number or a string.

If defined as an integer, the generated Node ID is ns=<namespace>;i=<nodeId>.

If defined as a string, the generated Node ID is ns=<namespace>;s=<nodeId>.

If not defined, it is auto-generated as integer, starting from 1000.

  • datatype: accepted values are Boolean, Byte, Double, Float, Int16, Int32, Int64, SByte, String, UInt16, UInt32, UInt64 Required
  • readOnly: if true the value is read only. Defaults to false.
  • value: (optional) the preset value when the container start.

NodeID Discovery

To test the ezvpn-gw-opcua, we suggest using the following software to test and read the NodeID.

OPC-UA Commander

UA Expert

Environment variables

When you start the ezvpn-gw-opcua image, you can adjust the instance's configuration by passing one or more environment variables to the docker run command.

  • OPCUA_CFG: OPC-UA mapping description, as documented above. Required.

Docker container details

Image: us-central1-docker.pkg.dev/ez-shared/iohub/iohub-gw-opcua

Supported architecture: amd64


  • enableDuplicates added
  • namespaceMode added
  • directWrite added
  • Fix bad server certificate
  • Fix for ns != 1
  • Openssl Fix
  • First release