Skip to content
Snippets Groups Projects
Select Git revision
  • 0ea04080cf818138f67a923adf875701df237bb2
  • master default protected
  • publish_python_package
  • AT5-374
  • AT5-373
  • AT5-370
  • ST-174
  • ST-85
  • ST94_Update_Pipfile
  • ST72_integrate_versioning_in_ci
  • test-code-climate
  • ST3_containerise_Python_device
  • ST59_Python_TANGO_device_to_be_demonstrated_as_part_of_PI_demo
13 results

decorators.py

Blame
  • decorators.py 3.84 KiB
    import functools
    import tango
    
    tasks = {}
    
    # note: f.__name__ is of type is_XXX_allowed
    # f.__name__[3:-8] select the command name
    # this decorator build a dictionary with the command name as key and
    # the handler as value.
    task = lambda f:tasks.setdefault(f.__name__[3:-8], f)
    
    @task
    def is_standby_allowed(device_instance):
        """
        Allowed method for Standby method.
        Command *Standby* is allowed when the device *State* is ON or
        STANDBY.
    
        :return: True if the method is allowed, otherwise False.
        """
        if device_instance.get_state() in [tango.DevState.ON, 
                                            tango.DevState.STANDBY]:
            return True
        return False
    
    @task
    def is_on_allowed(device_instance):
        """
        Allowed method for On method.
        Command *On* is allowed when the device *State* is ON or
        STANDBY.
    
        :return: True if the method is allowed, otherwise False.
        """
        if device_instance.get_state() in [tango.DevState.ON, 
                                            tango.DevState.STANDBY]:
            return True
        return False
    
    @task
    def is_off_allowed(device_instance):
        """
        Allowed method for Off method.
        Command *Off* is allowed when the device *State* is OFF or
        STANDBY.
    
        :return: True if the method is allowed, otherwise False.
        """
        if device_instance.get_state() in [tango.DevState.OFF, 
                                           tango.DevState.STANDBY]:
            return True
        return False
    
    def is_command_allowed(device_instance, cmd_name):
        """
        Call the allowed method for the command name specified
        as input argument
        :param device_istance: the TANGO device instance
        :param cmd_name: the name of command to execute
    
        :return: True/False
        """
        tasks[cmd_name](device_instance)
    
    class IsCommandAllowed(object):
        """
        Class designed to be a decorator for the Master power methods.
        The *decorator function* performs a check on the input argument
        to control if the command is issued on the whole sub-element.
        If this is the case, it checks the State of the sub-element Master
        device and rejects the command accordingly to the State
        machine setting.
    
        :raise: tango.DevFailed exception if the command can't be executed 
        """
        def __init__(self, *args, **kwargs):
            # store the decorators parameters:
            # args: the list of sub-element attributes to subscribe, to track the
            #       sub-element command progress and detect a command timeout
            # kwargs: a dictionary: key ="cmd_name",
            #                       value = command to execute ('on', 'off'...)
            self._args = args
            self._kwargs = kwargs
    
        def __call__(self, f):
            @functools.wraps(f)
            def input_args_check(*args, **kwargs):
                # the Master device instance
                dev_instance = args[0]
                # the command name
                cmd_to_exec = f.__name__
                # the command input argument
                input_arg = args[1]
                #device_list = input_arg
                # Note: device list is a reference to args[1]: changing
                # device_list content, args[1] changes accordingly!
                num_of_devices = len(input_arg)
                if num_of_devices == 0:
                    # check the device State: if it not the proper value the command is
                    # not executed
                    if not is_command_allowed(dev_instance, cmd_to_exec.lower()):
                        msg = "Command {} can't be executed when the device is {}".format(cmd_to_exec,
                                                                                           dev_instance.get_state())
                        tango.Except.throw_exception("Command failure",msg,
                                                 "IsCommandAllowed decorator",
                                                 tango.ErrSeverity.ERR)
                return f(*args, **kwargs)
            return input_args_check