A cross-platform OPC UA cloud publisher reference implementation leveraging OPC UA PubSub over MQTT. It runs in a container image on standard Docker hosts or on Kubernetes and comes with an easy-to-use web user interface.
publishednodes.json
file containing all OPC UA variable nodes from a connected serverpublishednodes.json
input file formatx64
and arm64
architectures (Raspberry Pi4, etc.) with pre-built container images ready for useDocker containers are automatically built and published. Simply run the UA Cloud Publisher on a Docker-enabled computer via:
docker run -itd -p 80:80 ghcr.io/barnstee/ua-cloudpublisher:main
And then point your browser to http://yourIPAddress.
Note: We have also provided a test environment to get you started.
UA Cloud Publisher settings and published nodes configuration can be persisted in the Cloud across Docker container restarts by running:
docker run -itd -e STORAGE_TYPE="Azure" -e STORAGE_CONNECTION_STRING="yourCloudStorageConnectionString" -p 80:80 ghcr.io/barnstee/ua-cloudpublisher:main
UA Cloud Publisher settings and published nodes configuration can be persisted locally across Docker container restarts by running:
docker run -itd -v c:/publisher/logs:/app/logs -v c:/publisher/settings:/app/settings -p 80:80 ghcr.io/barnstee/ua-cloudpublisher:main
For Linux hosts, remove the c:
instances from the command above.
And then point your browser to http://yourIPAddress
.
UA Cloud Publisher contains a second broker client that can be used either to send OPC UA PubSub metadata via Kafka to a second broker or it can be used to receive OPC UA PubSub data via MQTT. However, both features together can't be used right now.
LOG_FILE_PATH
- path to the log file to use. Default is /app/logs/UACloudPublisher.log (in the Docker container).STORAGE_TYPE
- type of storage to use for settings and configuration files. Current options are Azure
and OneLake
. Default is local file storage (under /app/settings/
in the Docker container).STORAGE_CONNECTION_STRING
- when using STORAGE_TYPE
=Azure
or OneLake
, specifies the connection string to the cloud storage. For OneLake
, this is called URL
and can be retrieved from your Lakehouse Files
folder properties in Microsoft Fabric.STORAGE_CONTAINER_NAME
- when using STORAGE_TYPE="Azure" or "OneLake", specifies the storage container name. Default is "uacloudpublisher".(All intervals must be specified in milliseconds)
[
{
"EndpointUrl": "string", // e.g. "opc.tcp://opcua.example.com/"
"OpcNodes": [
{
"Id": "string", // Expanded Node Id
"OpcSamplingInterval": 1000,
"OpcPublishingInterval": 1000,
"HeartbeatInterval": 0, // set to a value > 0 if you want to publish static values on regular intervals
"SkipFirst": false
}
],
"OpcEvents": [
{
"ExpandedNodeId": "string", // e.g. "nsu=http://example.com/Instance/;i=56643"
"Filter": [
{
"OfType": "string" // Expanded node ID of event type to filter by e.g. "nsu=http://opcfoundation.org/UA/MachineTool/;i=39"
}
]
}
],
"OpcAuthenticationMode": "Anonymous", // or "UsernamePassword"
"UserName": "string",
"Password": "string"
}
]
Payload: (All intervals must be specified in milliseconds)
{
"Command": "publishnodes",
"CorrelationId": "D892A987-56FB-4724-AF14-5EC6A7EBDD07", // a GUID
"TimeStamp": "2022-11-28T12:01:00.0923534Z", // sender timestamp in UTC
"EndpointUrl": "string",
"OpcNodes": [
{
"Id": "string", // Expanded Node Id
"OpcSamplingInterval": 1000,
"OpcPublishingInterval": 1000,
"HeartbeatInterval": 0,
"SkipFirst": false
}
],
"OpcEvents": [
{
"ExpandedNodeId": "string",
"Filter": [
{
"OfType": "string" // Expanded node ID of event type to filter by
}
]
}
],
"OpcAuthenticationMode": "Anonymous", // or "UsernamePassword"
"UserName": "string",
"Password": "string"
}
Response:
{
[
"string"
]
}
Payload:
{
"Command": "unpublishnodes",
"CorrelationId": "D892A987-56FB-4724-AF14-5EC6A7EBDD07", // a GUID
"TimeStamp": "2022-11-28T12:01:00.0923534Z", // sender timestamp in UTC
"EndpointUrl": "string",
"OpcNodes": [
{
"Id": "string" // Expanded Node Id
}
],
"OpcEvents": [
{
"ExpandedNodeId": "string"
}
]
}
Response:
{
[
"string"
]
}
Payload:
{
"Command": "unpublishallnodes",
"CorrelationId": "D892A987-56FB-4724-AF14-5EC6A7EBDD07", // a GUID
"TimeStamp": "2022-11-28T12:01:00.0923534Z" // sender timestamp in UTC
}
Response:
{
[
"string"
]
}
Payload:
{
"Command": "getpublishednodes",
"CorrelationId": "D892A987-56FB-4724-AF14-5EC6A7EBDD07", // a GUID
"TimeStamp": "2022-11-28T12:01:00.0923534Z" // sender timestamp in UTC
}
Response: (All intervals are in milliseconds)
[
{
"EndpointUrl": "string",
"OpcNodes": [
{
"Id": "string", // Expanded Node Id
"OpcSamplingInterval": 1000,
"OpcPublishingInterval": 1000,
"HeartbeatInterval": 0,
"SkipFirst": false
}
],
"OpcEvents": [
{
"ExpandedNodeId": "string",
"Filter": [
{
"OfType": "string"
}
]
}
],
"OpcAuthenticationMode": "string"
}
]
Payload:
{
"Command": "getinfo",
"CorrelationId": "D892A987-56FB-4724-AF14-5EC6A7EBDD07", // a GUID
"TimeStamp": "2022-11-28T12:01:00.0923534Z" // sender timestamp in UTC
}
Response:
{
"DiagnosticInfos": [
{
"PublisherStartTime": "2022-02-22T22:22:22.222Z",
"ConnectedToBroker": false,
"ConnectedToCloudStorage": false,
"NumberOfOpcSessionsConnected": 0,
"NumberOfOpcSubscriptionsConnected": 0,
"NumberOfOpcMonitoredItemsMonitored": 0,
"MonitoredItemsQueueCount": 0,
"EnqueueCount": 0,
"EnqueueFailureCount": 0,
"NumberOfEvents": 0,
"MissedSendIntervalCount": 0,
"TooLargeCount": 0,
"SentBytes": 0,
"SentMessages": 0,
"SentLastTime": "2022-02-22T22:22:22.222Z",
"FailedMessages": 0,
"AverageMessageLatency": 0,
"AverageNotificationsInBrokerMessage": 0
}
]
}