Select Git revision
decorators.py
Elisabetta Giani authored
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