python - 连接和断开连接时 OPC UA 客户端 python asyncua 错误

标签 python async-await python-asyncio opc-ua

我有以下代码,它连接到 OPC UA 服务器并调用 2 个方法:

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())

代码运行成功,但我不断收到此错误:

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

如何执行代码而不出现此错误?为什么会发生这种情况?

我尝试合并不同的错误处理程序,但没有成功。此外,当在 Windows 上运行此 python 代码时,不存在任何错误。我确实有一个无法更新的 Linux 系统,它运行 python 3.7(Windows 是 3.10)。我需要更改代码,以便它可以在最旧的系统(Python 3.7)上运行。

最佳答案

Asyncua 有一个后台任务,它正在读取 ServerState 值以检查连接是否处于事件状态。也许 call_method 花费的时间太长并且后台调用超时。您可以提高后台任务的间隔。

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

该错误可以被忽略,因此我会在finally调用中删除handle_error调用,因为它应该已经被处理了。

更新: 尝试将您的代码更改为此,这样您只需在触发异常时处理异常,并且此解决方案也不需要finaly子句:

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()

关于python - 连接和断开连接时 OPC UA 客户端 python asyncua 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76227798/

相关文章:

python - 如何删除 django 关系中的对象(同时保留所有相关对象)?

javascript - 如何将多个分隔符传递到 mongodb 查询中的 $split 管道函数中?

Python 异步 : what satisfies `isinstance( (generator-based coroutune), ???) == True` ?

javascript - 我可以在异步函数中抛出错误吗?

python - 除了 asyncio.Queue.put 之外,都错了?

python - 在 Tensorflow 中,为什么只有在准备导出模型时才为其添加激活函数?

python - 无法在正则表达式中检测到 '-' 字符

c# - .NET 中 yield 和 await 如何实现控制流?

Python:如果可用,则使用 epoll 的库,回退选择

python - 将 pytest fixture 与 asynctest 一起使用