For large-scale deployments, automating the configuration and management of OPC Publisher is critical. OPC Publisher version 2.8.2 and later implements IoT Hub Direct Methods, which can be called from an application using the IoT Hub Device SDK.
Azure IoT Hub's Cloud-to-Device (C2D) commands allow you to remotely configure and control OPC Publisher instances running on IoT Edge devices. For example, you can send commands to update the configuration, restart the module, or change runtime parameters without needing to manually intervene on each device. An example of sending a C2D command to update the configuration:
az iot hub invoke-module-method --hub-name <your-iot-hub> --device-id <your-device-id> --module-name <opc-publisher> --method-name SetConfiguredEndpoints --method-payload '{"Endpoints": [{"EndpointUrl": "opc.tcp://new-opc-server:4840", "OpcNodes": [{"Id": "ns=2;i=10853"}]}]}'
The following direct methods and many more can be used to remotely configure the OPC Publisher:
- Shutdown_V2
- GetServerCertificate_V2
- GetApiKey_V2
- PublishNodes_V1
- AddOrUpdateEndpoints_V1
- UnpublishNodes_V1
- UnpublishAllNodes_V1
- GetConfiguredEndpoints_V1
- SetConfiguredEndpoints_V1
- GetConfiguredNodesOnEndpoint_V1
- GetDiagnosticInfo_V1
The corresponding REST API of OPC Publisher 2.9 (with same operation names and type definitions) is documented here. In addition to calling the API through HTTP REST calls (Preview) you can call the configuration API through MQTT v5 (Preview) in OPC Publisher 2.9.
If you need to migrate your application from OPC Publisher 2.5.x to OPC Publisher 2.8.2 or later, we provide the needed information in a separate document.
It is important to understand the configuration schema as it is the foundation of the OPC Publisher configuration surface and represented by the PublishedNodesEntryModel.
Now let's dive into each direct method request and response payloads with examples.
This API call allows you to shutdown the publisher. By passing a true
, the publisher is immediately terminates the process with an error and reports an error message. When passing false
, the exits the process without a 0 exit code.
Request: true
or false
or nothing.
Response: Potentially nothing if the publisher is immediately shutdown
Example:
Method Name:
Shutdown_V2
Request:
true
Response:
n/a
This API can be called to retrieve the HTTP certificate that secures the REST endpoint. A caller should call this API and then validate the server certificate presented against this certificate. The certificate can be cached for the duration of its validity period.
Request: An empty object or null
can be passed since no argument is required.
Response: when successful Status 200 and the certificate in PEM format.
Exceptions: an exception is thrown when method call returns status other than 200
Example:
Method Name:
GetServerCertificate_V2
Request:
null
Response:
"-----BEGIN CERTIFICATE-----\n <base64 encoded certificate" -----END CERTIFICATE-----\n"
The certificate Key can also be read from the IoT Hub device twin as __certificate__
reported property, together with the ip address, hostname, schema, and port (__ip__
, __hostname__
, __scheme__
, and __port__
).
This API call allows a caller to programmatically obtain the current API key. The API key is passed in the Authorization
header of the HTTP request sent to the HTTP endpoint. The format of the header value is ApiKey <api-key>
, e.g., ApiKey 85....<redacted>.....F78
.
Request: follows strictly the request payload schema, the OpcNodes
attribute being mandatory.
Response: when successful Status 200 and an empty json ({}
) as payload
Exceptions: an exception is thrown when method call returns status other than 200
Example:
Method Name:
GetApiKey_V2
Request:
null
Response:
"85....<redacted>.....F78"
The API Key can also be read from the IoT Hub device twin as the __apikey__
reported property.
PublishNodes enables a client to add a set of nodes to be published. A DataSetWriter
groups nodes which results in seperate subscriptions being created (grouped further by the Publishing interval, if different ones are configured, but these have no bearing on the DataSetWriter
identity). A DataSetWriter
s identity is the combination of DataSetWriterId
, DataSetName
, DataSetKeyFrameCount
, DataSetClassId
, and connection relevant information such as credentials, security mode, and endpoint Url. To update a DataSetWriter
this information must match exactly.
When a DataSetWriter
already exists, the nodes are incrementally added to the same dataset
. When it doesn't already exist, a new DataSetWriter
is created with the initial set of nodes contained in the request. When working with DataSetWriterGroup
s it is important to note that all groups not part of the publish request are removed. To incrementally update DataSetWriterGroup
s of DataSetWriter
s use AddOrUpdateEndpoints_v1
API instead.
Request: follows strictly the request payload schema, the OpcNodes
attribute being mandatory.
Response: when successful Status 200 and an empty json ({}
) as payload
Exceptions: an exception is thrown when method call returns status other than 200
Example:
Method Name:
PublishNodes_V1
Request:
{ "EndpointUrl": "opc.tcp://opcplc:50000", "DataSetWriterGroup": "Asset0", "DataSetWriterId": "DataFlow0", "DataSetPublishingInterval": 5000, "OpcNodes": [ { "Id": "nsu=http://microsoft.com/Opc/OpcPlc/;s=FastUInt0" } ] }Response:
{ "status": 200, "payload": {} }
More information can be found in the API documentation
This method allows updating multiple endpoints (DataSetWriter
s) without effecting others. Unlike PublishNodes_V1
method, AddOrUpdateEndpoints_V1
replaces the nodes of an endpoint (DataSetWriter
) with the one provided in the method's request payload. By providing an empty list of nodes in a request, a endpoint (DataSetWriter
) can be removed from a DataSetWriterGroup
. Removing the last from a group removes the group.
Request: represents a list of objects, which should strictly follow the request payload schema as described above. The OpcNodes
attribute being empty list or null
will be interpreted as a removal request for that endpoint (DataSetWriter
).
Response: when successful - Status 200 and an empty json ({}
) as payload
Exceptions: a response corresponding to an exception will be returned if:
-
request payload contains deletion request for an endpoint (
DataSetWriter
) that isn't present in publisher configuration -
request payload contains two or more entries for the same endpoint (
DataSetWriter
)Example:
Method Name:
AddOrUpdateEndpoints_V1
Payload:
[ { "EndpointUrl": "opc.tcp://opcplc:50000", "DataSetWriterGroup": "Asset1", "DataSetWriterId": "DataFlow1", "DataSetPublishingInterval": 5000, "OpcNodes": [ { "Id": "nsu=http://microsoft.com/Opc/OpcPlc/;s=FastUInt0", } ] }, { "EndpointUrl": "opc.tcp://opcplc:50001", "DataSetWriterGroup": "Asset2", "DataSetWriterId": "DataFlow2", "OpcNodes": [] } ]
Response:
{ "status": 200, "payload": {} }
More information can be found in the API documentation
UnpublishNodes method enables a client to remove nodes from a previously configured DataSetWriter
. A DataSetWriter
s identity is the combination of DataSetWriterId
, DataSetName
, DataSetKeyFrameCount
, DataSetClassId
and connection relevant information such as credentials, security mode, and endpoint Url. To update a DataSetWriter
this information must match exactly.
If value of the OpcNodes
attribute is null
or an empty list, then the whole DataSetWriter entity is removed.
Note: If all the nodes from a DataSet are to be unpublished, the DataSetWriter entity is removed from the configuration storage.
Request: follows strictly the request payload schema, the OpcNodes
attribute not being mandatory.
Response: when successful - Status 200 and an empty json ({}
) as Payload
Exceptions: a response corresponding to an exception will be returned if:
-
request payload contains an endpoint (DataSet) that isn't present in publisher configuration
-
request payload contains a node that isn't present in publisher configuration
Example:
Method Name:
UnpublishNodes_V1
Request:
{ "EndpointUrl": "opc.tcp://opcplc:50000", "DataSetWriterGroup": "Asset0", "DataSetWriterId": "DataFlow0", "DataSetPublishingInterval": 5000, "OpcNodes": [ { "Id": "nsu=http://microsoft.com/Opc/OpcPlc/;s=FastUInt0" } ] }
Response:
{ "status": 200, "payload": {} }
More information can be found in the API documentation
UnpublishAllNodes method enables a client to remove all the nodes from a previously configured DataSetWriter. The DataSetWriter entity will be removed from the configuration storage. When an empty payload is set or the endpoint in payload is null, the complete configuration of the publisher will be purged.
Request: follows strictly the request payload schema, the OpcNodes
attribute should be excluded.
Response: when successful - Status 200 and an empty json ({}
) as Payload
Exceptions: a response corresponding to an exception will be returned if:
-
request payload contains an endpoint (DataSet) that isn't present in publisher configuration
-
request payload contains
OpcNodes
Example:
Method Name:
UnpublishAllNodes_V1
Payload:
{ "EndpointUrl": "opc.tcp://opcplc:50000", "DataSetWriterGroup": "Asset1", "DataSetWriterId": "DataFlow1", "DataSetPublishingInterval": 5000 }
Response:
{ "status": 200, "payload": {} }
More information can be found in the API documentation
Returns the configured endpoints (DataSetWriter
s)
Request: empty json ({}
)
Response: the list of configured endpoints (and optional parameters).
Exceptions: an exception is thrown when method call returns status other than 200
Example:
Method Name:
GetConfiguredEndpoints_V1
Response:
{ "status": 200, "payload": { "endpoints": [ { "endpointUrl": "opc.tcp://opcplc:50000", "dataSetWriterGroup": "Asset1", "dataSetWriterId": "DataFlow1", "dataSetPublishingInterval": 5000, }, { "endpointUrl": "opc.tcp://opcplc:50001" } ] } }
More information can be found in the API documentation
Sets the configured endpoints (DataSetWriter
s) and thus allows to update all configuration at once. The configuration on the OPC Publisher is replaced with the request payload content. Use empty array of endpoints to clear the entire content of the published nodes file.
Request: A list of configured endpoints (and optional parameters).
Response: empty json ({}
)
Exceptions: an exception is thrown when method call returns status other than 200
Example:
Method Name:
SetConfiguredEndpoints_V1
Payload:
{ "endpoints": [ { "endpointUrl": "opc.tcp://opcplc:50000", "dataSetWriterGroup": "Asset1", "dataSetWriterId": "DataFlow1", "dataSetPublishingInterval": 5000, }, { "endpointUrl": "opc.tcp://opcplc:50001" } ] }Response:
{ "status": 200, "payload": {} }
More information can be found in the API documentation
Returns the nodes configured for one Endpoint (DataSetWriter
s).
Request: contains the elements defining the Dataset. Please note that the Dataset definition should fully match the one that is present in OPC Publisher configuration.
Response: list of OpcNodes
configured for the selected Endpoint (and optional parameters).
Exceptions: an exception is thrown when method call returns status other than 200
Example:
Method Name:
GetConfiguredNodesOnEndpoints_V1
Payload:
{ "EndpointUrl": "opc.tcp://192.168.100.20:50000", "DataSetWriterGroup": "Asset0", "DataSetWriterId": "DataFlow0", "DataSetPublishingInterval": 5000 }Response:
{ "status": 200, "payload": { "opcNodes": [ { "id": "nsu=http://microsoft.com/Opc/OpcPlc/;s=SlowUInt1", "opcSamplingIntervalTimespan": "00:00:10", "heartbeatIntervalTimespan": "00:00:50" } ] } }
More information can be found in the API documentation
Returns a list of actual metrics for all concrete DataSetWriter
s. This includes virtual DataSetWriter
s created due to different publishing intervals configured. The name of these contain the original name provided and a hash value.
Request: empty json ({}
)
Response: list of actual metrics for every endpoint (Dataset).
Exceptions: an exception is thrown when method call returns status other than 200
Note: passwords aren't being part of the response.
Example:
Method Name:
GetDiagnosticInfo_V1
Response:
{ "status":200, "payload":[ { "endpoint": { "endpointUrl": "opc.tcp://opcplc:50000", "dataSetWriterGroup": "Asset1", "useSecurity": false, "opcAuthenticationMode": "UsernamePassword", "opcAuthenticationUsername": "Usr" }, "sentMessagesPerSec": 2.6, "ingestionDuration": "{00:00:25.5491702}", "ingressDataChanges": 25, "ingressValueChanges": 103, "ingressBatchBlockBufferSize": 0, "encodingBlockInputSize": 0, "encodingBlockOutputSize": 0, "encoderNotificationsProcessed": 83, "encoderNotificationsDropped": 0, "encoderIoTMessagesProcessed": 2, "encoderAvgNotificationsMessage": 41.5, "encoderAvgIoTMessageBodySize": 6128, "encoderAvgIoTChunkUsage": 1.158034, "estimatedIoTChunksPerDay": 13526.858105160689, "outgressBatchBlockBufferSize": 0, "outgressInputBufferCount": 0, "outgressInputBufferDropped": 0, "outgressIoTMessageCount": 0, "connectionRetries": 0, "opcEndpointConnected": true, "monitoredOpcNodesSucceededCount": 5, "monitoredOpcNodesFailedCount": 0, "ingressEventNotifications": 0, "ingressEvents": 0 } ] }
More information can be found in the API documentation