Loading csp-lmc-common/csp_lmc_common/utils/decorators.py +92 −66 Original line number Diff line number Diff line Loading @@ -5,20 +5,24 @@ import tango from .cspcommons import AdminMode, ObsState, CmdExecState import functools class AdminModeCheck(object): """ Class designed to be a decorator for the CspMaster methods. It checks the adminMode attribute value: if not ONLINE or MAINTENANCE it throws an exception. """ def __init__(self, cmd_to_execute): self._cmd_to_execute = cmd_to_execute def __call__(self, f): @functools.wraps(f) def admin_mode_check(*args, **kwargs): # get the device instance dev_instance = args[0] dev_instance.logger.debug("AdminModeCheck command to execute:", self._cmd_to_execute) dev_instance.logger.debug( "AdminModeCheck command to execute: {}".format(self._cmd_to_execute)) # Check the AdminMode value: the command is callable only if the # the administration mode is ONLINE or MAINTENACE Loading @@ -27,7 +31,8 @@ class AdminModeCheck(object): # DISABLE # Add only a check on State value to log a warning message if it # is different from DISABLE msg_args = (self._cmd_to_execute, dev_instance.get_state(), AdminMode(dev_instance._admin_mode).name) msg_args = (self._cmd_to_execute, dev_instance.get_state( ), AdminMode(dev_instance._admin_mode).name) if dev_instance.get_state() != tango.DevState.DISABLE: dev_instance.logger.warn("Command {}: incoherent device State {} " " with adminMode {}".format(*msg_args)) Loading @@ -41,6 +46,7 @@ class AdminModeCheck(object): return f(*args, **kwargs) return admin_mode_check VALID_OBS_STATE = {'abort': [ObsState.CONFIGURING, ObsState.SCANNING], 'reset': [ObsState.ABORTED], 'configscan': [ObsState.IDLE, ObsState.READY], Loading @@ -50,14 +56,18 @@ VALID_OBS_STATE = {'abort' : [ObsState.CONFIGURING, ObsState.SCANNING], 'addresources': [ObsState.IDLE], 'removeresources': [ObsState.IDLE] } class ObsStateCheck(object): """ Class designed to be a decorator for the CspMaster methods. It checks the obsMode attribute value """ def __init__(self, args=False, kwargs=False): self._args = args self._kwargs = kwargs def __call__(self, f): @functools.wraps(f) def obs_state_check(*args, **kwargs): Loading @@ -79,6 +89,7 @@ class ObsStateCheck(object): return f(*args, **kwargs) return obs_state_check class CmdInputArgsCheck(object): """ Class designed to be a decorator for the CspMaster methods. Loading @@ -89,6 +100,7 @@ class CmdInputArgsCheck(object): The *decorator function* accepts some parameters as input to customize its functionality """ def __init__(self, *args, **kwargs): # store the decorators parameters: # args: the list of sub-element attributes to subscribe, to track the Loading @@ -98,6 +110,7 @@ class CmdInputArgsCheck(object): # self._args = args self._kwargs = kwargs def __call__(self, f): @functools.wraps(f) def input_args_check(*args, **kwargs): Loading Loading @@ -134,7 +147,8 @@ class CmdInputArgsCheck(object): # too many devices specified-> log the warning but go on # with command execution dev_instance.logger.warn("Too many input parameters") dev_instance.logger.debug("CmdInputArgsCheck: devices {} to check:".format(device_list)) dev_instance.logger.debug( "CmdInputArgsCheck: devices {} to check:".format(device_list)) # If a sub-element device is already executing a power command, an exception is # thown only when the requested command is different from the one # already running (power commands have to be executed sequentially). Loading @@ -147,7 +161,8 @@ class CmdInputArgsCheck(object): # if a command is running, check if its the requested one if len(list_of_running_cmd) > 1: # should not happen!! throw an exception err_msg = "{} power commands are running. Something strange!".format(len(list_of_running_cmd)) err_msg = "{} power commands are running. Something strange!".format( len(list_of_running_cmd)) tango.Except.throw_exception("Command failure", err_msg, "CmdInputArgsCheck decorator", Loading @@ -169,7 +184,8 @@ class CmdInputArgsCheck(object): # check for devices that are not ONLINE/MAINTENANCE device_to_remove = [] for device in device_list: dev_instance.logger.debug("CmdInputArgsCheack-processing device:", device) dev_instance.logger.debug( "CmdInputArgsCheack-processing device:", device) # if the sub-element device server is not running or the adminMode # attribute is not ONLINE or MAINTENANCE: # - schedule the device for removing from the input arg list Loading @@ -187,7 +203,8 @@ class CmdInputArgsCheck(object): "CmdInputArgsCheck decorator", tango.ErrSeverity.ERR) device_to_remove.append(device) dev_instance.logger.debug("Devices to remove from the list:", device_to_remove) dev_instance.logger.debug( "Devices to remove from the list:{}".format(device_to_remove)) continue for device in device_to_remove: device_list.remove(device) Loading Loading @@ -216,7 +233,8 @@ class CmdInputArgsCheck(object): # (not tango.DevFailed) #dev_instance._se_cmd_duration_expected[device][cmd_to_exec] = device_proxy.onCmdDurationExpected # read_Attribute returns a DeviceAttribute object device_attr = device_proxy.read_attribute(cmd_time_attr_name) device_attr = device_proxy.read_attribute( cmd_time_attr_name) dev_instance._se_cmd_duration_expected[device][cmd_to_exec] = device_attr.value except tango.DevFailed as tango_err: # we get here if the attribute is not implemented Loading @@ -226,7 +244,8 @@ class CmdInputArgsCheck(object): if dev_instance._se_event_id[device][attr.lower()] == 0: evt_id = device_proxy.subscribe_event(attr, tango.EventType.CHANGE_EVENT, dev_instance._attributes_change_evt_cb, stateless=False) dev_instance._se_event_id[device][attr.lower()] = evt_id dev_instance._se_event_id[device][attr.lower( )] = evt_id except tango.DevFailed as tango_err: dev_instance.logger.info(tango_err.args[0].desc) # evaluate the total timeout value to execute the whole command Loading @@ -237,10 +256,12 @@ class CmdInputArgsCheck(object): # use the greatest value for the onCommand duration expected. if command_timeout > dev_instance._cmd_duration_expected[cmd_to_exec]: dev_instance._cmd_duration_expected[cmd_to_exec] = command_timeout dev_instance.logger.info("Modified the {} command Duration Expected value!!".format(cmd_to_exec)) dev_instance.logger.info( "Modified the {} command Duration Expected value!!".format(cmd_to_exec)) return f(*args, **kwargs) return input_args_check class SubarrayRejectCmd(object): """ Class designed to be a decorator for the CspSubarray methods. Loading @@ -250,6 +271,7 @@ class SubarrayRejectCmd(object): The *decorator function* accepts some parameters as input to customize its functionality """ def __init__(self, *args, **kwargs): # store the decorators parameters: # args: the list of command to reject Loading @@ -257,6 +279,7 @@ class SubarrayRejectCmd(object): self._args = args self._kwargs = kwargs print(args) def __call__(self, f): @functools.wraps(f) def input_args_check(*args, **kwargs): Loading @@ -264,7 +287,8 @@ class SubarrayRejectCmd(object): dev_instance = args[0] cmd_to_exec = f.__name__ commands_to_reject = self._args dev_instance.logger.debug("SubarrayRejectCmd: function {}".format(f.__name__)) dev_instance.logger.debug( "SubarrayRejectCmd: function {}".format(f.__name__)) # If a sub-array is executing an AddXXX (RemoveXX) command, an exception is # thown only when the requested command is RemoveXXX (AddXXX)remove/add resources or ConfigureScan. # If the requested command is already running, the decorator returns. Loading @@ -287,10 +311,12 @@ class SubarrayRejectCmd(object): tango.ErrSeverity.ERR) # reset alarm/timeout condition if dev_instance._alarm_raised: dev_instance.logger.info("A previous alarm condition is present") dev_instance.logger.info( "A previous alarm condition is present") dev_instance._alarm_raised = False if dev_instance._timeout_expired: dev_instance.logger.info("A previous timeout condition is present") dev_instance.logger.info( "A previous timeout condition is present") dev_instance._timeout_expired = False # TODO: how check if the alarm condition has been reset by AlarmHandler? return f(*args, **kwargs) Loading Loading
csp-lmc-common/csp_lmc_common/utils/decorators.py +92 −66 Original line number Diff line number Diff line Loading @@ -5,20 +5,24 @@ import tango from .cspcommons import AdminMode, ObsState, CmdExecState import functools class AdminModeCheck(object): """ Class designed to be a decorator for the CspMaster methods. It checks the adminMode attribute value: if not ONLINE or MAINTENANCE it throws an exception. """ def __init__(self, cmd_to_execute): self._cmd_to_execute = cmd_to_execute def __call__(self, f): @functools.wraps(f) def admin_mode_check(*args, **kwargs): # get the device instance dev_instance = args[0] dev_instance.logger.debug("AdminModeCheck command to execute:", self._cmd_to_execute) dev_instance.logger.debug( "AdminModeCheck command to execute: {}".format(self._cmd_to_execute)) # Check the AdminMode value: the command is callable only if the # the administration mode is ONLINE or MAINTENACE Loading @@ -27,7 +31,8 @@ class AdminModeCheck(object): # DISABLE # Add only a check on State value to log a warning message if it # is different from DISABLE msg_args = (self._cmd_to_execute, dev_instance.get_state(), AdminMode(dev_instance._admin_mode).name) msg_args = (self._cmd_to_execute, dev_instance.get_state( ), AdminMode(dev_instance._admin_mode).name) if dev_instance.get_state() != tango.DevState.DISABLE: dev_instance.logger.warn("Command {}: incoherent device State {} " " with adminMode {}".format(*msg_args)) Loading @@ -41,6 +46,7 @@ class AdminModeCheck(object): return f(*args, **kwargs) return admin_mode_check VALID_OBS_STATE = {'abort': [ObsState.CONFIGURING, ObsState.SCANNING], 'reset': [ObsState.ABORTED], 'configscan': [ObsState.IDLE, ObsState.READY], Loading @@ -50,14 +56,18 @@ VALID_OBS_STATE = {'abort' : [ObsState.CONFIGURING, ObsState.SCANNING], 'addresources': [ObsState.IDLE], 'removeresources': [ObsState.IDLE] } class ObsStateCheck(object): """ Class designed to be a decorator for the CspMaster methods. It checks the obsMode attribute value """ def __init__(self, args=False, kwargs=False): self._args = args self._kwargs = kwargs def __call__(self, f): @functools.wraps(f) def obs_state_check(*args, **kwargs): Loading @@ -79,6 +89,7 @@ class ObsStateCheck(object): return f(*args, **kwargs) return obs_state_check class CmdInputArgsCheck(object): """ Class designed to be a decorator for the CspMaster methods. Loading @@ -89,6 +100,7 @@ class CmdInputArgsCheck(object): The *decorator function* accepts some parameters as input to customize its functionality """ def __init__(self, *args, **kwargs): # store the decorators parameters: # args: the list of sub-element attributes to subscribe, to track the Loading @@ -98,6 +110,7 @@ class CmdInputArgsCheck(object): # self._args = args self._kwargs = kwargs def __call__(self, f): @functools.wraps(f) def input_args_check(*args, **kwargs): Loading Loading @@ -134,7 +147,8 @@ class CmdInputArgsCheck(object): # too many devices specified-> log the warning but go on # with command execution dev_instance.logger.warn("Too many input parameters") dev_instance.logger.debug("CmdInputArgsCheck: devices {} to check:".format(device_list)) dev_instance.logger.debug( "CmdInputArgsCheck: devices {} to check:".format(device_list)) # If a sub-element device is already executing a power command, an exception is # thown only when the requested command is different from the one # already running (power commands have to be executed sequentially). Loading @@ -147,7 +161,8 @@ class CmdInputArgsCheck(object): # if a command is running, check if its the requested one if len(list_of_running_cmd) > 1: # should not happen!! throw an exception err_msg = "{} power commands are running. Something strange!".format(len(list_of_running_cmd)) err_msg = "{} power commands are running. Something strange!".format( len(list_of_running_cmd)) tango.Except.throw_exception("Command failure", err_msg, "CmdInputArgsCheck decorator", Loading @@ -169,7 +184,8 @@ class CmdInputArgsCheck(object): # check for devices that are not ONLINE/MAINTENANCE device_to_remove = [] for device in device_list: dev_instance.logger.debug("CmdInputArgsCheack-processing device:", device) dev_instance.logger.debug( "CmdInputArgsCheack-processing device:", device) # if the sub-element device server is not running or the adminMode # attribute is not ONLINE or MAINTENANCE: # - schedule the device for removing from the input arg list Loading @@ -187,7 +203,8 @@ class CmdInputArgsCheck(object): "CmdInputArgsCheck decorator", tango.ErrSeverity.ERR) device_to_remove.append(device) dev_instance.logger.debug("Devices to remove from the list:", device_to_remove) dev_instance.logger.debug( "Devices to remove from the list:{}".format(device_to_remove)) continue for device in device_to_remove: device_list.remove(device) Loading Loading @@ -216,7 +233,8 @@ class CmdInputArgsCheck(object): # (not tango.DevFailed) #dev_instance._se_cmd_duration_expected[device][cmd_to_exec] = device_proxy.onCmdDurationExpected # read_Attribute returns a DeviceAttribute object device_attr = device_proxy.read_attribute(cmd_time_attr_name) device_attr = device_proxy.read_attribute( cmd_time_attr_name) dev_instance._se_cmd_duration_expected[device][cmd_to_exec] = device_attr.value except tango.DevFailed as tango_err: # we get here if the attribute is not implemented Loading @@ -226,7 +244,8 @@ class CmdInputArgsCheck(object): if dev_instance._se_event_id[device][attr.lower()] == 0: evt_id = device_proxy.subscribe_event(attr, tango.EventType.CHANGE_EVENT, dev_instance._attributes_change_evt_cb, stateless=False) dev_instance._se_event_id[device][attr.lower()] = evt_id dev_instance._se_event_id[device][attr.lower( )] = evt_id except tango.DevFailed as tango_err: dev_instance.logger.info(tango_err.args[0].desc) # evaluate the total timeout value to execute the whole command Loading @@ -237,10 +256,12 @@ class CmdInputArgsCheck(object): # use the greatest value for the onCommand duration expected. if command_timeout > dev_instance._cmd_duration_expected[cmd_to_exec]: dev_instance._cmd_duration_expected[cmd_to_exec] = command_timeout dev_instance.logger.info("Modified the {} command Duration Expected value!!".format(cmd_to_exec)) dev_instance.logger.info( "Modified the {} command Duration Expected value!!".format(cmd_to_exec)) return f(*args, **kwargs) return input_args_check class SubarrayRejectCmd(object): """ Class designed to be a decorator for the CspSubarray methods. Loading @@ -250,6 +271,7 @@ class SubarrayRejectCmd(object): The *decorator function* accepts some parameters as input to customize its functionality """ def __init__(self, *args, **kwargs): # store the decorators parameters: # args: the list of command to reject Loading @@ -257,6 +279,7 @@ class SubarrayRejectCmd(object): self._args = args self._kwargs = kwargs print(args) def __call__(self, f): @functools.wraps(f) def input_args_check(*args, **kwargs): Loading @@ -264,7 +287,8 @@ class SubarrayRejectCmd(object): dev_instance = args[0] cmd_to_exec = f.__name__ commands_to_reject = self._args dev_instance.logger.debug("SubarrayRejectCmd: function {}".format(f.__name__)) dev_instance.logger.debug( "SubarrayRejectCmd: function {}".format(f.__name__)) # If a sub-array is executing an AddXXX (RemoveXX) command, an exception is # thown only when the requested command is RemoveXXX (AddXXX)remove/add resources or ConfigureScan. # If the requested command is already running, the decorator returns. Loading @@ -287,10 +311,12 @@ class SubarrayRejectCmd(object): tango.ErrSeverity.ERR) # reset alarm/timeout condition if dev_instance._alarm_raised: dev_instance.logger.info("A previous alarm condition is present") dev_instance.logger.info( "A previous alarm condition is present") dev_instance._alarm_raised = False if dev_instance._timeout_expired: dev_instance.logger.info("A previous timeout condition is present") dev_instance.logger.info( "A previous timeout condition is present") dev_instance._timeout_expired = False # TODO: how check if the alarm condition has been reset by AlarmHandler? return f(*args, **kwargs) Loading