diff --git a/asyncua/client/client.py b/asyncua/client/client.py index 308456b0e..4a7262ea9 100644 --- a/asyncua/client/client.py +++ b/asyncua/client/client.py @@ -23,7 +23,6 @@ class Client: """ High level client to connect to an OPC-UA server. - This class makes it easy to connect and browse address space. It attempts to expose as much functionality as possible but if you want more flexibility it is possible and advised to @@ -35,11 +34,9 @@ def __init__(self, url: str, timeout: int = 4, loop=None): :param url: url of the server. if you are unsure of url, write at least hostname and port and call get_endpoints - :param timeout: Each request sent to the server expects an answer within this time. The timeout is specified in seconds. - Some other client parameters can be changed by setting attributes on the constructed object: See the source code for the exhaustive list. @@ -110,17 +107,13 @@ def set_password(self, pwd: str): async def set_security_string(self, string: str): """ Set SecureConnection mode. - :param string: Mode format ``Policy,Mode,certificate,private_key[,server_private_key]`` - where: - - ``Policy`` is ``Basic128Rsa15``, ``Basic256`` or ``Basic256Sha256`` - ``Mode`` is ``Sign`` or ``SignAndEncrypt`` - ``certificate`` and ``server_private_key`` are paths to ``.pem`` or ``.der`` files - ``private_key`` may be a path to a ``.pem`` or ``.der`` file or a conjunction of ``path``::``password`` where ``password`` is the private key password. - Call this before connect() """ if not string: @@ -542,10 +535,8 @@ async def create_subscription(self, period, handler, publishing=True): """ Create a subscription. Returns a Subscription object which allows to subscribe to events or data changes on server. - :param period: Either a publishing interval in milliseconds or a `CreateSubscriptionParameters` instance. The second option should be used, if the asyncua-server has problems with the default options. - :param handler: Class instance with data_change and/or event methods (see `SubHandler` base class for details). Remember not to block the main event loop inside the handler methods. """ diff --git a/asyncua/client/ua_file.py b/asyncua/client/ua_file.py new file mode 100644 index 000000000..be9ce93c3 --- /dev/null +++ b/asyncua/client/ua_file.py @@ -0,0 +1,45 @@ +from asyncua import ua + + +class UaFile: + + def __init__(self, file_node, open_mode): + self._file_node = file_node + self._handle = None + if open_mode == 'r': + self._init_open = ua.OpenFileMode.Read.value + else: + raise ValueError("file mode is not supported") + + async def __aenter__(self): + self._handle = await self.open(self._init_open) + return self + + async def __aexit__(self, exc_type, exc_value, traceback): + return await self.close() + + async def open(self, open_mode): + """ open file method """ + open_node = await self._file_node.get_child("Open") + arg = ua.Variant(open_mode, ua.VariantType.Byte) + return await self._file_node.call_method(open_node, arg) + + async def close(self): + """ close file method """ + read_node = await self._file_node.get_child("Close") + arg1 = ua.Variant(self._handle, ua.VariantType.UInt32) + return await self._file_node.call_method(read_node, arg1) + + async def read(self): + """ reads file contents """ + size = await self.get_size() + read_node = await self._file_node.get_child("Read") + arg1 = ua.Variant(self._handle, ua.VariantType.UInt32) + arg2 = ua.Variant(size, ua.VariantType.Int32) + return await self._file_node.call_method(read_node, arg1, arg2) + + async def get_size(self): + """ gets size of file """ + size_node = await self._file_node.get_child("Size") + return await size_node.read_value() + diff --git a/examples/client-file.py b/examples/client-file.py new file mode 100644 index 000000000..96225771b --- /dev/null +++ b/examples/client-file.py @@ -0,0 +1,15 @@ +import asyncio +from asyncua.client import Client +from asyncua.client.ua_file import UaFile + +async def read_file(): + """ read file example """ + + url = "opc.tcp://10.0.0.199:4840" + async with Client(url=url) as client: + file_node = client.get_node("ns=2;s=NameOfNode") + async with UaFile(file_node, 'r') as ua_file: + contents = await ua_file.read() # read file + print(contents) + +asyncio.run(read_file())