2 High level interface to pure python OPC-UA server 6 from datetime
import timedelta
8 from urllib.parse
import urlparse
10 from urlparse
import urlparse
32 print(
"cryptography is not installed, use of crypto disabled")
39 High level Server class 41 This class creates an opcua server with default values 43 Create your own namespace and then populate your server address space 44 using use the get_root() or get_objects() to get Node objects. 45 and get_event_object() to fire events. 46 Then start server. See example_server.py 47 All methods are threadsafe 49 If you need more flexibility you call directly the Ua Service methods 50 on the iserver or iserver.isesssion object members. 52 During startup the standard address space will be constructed, which may be 53 time-consuming when running a server on a less powerful device (e.g. a 54 Raspberry Pi). In order to improve startup performance, a optional path to a 55 cache file can be passed to the server constructor. 56 If the parameter is defined, the address space will be loaded from the 57 cache file or the file will be created if it does not exist yet. 58 As a result the first startup will be even slower due to the cache file 59 generation but all further start ups will be significantly faster. 61 :ivar application_uri: 62 :vartype application_uri: uri 64 :vartype product_uri: uri 67 :ivar default_timeout: timeout in milliseconds for sessions and secure channel 68 :vartype default_timeout: int 69 :ivar iserver: internal server object 70 :vartype default_timeout: InternalServer 71 :ivar bserver: binary protocol server 72 :vartype bserver: BinaryServer 73 :ivar nodes: shortcuts to common nodes 74 :vartype nodes: Shortcuts 78 def __init__(self, shelffile=None, iserver=None):
79 self.
logger = logging.getLogger(__name__)
80 self.
endpoint = urlparse(
"opc.tcp://0.0.0.0:4840/freeopcua/server/")
83 self.
name =
"FreeOpcUa Python Server" 86 if iserver
is not None:
107 def __exit__(self, exc_type, exc_value, traceback):
112 load server certificate from file, either pem or der 121 for debugging you may want to disable clock that write every second 124 self.iserver.disabled_clock = val
128 Set application/server URI. 129 This uri is supposed to be unique. If you intent to register 130 your server to a discovery server, it really should be unique in 132 default is : "urn:freeopcua:python:server" 138 find_servers. mainly implemented for symmetry with client 143 params.EndpointUrl = self.endpoint.geturl()
144 params.ServerUris = uris
145 return self.iserver.find_servers(params)
149 Register to an OPC-UA Discovery server. Registering must be renewed at 150 least every 10 minutes, so this method will use our asyncio thread to 151 re-register every period seconds 152 if period is 0 registration is not automatically renewed 166 stop registration thread 172 for client
in self._discovery_clients.values():
173 client.register_server(self)
178 Create a client to discovery server and return it 186 Enable or disable the builtin Admin user from network clients 188 self.iserver.allow_remote_admin = allow
194 return self.iserver.get_endpoints()
201 self.
_set_endpoints(security_policies.SecurityPolicyBasic128Rsa15,
202 ua.MessageSecurityMode.SignAndEncrypt)
204 ua.MessageSecurityMode.SignAndEncrypt,
208 self.
_set_endpoints(security_policies.SecurityPolicyBasic128Rsa15,
209 ua.MessageSecurityMode.Sign)
211 ua.MessageSecurityMode.Sign,
216 ua.MessageSecurityMode.SignAndEncrypt)
218 ua.MessageSecurityMode.SignAndEncrypt,
223 ua.MessageSecurityMode.Sign)
225 ua.MessageSecurityMode.Sign,
230 def _set_endpoints(self, policy=ua.SecurityPolicy, mode=ua.MessageSecurityMode.None_):
232 idtoken.PolicyId =
'anonymous' 233 idtoken.TokenType = ua.UserTokenType.Anonymous
236 idtoken2.PolicyId =
'certificate_basic256' 237 idtoken2.TokenType = ua.UserTokenType.Certificate
240 idtoken3.PolicyId =
'certificate_basic128' 241 idtoken3.TokenType = ua.UserTokenType.Certificate
244 idtoken4.PolicyId =
'username' 245 idtoken4.TokenType = ua.UserTokenType.UserName
252 appdesc.DiscoveryUrls.append(self.endpoint.geturl())
255 edp.EndpointUrl = self.endpoint.geturl()
258 edp.ServerCertificate = uacrypto.der_from_x509(self.
certificate)
259 edp.SecurityMode = mode
260 edp.SecurityPolicyUri = policy.URI
261 edp.UserIdentityTokens = [idtoken, idtoken2, idtoken3, idtoken4]
262 edp.TransportProfileUri =
'http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary' 263 edp.SecurityLevel = 0
264 self.iserver.add_endpoint(edp)
271 Start to listen on network 276 self.bserver.set_policies(self.
_policies)
283 for client
in self._discovery_clients.values():
290 Get Root node of server. Returns a Node object. 296 Get Objects node of server. Returns a Node object. 302 Get Server node of server. Returns a Node object. 308 Get a specific node using NodeId object or a string representing a NodeId 310 return Node(self.iserver.isession, nodeid)
314 Create a subscription. 315 returns a Subscription object which allow 316 to subscribe to events or data on server 319 params.RequestedPublishingInterval = period
320 params.RequestedLifetimeCount = 3000
321 params.RequestedMaxKeepAliveCount = 10000
322 params.MaxNotificationsPerPublish = 0
323 params.PublishingEnabled =
True 325 return Subscription(self.iserver.isession, params, handler)
329 get all namespace defined in server 332 return ns_node.get_value()
336 Register a new namespace. Nodes should in custom namespace, not 0. 339 uries = ns_node.get_value()
341 return uries.index(uri)
343 ns_node.set_value(uries)
344 return len(uries) - 1
348 get index of a namespace using its uri 351 return uries.index(uri)
355 Returns an event object using an event type from address space. 356 Use this object to fire events 363 if properties
is None:
368 if properties
is None:
373 if properties
is None:
375 if variables
is None:
385 if properties
is None:
387 if variables
is None:
394 if isinstance(basetype, Node):
397 base_t =
Node(self.iserver.isession, basetype)
401 custom_t = base_t.add_object_type(idx, name)
402 for prop
in properties:
406 custom_t.add_property(idx, prop[0], ua.get_default_value(prop[1]), varianttype=prop[1], datatype=datatype)
407 for variable
in variables:
409 if len(variable) > 2:
410 datatype = variable[2]
411 custom_t.add_variable(idx, variable[0], ua.get_default_value(variable[1]), varianttype=variable[1], datatype=datatype)
412 for method
in methods:
413 custom_t.add_method(idx, method[0], method[1], method[2], method[3])
419 Import nodes defined in xml 421 importer = xmlimporter.XmlImporter(self)
422 return importer.import_xml(path)
426 Export defined nodes to xml 429 exp.build_etree(nodes)
430 return exp.write_xml(path)
434 Export nodes of one or more namespaces to an XML file. 435 Namespaces used by nodes are always exported for consistency. 437 server: opc ua server to use 438 path: name of the xml file to write 439 namespaces: list of string uris or int indexes of the namespace to export, if not provide all ns are used except 0 443 if namespaces
is None:
449 return delete_nodes(self.iserver.isession, nodes, recursive)
453 Start historizing supplied nodes; see history module 455 node: node or list of nodes that can be historized (variables/properties) 456 period: time delta to store the history; older data will be deleted from the storage 457 count: number of changes to store in the history 463 self.iserver.enable_history_data_change(node, period, count)
467 Stop historizing supplied nodes; see history module 469 node: node or list of nodes that can be historized (UA variables/properties) 475 self.iserver.disable_history_data_change(node)
479 Start historizing events from node (typically a UA object); see history module 481 node: node or list of nodes that can be historized (UA objects) 482 period: time delta to store the history; older data will be deleted from the storage 483 count: number of events to store in the history 489 self.iserver.enable_history_event(node, period, count)
493 Stop historizing events from node (typically a UA object); see history module 495 node: node or list of nodes that can be historized (UA objects) 501 self.iserver.disable_history_event(node)
504 self.iserver.subscribe_server_callback(event, handle)
507 self.iserver.unsubscribe_server_callback(event, handle)
511 Link a python function to a UA method in the address space; required when a UA method has been imported 512 to the address space via XML; the python executable must be linked manually 515 callback: python function that the UA method will call 519 self.iserver.isession.add_method_callback(node.nodeid, callback)
def load_private_key(self, path)
def dehistorize_node_data_change(self, node)
def get_node(self, nodeid)
def create_custom_variable_type(self, idx, name, basetype=ua.ObjectIds.BaseVariableType, properties=None, variables=None, methods=None)
def create_custom_event_type(self, idx, name, basetype=ua.ObjectIds.BaseEventType, properties=None)
def allow_remote_admin(self, allow)
def import_xml(self, path)
def _create_custom_type(self, idx, name, basetype, properties, variables, methods)
def register_to_discovery(self, url="opc.tcp://localhost:4840", period=60)
def __exit__(self, exc_type, exc_value, traceback)
def get_nodes_of_namespace(server, namespaces=None)
def historize_node_event(self, node, period=timedelta(days=7), count=0)
def export_xml(self, nodes, path)
def __init__(self, shelffile=None, iserver=None)
def _renew_registration(self)
def set_application_uri(self, uri)
def create_custom_object_type(self, idx, name, basetype=ua.ObjectIds.BaseObjectType, properties=None, variables=None, methods=None)
def _setup_server_nodes(self)
def link_method(self, node, callback)
def _set_endpoints(self, policy=ua.SecurityPolicy, mode=ua.MessageSecurityMode.None_)
def create_custom_data_type(self, idx, name, basetype=ua.ObjectIds.BaseDataType, properties=None)
def create_subscription(self, period, handler)
def dehistorize_node_event(self, node)
def unregister_to_discovery(self, url="opc.tcp://localhost:4840")
def export_xml_by_ns(self, path, namespaces=None)
def get_client_to_discovery(self, url="opc.tcp://localhost:4840")
def unsubscribe_server_callback(self, event, handle)
def subscribe_server_callback(self, event, handle)
def register_namespace(self, uri)
def set_endpoint(self, url)
def get_event_generator(self, etype=None, source=ua.ObjectIds.Server)
def disable_clock(self, val=True)
def get_server_node(self)
def delete_nodes(self, nodes, recursive=False)
def historize_node_data_change(self, node, period=timedelta(days=7), count=0)
def find_servers(self, uris=None)
def get_namespace_index(self, uri)
def set_server_name(self, name)
def get_objects_node(self)
def load_certificate(self, path)
def get_namespace_array(self)