diff --git a/RCUSCC/RCUSCC/RCUSCC.py b/RCUSCC/RCUSCC/RCUSCC.py index 70775db826b5c85045e451c7a46f80f4214d4c77..50bd74d45c40de049b8df2e5b200d5fcf06456a3 100644 --- a/RCUSCC/RCUSCC/RCUSCC.py +++ b/RCUSCC/RCUSCC/RCUSCC.py @@ -26,6 +26,29 @@ import sys import opcua import traceback import numpy + +from functools import wraps +import socket + +def fault_on_opcua_error(func): + """ + Wrapper to catch exceptions generated by the OPC-UA connection. + + Sets the device in a FAULT state if that occurs. + """ + + @wraps(func) + def opcua_error_wrapper(self, *args, **kwargs): + try: + return func(self, *args, **kwargs) + except socket.error as e: + self.error_stream("Communication with the OPC-UA server %s:%d failed. Trace: %s" % (self.OPC_Server_Name, self.OPC_Server_Port, traceback.format_exc())) + self.set_state(DevState.FAULT) + self._disconnect() + + return None + + return opcua_error_wrapper # PROTECTED REGION END # // RCUSCC.additionnal_import __all__ = ["RCUSCC", "main"] @@ -136,6 +159,7 @@ class RCUSCC(Device): # General methods # --------------- + def init_device(self): """Initialises the attributes and properties of the RCUSCC.""" Device.init_device(self) @@ -253,6 +277,14 @@ class RCUSCC(Device): # PROTECTED REGION ID(RCUSCC.always_executed_hook) ENABLED START # # PROTECTED REGION END # // RCUSCC.always_executed_hook + def _disconnect(self): + try: + if self.client is not None: + self.client.close_session() + self.client.close_secure_channel() + except Exception as e: + self.warn_stream("Disconnect from OPC-UA server %s:%d failed. Trace: %s" % (self.OPC_Server_Name, self.OPC_Server_Port, traceback.format_exc())) + def delete_device(self): """Hook to delete resources allocated in init_device. @@ -263,15 +295,14 @@ class RCUSCC(Device): # PROTECTED REGION ID(RCUSCC.delete_device) ENABLED START # self.debug_stream("Shutting down...") self.set_state(DevState.OFF) - - if self.client is not None: - self.client.close_session() - self.client.close_secure_channel() + self._disconnect() self.debug_stream("Shut down. Good bye.") # PROTECTED REGION END # // RCUSCC.delete_device # ------------------ # Attributes methods # ------------------ + + @fault_on_opcua_error def read_Attenuator_R(self): # PROTECTED REGION ID(RCUSCC.Attenuator_R_read) ENABLED START # """Return the Attenuator_R attribute.""" @@ -279,6 +310,7 @@ class RCUSCC(Device): return self._Attenuator_R # PROTECTED REGION END # // RCUSCC.Attenuator_R_read + @fault_on_opcua_error def read_Attenuator_RW(self): # PROTECTED REGION ID(RCUSCC.Attenuator_RW_read) ENABLED START # """Return the Attenuator_R attribute.""" @@ -286,6 +318,7 @@ class RCUSCC(Device): return self._Attenuator_RW # PROTECTED REGION END # // RCUSCC.Attenuator_RW_read + @fault_on_opcua_error def write_Attenuator_RW(self, value): # PROTECTED REGION ID(RCUSCC.Attenuator_RW_write) ENABLED START # """Set the Attenuator_RW attribute.""" @@ -295,6 +328,7 @@ class RCUSCC(Device): self._Attenuator_RW = value # PROTECTED REGION END # // RCUSCC.Attenuator_RW_write + @fault_on_opcua_error def read_Band_R(self): # PROTECTED REGION ID(RCUSCC.Band_R_read) ENABLED START # """Return the Band_R attribute.""" @@ -302,6 +336,7 @@ class RCUSCC(Device): return self._Band_R # PROTECTED REGION END # // RCUSCC.Band_R_read + @fault_on_opcua_error def read_Band_RW(self): # PROTECTED REGION ID(RCUSCC.Band_RW_read) ENABLED START # """Return the Band_R attribute.""" @@ -309,6 +344,7 @@ class RCUSCC(Device): return self._Band_RW # PROTECTED REGION END # // RCUSCC.Band_RW_read + @fault_on_opcua_error def write_Band_RW(self, value): # PROTECTED REGION ID(RCUSCC.Band_RW_write) ENABLED START # """Set the Band_RW attribute.""" @@ -318,6 +354,7 @@ class RCUSCC(Device): self._Band_RW = value # PROTECTED REGION END # // RCUSCC.Band_RW_write + @fault_on_opcua_error def read_Dither_Frequency_R(self): # PROTECTED REGION ID(RCUSCC.Dither_Frequency_R_read) ENABLED START # """Return the Dither_Frequency_R attribute.""" @@ -325,6 +362,7 @@ class RCUSCC(Device): return self._Dither_Frequency_R # PROTECTED REGION END # // RCUSCC.Dither_Frequency_R_read + @fault_on_opcua_error def read_Dither_Frequency_RW(self): # PROTECTED REGION ID(RCUSCC.Dither_Frequency_RW_read) ENABLED START # """Return the Dither_Frequency_R attribute.""" @@ -332,6 +370,7 @@ class RCUSCC(Device): return self._Dither_Frequency_RW # PROTECTED REGION END # // RCUSCC.Dither_Frequency_RW_read + @fault_on_opcua_error def write_Dither_Frequency_RW(self, value): # PROTECTED REGION ID(RCUSCC.Dither_Frequency_RW_write) ENABLED START # """Set the Dither_Frequency_RW attribute.""" @@ -340,6 +379,7 @@ class RCUSCC(Device): self._Dither_Frequency_RW = value # PROTECTED REGION END # // RCUSCC.Dither_Frequency_RW_write + @fault_on_opcua_error def read_LED_R(self): # PROTECTED REGION ID(RCUSCC.LED_R_read) ENABLED START # """Return the LED_R attribute.""" @@ -347,6 +387,7 @@ class RCUSCC(Device): return self._LED_R # PROTECTED REGION END # // RCUSCC.LED_R_read + @fault_on_opcua_error def read_LED_RW(self): # PROTECTED REGION ID(RCUSCC.LED_RW_read) ENABLED START # """Return the LED_RW attribute.""" @@ -354,6 +395,7 @@ class RCUSCC(Device): return self._LED_RW # PROTECTED REGION END # // RCUSCC.LED_RW_read + @fault_on_opcua_error def write_LED_RW(self, value): # PROTECTED REGION ID(RCUSCC.LED_RW_write) ENABLED START # """Set the LED_RW attribute.""" @@ -361,6 +403,7 @@ class RCUSCC(Device): self._LED_RW = value # PROTECTED REGION END # // RCUSCC.LED_RW_write + @fault_on_opcua_error def read_Pwr_dig_R(self): # PROTECTED REGION ID(RCUSCC.Pwr_dig_R_read) ENABLED START # """Return the Pwr_dig_R attribute.""" @@ -368,6 +411,7 @@ class RCUSCC(Device): return self._Pwr_dig_R # PROTECTED REGION END # // RCUSCC.Pwr_dig_R_read + @fault_on_opcua_error def read_Temperature_R(self): # PROTECTED REGION ID(RCUSCC.Temperature_R_read) ENABLED START # """Return the Temperature_R attribute.""" @@ -375,6 +419,7 @@ class RCUSCC(Device): return self._Temperature_R # PROTECTED REGION END # // RCUSCC.Temperature_R_read + @fault_on_opcua_error def read_CLK_PLL_locked_R(self): # PROTECTED REGION ID(RCUSCC.CLK_PLL_locked_R_read) ENABLED START # """Return the CLK_PLL_locked_R attribute."""