Hi,I am using QuickOPC 2018.3, in particular the OPC-UA client functionality through COM from Python, to connect to a Siemens S7 OPC-UA server (using username/password authentication). See below for the code of the client class. I instantiate two such client objects, one of which reads and writes a tag once every 5 seconds, and one which reads a couple of tags (less than 10) once every minute. As you can see, even in case of failure of read or write, I wait 5 seconds before retrying. I am not adjusting any other QuickOPC default settings like timeouts, retry or keep alive.
This code works fine for about 30 to 45 minutes, after which suddenly very many connections are being made (about 12 per second), and eventually causing the Siemens S7 core to crash. I have a snippet of the Siemens OPC-UA server log where you can see this occur between 15:15:49.588 and 16:07:49.737. For some reason I cannot attach it to this message so I uploaded it to wetransfer:
here
. I have confirmed that it is indeed my client creating these connections.
My questions are:-
Is this a known issue with this or later versions of QuickOPC?
- Do you see anything in the way I use QuickOPC which could cause this behaviour?
Any ideas are very welcome. If I can provide additional info please let me know.
Kind regards.
class OPCUAClient:
"""OPC UA Client"""
def __init__(self, server, username=opcua_username, password=opcua_password):
"""Initialize OPC UA client"""
self.server = server
self.client = None
self.init_client(username, password)
def init_client(self, username=opcua_username, password=opcua_password):
"""Initialize the OPC-UA client"""
self.client = win32com.client.Dispatch("OpcLabs.EasyOpc.UA.EasyUAClient")
if username and password:
self.client.Isolated = True
identity = self.client.IsolatedParameters.SessionParameters.UserIdentity
identity.UserNameTokenInfo.UserName = username
identity.UserNameTokenInfo.password = password
def convert_to_tag(self, plant, item):
"""Convert plant name and OPC item to tag string"""
tag = C.TAG_PREFIX
if plant:
tag += "%s_" % C.PLANT_TAGS.get(plant)
tag += "%s" % item
return str(tag)
@retry(stop_max_attempt_number=3, wait_fixed=5000)
def read(self, name, tag_item):
"""Read OPC tags from server."""
if not self.client:
self.init_client()
tag_name = self.convert_to_tag(name, tag_item)
try:
value = self.client.ReadValue(self.server, tag_name)
return value
except Exception as ex:
ex.message = "Failed to read OPC tag '%s': %s" % (tag_name, ex)
raise
@retry(stop_max_attempt_number=3, wait_fixed=5000)
def write(self, name, tag_item, tag_value):
"""Write value to OPC tag"""
if not self.client:
self.init_client()
tag_name = self.convert_to_tag(name, tag_item)
try:
self.client.WriteValue(self.server, tag_name, tag_value)
except Exception as ex:
ex.message = "Failed to write OPC value for '%s': %s" % (tag_name, ex)
raise