Skip to content

Commit

Permalink
Fixed stack overflow error for overloaded __gettattr__ proxy method, …
Browse files Browse the repository at this point in the history
…removed unnecessary autoconnect methods and added tests for timeout mechanic for PCIC and RPC client
  • Loading branch information
Galoshi committed Apr 4, 2024
1 parent 3f24e51 commit a75903d
Show file tree
Hide file tree
Showing 16 changed files with 188 additions and 259 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

# Cache data unittests
/.pytest_cache
/.coverage

# proto folders/scripts
/examples_development
23 changes: 8 additions & 15 deletions source/device/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@
class O2x5xxDevice(O2x5xxPCICDevice):
def __init__(self, address="192.168.0.69", port=50010, autoconnect=True, timeout=SOCKET_TIMEOUT):
self._address = address
self._port = port
self._autoconnect = autoconnect
self._device_timeout = timeout
self._timeout = timeout
self._rpc = None
if autoconnect:
self._rpc = O2x5xxRPCDevice(address=self._address, timeout=self._device_timeout)
self._rpc = O2x5xxRPCDevice(address=address, timeout=timeout)
super(O2x5xxPCICDevice, self).__init__(address=address, port=port, autoconnect=autoconnect, timeout=timeout)

def __enter__(self):
Expand All @@ -25,22 +22,18 @@ def __exit__(self, exc_type, exc_val, exc_tb):
@property
def rpc(self) -> O2x5xxRPCDevice:
if not self._rpc:
self._rpc = O2x5xxRPCDevice(address=self._address, timeout=self._device_timeout)
self._rpc = O2x5xxRPCDevice(address=self._address, timeout=self._timeout)
return self._rpc


class O2x5xxDeviceV2(object):
def __init__(self, address="192.168.0.69", port=50010, autoconnect=True, timeout=SOCKET_TIMEOUT):
self._address = address
self._port = port
self.__timeout = timeout
self._timeout = timeout
self._autoconnect = autoconnect
self._pcic = None
self._rpc = None
if autoconnect:
self._pcic = O2x5xxPCICDevice(address=self._address, port=self._port,
autoconnect=self._autoconnect, timeout=self.__timeout)
self._rpc = O2x5xxRPCDevice(address=self._address)
self._rpc = O2x5xxRPCDevice(address=address, timeout=timeout)
self._pcic = O2x5xxPCICDevice(address=address, port=port, autoconnect=autoconnect, timeout=timeout)

def __enter__(self):
return self
Expand All @@ -56,12 +49,12 @@ def __exit__(self, exc_type, exc_val, exc_tb):
@property
def rpc(self) -> O2x5xxRPCDevice:
if not self._rpc:
self._rpc = O2x5xxRPCDevice(address=self._address, timeout=self.__timeout)
self._rpc = O2x5xxRPCDevice(address=self._address, timeout=self._timeout)
return self._rpc

@property
def pcic(self) -> O2x5xxPCICDevice:
if not self._pcic:
self._pcic = O2x5xxPCICDevice(address=self._address, port=self._port,
autoconnect=self._autoconnect, timeout=self.__timeout)
autoconnect=self._autoconnect, timeout=self._timeout)
return self._pcic
18 changes: 9 additions & 9 deletions source/pcic/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,29 @@ def connect(self):
:return: None
"""
if not self.connected:
self.pcicSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.pcicSocket.settimeout(self.timeout)
self.pcicSocket.connect((self.address, self.port))
self.pcicSocket = socket.create_connection((self.address, self.port), timeout=self.timeout)
self.connected = True

@property
def timeout(self):
"""
Get the current timeout value on blocking socket operations as a floating point number expressing seconds.
Get the current timeout value on blocking socket operations. If no socket instance available
the preset timeout value will be returned.
:return: (float) socket timeout in seconds
"""
if self.pcicSocket:
return self.pcicSocket.gettimeout()
return self._timeout

@timeout.setter
def timeout(self, value):
"""
Set a timeout on blocking socket operations. The value argument can be a non-negative floating point number
expressing seconds, or None. If a non-zero value is given, subsequent socket operations will raise a timeout
exception if the timeout period value has elapsed before the operation has completed. If zero is given,
the socket is put in non-blocking mode. If None is given, the socket is put in blocking mode.
Set a timeout on blocking socket operations. If a non-zero value is given, subsequent socket operations will
raise a timeout exception if the timeout period value has elapsed before the operation has completed.
If zero is given, the socket is put in non-blocking mode. If None is given, the socket is put in blocking mode.
:param value: (float) in seconds.
:param value: (float) non-negative socket timeout in seconds
:return: None
"""
self._timeout = value
Expand Down
18 changes: 0 additions & 18 deletions source/pcic/utils.py

This file was deleted.

64 changes: 27 additions & 37 deletions source/rpc/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def getAllParameters(self):
:return: (dict) name contains parameter-name, value the stringified parameter-value
"""
result = self._applicationProxy.getAllParameters()
result = self._applicationProxy.proxy.getAllParameters()
return result

