2

I have the following code which connets to a OPC UA Server and calls 2 methods:

async def handle_error():
    with open('traceback.txt', 'w') as file:
         file.write(traceback.format_exc())


async def main():
    try:
      
        # Connect to the server
        client = Client(SERVER_URL, timeout=TMOUT)
        client.set_user(USERNAME)
        client.set_password(PASSWORD)
      
        await client.connect()
       
        print("Connected")
    
        await client.load_data_type_definitions()
        print("Defs loaded")
                       
        # Call method
 
        print("Before method call")
        
        # Prepare args
        method_type = "WriteTag"
        METHODID, arg1, arg2, arg3, arg4, arg5, arg6 = await prepare_args(method_type);
        
        #WriteTag
        result = await call_method(method_type, client, OBJECTID, METHODID, arg1, arg2, arg3, arg4, arg5, arg6)
        print("Result: ", result)
        
        time.sleep(1)
        
        # Prepare args
        method_type = "ReadTag"
        METHODID, arg1, arg2, arg3, arg4, arg5, arg6 = await prepare_args(method_type);
        
        #ReadTag
        method_type = "ReadTag"
        result = await call_method(method_type, client, OBJECTID, METHODID, arg1, arg2, arg3, arg4, arg5, arg6)
        print("Result: ", result)
        
        
        #print("Output arguments: ", output_args)
   
    except concurrent.futures._base.CancelledError:
        print("Session cancelled")

    except Exception as e:
        print("Error: ", e)
        await handle_error()
    

    except KeyboardInterrupt:
        print("Programm stopped by user")
        await handle_error()

    finally:
        # Disconnect from the server
        print("Closing...")
        await handle_error()
        await client.disconnect()
        print("Disconnected")
        exit(0)
        
asyncio.run(main())

The code runs successfully but I keep getting this error:

Closing...
Error in watchdog loop
Traceback (most recent call last):
  File "/home/pi/.local/lib/python3.7/site-packages/asyncua/client/client.py", line 520, in _monitor_server_loop
    _ = await self.nodes.server_state.read_value()
  File "/home/pi/.local/lib/python3.7/site-packages/asyncua/common/node.py", line 179, in read_value
    result = await self.read_data_value()
  File "/home/pi/.local/lib/python3.7/site-packages/asyncua/common/node.py", line 190, in read_data_value
    return await self.read_attribute(ua.AttributeIds.Value, None, raise_on_bad_status)
  File "/home/pi/.local/lib/python3.7/site-packages/asyncua/common/node.py", line 304, in read_attribute
    result = await self.session.read(params)
  File "/home/pi/.local/lib/python3.7/site-packages/asyncua/client/ua_client.py", line 397, in read
    data = await self.protocol.send_request(request)
  File "/home/pi/.local/lib/python3.7/site-packages/asyncua/client/ua_client.py", line 160, in send_request
    data = await asyncio.wait_for(self._send_request(request, timeout, message_type), timeout if timeout else None)
  File "/usr/lib/python3.7/asyncio/tasks.py", line 409, in wait_for
    await waiter
concurrent.futures._base.CancelledError
Error while renewing session
Traceback (most recent call last):
  File "/home/pi/.local/lib/python3.7/site-packages/asyncua/client/client.py", line 541, in _renew_channel_loop
    await asyncio.sleep(duration)
  File "/usr/lib/python3.7/asyncio/tasks.py", line 568, in sleep
    return await future
concurrent.futures._base.CancelledError
Disconnected

What can be done to execute the code without this error? Why is this happening?

I tried incorporating different error handlers, but no success. Also when running this python code on windows none of the erorrs are present. I do have a Linux system that I am not able to update which runs python 3.7 (Windows was 3.10). I need to change the code so it runs on the oldest system (Python 3.7).

kirba22
  • 53
  • 4

1 Answers1

3

Asyncua has a background task which is reading a the ServerState value to check if the connection is alive. Maybe the call_method is taking to long and the background call times out. You can higher the intervall for the background task.

client = Client(SERVER_URL, timeout=TMOUT, watchdog_intervall=TMOUT)

The error can be ignored, so I would remove the handle_error call in the finally call, because it should already be handled.

Update: Try to change your code to this, So you only handle the exception if a exception is triggered, also no finaly clause is need with this solution:

try:
  
    # Connect to the server
    client = Client(SERVER_URL, timeout=TMOUT)
    client.set_user(USERNAME)
    client.set_password(PASSWORD)
  
    async with client:
   
        print("Connected")
    
        await client.load_data_type_definitions()
        print("Defs loaded")
                       
        # Call method
 
        print("Before method call")
        
        # Prepare args
        method_type = "WriteTag"
        METHODID, arg1, arg2, arg3, arg4, arg5, arg6 = await prepare_args(method_type);
        
        #WriteTag
        result = await call_method(method_type, client, OBJECTID, METHODID, arg1, arg2, arg3, arg4, arg5, arg6)
        print("Result: ", result)
        
        time.sleep(1)
        
        # Prepare args
        method_type = "ReadTag"
        METHODID, arg1, arg2, arg3, arg4, arg5, arg6 = await prepare_args(method_type);
        
        #ReadTag
        method_type = "ReadTag"
        result = await call_method(method_type, client, OBJECTID, METHODID, arg1, arg2, arg3, arg4, arg5, arg6)
        print("Result: ", result)
        
        
        #print("Output arguments: ", output_args)

except concurrent.futures._base.CancelledError:
    print("Session cancelled")

except Exception as e:
    print("Error: ", e)
    await handle_error()


except KeyboardInterrupt:
    print("Programm stopped by user")
    await handle_error()
Schroeder
  • 749
  • 4
  • 10