pyuaf.client
¶
SUMMARY of submodules:
connectionsteps |
|
monitoreditemstates |
|
requests |
|
results |
|
sessionstates |
|
settings |
|
subscriptionstates |
SUMMARY of classes:
See sidebar.
class Client¶
SUMMARY:
- Constructor:
Client
([settings, loggingCallback])Construct a UAF client. - Client settings:
Client.clientSettings
()Get a copy of the current client settings. Client.setClientSettings
(settings)Change the client settings. - Synchronous service calls:
Client.browse
(addresses[, maxAutoBrowseNext])Browse a number of nodes synchronously. Client.browseNext
(addresses, ...)Continue a previous synchronous Browse request, in case you didn’t use the automatic BrowseNext feature of the UAF. Client.call
(objectAddress, methodAddress[, ...])Invoke a remote method call. Client.createMonitoredData
(addresses[, ...])Create one or more monitored data items. Client.createMonitoredEvents
(addresses[, ...])Create one or more monitored event items. Client.historyReadModified
(addresses, ...[, ...])Read the modification information of the historical data from one or more nodes synchronously. Client.historyReadRaw
(addresses, startTime, ...)Read the raw historical data from one or more nodes synchronously. Client.read
(addresses[, attributeId])Read a number of node attributes synchronously. Client.setMonitoringMode
(clientHandles, ...)Set the monitoring mode for the specified monitored items. Client.setPublishingMode
(...[, serviceSettings])Set the publishing mode, by specifying a subscription handle. Client.write
(addresses, data[, attributeId])Write a number of node attributes synchronously. - Asynchronous service calls:
Client.beginCall
(objectAddress, methodAddress)Invoke a remote method call asynchronously. Client.beginRead
(addresses[, attributeId, ...])Read a number of node attributes asynchronously. Client.beginWrite
(addresses, data[, ...])Write a number of node attributes asynchronously. - Callback functions for asynchronous service calls:
Client.callComplete
(result)Override this method to catch the result of asynchronous method call requests. Client.readComplete
(result)Override this method to catch the result of asynchronous read requests. Client.writeComplete
(result)Override this method to catch the result of asynchronous write requests. - Callback functions for sessions, subscriptions and monitored items:
Client.dataChangesReceived
(dataNotifications)Override this method to catch the “data change” notifications of MonitoredItems. Client.eventsReceived
(eventNotifications)Override this method to catch the “event” notifications of MonitoredItems. Client.connectionStatusChanged
(info)Override this method to receive connection status changes. Client.subscriptionStatusChanged
(info)Override this method to receive subscription status changes. Client.keepAliveReceived
(notification)You should override this method if you want to process keep alive messages from the UAF. Client.notificationsMissing
(info, ...)Override this method to handle missing notifications. - Register your own callback functions for sessions, subscriptions and monitored items:
Client.registerConnectionStatusCallback
(callback)Register a callback to receive connection status changes. Client.registerSubscriptionStatusCallback
(...)Register a callback to receive connection status changes. Client.registerKeepAliveCallback
(callback[, ...])Register a callback to handle KeepAlive notifications. Client.registerNotificationsMissingCallback
(...)Register a callback to handle missing notifications. - Information about the current sessions, subscriptions and monitored items:
Client.allSessionInformations
()Get information about all sessions. Client.allSubscriptionInformations
()Get information about all subscriptions. Client.monitoredItemInformation
(clientHandle)Get information about the specified monitored item. Client.sessionInformation
(clientConnectionId)Get information about the specified session. Client.subscriptionInformation
(...)Get information about the specified subscription. - Fully configurable generic service calls:
Client.processRequest
(request[, ...])Process a generic request (as found in pyuaf.client.requests
).- Manually created sessions and subscriptions:
Client.manuallyConnect
(serverUri[, ...])Create a session manually (instead of having the UAF do it behind the scenes). Client.manuallyConnectToEndpoint
(endpointUrl)Manually connect to a specific endpoint, without using the discovery services. Client.manuallyDisconnect
(clientConnectionId)Disconnect the session manually. Client.manuallySubscribe
(clientConnectionId)Create a subscription manually. Client.manuallyUnsubscribe
(...)Delete the subscription manually. - Handle untrusted server certificates:
Client.untrustedServerCertificateReceived
(...)Override this method if you want to handle an untrusted certificate. Client.registerUntrustedServerCertificateCallback
(...)Register a callback function to handle untrusted certificates during the connection process. Client.unregisterUntrustedServerCertificateCallback
()Unregister a callback function to stop handling untrusted certificates. - Catch the logging of the UAF:
Client.logMessageReceived
(message)Override this method if you want to process logging output from the UAF. Client.registerLoggingCallback
(callback)Register a callback function to receive all log messages. Client.unregisterLoggingCallback
()Unregister a callback function to stop receiving all log messages. - Discovery:
Client.serversFound
()Get a list of the application descriptions of the servers found in the discovery process. Client.findServersNow
()Discover the servers immediately (instead of waiting for the background thread) by using the OPC UA FindServers service. Client.serversOnNetworkFound
()Get a list of the server descriptions of the servers found by querying the LDS. Client.findServersOnNetworkNow
()Discover the servers on the network immediately (instead of waiting for the background thread) by using the OPC UA FindServersOnNetwork service. - Override connect errors:
Client.connectErrorReceived
(...)Override this method to handle connect errors by the SDK. Client.registerConnectErrorCallback
(callback)Register a callback function to handle connect errors. Client.unregisterConnectErrorCallback
()Unregister a callback function to stop handling connect errors.
DETAILED DESCRIPTION::
-
class
pyuaf.client.
Client
(settings=None, loggingCallback=None)¶ Construct a UAF client.
Usage example:
# examples/pyuaf/client/how_to_create_a_client.py """ EXAMPLE: how to create a client ==================================================================================================== The Client constructor signature looks like this: pyuaf.client.Client.__init__(settings=None, loggingCallback=None) with: - 'settings': optional: could be - a pyuaf.client.settings.ClientSettings instance - or simply a string (the name of the client) - or None (so default pyuaf.client.settings.ClientSettings() are used). - 'loggingCallback': optional: a callback function to catch log messages of type pyuaf.util.LogMessage. See the PyUAF HTML documentation for more info. """ import time, os import pyuaf from pyuaf.client import Client from pyuaf.client.settings import ClientSettings from pyuaf.util import loglevels, Address, NodeId # we can create some ClientSettings: settings = ClientSettings() settings.applicationName = "MyClient" settings.discoveryUrls.append("opc.tcp://localhost:4841") settings.logToStdOutLevel = loglevels.Info # print Info, Warning and Error logging to the console settings.logToCallbackLevel = loglevels.Debug # send Debug, Info, Warning and Error logging to the callback # And if you want to catch the logging output, you may also define a callback. # In this case we define a callback to write the logging output to a file in the user's home directory. # (but this callback is optional of course, only define one if you want to do something more with the # logging output than simply printing it to the console (i.e. sending it to the stdout)) f = open(os.path.expanduser("~/my_logging_output.txt"), "w") def callback(msg): logDetailsString = "" logDetailsString += time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime(msg.ctime)) logDetailsString += ".%.3d " %msg.msec logDetailsString += "%-10s " %msg.applicationName logDetailsString += "%-20s " %msg.loggerName logDetailsString += "%-8s " %loglevels.toString(msg.level) # msg.message may contain multiple lines, so we prepend the other logging details in # front of each line: for line in msg.message.splitlines(): f.write("%s: %s\n" %(logDetailsString, line)) # Example 0: create a client with the default settings and no logging callback # -------------------------------------------------------------------------------------------------- client0 = Client() # Example 1: create a client by specifying the settings # -------------------------------------------------------------------------------------------------- client1 = Client(settings) # Example 2: create a client by specifying the settings # -------------------------------------------------------------------------------------------------- client2 = Client(settings, callback) # Example 3: create a client by specifying only the logging callback # -------------------------------------------------------------------------------------------------- client3 = Client(loggingCallback=callback) # you can still provide settings and register a logging callback afterwards, but you'll need to use: # client0.setClientSettings(settings) # client0.registerLoggingCallback(callback) # read the Value attribute of some non-existing node in order to have some Error output sent to the callback: client2.read([Address(NodeId("InvalidIdentifier","InvalidNamespace"),"InvalidServerURI")]) f.close()
Parameters: - settings (
pyuaf.client.settings.ClientSettings
orstr
or None) –Can be:
- the settings of the client (of type
pyuaf.client.settings.ClientSettings
) - or simply the name of the client application (as a
str
) - or None for defaults.
- the settings of the client (of type
- callback – A callback function for the logging. This function should have one
input argument, which you should call “msg” or so,
because this argument is of type
pyuaf.util.LogMessage
.
-
allSessionInformations
()¶ Get information about all sessions.
Returns: A list of information objects about all sessions. Return type: list
ofSessionInformation
-
allSubscriptionInformations
()¶ Get information about all subscriptions.
Returns: A list of information objects about all subscriptions. Return type: list
ofSubscriptionInformation
-
beginCall
(objectAddress, methodAddress, inputArgs=[], callback=None, **kwargs)¶ Invoke a remote method call asynchronously.
- Unlike “strict object-oriented” method calling, a method is called by specifying both
- the method itself (parameter methodAddress)
- the object in which context the method should be invoked (parameter objectAddress).
In other words, in OPC UA you can call a method on different objects. In contrast to strict object-oriented languages, where a method can only be called on the object that “owns” the method.
This is a convenience function for calling
processRequest
with aMethodCallRequest
as its first argument. For full flexibility, use that function. For instance, if you want to call multiple methods at once, you can do so by creating aMethodCallRequest
and adding multiple targets.Warning
The callbacks will run in a separate thread, and therefore any exception they raise will not be handled or propagated. So your callbacks should have a try-except clause if you want to be able to properly handle the exceptions that they may raise.
Parameters: - objectAddress (
Address
) – The address of the object node on which to call the method. - methodAddress (
Address
) – The address of the method node to call. - inputArgs (
list
ofUInt32
, orlist
of any other supported data type.) – A list of input arguments. - callback – A callback function to receive the result. This function should have one
argument (which will be of type
MethodCallResult
). - kwargs –
The following **kwargs are available (see A note on **kwargs for Client services):
- clientConnectionId: (type:
int
) - sessionSettings (type:
SessionSettings
) - serviceSettings (type:
MethodCallSettings
) - translateSettings (type:
TranslateBrowsePathsToNodeIdsSettings
)
- clientConnectionId: (type:
Returns: The result of the asynchronous method call request.
Return type: Raises: pyuaf.util.errors.UafError – Base exception, catch this to handle any UAF errors.
-
beginRead
(addresses, attributeId=13, callback=None, **kwargs)¶ Read a number of node attributes asynchronously.
This is a convenience function for calling
processRequest
with aReadRequest
as its first argument. For full flexibility, use that function.- Asynchronous communication can be handled in two ways:
- you specify a callback function (a function with one argument). This function
will be called by the UAF when the asynchronous result is received. The argument of this
function call will be of type
ReadResult
. - you leave the ‘callback’ argument None. In this case, your client application need to
inherit from the
Client
class, so it can override thereadComplete()
method.
- you specify a callback function (a function with one argument). This function
will be called by the UAF when the asynchronous result is received. The argument of this
function call will be of type
Warning
Asynchronous requests MUST be invoked on a single session. Meaning: the targets of asynchronous requests MUST belong to the same server (as the UAF can currently not reconstruct an asynchronous request that must be “split up” to be called on multiple servers). If they don’t belong to the same server, an error will be raised.
Warning
The callbacks will run in a separate thread, and therefore any exception they raise will not be handled or propagated. So your callbacks should have a try-except clause if you want to be able to properly handle the exceptions that they may raise.
Parameters: - addresses (
Address
or alist
ofAddress
) – A single address or a list of addresses of nodes of which the specified attribute should be read. - attributeId (
int
) – The id of the attribute to be read (e.g.pyuaf.util.attributeids.Value
orpyuaf.util.attributeids.DisplayName
). - callback – A callback function to receive the asynchronous result. This function
should have one argument (which will be of type
ReadResult
). - kwargs –
The following **kwargs are available (see A note on **kwargs for Client services):
- clientConnectionId: (type:
int
) - sessionSettings (type:
SessionSettings
) - serviceSettings (type:
ReadSettings
) - translateSettings (type:
TranslateBrowsePathsToNodeIdsSettings
)
- clientConnectionId: (type:
Returns: The “immediate” result of the asynchronous read request.
Return type: Raises: pyuaf.util.errors.UafError – Base exception, catch this to handle any UAF errors.
-
beginWrite
(addresses, data, attributeId=13, callback=None, **kwargs)¶ Write a number of node attributes asynchronously.
This is a convenience function for calling
processRequest
with aAsyncWriteRequest
as its first argument. For full flexibility, use that function.- Asynchronous communication can be handled in two ways:
- you specify a callback function (a function with one argument). This function
will be called by the UAF when the asynchronous result is received. The argument of this
function call will be of type
WriteResult
. - you leave the ‘callback’ argument None. In this case, your client application need to
inherit from the
Client
class, so it can override thewriteComplete()
method.
- you specify a callback function (a function with one argument). This function
will be called by the UAF when the asynchronous result is received. The argument of this
function call will be of type
Warning
Asynchronous requests MUST be invoked on a single session. Meaning: the targets of asynchronous requests MUST belong to the same server (as the UAF can currently not reconstruct an asynchronous request that must be “split up” to be called on multiple servers). If they don’t belong to the same server, an error will be raised.
Warning
The callbacks will run in a separate thread, and therefore any exception they raise will not be handled or propagated. So your callbacks should have a try-except clause if you want to be able to properly handle the exceptions that they may raise.
Parameters: - addresses (
Address
or alist
ofAddress
) – A single address or a list of addresses of nodes of which the specified attribute should be written. - data (
UInt32
orlist
ofUInt32
or any other data type of the supported dynamic data types (or alist
of them).) – A single value or a list of values to be written. - attributeId (
int
) – The id of the attribute to be written (e.g.pyuaf.util.attributeids.Value
orpyuaf.util.attributeids.DisplayName
) for all addresses. - callback – A callback function to receive the asynchronous result. This function
should have one argument (which will be of type
WriteResult
). - kwargs –
The following **kwargs are available (see A note on **kwargs for Client services):
- clientConnectionId: (type:
int
) - sessionSettings (type:
SessionSettings
) - serviceSettings (type:
WriteSettings
) - translateSettings (type:
TranslateBrowsePathsToNodeIdsSettings
)
- clientConnectionId: (type:
Returns: The “immediate” result of the asynchronous write request.
Return type: Raises: pyuaf.util.errors.UafError – Base exception, catch this to handle any UAF errors.
-
browse
(addresses, maxAutoBrowseNext=100, **kwargs)¶ Browse a number of nodes synchronously.
This is a convenience method for calling
processRequest
with aBrowseRequest
as its first argument. A BrowseRequest has many parameters (only few of them can be configured by this convenience method), so for full flexibility use the other method.The second parameter (maxAutoBrowseNext) allows you to use some handy extra functionality of the UAF: the UAF can automatically invoke the BrowseNext service for you, if all browse results couldn’t be fetched by the initial Browse service. This parameter specifies how many times the UAF may silently invoke the BrowseNext service for you. Put it to 0 if you want the “normal SDK behavior”, i.e. if you want to invoke the BrowseNext service manually.
Parameters: - addresses (
Address
or alist
ofAddress
) – A single address or a list of addresses of nodes that serve as the starting point to browse. - maxAutoBrowseNext (
int
) – How many times do you allow the UAF to automatically invoke a BrowseNext for you (if that’s needed to fetch all results)? This parameter will always be used instead of the maxAutoBrowseNext attribute of the serviceSettings! - kwargs –
The following **kwargs are available (see A note on **kwargs for Client services):
- clientConnectionId: (type:
int
) - sessionSettings (type:
SessionSettings
) - serviceSettings (type:
BrowseSettings
) - translateSettings (type:
TranslateBrowsePathsToNodeIdsSettings
)
- clientConnectionId: (type:
Returns: The result of the browse request.
Return type: Raises: pyuaf.util.errors.UafError – Base exception, catch this to handle any UAF errors.
- addresses (
-
browseNext
(addresses, continuationPoints, **kwargs)¶ Continue a previous synchronous Browse request, in case you didn’t use the automatic BrowseNext feature of the UAF.
You only need to use this function if you have put maxAutoBrowseNext to 0 in the previous Browse request (or if the automatic BrowseNext calls still resulted in continuationPoints). For your convenience, it’s much easier to simple use the browse() method, and let the UAF do the BrowseNext calls for you!
This is a convenience method for calling
processRequest
with aBrowseNextRequest
as its first argument. A BrowseNextRequest has many parameters (only few of them can be configured by this convenience method), so for full flexibility use the other method.Parameters: - addresses (
Address
or alist
ofAddress
) – A single address or a list of addresses of nodes that serve as the starting point to browse. You need to copy the addresses here from the original Browse request, so that the UAF can use these addresses to find out to which server the BrowseNext call should be sent. - continuationPoints (
ByteStringVector
or alist
of Pythonbytearray
objects.) – Alist
of continuation points (represented by the built-in Pythonbytearray
objects). - kwargs –
The following **kwargs are available (see A note on **kwargs for Client services):
- clientConnectionId: (type:
int
) - sessionSettings (type:
SessionSettings
) - serviceSettings (type:
BrowseNextSettings
) - translateSettings (type:
TranslateBrowsePathsToNodeIdsSettings
)
- clientConnectionId: (type:
Returns: The result of the BrowseNext request.
Return type: Raises: pyuaf.util.errors.UafError – Base exception, catch this to handle any UAF errors.
- addresses (
-
call
(objectAddress, methodAddress, inputArgs=[], **kwargs)¶ Invoke a remote method call.
- Unlike “strict object-oriented” method calling, a method is called by specifying both
- the method itself (parameter methodAddress)
- the object in which context the method should be invoked (parameter objectAddress).
In other words, in OPC UA you can call a method on different objects. In contrast to strict object-oriented languages, where a method can only be called on the object that “owns” the method.
This is a convenience function for calling
processRequest
with aMethodCallRequest
as its first argument. For full flexibility, use that function. For instance, if you want to call multiple methods at once, you can do so by creating aMethodCallRequest
and adding multiple targets.Parameters: - objectAddress (
Address
) – The address of the object node on which to call the method. - methodAddress (
Address
) – The address of the method node to call. - inputArgs (
list
ofUInt32
, orlist
of any other supported data type.) – A list of input arguments. - kwargs –
The following **kwargs are available (see A note on **kwargs for Client services):
- clientConnectionId: (type:
int
) - sessionSettings (type:
SessionSettings
) - serviceSettings (type:
MethodCallSettings
) - translateSettings (type:
TranslateBrowsePathsToNodeIdsSettings
)
- clientConnectionId: (type:
Returns: The result of the method call request.
Return type: Raises: pyuaf.util.errors.UafError – Base exception, catch this to handle any UAF errors.
-
callComplete
(result)¶ Override this method to catch the result of asynchronous method call requests.
This method will only be called by the UAF if you didn’t provide an “external” callback function already when you began the asynchronous method call request.
In other words, there are two ways how you can catch the result of asynchronous method calls:
- either by calling
processRequest()
without providing an external callback function via the ‘resultCallback’ argument –> then you need to overridecallComplete()
- or by calling
processRequest()
with providing an external callback function via the ‘resultCallback’ argument –> then only the external callback function will be called.
Parameters: result ( MethodCallResult
) – The asynchronously received method call result.- either by calling
-
clientSettings
()¶ Get a copy of the current client settings.
Returns: The currently active settings. Return type: pyuaf.client.settings.ClientSettings
-
connectErrorReceived
(clientConnectionId, connectionStep, sdkStatus, clientSideError)¶ Override this method to handle connect errors by the SDK.
By default, this method returns False, which means that client errors by the SDK will cause a failure of the connection. Return True if the client SDK error should be ignored. If the error was not a client-side SDK error (meaning: if clientSideError is False) then the return value will be ignored.
Parameters: - clientConnectionId (
int
) – The ID of the session that raised the connectError. - connectionStep (
int
) – The failing connection step, as anint
defined bypyuaf.client.connectionsteps
- sdkStatus (
pyuaf.util.SdkStatus
) – The error by the SDK. - clientSideError (
bool
) – True if the error was created inside the SDK.
Returns: True to override the error a client SDK error, False by default.
Return type: bool
- clientConnectionId (
-
connectionStatusChanged
(info)¶ Override this method to receive connection status changes.
Alternatively, you can also register callback functions which you defined yourself, by registering them using
pyuaf.client.Client.registerConnectionStatusCallback()
.Parameters: info ( SessionInformation
) – Updated session information.
-
createMonitoredData
(addresses, notificationCallbacks=[], **kwargs)¶ Create one or more monitored data items.
This is a convenience function for calling
processRequest
with aCreateMonitoredDataRequest
as its first argument. For full flexibility, use that function.Note
Both
CreateMonitoredDataRequest
andCreateMonitoredEventsRequest
are “persistent” requests. It means that even when communication fails (e.g. because the server was not online), a handle is already assigned to each monitored item as soon as you call createMonitoredEvents(). In the background, the UAF will try to (re)establish the connection, and as soon as this is successful, it will create the monitored items for you on the server. From that point on, you may start to receive notifications (that can be identified by the handles that were already assigned and returned to you now). So when createMonitoredData() fails, you need to be aware that in the background the UAF will retry to create them on the server. You can access the handles that will identify their notifications- via the returned
CreateMonitoredDataResult
, in case createMonitoredData() was successful and didn’t raise an exception - via the
CreateMonitoredItemsError
exception that was raised in case processRequest() was not successful. This exception has aassignedClientHandles
attribute, providing the assigned client handles.
Warning
The callbacks will run in a separate thread, and therefore any exception they raise will not be handled or propagated. So your callbacks should have a try-except clause if you want to be able to properly handle the exceptions that they may raise.
Parameters: - addresses (
Address
or alist
ofAddress
) – A single address or a list of addresses, identifying the nodes to be monitored. - notificationCallbacks (
list
of functions) – A list of callback functions (one for each node to be monitored). These callback functions should have a single argument, which will be of typeDataChangeNotification
. If you don’t provide callback functions in this way, you’ll need to overridedataChangesReceived()
in order to receive the notifications. - kwargs –
The following **kwargs are available (see A note on **kwargs for Client services):
- clientConnectionId: (type:
int
) - sessionSettings (type:
SessionSettings
) - clientSubscriptionHandle (type:
int
) - subscriptionSettings (type:
SubscriptionSettings
) - serviceSettings (type:
CreateMonitoredDataSettings
) - translateSettings (type:
TranslateBrowsePathsToNodeIdsSettings
)
- clientConnectionId: (type:
Returns: The result of the CreateMonitoredData request.
Return type: Raises: pyuaf.util.errors.UafError – Base exception, catch this to handle any UAF errors.
- via the returned
-
createMonitoredEvents
(addresses, eventFilter=None, notificationCallbacks=[], **kwargs)¶ Create one or more monitored event items.
This is a convenience function for calling
processRequest
with aCreateMonitoredEventsRequest
as its first argument. For full flexibility, use that function.Note
Both
CreateMonitoredDataRequest
andCreateMonitoredEventsRequest
are “persistent” requests. It means that even when communication fails (e.g. because the server was not online), a handle is already assigned to each monitored item as soon as you call createMonitoredEvents(). In the background, the UAF will try to (re)establish the connection, and as soon as this is successful, it will create the monitored items for you on the server. From that point on, you may start to receive notifications (that can be identified by the handles that were already assigned and returned to you now). So when createMonitoredEvents() fails, you need to be aware that in the background the UAF will retry to create them on the server. You can access the handles that will identify their notifications- via the returned
CreateMonitoredEventsResult
, in case createMonitoredEvents() was successful and didn’t raise an exception - via the
CreateMonitoredItemsError
exception that was raised in case processRequest() was not successful. This exception has aassignedClientHandles
attribute, providing the assigned client handles.
Warning
The callbacks will run in a separate thread, and therefore any exception they raise will not be handled or propagated. So your callbacks should have a try-except clause if you want to be able to properly handle the exceptions that they may raise.
Parameters: - addresses (
Address
or alist
ofAddress
) – A single address or a list of addresses, identifying the nodes to be monitored. - eventFilter (
EventFilter
) – The event filter, common to all nodes that you want to monitor! If you want to specify a different filter for each target, you need to use the genericprocessRequest()
method with aCreateMonitoredEventsRequest
as argument. Leave None for defaults. - notificationCallbacks (
list
of functions) – A list of callback functions (one for each node to be monitored). These callback functions should have a single argument, which will be of typeEventNotification
. If you don’t provide callback functions in this way, you’ll need to overrideeventsReceived()
in order to receive the notifications. - kwargs –
The following **kwargs are available (see A note on **kwargs for Client services):
- clientConnectionId: (type:
int
) - sessionSettings (type:
SessionSettings
) - clientSubscriptionHandle (type:
int
) - subscriptionSettings (type:
SubscriptionSettings
) - serviceSettings (type:
CreateMonitoredEventsSettings
) - translateSettings (type:
TranslateBrowsePathsToNodeIdsSettings
)
- clientConnectionId: (type:
Returns: The result of the CreateMonitoredEvents request.
Return type: Raises: pyuaf.util.errors.UafError – Base exception, catch this to handle any UAF errors.
- via the returned
-
dataChangesReceived
(dataNotifications)¶ Override this method to catch the “data change” notifications of MonitoredItems.
This method will only be called by the UAF if you didn’t provide “external” callback functions already when you created the monitored items.
In other words, there are two ways how you can catch the data change notifications of monitored data items:
- either by calling
processRequest()
orcreateMonitoredData()
without providing external callback functions via the ‘notificationCallbacks’ argument –> then you need to overridedataChangesReceived()
- or by calling
processRequest()
orcreateMonitoredData()
with providing external callback functions via the ‘notificationCallbacks’ argument –> then only the external callback functions will be called.
Parameters: dataNotifications ( list
ofDataChangeNotification
) – The asynchronously received notifications.- either by calling
-
eventsReceived
(eventNotifications)¶ Override this method to catch the “event” notifications of MonitoredItems.
This method will only be called by the UAF if you didn’t provide “external” callback functions already when you created the monitored items.
In other words, there are two ways how you can catch the event notifications of monitored event items:
- either by calling
processRequest()
orcreateMonitoredEvents()
without providing external callback functions via the ‘notificationCallbacks’ argument –> then you need to overrideeventsReceived()
- or by calling
processRequest()
orcreateMonitoredEvents()
with providing external callback functions via the ‘notificationCallbacks’ argument –> then only the external callback functions will be called.
Parameters: eventNotifications ( list
ofEventNotification
) – The asynchronously received notifications.- either by calling
-
findServersNow
()¶ Discover the servers immediately (instead of waiting for the background thread) by using the OPC UA FindServers service.
The URLs to use for discovery are specified by the
discoveryUrls
attribute of theClientSettings
. Since discovery is also handled silently (and periodically) in the background, you normally don’t have to callfindServersNow()
manually.Raises: - pyuaf.util.errors.DiscoveryError – Raised in case the FindServers service failed for one or more URLs.
- pyuaf.util.errors.InvalidRequestError – Raised in case the FindServers service is already being invoked by the client (because no parallel FindServers invocations are allowed!). This can happen for instance when multiple threads (created by the user, or running in the background of the Client instance) try to use the FindServers service at the same time.
- pyuaf.util.errors.UafError – Base exception, catch this to handle any other errors.
-
findServersOnNetworkNow
()¶ Discover the servers on the network immediately (instead of waiting for the background thread) by using the OPC UA FindServersOnNetwork service.
The URL of the discovery server is specified by the
discoveryOnNetworkDiscoveryServer
attribute of theClientSettings
. Since discovery is also handled silently (and periodically) in the background ifdiscoveryOnNetworkEnable
is True, you normally don’t have to callfindServersOnNetworkNow()
manually.Raises: - pyuaf.util.errors.DiscoveryError – Raised in case the FindServers service failed for one or more URLs.
- pyuaf.util.errors.InvalidRequestError – Raised in case the FindServers service is already being invoked by the client (because no parallel FindServers invocations are allowed!). This can happen for instance when multiple threads (created by the user, or running in the background of the Client instance) try to use the FindServers service at the same time.
- pyuaf.util.errors.UafError – Base exception, catch this to handle any other errors.
-
getEndpoints
(discoveryUrl)¶ Get a list of endpoint descriptions supported by the server.
Parameters: discoveryUrl (
str
) – The URL of a Discovery Server (e.g. opc.tcp://mymachine:4840).Returns: A list of the endpoint descriptions that were found.
Return type: list
ofpyuaf.util.EndpointDescription
Raises: - pyuaf.util.errors.DiscoveryError – Raised in case no endpoints could be retrieved.
- pyuaf.util.errors.UafError – Base exception, catch this to handle any other errors.
-
historyReadModified
(addresses, startTime, endTime, numValuesPerNode=0, maxAutoReadMore=0, continuationPoints=[], **kwargs)¶ Read the modification information of the historical data from one or more nodes synchronously.
This is a convenience function for calling
processRequest
with aHistoryReadRawModifiedRequest
as its first argument. For full flexibility, use that function.Since this convenience method is meant to fetch the modification info of historical data, the
isReadModified
flag of the serviceSettings will be forced to True!Parameters: - addresses (
Address
or alist
ofAddress
) – A single address or a list of addresses of nodes of which the historical data should be retrieved. - startTime (
DateTime
) – The start time of the interval from which you would like to see the historical data. This parameter will always be used instead of the startTime attribute of the serviceSettings . - endTime (
DateTime
) – The end time of the interval from which you would like to see the historical data. This parameter will always be used instead of the startTime attribute of the serviceSettings . - numValuesPerNode (
int
) – The maximum number of values that may be returned for each node. 0 means no limit, but you may want to put it to a “safe” value (e.g. 100 if you expect to receive at most 50 historical values or so) to make sure that you’re not flooded by a huge stream of data values, e.g. in case you’ve made some mistake in the time interval! Default = 0. - maxAutoReadMore (
int
) – How many times do you allow the UAF to automatically invoke a “continuation request” for you (if that’s needed to fetch all results)? E.g. if you specify maxAutoReadMore = 10, then the UAF will automatically perform subsequent history requests, until either all results are fetched, or until 10 additional requests have been invoked automatically. This parameter will always be used instead of the maxAutoReadMore attribute of the serviceSettings. Default = 0, which means that no “automatic” continuation requests will be invoked by the UAF (so if you leave this parameter as 0 and you see that the len(result.targets[x].continuationPoint) > 0, then you must call the historyReadRaw method again with this continuationPoint to receive more historical data). - continuationPoints (
ByteStringVector
or alist
of Pythonbytearray
objects.) – Continuation points, in case you’re continuing to read the istorical data of a previous request manually. By specifying a sufficiently large number for maxAutoReadMore, you can actually let the UAF handle the “continuation requests”, if you want. If you’re not using continuationPoints manually, you can simply provide an empty list or vector. Default = empty list. - kwargs –
The following **kwargs are available (see A note on **kwargs for Client services):
- clientConnectionId: (type:
int
) - sessionSettings (type:
SessionSettings
) - serviceSettings (type:
HistoryReadRawModifiedSettings
) - translateSettings (type:
TranslateBrowsePathsToNodeIdsSettings
)
- clientConnectionId: (type:
Returns: The result of the history read request.
Return type: Raises: pyuaf.util.errors.UafError – Base exception, catch this to handle any UAF errors.
- addresses (
-
historyReadRaw
(addresses, startTime, endTime, numValuesPerNode=0, maxAutoReadMore=0, continuationPoints=[], **kwargs)¶ Read the raw historical data from one or more nodes synchronously.
This is a convenience function for calling
processRequest
with aHistoryReadRawModifiedRequest
as its first argument. For full flexibility, use that function.Since this convenience method is meant to fetch raw historical data, the
isReadModified
flag of the serviceSettings will be forced to False!Parameters: - addresses (
Address
or alist
ofAddress
) – A single address or a list of addresses of nodes of which the historical data should be retrieved. - startTime (
DateTime
) – The start time of the interval from which you would like to see the historical data. This parameter will always be used instead of the startTime attribute of the serviceSettings. - endTime (
DateTime
) – The end time of the interval from which you would like to see the historical data. This parameter will always be used instead of the startTime attribute of the serviceSettings. - numValuesPerNode (
int
) – The maximum number of values that may be returned for each node. 0 means no limit, but you may want to put it to a “safe” value (e.g. 100 if you expect to receive at most 50 historical values or so) to make sure that you’re not flooded by a huge stream of data values, e.g. in case you’ve made some mistake in the time interval! Default = 0. - maxAutoReadMore (
int
) – How many times do you allow the UAF to automatically invoke a “continuation request” for you (if that’s needed to fetch all results)? E.g. if you specify maxAutoReadMore = 10, then the UAF will automatically perform subsequent history requests, until either all results are fetched, or until 10 additional requests have been invoked automatically. This parameter will always be used instead of the maxAutoReadMore attribute of the serviceSettings. Default = 0, which means that no “automatic” continuation requests will be invoked by the UAF (so if you leave this parameter as 0 and you see that the len(result.targets[x].continuationPoint) > 0, then you must call the historyReadRaw method again with this continuationPoint to receive more historical data). - continuationPoints (
ByteStringVector
or alist
of Pythonbytearray
objects.) – Continuation points, in case you’re continuing to read the istorical data of a previous request manually. By specifying a sufficiently large number for maxAutoReadMore, you can actually let the UAF handle the “continuation requests”, if you want. If you’re not using continuationPoints manually, you can simply provide an empty list or vector. Default = empty list. - kwargs –
The following **kwargs are available (see A note on **kwargs for Client services):
- clientConnectionId: (type:
int
) - sessionSettings (type:
SessionSettings
) - serviceSettings (type:
HistoryReadRawModifiedSettings
) - translateSettings (type:
TranslateBrowsePathsToNodeIdsSettings
)
- clientConnectionId: (type:
Returns: The result of the history read request.
Return type: Raises: pyuaf.util.errors.UafError – Base exception, catch this to handle any UAF errors.
- addresses (
-
keepAliveReceived
(notification)¶ You should override this method if you want to process keep alive messages from the UAF.
Parameters: notification ( pyuaf.client.KeepAliveNotification
) – The received KeepAliveNotification.
-
logMessageReceived
(message)¶ Override this method if you want to process logging output from the UAF.
- This method is called by the UAF if:
pyuaf.client.settings.ClientSettings.logToCallbackLevel
is not set topyuaf.util.loglevels.Disabled
- no external logging callback function is registered
(via
Client()
or viaregisterLoggingCallback()
).
Parameters: message ( pyuaf.util.LogMessage
) – The received LogMessage.
-
manuallyConnect
(serverUri, sessionSettings=None)¶ Create a session manually (instead of having the UAF do it behind the scenes).
One of the advantages of the UAF is that you can just define the addresses of some nodes, and then read/write/monitor/... them without worrying about the technical concerns such as session creation, subscription creation etc. So you don’t have to create sessions yourself, because the UAF will do it for you. However, if you want to “keep control” over the session/subscription/... management yourself, you can use methods like
manuallyConnect()
,manuallyDisconnect()
,manuallySubscribe()
, etc. In this case, you can create the sessions/subscriptions/... in advance, and then afterwards read/write/... variables by using the same sessions and subscriptions. So these “manual” methods allow you to use OPC UA in the “traditional way”, however it’s much easier to do it the “UAF way” and simply forget about the creation and deletion of sessions, subscriptions, and monitored items.The URL(s) needed to discover the server with the given server URI, can be specified via the
ClientSettings
(which you can set viaClient()
and viasetClientSettings()
).Warning
If the connection fails (e.g. because you specified a wrong server URI, or because the security settings were incorrect), this methd will not raise an Exception! It will simply return the ClientConnectionId assigned to the internal Session object, which the UAF will try to reconnect in the background! So if you want to make sure this method call resulted in a connected session, you should do something like this:
clientConnectionId = myClient.manuallyConnect(SERVER_URI) sessionInformation = myClient.sessionInformation(clientConnectionId) if sessionInformation.sessionState == pyuaf.client.sessionstates.Disconnected: pass # OK, we can proceed else: print("Oops, something went wrong:") print(sessionInformation.lastConnectionAttemptStatus)
Parameters: - serverUri (
str
) – The server URI to manually connect to. - sessionSettings (
SessionSettings
) – The settings for the session (leave None for a default instance).
Returns: The client connection id: a number identifying the session.
Return type: int
Raises: - pyuaf.util.errors.DiscoveryError – Raised in case the FindServers service failed to discover a server that matches the given server URI.
- pyuaf.util.errors.UafError – Base exception, catch this to handle any other errors.
- serverUri (
-
manuallyConnectToEndpoint
(endpointUrl, sessionSettings=None, serverCertificate=None)¶ Manually connect to a specific endpoint, without using the discovery services.
A UAF client normally uses the discovery process to identify a server and connect to it. The user therefore doesn’t have to worry about connecting, disconnecting, session management, etc.
However, in certain cases you may want to connect manually to a specific endpoint, without using the discovery process (i.e. without relying on the discovery endpoint of the server). In these cases you can use this method.
You should probably only use this method if you have a good reason not to rely on the discovery services provided by the server. A server should be identified by a serverURI, not by an endpointURL!
The
securitySettings
attribute of the sessionSettings argument (in other words: sessionSettings.securitySettings) defines how you want to connect to the server.- This default instance has
- no security policy (
pyuaf.util.securitypolicies.UA_None
) - no security mode (
pyuaf.util.messagesecuritymodes.Mode_None
) - no authentication (
pyuaf.util.usertokentypes.Anonymous
)
- no security policy (
Compliant to OPC UA specs, the serverCertificate will:
- first be checked at the application level. If it’s not valid or not found in the trust list, then the untrustedServerCertificateReceived() callback function will be called. Override this method if you want to handle those cases.
- then it may be used for encryption and/or signing (if a secure connection is needed, of course).
You can leave serverCertificate
None
(or provide a default, invalid, nullPkiCertificate
instance) if you trust the server (i.e. if you make sureuntrustedServerCertificateReceived()
returnsAction_AcceptTemporarily
), and if you don’t need signing or encryption.Warning
If this method fails (in other words, when an Error is raised), then no Session has been created! This is different behavior from
manuallyConnect()
, which will have created a Session that automatically retries to connect.See also
Check out example How to manually connect to an endpoint without discovery? for more information.
Parameters: - endpointUrl – The endpoint URL to manually connect to.
- sessionSettings (
SessionSettings
) – The settings for the session (leave None for a default instance). - serverCertificate (
PkiCertificate
) – The server certificate (will be checked!)
Returns: The client connection id: a number identifying the session.
Return type: int
Raises: - pyuaf.util.errors.ConnectionError – Raised in case the connection fails.
- pyuaf.util.errors.UafError – Base exception, catch this to handle any other errors.
-
manuallyDisconnect
(clientConnectionId)¶ Disconnect the session manually.
A session which has been disconnected manually is “garbage collected” on the client side. When a session is created afterwards, a new ClientConnectionId will be assigned to this session (even if the properties of the new session are exactly the same as the old one).
Only use this for sessions that were created via the manuallyConnect method!
Parameters: clientConnectionId (
int
) – The id of the session (that was returned by themanuallyConnect()
method).Raises: - pyuaf.util.errors.InvalidRequestError – Raised in case no session is known for the given client connection id.
- pyuaf.util.errors.UafError – Base exception, catch this to handle any other errors.
-
manuallyDisconnectAllSessions
()¶ Disconnect all sessions.
To stress that normally the UAF takes care of session connection and disconnection, this method has a “manually” prefix. Normally it should not be used explicitely, as all sessions will be disconnected automatically when the client is deleted.
-
manuallySubscribe
(clientConnectionId, subscriptionSettings=None)¶ Create a subscription manually.
For more info about “manual” methods, see the documentation on the
manuallyConnect()
method.Parameters: - clientConnectionId (
int
) – The id of the session which should host the subscription. - settings (
SubscriptionSettings
) – The settings of the subscription you’d like to create.
Returns: The clientSubscriptionHandle: the handle identifying the newly created subscription.
Return type: int
Raises: pyuaf.util.errors.UafError – Base exception, catch this to handle any other errors.
- clientConnectionId (
-
manuallyUnsubscribe
(clientConnectionId, clientSubscriptionHandle)¶ Delete the subscription manually.
A subscription which has been deleted manually is “garbage collected” on the client side. When a subscription is created afterwards, a new clientSubscriptionHandle will be assigned to this session (even if the properties of the new subscription are exactly the same as the old one).
Parameters: - clientConnectionId (
int
) – The id of the session that hosts the subscription. - clientSubscriptionHandle (
int
) – The id of the subscription.
Raises: - pyuaf.util.errors.InvalidRequestError – Raised in case no session is known for the given clientSubscriptionHandle.
- pyuaf.util.errors.UafError – Base exception, catch this to handle any other errors.
- clientConnectionId (
-
monitoredItemInformation
(clientHandle)¶ Get information about the specified monitored item.
Check the
monitoredItemState
before interpreting the results of theMonitoredItemInformation
! Because if themonitoredItemState
isNotCreated
, then the monitored item not created on the server, but instead it’s cached by the client (which tries to re-create the monitored item periodically -as configurable by theClientSettings
-).Parameters: clientHandle (
int
) – The handle of the monitored item (always assigned by the UAF, not by the user!). This clientHandle is assigned when the monitored item is requested (e.g. by callingcreateMonitoredData()
), regardless of whether the monitored items were indeed created on the server, or not (e.g. in case of failures, or in case the server is not on-line yet).Returns: Information about the specified monitored item.
Return type: Raises: - pyuaf.util.errors.UnknownClientHandleError – Raised in case no monitored item is known for the given client handle.
- pyuaf.util.errors.UafError – Base exception, catch this to handle any other errors.
-
notificationsMissing
(info, previousSequenceNumber, newSequenceNumber)¶ Override this method to handle missing notifications.
Alternatively, you can also register callback functions which you defined yourself, by registering them using
pyuaf.client.Client.registerNotificationsMissingCallback()
.Parameters: - info (
SubscriptionInformation
) – Subscription information about the subscription which has missing notifications. - previousSequenceNumber (
int
) – Sequence number of the last notification just before notifications went missing. - newSequenceNumber (
int
) – Sequence number of the first notification just after notifications went missing.
- info (
-
processRequest
(request, resultCallback=None, notificationCallbacks=[])¶ Process a generic request (as found in
pyuaf.client.requests
).- As for callbacks, you may:
- specify no callbacks at all. In this case, you need to override (“virtually inherit”)
the
readComplete()
/writeComplete()
/dataChangesReceived()
/... functions - specify a resultCallback function (only for AsyncXXXXX functions!). In this case, the ReadResult/WriteResult/MethodCallResult/... of the corresponding asynchronous requests will be forwarded to the resultCallback function.
- specify a list of notificationCallback functions (only for CreateMonitoredDataRequests, CreateMonitoredEventsRequests, AsyncCreateMonitoredDataRequests and AsyncCreateMonitoredEventsRequests!). The number of callbacks must correspond exactly to the number of targets of the request.
- specify no callbacks at all. In this case, you need to override (“virtually inherit”)
the
Note
Both
CreateMonitoredDataRequest
andCreateMonitoredEventsRequest
are “persistent” requests. It means that even when communication fails (e.g. because the server was not online), a handle is already assigned to each monitored item as soon as you call processRequest(). In the background, the UAF will try to (re)establish the connection, and as soon as this is successful, it will create the monitored items for you on the server. From that point on, you may start to receive notifications (that can be identified by the handles that were already assigned and returned to you now). So when processRequest() fails, you need to be aware that in the background the UAF will retry to create them on the server. You can access the handles that will identify their notifications:- via the returned
CreateMonitoredDataResult
(orCreateMonitoredEventsResult
), in case processRequest() was successful and didn’t raise an exception - via the
CreateMonitoredItemsError
exception that was raised in case processRequest() was not successful. This exception has aassignedClientHandles
attribute, providing the assigned client handles.
Warning
Asynchronous requests MUST be invoked on a single session. Meaning: the targets of asynchronous requests MUST belong to the same server (as the UAF can currently not reconstruct an asynchronous request that must be “split up” to be called on multiple servers). If they don’t belong to the same server, an error will be raised.
Warning
The callbacks will run in a separate thread, and therefore any exception they raise will not be handled or propagated. So your callbacks should have a try-except clause if you want to be able to properly handle the exceptions that they may raise.
Parameters: request – The request (e.g. a ReadRequest
or class:~pyuaf.client.requests.WriteRequest or ...Returns: The result of the request (e.g. a ReadResult
orWriteResult
or ...Raises: pyuaf.util.errors.UafError – Base exception, catch this to handle any UAF errors.
-
read
(addresses, attributeId=13, **kwargs)¶ Read a number of node attributes synchronously.
This is a convenience function for calling
processRequest
with aReadRequest
as its first argument. For full flexibility, use that function.Parameters: - addresses (
Address
or alist
ofAddress
) – A single address or a list of addresses of nodes of which the specified attribute should be read. - attributeId (
int
) – The id of the attribute to be read (e.g.pyuaf.util.attributeids.Value
orpyuaf.util.attributeids.DisplayName
). - kwargs –
The following **kwargs are available (see A note on **kwargs for Client services):
- clientConnectionId: (type:
int
) - sessionSettings (type:
SessionSettings
) - serviceSettings (type:
ReadSettings
) - translateSettings (type:
TranslateBrowsePathsToNodeIdsSettings
)
- clientConnectionId: (type:
Returns: The result of the read request.
Return type: Raises: pyuaf.util.errors.UafError – Base exception, catch this to handle any UAF errors.
- addresses (
-
readComplete
(result)¶ Override this method to catch the result of asynchronous read requests.
This method will only be called by the UAF if you didn’t provide an “external” callback function already when you began the asynchronous read request.
In other words, there are two ways how you can catch the result of asynchronous read requests:
- either by calling
processRequest()
or :meth:~pyuaf.client.Client.beginRead without providing an external callback function –> then you need to overridereadComplete()
- or by calling
processRequest()
with providing an external callback function –> then only the external callback function will be called.
Parameters: result ( ReadResult
) – The asynchronously received read result.- either by calling
-
registerConnectErrorCallback
(callback)¶ Register a callback function to handle connect errors.
If you register a callback function, this callback function will be called instead of the
connectErrorReceived()
function (so the latter function will NOT be called anymore!).The callback function should have:
- 4 input arguments: clientConnectionId, connectionStep, sdkStatus, clientSideError
- 1 returned value: a bool
The signature of this method (and the meaning of these input arguments and returned value) is exactly the same as
connectErrorReceived()
.Parameters: callback – A callback function for handling connectErrors.
-
registerConnectionStatusCallback
(callback, onlyServerUri=None, onlyClientConnectionId=None)¶ Register a callback to receive connection status changes.
You can register multiple callbacks: all of them will be called. The
pyuaf.client.Client.connectionStatusChanged()
method (which you may override) will also always be called, regardless of the callbacks you register.There’s no need to provide more than one optional argument (it doesn’t make much sense in fact, since onlyClientConnectionId is more restrictive than onlyServerUri), but it’s not forbidden either. In case you provide multiple optional arguments, all of the conditions need to be satisfied for the callback function to be called.
Parameters: - callback – A callback function. This function should have one input
argument, to which the changed
SessionInformation
instance will be passed. - onlyServerUri (
str
) – Optional argument: provide this argument if you don’t want to listen to the status changes of all sessions to any server, but only listen to the connection changes for all sessions to the server identified by the given serverUri. - onlyClientConnectionId (
int
) – Optional argument: provide this argument if you don’t want to listen to the status changes of all sessions to any server, but only listen to the connection changes for the single session identified by the given unique clientConnectionId.
- callback – A callback function. This function should have one input
argument, to which the changed
-
registerKeepAliveCallback
(callback, onlyClientSubscriptionHandle=None)¶ Register a callback to handle KeepAlive notifications.
You can register multiple callbacks: all of them will be called. The
pyuaf.client.Client.keepAliveReceived()
method (which you may override) will also always be called, regardless of the callbacks you register.Parameters: - callback – A callback function. This function should have one input
argument of type
pyuaf.client.KeepAliveNotification
. - onlyClientSubscriptionHandle (
int
) – Optional argument: provide this argument if you don’t want to listen to the KeepAlive notifications of all subscriptions, but only listen to the KeepAlive notifications for the single subscription identified by the given unique clientSubscriptionHandle.
- callback – A callback function. This function should have one input
argument of type
-
registerLoggingCallback
(callback)¶ Register a callback function to receive all log messages.
If you register a callback function, this callback function will be called instead of the
logMessageReceived()
function (so the latter function will NOT be called anymore!).Parameters: callback – A callback function for the logging. This function should have one input argument, which you should call “msg” or so, because this argument is of type pyuaf.util.LogMessage
.
-
registerNotificationsMissingCallback
(callback, onlyClientSubscriptionHandle=None)¶ Register a callback to handle missing notifications.
You can register multiple callbacks: all of them will be called. The
pyuaf.client.Client.notificationsMissing()
method (which you may override) will also always be called, regardless of the callbacks you register.Parameters: - callback –
A callback function. This function should have three input arguments:
- first argument will be a
SessionInformation
instance, describing the subscription that has missing notifications. - second argument will be an
int
representing the sequence number of the last notification just before notifications went missing. - third argument will be an
int
representing the sequence number of the first notification just after notifications went missing.
- first argument will be a
- onlyClientSubscriptionHandle (
int
) – Optional argument: provide this argument if you don’t want to listen to the missing notifications of all subscriptions, but only listen to the missing notifications for the single subscription identified by the given unique clientSubscriptionHandle.
- callback –
-
registerSubscriptionStatusCallback
(callback, onlyClientSubscriptionHandle=None)¶ Register a callback to receive connection status changes.
You can register multiple callbacks: all of them will be called. The
pyuaf.client.Client.subscriptionStatusChanged()
method (which you may override) will also always be called, regardless of the callbacks you register.Parameters: - callback – A callback function. This function should have one input
argument, to which the changed
SessionInformation
instance will be passed. - onlyClientSubscriptionHandle (
int
) – Optional argument: provide this argument if you don’t want to listen to the status changes of all subscriptions, but only listen to the subscription changes for the single subscription identified by the given unique clientSubscriptionHandle.
- callback – A callback function. This function should have one input
argument, to which the changed
-
registerUntrustedServerCertificateCallback
(callback)¶ Register a callback function to handle untrusted certificates during the connection process.
If you register a callback function, this callback function will be called instead of the
untrustedServerCertificateReceived()
function (so the latter function will NOT be called anymore!).The callback function should have:
- 2 input arguments: ‘certificate’ and ‘cause’
- 1 returned value: either
Action_Reject
orAction_AcceptTemporarily
orAction_AcceptPermanently
.
The signature of this method (and the meaning of these input arguments and returned value) is exactly the same as
untrustedServerCertificateReceived()
.Parameters: callback – A callback function for handling untrusted certificates.
-
serversFound
()¶ Get a list of the application descriptions of the servers found in the discovery process.
The discovery is periodically being run in the background, so the returned list may change. The cycle time is of the discovery is configurable via the
ClientSettings
.Returns: A list of the application descriptions that were found. Return type: list
ofpyuaf.util.ApplicationDescription
-
serversOnNetworkFound
()¶ Get a list of the server descriptions of the servers found by querying the LDS.
The discovery is periodically being run in the background, so the returned list may change. The cycle time is of the discovery is configurable via the
ClientSettings
.Returns: A list of the servers that were found. Return type: list
ofpyuaf.util.ServerOnNetwork
-
sessionInformation
(clientConnectionId)¶ Get information about the specified session.
Parameters: clientConnectionId (
int
) – The client connection id (always assigned by the UAF, not by the user!).Returns: Information about the specified session.
Return type: Raises: - pyuaf.util.errors.InvalidRequestError – Raised in case no session is known for the given client connection id.
- pyuaf.util.errors.UafError – Base exception, catch this to handle any other errors.
-
setClientSettings
(settings)¶ Change the client settings.
Parameters: settings ( pyuaf.client.settings.ClientSettings
) – The new settings.
-
setMonitoringMode
(clientHandles, monitoringMode, serviceSettings=None)¶ Set the monitoring mode for the specified monitored items.
This is the preferred way to temporarily stop receiving notifications for certain monitored items (e.g. because a tab in a User Interface is not visible). See the example below.
Note that clientHandles instead of MonitoredItemIds are used to identify a monitored item. ClientHandles are assigned by the client and are therefore static, while MonitoredItemIds are assigned by the server, so they may change over time (e.g. after restarting the server, of after failover to a redundant server). The UAF will keep track of the mapping between both. This means that your monitored items are always identified in the same way (by their clientHandles), no matter what happens on the server-side. The UAF takes care of the conversion automatically, so you don’t have to worry about it.
Example:
>>> import pyuaf >>> from pyuaf.util.errors import UafError, CreateMonitoredItemsError >>> from pyuaf.util import Address, NodeId >>> from pyuaf.client import Client >>> from pyuaf.util import monitoringmodes >>> >>> myClient = Client("myClient", ["opc.tcp://localhost:4841"]) >>> >>> nameSpaceUri = "http://mycompany.com/mymachine" >>> serverUri = "http://mycompany.com/servers/plc1" >>> temperature = Address( NodeId("myMachine.temperature", nameSpaceUri), serverUri) >>> pressure = Address( NodeId("myMachine.pressure", nameSpaceUri), serverUri) >>> >>> def updateTemperatureWidget(notification): ... temperatureIndicator.display("%.1f K" %notification.data.value) >>> >>> def updatePressureWidget(notification): ... pressureIndicator.display("%.1f Bar" %notification.data.value) >>> >>> try: ... result = myClient.createMonitoredData( ... addresses = [temperature, pressure], ... notificationCallbacks = [updateTemperatureWidget, updatePressureWidget]) ... # store the clientHandles: ... clientHandles = [ target.clientHandle for target in result.targets ] ... except CreateMonitoredItemsError, e: ... # The monitored items could not be created, because there was some failure ... # (maybe the server is off-line?). ... # Nevertheless, the client handles were already assigned, and we can get them like this: ... clientHandle = e.assignedClientHandles[0] ... except UafError, e: ... print("Oops, an unexpected error!") >>> >>> def uiTabChangedState(visible): ... if visible: ... monitoringMode = monitoringmodes.Sampling ... else: ... monitoringMode = monitoringmodes.Reporting ... try: ... statuses = myClient.setMonitoringMode(clientHandles, monitoringMode) ... for i in xrange(len(statuses)): ... if not statuses[i].isGood(): ... print("Could not set monitoring mode of widget %d: %s" %(i, statuses[i])) ... except UafError, e: ... print("Couldn't set the new monitoring mode: %s" %e)
Parameters: - clientHandles (
list
ofint
) – List of client handles of the monitored items you want to change. - monitoringMode (
int
) – New monitoring mode, as defined inpyuaf.util.monitoringmodes
. - serviceSettings (
pyuaf.client.settings.ServiceSettings
) – The service settings to be used (leave None for default settings).
Returns: A list of statuses, one for each client handle.
Return type: Raises: pyuaf.util.errors.UafError – Base exception, catch this to handle any UAF errors.
- clientHandles (
-
setPublishingMode
(clientSubscriptionHandle, publishingEnabled, serviceSettings=None)¶ Set the publishing mode, by specifying a subscription handle.
Note that a subscription handle may not be known at the time when you create the monitored items. E.g. when you call
createMonitoredData()
orcreateMonitoredEvents()
, it can happen that the server that hosts the monitored items is not on-line yet. In this case, the ClientSubscriptionHandle is not assigned yet, but ClientHandles are assigned yet. Therefore it makes sense to first callmonitoredItemInformation()
of your monitored item, and get the subscription handle from there.E.g. like this:
>>> import pyuaf >>> from pyuaf.util.errors import UafError, CreateMonitoredItemsError >>> from pyuaf.util import Address, NodeId >>> from pyuaf.client import Client >>> >>> myClient = Client("myClient", ["opc.tcp://localhost:4841"]) >>> >>> nameSpaceUri = "http://mycompany.com/mymachine" >>> serverUri = "http://mycompany.com/servers/plc1" >>> address = Address( NodeId("myMachine.myVariable", nameSpaceUri), serverUri) >>> >>> def myCallback(notification): ... print("A data change was received: %s" %notification) >>> >>> try: ... result = myClient.createMonitoredData([address], ... notificationCallbacks = [myCallback]) ... clientHandle = result.targets[0].clientHandle ... except CreateMonitoredItemsError, e: ... # The monitored items could not be created, because there was some failure ... # (maybe the server is off-line?). ... # Nevertheless, the client handles were already assigned, and we can get them like this: ... clientHandle = e.assignedClientHandles[0] ... except UafError, e: ... print("Oops, an unexpected error!") >>> >>> >>> info = myClient.monitoredItemInformation(clientHandle) >>> >>> if info.monitoredItemState == pyuaf.client.monitoreditemstates.Created: ... # enable the subscription that hosts the monitored item: ... myClient.setPublishingMode(info.clientSubscriptionHandle, True) ... ... # ... do some stuff ... ... ... # disable the subscription that hosts the monitored item: ... myClient.setPublishingMode(info.clientSubscriptionHandle, False)
Parameters: - clientSubscriptionHandle (
int
) – The handle identifying the subscription. - publishingEnabled (
bool
) – True to enable the publishing mode, false to disable. - serviceSettings (
pyuaf.client.settings.ServiceSettings
) – The service settings to be used (leave None for default settings).
Raises: - pyuaf.util.errors.UnknownClientHandleError – The clientSubscriptionHandle is unknown!
- pyuaf.util.errors.UafError – Base exception, catch this to handle any UAF errors.
- clientSubscriptionHandle (
-
structureDefinition
(dataTypeId)¶ Get a structure definition for the given datatype NodeId.
Parameters: dataTypeId (
NodeId
.) – NodeId of the datatype.Returns: The definition of this datatype.
Return type: Raises: - pyuaf.util.errors.DefinitionNotFoundError – Will be raised if no definition could be found.
- pyuaf.util.errors.UafError – Base exception, catch this to handle any UAF errors.
-
subscriptionInformation
(clientSubscriptionHandle)¶ Get information about the specified subscription.
Parameters: clientSubscriptionHandle (
int
) – The client subscription handle (always assigned by the UAF, not by the user!).Returns: Information about the specified subscription.
Return type: Raises: - pyuaf.util.errors.InvalidRequestError – Raised in case no subscription is known for the given client subscription handle.
- pyuaf.util.errors.UafError – Base exception, catch this to handle any other errors.
-
subscriptionStatusChanged
(info)¶ Override this method to receive subscription status changes.
Alternatively, you can also register callback functions which you defined yourself, by registering them using
pyuaf.client.Client.registerSubscriptionStatusCallback()
.Parameters: info ( SubscriptionInformation
) – Updated subscription information.
-
unregisterConnectErrorCallback
()¶ Unregister a callback function to stop handling connect errors.
If you unregister a callback function, the connect error will be send to
connectErrorReceived()
instead.
-
unregisterLoggingCallback
()¶ Unregister a callback function to stop receiving all log messages.
If you unregister a callback function, and callback logging is still enabled (via the client settings), the log messages will be sent to the :meth:logMessageReceived method (so you can virtually override this method to receive the log messages).
-
unregisterUntrustedServerCertificateCallback
()¶ Unregister a callback function to stop handling untrusted certificates.
If you unregister a callback function, the untrusted certificates will be send to
untrustedServerCertificateReceived()
instead (so you can override this method to receive the certificates).
-
untrustedServerCertificateReceived
(certificate, cause)¶ Override this method if you want to handle an untrusted certificate.
This method is called by the UAF whenever an untrusted (e.g. unknown) server certificate must be checked at the application level (as part of the connection step, before a communication channel is established). Note that this has nothing to do with signed or encrypted communication! Even if you don’t want to connect to a secured endpoint, you’re advised to verify the certificate of the server to make sure you’re talking to the right one.
It will not be called however when you registered a callback function via
registerUntrustedServerCertificateCallback()
. So you must choose how to handle untrusted server certificates: - either by overridinguntrustedServerCertificateReceived()
- or by registering a callback viaregisterUntrustedServerCertificateCallback()
.This method will be called by the UAF, so you must override it. It is called by the UAF whenever it thinks that it should verify the certificate of the server (i.e. during (re)connection).
Typically, during the first connection to a server, the certificate of the server is not known to the client yet. By overriding this method, you can therefore show the certificate to the user of your software, and ask him/her whether or not he/she thinks the certificate can be trusted.
Three options are available:
Action_Reject
: don’t trust the certificate, and therefore don’t try to connect.Action_AcceptTemporarily
: trust the certificate temporarily, i.e. don’t store it in the trust list but just -for now- allow connection to the server. If the UAF must reconnect at some point to the server and the server certificate must be checked again, the user shall again have to confirm the certificate.Action_AcceptPermanently
: store the certificate in the trust list (as defined by thecertificateTrustListLocation
: setting) and accept the connection. Since the certificate is stored on disk in the trust list, the client application will automatically trust the certificate in the future (until the certificate expires, of course).
Warning
You must always return one of the following integers:
Warning
By default,
Action_AcceptTemporarily
is returned, which means that all untrusted certificates will be accepted by default! Admittingly that doesn’t sound very safe, but it simply implies that by default a pyuaf Client will be able to connect to any (unknown) server without needing to override this method. If you don’t trust the servers in your network, you should override this method.See also
Check out example “how_to_connect_to_a_secured_endpoint.py” for more information.
Parameters: - certificate (
pyuaf.util.PkiCertificate
) – The untrusted certificate. - cause (
pyuaf.util.Status
) – The reason why it was untrusted (mostly because it is simply not found in the trust list, but it may also be that it’s not trusted because e.g. the trust list could not be opened).
Returns: either
Action_Reject
orAction_AcceptTemporarily
orAction_AcceptPermanently
.Return type: int
-
write
(addresses, data, attributeId=13, **kwargs)¶ Write a number of node attributes synchronously.
This is a convenience function for calling
processRequest
with aWriteRequest
as its first argument. For full flexibility, use that function.Parameters: - addresses (
Address
or alist
ofAddress
) – A single address or a list of addresses of nodes of which the specified attribute should be written. - data (
UInt32
orlist
ofUInt32
or any other data type of the supported dynamic data types (or alist
of them).) – A single value or a list of values to be written. - attributeId (
int
) – The id of the attribute to be written (e.g.pyuaf.util.attributeids.Value
orpyuaf.util.attributeids.DisplayName
) for all addresses. - kwargs –
The following **kwargs are available (see A note on **kwargs for Client services):
- clientConnectionId: (type:
int
) - sessionSettings (type:
SessionSettings
) - serviceSettings (type:
WriteSettings
) - translateSettings (type:
TranslateBrowsePathsToNodeIdsSettings
)
- clientConnectionId: (type:
Returns: The result of the write request.
Return type: Raises: pyuaf.util.errors.UafError – Base exception, catch this to handle any UAF errors.
- addresses (
-
writeComplete
(result)¶ Override this method to catch the result of asynchronous write requests.
This method will only be called by the UAF if you didn’t provide an “external” callback function already when you began the asynchronous write request.
In other words, there are two ways how you can catch the result of asynchronous write requests:
- either by calling
processRequest()
or :meth:~pyuaf.client.Client.beginWrite without providing an external callback function –> then you need to overridewriteComplete()
- or by calling
processRequest()
with providing an external callback function –> then only the external callback function will be called.
Parameters: result ( WriteResult
) – The asynchronously received write result.- either by calling
- settings (
class MonitoredItemInformation¶
-
class
pyuaf.client.
MonitoredItemInformation
(*args)¶ A MonitoredItemInformation object contains information about a monitored item.
Methods:
Attributes:
-
monitoredItemState
¶ An
int
representing the state of the monitored item (e.g.Created
).The possible states are defined in the
pyuaf.client.monitoreditemstates
module.
-
clientConnectionId
¶ The id of the session that hosts the subscription (which in turn hosts the monitored item), as a
long
.
-
clientSubscriptionHandle
¶ The handle of the subscription that hosts the monitored item, as a
long
.
-
clientHandle
¶ The handle of the monitored item, as a
long
.
-
settings
¶ The settings of this particular monitored item, as an instance of type
MonitoredItemSettings
.
-
class MonitoredItemNotification¶
-
class
pyuaf.client.
MonitoredItemNotification
(*args)¶ A MonitoredItemNotification is the common superclass class of
DataChangeNotification
andEventNotification
.Methods:
-
__init__
(*args)¶ Construct a new MonitoredItemNotification.
- You’ll never need to create notifications like this yourself because:
- only the subclasses
pyuaf.client.DataChangeNotification
andpyuaf.client.EventNotification
will be instantiated, never the superclass itself - the UAF will produce notifications and provide them to you, so you can consume them.
- only the subclasses
-
__str__
(*args)¶ Get a string representation.
-
Attributes:
-
clientHandle
¶ A clientHandle is a 32-bit number assigned by the UAF to newly created monitored items. Essentially, it allows you to identify the monitored item of which you receive this notification.
You can store the client handle when you created the monitored item, see for example the use case example at
pyuaf.client.results.CreateMonitoredDataResultTarget.clientHandle()
.If you use “notification callbacks”, you don’t need to worry about client handles (because the notifications will be automatically mapped to your callback functions that implement behavior for a specific monitored item.
-
class DataChangeNotification¶
-
class
pyuaf.client.
DataChangeNotification
(*args)¶ A DataChangeNotification is a notification for a monitored data item.
Methods:
-
__init__
(*args)¶ Construct a new DataChangeNotification.
You’ll never need to create notifications like this yourself, because the UAF will produce them and provide them to you, so you can consume them.
-
Attributes inherited from
MonitoredItemNotification
:-
clientHandle
¶
-
Other attributes:
-
status
¶ The status of the data (a
pyuaf.util.Status
).
-
data
¶ The changed data.
The type of this data depends on the type of the variable you are monitoring. This means that it has a dynamic data type.
See also
-
class EventNotification¶
-
class
pyuaf.client.
EventNotification
(*args)¶ An EventNotification is a notification for a monitored event item.
Methods:
-
__init__
(*args)¶ Construct a new EventNotification.
You’ll never need to create notifications like this yourself, because the UAF will produce them and provide them to you, so you can consume them.
-
Attributes inherited from
MonitoredItemNotification
:-
clientHandle
¶
-
Other attributes:
-
fields
¶ The values of the fields you are monitoring (in the same order as the select clauses which you specified in the
pyuaf.client.requests.CreateMonitoredEventsRequestTarget
).Since the type of the fields depend on the type of the select clauses of your
pyuaf.client.requests.CreateMonitoredEventsRequestTarget
, the fields are presented to you as apyuaf.util.VariantVector
.
-
class KeepAliveNotification¶
-
class
pyuaf.client.
KeepAliveNotification
(*args)¶ A KeepAliveNotification is sent by the server to notify the client that the subscription is still alive.
It is sent when the data that is monitored by the client has not changed for a while. E.g. suppose a client wants to monitor some data, and it specifies a
publishingIntervalSec
of 1.0 seconds and amaxKeepAliveCount
of 5. As a result, when the monitored data changes rapidly, the client will be notified once per second. But every time the monitored data remains constant for 1.0 * 5 = 5.0 seconds, a KeepAliveNotification will be sent instead to notify the client that everything is still OK.Methods:
-
__init__
(*args)¶ Construct a new KeepAliveNotification.
You’ll never need to create notifications like this yourself, because the UAF will produce them and provide them to you, so you can consume them.
-
Attributes inherited from
SubscriptionInformation
:-
clientConnectionId
¶ –> See
pyuaf.client.SubscriptionInformation.clientConnectionId
.
-
clientSubscriptionHandle
¶ –> See
pyuaf.client.SubscriptionInformation.clientSubscriptionHandle
.
-
subscriptionState
¶ –> See
pyuaf.client.SubscriptionInformation.subscriptionState
.
-
Other attributes:
-
clientHandles
¶ The client handles assigned to the subscription that got a keep alive message, as a
UInt32Vector
.So if you receive a KeepAliveNotification, you know that the monitored items identified by these handles are OK.
-
class SessionInformation¶
-
class
pyuaf.client.
SessionInformation
(*args)¶ A SessionInformation object contains information about a session such as the state of the session, the server URI of the server to which it is connected, etc.
Methods:
Attributes:
-
clientConnectionId
¶ The id of the session, as a
long
.
-
serverState
¶ An
int
representing the state of the server (e.g.Running
).The possible states are defined in the
pyuaf.util.serverstates
module.
-
serverUri
¶ The URI of the server to which the session should be connected, as a
str
.
-
lastConnectionAttemptStep
¶ The step of the connection process (corresponding to the
lastConnectionAttemptStatus
), as anint
.The possible steps are defined in the
pyuaf.client.connectionsteps
module.
-
sessionSettings
¶ The session settings of the session (type:
SessionSettings
).
-
class SubscriptionInformation¶
-
class
pyuaf.client.
SubscriptionInformation
(*args)¶ A SubscriptionInformation object contains information about a subscription such as the state of the subscription, the handle, etc.
Methods:
Attributes:
-
clientConnectionId
¶ The id of the session that hosts the subscription, as a
long
.
-
clientSubscriptionHandle
¶ The handle of the subscription, as a
long
.
-
subscriptionState
¶ An
int
representing the state of the subscription (e.g.Created
).The possible states are defined in the
pyuaf.client.subscriptionstates
module.
-
subscriptionSettings
¶ The subscription settings of the subscription (type:
SubscriptionSettings
).
-