def getParameter(self, value):
Expand All @@ -49,7 +49,7 @@ def getParameter(self, value):
:param value: (str) parameter name
:return: (str)
"""
result = self._applicationProxy.getParameter(value)
result = self._applicationProxy.proxy.getParameter(value)
return result

def getAllParameterLimits(self) -> dict:
Expand All @@ -60,7 +60,7 @@ def getAllParameterLimits(self) -> dict:
:return: (dict)
"""
result = self._applicationProxy.getAllParameterLimits()
result = self._applicationProxy.proxy.getAllParameterLimits()
return result

@property
Expand Down Expand Up @@ -94,7 +94,7 @@ def Name(self, value: str) -> None:
max_chars = 64
if value.__len__() > max_chars:
raise ValueError("Max. {} characters".format(max_chars))
self._applicationProxy.setParameter("Name", value)
self._applicationProxy.proxy.setParameter("Name", value)
self.waitForConfigurationDone()

@property
Expand All @@ -118,7 +118,7 @@ def Description(self, value: str) -> None:
max_chars = 500
if value.__len__() > 500:
raise ValueError("Max. {} characters".format(max_chars))
self._applicationProxy.setParameter("Description", value)
self._applicationProxy.proxy.setParameter("Description", value)
self.waitForConfigurationDone()

@property
Expand Down Expand Up @@ -159,7 +159,7 @@ def TriggerMode(self, value: int) -> None:
if value not in range(int(limits["min"]), int(limits["max"]), 1):
raise ValueError("RPC Trigger value not available. Available range: {}\n"
"For more help take a look on the docstring documentation.".format(limits))
self._applicationProxy.setParameter("TriggerMode", value)
self._applicationProxy.proxy.setParameter("TriggerMode", value)
self.waitForConfigurationDone()

@property
Expand All @@ -184,7 +184,7 @@ def FrameRate(self, value: float) -> None:
if not float(limits["min"]) <= float(value) <= float(limits["max"]):
raise ValueError("FrameRate value not available. Available range: {}"
.format(self.getAllParameterLimits()["FrameRate"]))
self._applicationProxy.setParameter("FrameRate", value)
self._applicationProxy.proxy.setParameter("FrameRate", value)
self.waitForConfigurationDone()

@property
Expand Down Expand Up @@ -248,7 +248,7 @@ def getValueErrorListNumber():
lower=width_lower, upper=width_upper))
if valueErrorList:
raise ValueError("".join(valueErrorList))
self._applicationProxy.setParameter("HWROI", json.dumps(value))
self._applicationProxy.proxy.setParameter("HWROI", json.dumps(value))
self.waitForConfigurationDone()

@property
Expand All @@ -258,7 +258,7 @@ def Rotate180Degree(self) -> bool:
:return: (bool) True / False
"""
result = self._applicationProxy.getParameter("Rotate180Degree")
result = self._applicationProxy.proxy.getParameter("Rotate180Degree")
if result == "false":
return False
return True
Expand All @@ -271,7 +271,7 @@ def Rotate180Degree(self, value: bool) -> None:
:param value: (bool) True / False
:return: None
"""
self._applicationProxy.setParameter("Rotate180Degree", value)
self._applicationProxy.proxy.setParameter("Rotate180Degree", value)
self.waitForConfigurationDone()

@property
Expand All @@ -281,7 +281,7 @@ def FocusDistance(self) -> float:
:return: (float) current focus distance in meter
"""
result = float(self._applicationProxy.getParameter("FocusDistance"))
result = float(self._applicationProxy.proxy.getParameter("FocusDistance"))
return result

@FocusDistance.setter
Expand All @@ -296,7 +296,7 @@ def FocusDistance(self, value: float) -> None:
if not float(limits["min"]) <= float(value) <= float(limits["max"]):
raise ValueError("FocusDistance value not available. Available range: {}"
.format(self.getAllParameterLimits()["FocusDistance"]))
self._applicationProxy.setParameter("FocusDistance", value)
self._applicationProxy.proxy.setParameter("FocusDistance", value)
# TODO: Wird hier geblockt? Wird der Focus Distance direkt nach dem setzen angefahren?
# Edit: Kein Error, jedoch sind die Bilder unscharf wenn direkt danach das Bild angefordert wird: Fokus wird während requestImage im PCIC noch angefahren!
self.waitForConfigurationDone()
Expand All @@ -309,7 +309,7 @@ def ImageEvaluationOrder(self) -> str:
:return: (str)
"""
result = self._applicationProxy.getParameter("ImageEvaluationOrder")
result = self._applicationProxy.proxy.getParameter("ImageEvaluationOrder")
return result

@ImageEvaluationOrder.setter
Expand All @@ -321,7 +321,7 @@ def ImageEvaluationOrder(self, value: list) -> None:
:param value: (list) a whitespace separated list of ImagerConfig ids
:return: None
"""
self._applicationProxy.setParameter("ImageEvaluationOrder", value)
self._applicationProxy.proxy.setParameter("ImageEvaluationOrder", value)
self.waitForConfigurationDone()

@property
Expand All @@ -330,7 +330,7 @@ def PcicTcpResultSchema(self) -> str:
The PCIC TCP/IP Schema defines which result-data will be sent via TCP/IP.
:return: (str) pcic tcp/ip schema config
"""
return self._applicationProxy.getParameter("PcicTcpResultSchema")
return self._applicationProxy.proxy.getParameter("PcicTcpResultSchema")

