Overview

This OPC UA RESTful API exposes services in OPC UA Servers as http endpoints. The API is generic and shall work for all OPC UA Servers supporting the services which are exposed. This API consists in fact of two APIs. One API is purely http RESTful, and the other exposes an SignalR hub which enables real-time callbacks to clients. The two APIs are somewhat overlapping in functionality, but only the SignalR API has subcriptions for real-time data values and events.

The format of the data being transported back and forth between server and client is Json. This documentation lists the data types used in the API, and will show how these data types are represented in Json. The same data types are used in SignalR and the RESTful API.

Getting started

The API is a .Net 6 application, and it will run on all platforms supported by .Net 6. The application may be hosted in different enviroments (e.g. IIS for windows). The default host is Kestrel.

Make sure .Net 6 is installed on the computer. Download .Net 6

Hosting

This article describes how to host the application.

Kestrel

The default hosting environment is Kestrel. Simply run the Prediktor.OpcUa.Api.exe to host in Kestrel.

The endpoints used by Kestrel are by default http://localhost:5000 and https://localhost:5001.

This can be changed as shown here.

Licensing

This application is licensed. The licensing system stores the license on disk at an undisclosed location. This means that when running the application it should have write access to disk.

The API exposes endpoints for handling licenses.

GET
​/license
Tests if a valid license is in place

POST
​/license​/activate_online
Activates a license online

GET
​/license​/generate_offline_request
Generates offline activation requests.

POST
​/license​/activate_offline
Activates license offline

The license is activated by retreiving a license key from Prediktor. This key should be distributed with the API. If that is not the case please contact Prediktor to get a license key.

When you have a valid license key, the key can be posted in the /license/activate_online endpoint. It is only necessary to do this once. However, if the application is deleted/updated the license has to be actived again.

In-memory license

If hosted in an environment which does not have write permissions to disk, the appsettings.json must be changed to include the license key.

Add or uncomment the following:

  "License": {  
    "Key": "<enter key here>",  
    "Store": "memory"  
  },  

Authentication

The authentication can be enabled by adding:

"EnableAuthentication": true

to the appsettings.json.

The authentication used is JWT bearer authentication.

OPC UA settings

The API application contains an OPC UA Client, this client has a few settings which can be tweaked. It is, however, not encouraged to change those settings without having a thorough understanding of how the settings affect the application.

The settings are stored in the uaclient.xml file.

OPC UA certificates

The UA communication can be done in a secure or unsecure way. The Connection datatype decides if the connection is secure or not. It is highly encouraged to use a secure connection in a production environment.

If a secure connection is used, the client needs to have a valid certificate. The uaclient.xml file decides where these certificate files are located. If a valid certificate is not present, the application will create one. This certificate will be a self-signed certificate, and thus may not be automatically accepted and trusted by the OPC UA Server.

The default content of the uaclient.xml is:

<ApplicationCertificate>
  <StoreType>Directory</StoreType>
  <StorePath>%ProgramData%/Prediktor/opcuaapi/Config/pki</StorePath>
  <SubjectName>OPC UA API</SubjectName>
</ApplicationCertificate>

Some OPC UA servers have a way of trusting self-signed certificates, please take a look at the documentation for the OPC UA Server in question.

It is also possible to get a hold of a certificate from a trusted certificate issuer. This certificate must have a SubjectName equal to the subject name in the uaclient.xml file. (OPC UA API is the default subject name.)

OPC UA Namespaces

In OPC UA Servers there are one or more namespaces. Nodes belong to a namespace. The namespace is identified by a URL, however, due to the ubiquity of nodes, and the need to send node information back and forth between the server and clients, namespace indices are commonly used. The namespace index refer to the index of the namespace URL in a namespace array. The namespace array is exposed by the OPC UA Server. The namespace array may change during the life time of the OPC UA Server.

This means that a namespace index does not necessarily refer to the same namespace url, for instance after a restart of the OPC UA Server. To alleviate this problem somewhat it is possible for the client to send a namespace array in requests which will be mapped to the actual namespace array on the server.

Example:

A client uses nodes in namespaces called "ns1" and "ns2". In a call to the server the client can send over a namespace table like {"http://opcfoundation.org/UA/", "ns1", "ns2"}. Note that the first element in the namespace table must always be: "http://opcfoundation.org/UA/". All the node ids the client send over in the call will refer to this namespace table regardless of the status of the namespace table on the server. In this case the node id can for instance refer to namespace index 2 meaning "ns2".

OpenAPI

OpenAPI is used to describe the REST API.

Make sure the OPC UA API application is running.

Navigate to https://localhost:5001/index.html in a web browser to see the Swagger UI which can be used to test the REST API.

Read a value with Swagger UI

Open https://localhost:5001/index.html in a web browser, and find the /values/get endpoint.

Expand the node and click Try it out.

Change the entries to something that is available in a an OPC UA server.

Example:

 [  
     {
         "NodeIds":[
             {
                 "IdType":1,
                 "Id":"V|Worker.Signal1",
                 "Namespace":1
             }
         ],
         "ClientNamespaces":[
             "http://opcfoundation.org/UA/",
             "urn:prediktor:UAA-W2019-01:Solar"
         ],
         "Connection":{
             "Url":"opc.tcp://10.100.59.218:4852",
             "AuthenticationType":1
         }
     }
 ]

Click execute.

The respons will contain something like this if everything went OK.

[
  {
    "Values": [
      {
        "Value": {
          "Type": 10,
          "Body": 54
        },
        "SourceTimestamp": "2021-12-16T08:58:18.9825545Z",
        "ServerTimestamp": "2021-12-16T08:58:18.9825545Z"
      }
    ],
    "ServerNamespaces": [
      "http://opcfoundation.org/UA/",
      "http://prediktor.no/apis/ua/",
      "urn:prediktor:UAA-W2019-01:Solar",
      "http://scatecsolar.com/Enterprise",
      "http://scatecsolar.com/JO-GL",
      "http://scatecsolar.com/JO-GM",
      "http://prediktor.no/PVTypes/"
    ],
    "Success": true
  }
]