@PcicTcpResultSchema.setter
def PcicTcpResultSchema(self, schema: str) -> None:
Expand All @@ -339,7 +339,7 @@ def PcicTcpResultSchema(self, schema: str) -> None:
:param schema: (str) pcic tcp/ip schema config
:return: None
"""
self._applicationProxy.setParameter("PcicTcpResultSchema", schema)
self._applicationProxy.proxy.setParameter("PcicTcpResultSchema", schema)
validation = self.validate()
if validation:
warnings.warn(str(validation), UserWarning)
Expand All @@ -352,7 +352,7 @@ def LogicGraph(self) -> str:
JSON string describing a flow-graph which allows to program the logic between model-results and output-pins.
:return: (str) JSON string flow-graph of Logic Layer
"""
return self._applicationProxy.getParameter("LogicGraph")
return self._applicationProxy.proxy.getParameter("LogicGraph")

@LogicGraph.setter
def LogicGraph(self, schema: str) -> None:
Expand All @@ -361,7 +361,7 @@ def LogicGraph(self, schema: str) -> None:
:param schema: (str) JSON string flow-graph of Logic Layer
:return: None
"""
self._applicationProxy.setParameter("LogicGraph", schema)
self._applicationProxy.proxy.setParameter("LogicGraph", schema)
validation = self.validate()
if validation:
warnings.warn(str(validation), UserWarning)
Expand Down Expand Up @@ -440,7 +440,7 @@ def save(self) -> None:
:return: None
"""
self._applicationProxy.save()
self._applicationProxy.proxy.save()
self.waitForConfigurationDone()

def validate(self) -> list:
Expand All @@ -449,7 +449,7 @@ def validate(self) -> list:
:return: Array of fault-structs (Id: int, Text: string)
"""
result = self._applicationProxy.validate()
result = self._applicationProxy.proxy.validate()
return result

def getImagerConfigList(self) -> list:
Expand All @@ -458,7 +458,7 @@ def getImagerConfigList(self) -> list:
:return: (list) Array of strings
"""
result = self._applicationProxy.getImagerConfigList()
result = self._applicationProxy.proxy.getImagerConfigList()
return result

def availableImagerConfigTypes(self) -> list:
Expand All @@ -467,7 +467,7 @@ def availableImagerConfigTypes(self) -> list:
:return: (list) Array of strings
"""
result = self._applicationProxy.availableImagerConfigTypes()
result = self._applicationProxy.proxy.availableImagerConfigTypes()
return result

def createImagerConfig(self, imagerType='normal', addToEval=True):
Expand All @@ -479,7 +479,7 @@ def createImagerConfig(self, imagerType='normal', addToEval=True):
not be activated for the image acquisition/evaluation run
:return: (int) ID of new image-config
"""
imagerIndex = self._applicationProxy.createImagerConfig(imagerType)
imagerIndex = self._applicationProxy.proxy.createImagerConfig(imagerType)
if addToEval:
imageEvalOrder = self.ImageEvaluationOrder
imageEvalOrder += "{} ".format(imagerIndex)
Expand All @@ -494,7 +494,7 @@ def copyImagerConfig(self, imagerIndex: int) -> int:
:param imagerIndex: (int) ID of other Imager config
:return: (int) ID of new image-config
"""
imagerIndex = self._applicationProxy.copyImagerConfig(imagerIndex)
imagerIndex = self._applicationProxy.proxy.copyImagerConfig(imagerIndex)
self.waitForConfigurationDone()
return imagerIndex

Expand All @@ -506,7 +506,7 @@ def deleteImagerConfig(self, imagerIndex: int) -> None:
:param imagerIndex: (int) ID of image-config that should be removed
:return: None
"""
self._applicationProxy.deleteImagerConfig(imagerIndex)
self._applicationProxy.proxy.deleteImagerConfig(imagerIndex)
self.waitForConfigurationDone()

def isConfigurationDone(self) -> bool:
Expand All @@ -516,7 +516,7 @@ def isConfigurationDone(self) -> bool:
:return: (bool) True or False
"""
result = self._applicationProxy.isConfigurationDone()
result = self._applicationProxy.proxy.isConfigurationDone()
return result

def waitForConfigurationDone(self):
Expand All @@ -527,14 +527,4 @@ def waitForConfigurationDone(self):
:return: None
"""
self._applicationProxy.waitForConfigurationDone()

def __getattr__(self, name):
"""Pass given name to the actual xmlrpc.client.ServerProxy.
Args:
name (str): name of attribute
Returns:
Attribute of xmlrpc.client.ServerProxy
"""
return self._editProxy.__getattr__(name)
self._applicationProxy.proxy.waitForConfigurationDone()
Loading

0 comments on commit a75903d

Please sign in to comment.