remove support for declaring parameters/commands as accessibles

use parameters/commands for this

Change-Id: I41f68c7f65f0ea451e639092a44a8ff8f5710bfc
Reviewed-on: https://forge.frm2.tum.de/review/20275
Tested-by: JenkinsCodeReview <bjoern_pedersen@frm2.tum.de>
Reviewed-by: Markus Zolliker <markus.zolliker@psi.ch>
Reviewed-by: Enrico Faulhaber <enrico.faulhaber@frm2.tum.de>
Tested-by: Enrico Faulhaber <enrico.faulhaber@frm2.tum.de>
This commit is contained in:
Enrico Faulhaber
2019-03-28 17:46:46 +01:00
parent 568e214a91
commit 752f8f8093
9 changed files with 44 additions and 47 deletions

View File

@ -42,7 +42,7 @@ class HAS_PID(Feature):
# note: (i would still but them in the same group, though) # note: (i would still but them in the same group, though)
# note: if extra elements are implemented in the pid struct they MUST BE # note: if extra elements are implemented in the pid struct they MUST BE
# properly described in the description of the pid Parameter # properly described in the description of the pid Parameter
accessibles = { parameters = {
'use_pid' : Parameter('use the pid mode', datatype=EnumType(openloop=0, pid_control=1), ), 'use_pid' : Parameter('use the pid mode', datatype=EnumType(openloop=0, pid_control=1), ),
'p' : Parameter('proportional part of the regulation', datatype=FloatRange(0), ), 'p' : Parameter('proportional part of the regulation', datatype=FloatRange(0), ),
'i' : Parameter('(optional) integral part', datatype=FloatRange(0), optional=True), 'i' : Parameter('(optional) integral part', datatype=FloatRange(0), optional=True),
@ -60,7 +60,7 @@ class HAS_PID(Feature):
class Has_PIDTable(HAS_PID): class Has_PIDTable(HAS_PID):
accessibles = { parameters = {
'use_pidtable' : Parameter('use the zoning mode', datatype=EnumType(fixed_pid=0, zone_mode=1)), 'use_pidtable' : Parameter('use the zoning mode', datatype=EnumType(fixed_pid=0, zone_mode=1)),
'pidtable' : Parameter('Table of pid-values vs. target temperature', datatype=ArrayOf(TupleOf(FloatRange(0), 'pidtable' : Parameter('Table of pid-values vs. target temperature', datatype=ArrayOf(TupleOf(FloatRange(0),
StructOf(p=FloatRange(0), StructOf(p=FloatRange(0),
@ -78,7 +78,7 @@ class HAS_Persistent(Feature):
# 'coupled' : Status.BUSY+2, # to be discussed. # 'coupled' : Status.BUSY+2, # to be discussed.
# 'decoupling' : Status.BUSY+3, # to be discussed. # 'decoupling' : Status.BUSY+3, # to be discussed.
#} #}
accessibles = { parameters = {
'persistent_mode': Parameter('Use persistent mode', 'persistent_mode': Parameter('Use persistent mode',
datatype=EnumType(off=0,on=1), datatype=EnumType(off=0,on=1),
default=0, readonly=False), default=0, readonly=False),
@ -95,7 +95,7 @@ class HAS_Tolerance(Feature):
# detects IDLE status by checking if the value lies in a given window: # detects IDLE status by checking if the value lies in a given window:
# tolerance is the maximum allowed deviation from target, value must lie in this interval # tolerance is the maximum allowed deviation from target, value must lie in this interval
# for at least ´timewindow´ seconds. # for at least ´timewindow´ seconds.
accessibles = { parameters = {
'tolerance': Parameter('Half height of the Window', 'tolerance': Parameter('Half height of the Window',
datatype=FloatRange(0), default=1, unit='$'), datatype=FloatRange(0), default=1, unit='$'),
'timewindow': Parameter('Length of the timewindow to check', 'timewindow': Parameter('Length of the timewindow to check',
@ -105,7 +105,7 @@ class HAS_Tolerance(Feature):
class HAS_Timeout(Feature): class HAS_Timeout(Feature):
accessibles = { parameters = {
'timeout': Parameter('timeout for movement', 'timeout': Parameter('timeout for movement',
datatype=FloatRange(0), default=0, unit='s'), datatype=FloatRange(0), default=0, unit='s'),
} }
@ -113,7 +113,7 @@ class HAS_Timeout(Feature):
class HAS_Pause(Feature): class HAS_Pause(Feature):
# just a proposal, can't agree on it.... # just a proposal, can't agree on it....
accessibles = { parameters = {
'pause': Command('pauses movement', argument=None, result=None), 'pause': Command('pauses movement', argument=None, result=None),
'go': Command('continues movement or start a new one if target was change since the last pause', 'go': Command('continues movement or start a new one if target was change since the last pause',
argument=None, result=None), argument=None, result=None),
@ -121,7 +121,7 @@ class HAS_Pause(Feature):
class HAS_Ramp(Feature): class HAS_Ramp(Feature):
accessibles = { parameters = {
'ramp': Parameter('speed of movement', unit='$/min', 'ramp': Parameter('speed of movement', unit='$/min',
datatype=FloatRange(0)), datatype=FloatRange(0)),
'use_ramp': Parameter('use the ramping of the setpoint, or jump', 'use_ramp': Parameter('use the ramping of the setpoint, or jump',
@ -134,14 +134,14 @@ class HAS_Ramp(Feature):
class HAS_Speed(Feature): class HAS_Speed(Feature):
accessibles = { parameters = {
'speed' : Parameter('(maximum) speed of movement (of the main value)', 'speed' : Parameter('(maximum) speed of movement (of the main value)',
unit='$/s', datatype=FloatRange(0)), unit='$/s', datatype=FloatRange(0)),
} }
class HAS_Accel(HAS_Speed): class HAS_Accel(HAS_Speed):
accessibles = { parameters = {
'accel' : Parameter('acceleration of movement', unit='$/s^2', 'accel' : Parameter('acceleration of movement', unit='$/s^2',
datatype=FloatRange(0)), datatype=FloatRange(0)),
'decel' : Parameter('deceleration of movement', unit='$/s^2', 'decel' : Parameter('deceleration of movement', unit='$/s^2',
@ -150,7 +150,7 @@ class HAS_Accel(HAS_Speed):
class HAS_MotorCurrents(Feature): class HAS_MotorCurrents(Feature):
accessibles = { parameters = {
'movecurrent' : Parameter('Current while moving', 'movecurrent' : Parameter('Current while moving',
datatype=FloatRange(0)), datatype=FloatRange(0)),
'idlecurrent' : Parameter('Current while idle', 'idlecurrent' : Parameter('Current while idle',
@ -160,7 +160,7 @@ class HAS_MotorCurrents(Feature):
class HAS_Curve(Feature): class HAS_Curve(Feature):
# proposed, not yet agreed upon! # proposed, not yet agreed upon!
accessibles = { parameters = {
'curve' : Parameter('Calibration curve', datatype=StringType(80), default='<unset>'), 'curve' : Parameter('Calibration curve', datatype=StringType(80), default='<unset>'),
# XXX: tbd. (how to upload/download/select a curve?) # XXX: tbd. (how to upload/download/select a curve?)
} }

View File

@ -88,7 +88,7 @@ class ModuleMeta(type):
for base in reversed(bases): for base in reversed(bases):
if hasattr(base, "accessibles"): if hasattr(base, "accessibles"):
accessibles_list.append(base.accessibles) accessibles_list.append(base.accessibles)
for accessibles in [attrs.get('accessibles', {}), parameters, commands, overrides]: for accessibles in [parameters, commands, overrides]:
accessibles_list.append(accessibles) accessibles_list.append(accessibles)
accessibles = {} # unordered dict of accessibles, will be sorted later accessibles = {} # unordered dict of accessibles, will be sorted later
for accessibles_dict in accessibles_list: for accessibles_dict in accessibles_list:
@ -121,10 +121,9 @@ class ModuleMeta(type):
if isinstance(v.datatype, EnumType) and not v.datatype._enum.name: if isinstance(v.datatype, EnumType) and not v.datatype._enum.name:
v.datatype._enum.name = k v.datatype._enum.name = k
# newtype.accessibles will be used in 3 places only: # newtype.accessibles will be used in 2 places only:
# 1) for inheritance (see above) # 1) for inheritance (see above)
# 2) for the describing message # 2) for the describing message
# 3) by code needing to access the Parameter/Command object (i.e. checking datatypes)
newtype.accessibles = OrderedDict(sorted(accessibles.items(), key=lambda item: item[1].ctr)) newtype.accessibles = OrderedDict(sorted(accessibles.items(), key=lambda item: item[1].ctr))
# check validity of Parameter entries # check validity of Parameter entries

View File

@ -73,8 +73,8 @@ class Module(object):
# what else? # what else?
} }
# properties, parameter and commands are auto-merged upon subclassing # properties, parameters and commands are auto-merged upon subclassing
accessibles = {} parameters = {}
commands = {} commands = {}
# reference to the dispatcher (used for sending async updates) # reference to the dispatcher (used for sending async updates)
@ -246,7 +246,7 @@ class Readable(Module):
DISABLED = 500, DISABLED = 500,
UNKNOWN = 0, UNKNOWN = 0,
) )
accessibles = { parameters = {
'value': Parameter('current value of the Module', readonly=True, 'value': Parameter('current value of the Module', readonly=True,
default=0., datatype=FloatRange(), default=0., datatype=FloatRange(),
unit='', poll=True, unit='', poll=True,
@ -313,7 +313,7 @@ class Writable(Readable):
providing a settable 'target' parameter to those of a Readable providing a settable 'target' parameter to those of a Readable
""" """
accessibles = { parameters = {
'target': Parameter('target value of the Module', 'target': Parameter('target value of the Module',
default=0., readonly=False, datatype=FloatRange(), default=0., readonly=False, datatype=FloatRange(),
), ),

View File

@ -35,7 +35,7 @@ from secop.modules import Drivable, Override, Parameter, Readable
class Switch(Drivable): class Switch(Drivable):
"""switch it on or off.... """switch it on or off....
""" """
accessibles = { parameters = {
'value': Override('current state (on or off)', 'value': Override('current state (on or off)',
datatype=EnumType(on=1, off=0), default=0, datatype=EnumType(on=1, off=0), default=0,
), ),
@ -97,7 +97,7 @@ class Switch(Drivable):
class MagneticField(Drivable): class MagneticField(Drivable):
"""a liquid magnet """a liquid magnet
""" """
accessibles = { parameters = {
'value': Override('current field in T', 'value': Override('current field in T',
unit='T', datatype=FloatRange(-15, 15), default=0, unit='T', datatype=FloatRange(-15, 15), default=0,
), ),
@ -197,7 +197,7 @@ class MagneticField(Drivable):
class CoilTemp(Readable): class CoilTemp(Readable):
"""a coil temperature """a coil temperature
""" """
accessibles = { parameters = {
'value': Override('Coil temperatur', 'value': Override('Coil temperatur',
unit='K', datatype=FloatRange(), default=0, unit='K', datatype=FloatRange(), default=0,
), ),
@ -213,7 +213,7 @@ class CoilTemp(Readable):
class SampleTemp(Drivable): class SampleTemp(Drivable):
"""a sample temperature """a sample temperature
""" """
accessibles = { parameters = {
'value': Override('Sample temperature', 'value': Override('Sample temperature',
unit='K', datatype=FloatRange(), default=10, unit='K', datatype=FloatRange(), default=10,
), ),
@ -260,7 +260,7 @@ class Label(Readable):
of several subdevices. used for demoing connections between of several subdevices. used for demoing connections between
modules. modules.
""" """
accessibles = { parameters = {
'system': Parameter("Name of the magnet system", 'system': Parameter("Name of the magnet system",
datatype=StringType, export=False, datatype=StringType, export=False,
), ),
@ -305,7 +305,7 @@ class Label(Readable):
class DatatypesTest(Readable): class DatatypesTest(Readable):
"""for demoing all datatypes """for demoing all datatypes
""" """
accessibles = { parameters = {
'enum': Parameter('enum', datatype=EnumType(boo=None, faar=None, z=9), 'enum': Parameter('enum', datatype=EnumType(boo=None, faar=None, z=9),
readonly=False, default=1), readonly=False, default=1),
'tupleof': Parameter('tuple of int, float and str', 'tupleof': Parameter('tuple of int, float and str',
@ -327,7 +327,7 @@ class DatatypesTest(Readable):
class ArrayTest(Readable): class ArrayTest(Readable):
accessibles = { parameters = {
"x": Parameter('value', datatype=ArrayOf(FloatRange(), 0, 100000), "x": Parameter('value', datatype=ArrayOf(FloatRange(), 0, 100000),
default = 100000 * [0]), default = 100000 * [0]),
} }

View File

@ -54,7 +54,7 @@ class Heater(Drivable):
class name indicates it to be some heating element, class name indicates it to be some heating element,
but the implementation may do anything but the implementation may do anything
""" """
accessibles = { parameters = {
'maxheaterpower': Parameter('maximum allowed heater power', 'maxheaterpower': Parameter('maximum allowed heater power',
datatype=FloatRange(0, 100), unit='W', datatype=FloatRange(0, 100), unit='W',
), ),
@ -73,7 +73,7 @@ class Temp(Drivable):
class name indicates it to be some temperature controller, class name indicates it to be some temperature controller,
but the implementation may do anything but the implementation may do anything
""" """
accessibles = { parameters = {
'sensor': Parameter( 'sensor': Parameter(
"Sensor number or calibration id", "Sensor number or calibration id",
datatype=StringType( datatype=StringType(

View File

@ -59,7 +59,7 @@ except ImportError:
class EpicsReadable(Readable): class EpicsReadable(Readable):
"""EpicsDrivable handles a Drivable interfacing to EPICS v4""" """EpicsDrivable handles a Drivable interfacing to EPICS v4"""
# Commmon parameter for all EPICS devices # Commmon parameter for all EPICS devices
accessibles = { parameters = {
'value': Parameter('EPICS generic value', 'value': Parameter('EPICS generic value',
datatype=FloatRange(), datatype=FloatRange(),
default=300.0,), default=300.0,),
@ -119,7 +119,7 @@ class EpicsReadable(Readable):
class EpicsDrivable(Drivable): class EpicsDrivable(Drivable):
"""EpicsDrivable handles a Drivable interfacing to EPICS v4""" """EpicsDrivable handles a Drivable interfacing to EPICS v4"""
# Commmon parameter for all EPICS devices # Commmon parameter for all EPICS devices
accessibles = { parameters = {
'target': Parameter('EPICS generic target', datatype=FloatRange(), 'target': Parameter('EPICS generic target', datatype=FloatRange(),
default=300.0, readonly=False), default=300.0, readonly=False),
'value': Parameter('EPICS generic value', datatype=FloatRange(), 'value': Parameter('EPICS generic value', datatype=FloatRange(),
@ -192,7 +192,7 @@ class EpicsDrivable(Drivable):
class EpicsTempCtrl(EpicsDrivable): class EpicsTempCtrl(EpicsDrivable):
accessibles = { parameters = {
# TODO: restrict possible values with oneof datatype # TODO: restrict possible values with oneof datatype
'heaterrange': Parameter('Heater range', datatype=StringType(), 'heaterrange': Parameter('Heater range', datatype=StringType(),
default='Off', readonly=False,), default='Off', readonly=False,),

View File

@ -48,7 +48,7 @@ class GarfieldMagnet(SequencerMixin, Drivable):
the symmetry setting selects which. the symmetry setting selects which.
""" """
accessibles = { parameters = {
'subdev_currentsource': Parameter('(bipolar) Powersupply', datatype=StringType(), readonly=True, export=False), 'subdev_currentsource': Parameter('(bipolar) Powersupply', datatype=StringType(), readonly=True, export=False),
'subdev_enable': Parameter('Switch to set for on/off', datatype=StringType(), readonly=True, export=False), 'subdev_enable': Parameter('Switch to set for on/off', datatype=StringType(), readonly=True, export=False),
'subdev_polswitch': Parameter('Switch to set for polarity', datatype=StringType(), readonly=True, export=False), 'subdev_polswitch': Parameter('Switch to set for polarity', datatype=StringType(), readonly=True, export=False),

View File

@ -159,7 +159,7 @@ class PyTangoDevice(Module):
execution and attribute operations with logging and exception mapping. execution and attribute operations with logging and exception mapping.
""" """
accessibles = { parameters = {
'comtries': Parameter('Maximum retries for communication', 'comtries': Parameter('Maximum retries for communication',
datatype=IntRange(1, 100), default=3, readonly=False, datatype=IntRange(1, 100), default=3, readonly=False,
group='communication'), group='communication'),
@ -426,7 +426,7 @@ class AnalogOutput(PyTangoDevice, Drivable):
controllers, ... controllers, ...
""" """
accessibles = { parameters = {
'userlimits': Parameter('User defined limits of device value', 'userlimits': Parameter('User defined limits of device value',
datatype=TupleOf(FloatRange(), FloatRange()), datatype=TupleOf(FloatRange(), FloatRange()),
default=(float('-Inf'), float('+Inf')), default=(float('-Inf'), float('+Inf')),
@ -604,7 +604,7 @@ class Actuator(AnalogOutput):
""" """
# for secop: support the speed and ramp parameters # for secop: support the speed and ramp parameters
accessibles = { parameters = {
'speed': Parameter('The speed of changing the value', 'speed': Parameter('The speed of changing the value',
unit='main/s', readonly=False, datatype=FloatRange(0), unit='main/s', readonly=False, datatype=FloatRange(0),
), ),
@ -644,7 +644,7 @@ class Motor(Actuator):
It has the ability to move a real object from one place to another place. It has the ability to move a real object from one place to another place.
""" """
accessibles = { parameters = {
'refpos': Parameter('Reference position', 'refpos': Parameter('Reference position',
datatype=FloatRange(), unit='main', datatype=FloatRange(), unit='main',
), ),
@ -684,7 +684,7 @@ class TemperatureController(Actuator):
"""A temperature control loop device. """A temperature control loop device.
""" """
accessibles = { parameters = {
'p': Parameter('Proportional control Parameter', datatype=FloatRange(), 'p': Parameter('Proportional control Parameter', datatype=FloatRange(),
readonly=False, group='pid', readonly=False, group='pid',
), ),
@ -759,7 +759,7 @@ class PowerSupply(Actuator):
"""A power supply (voltage and current) device. """A power supply (voltage and current) device.
""" """
accessibles = { parameters = {
'ramp': Parameter('Current/voltage ramp', unit='main/min', 'ramp': Parameter('Current/voltage ramp', unit='main/min',
datatype=FloatRange(), readonly=False, poll=30,), datatype=FloatRange(), readonly=False, poll=30,),
'voltage': Parameter('Actual voltage', unit='V', 'voltage': Parameter('Actual voltage', unit='V',
@ -797,7 +797,7 @@ class NamedDigitalInput(DigitalInput):
"""A DigitalInput with numeric values mapped to names. """A DigitalInput with numeric values mapped to names.
""" """
accessibles = { parameters = {
'mapping': Parameter('A dictionary mapping state names to integers', 'mapping': Parameter('A dictionary mapping state names to integers',
datatype=StringType(), export=False), # XXX:!!! datatype=StringType(), export=False), # XXX:!!!
} }
@ -820,7 +820,7 @@ class PartialDigitalInput(NamedDigitalInput):
bit width accessed. bit width accessed.
""" """
accessibles = { parameters = {
'startbit': Parameter('Number of the first bit', 'startbit': Parameter('Number of the first bit',
datatype=IntRange(0), default=0), datatype=IntRange(0), default=0),
'bitwidth': Parameter('Number of bits', 'bitwidth': Parameter('Number of bits',
@ -864,7 +864,7 @@ class NamedDigitalOutput(DigitalOutput):
"""A DigitalOutput with numeric values mapped to names. """A DigitalOutput with numeric values mapped to names.
""" """
accessibles = { parameters = {
'mapping': Parameter('A dictionary mapping state names to integers', 'mapping': Parameter('A dictionary mapping state names to integers',
datatype=StringType(), export=False), datatype=StringType(), export=False),
} }
@ -890,7 +890,7 @@ class PartialDigitalOutput(NamedDigitalOutput):
bit width accessed. bit width accessed.
""" """
accessibles = { parameters = {
'startbit': Parameter('Number of the first bit', 'startbit': Parameter('Number of the first bit',
datatype=IntRange(0), default=0), datatype=IntRange(0), default=0),
'bitwidth': Parameter('Number of bits', 'bitwidth': Parameter('Number of bits',
@ -921,7 +921,7 @@ class StringIO(PyTangoDevice, Module):
receives strings. receives strings.
""" """
accessibles = { parameters = {
'bustimeout': Parameter('Communication timeout', 'bustimeout': Parameter('Communication timeout',
datatype=FloatRange(), readonly=False, datatype=FloatRange(), readonly=False,
unit='s', group='communication'), unit='s', group='communication'),

View File

@ -65,14 +65,12 @@ def test_ModuleMeta():
'pollinterval': Override(reorder=True), 'pollinterval': Override(reorder=True),
'param1' : Parameter('param1', datatype=BoolType(), default=False), 'param1' : Parameter('param1', datatype=BoolType(), default=False),
'param2': Parameter('param2', datatype=BoolType(), default=True), 'param2': Parameter('param2', datatype=BoolType(), default=True),
"cmd": Command('stuff', BoolType(), BoolType())
}, },
"commands": { "commands": {
"cmd": Command('stuff',BoolType(), BoolType())
},
"accessibles": {
'a1': Parameter('a1', datatype=BoolType(), default=False), 'a1': Parameter('a1', datatype=BoolType(), default=False),
'a2': Parameter('a2', datatype=BoolType(), default=True), 'a2': Parameter('a2', datatype=BoolType(), default=True),
'value':Override(datatype=BoolType(), default = True), 'value': Override(datatype=BoolType(), default=True),
'cmd2': Command('another stuff', BoolType(), BoolType()), 'cmd2': Command('another stuff', BoolType(), BoolType()),
}, },
"do_cmd": lambda self, arg: not arg, "do_cmd": lambda self, arg: not arg,
@ -89,7 +87,7 @@ def test_ModuleMeta():
'param1', 'param2', 'cmd', 'a1', 'a2', 'cmd2'] 'param1', 'param2', 'cmd', 'a1', 'a2', 'cmd2']
newclass2 = ModuleMeta.__new__(ModuleMeta, 'UpperClass', (newclass1,), { newclass2 = ModuleMeta.__new__(ModuleMeta, 'UpperClass', (newclass1,), {
"accessibles": { "parameters": {
'cmd2': Override('another stuff'), 'cmd2': Override('another stuff'),
'a1': Override(datatype=FloatRange(), reorder=True), 'a1': Override(datatype=FloatRange(), reorder=True),
'b2': Parameter('a2', datatype=BoolType(), default=True), 'b2': Parameter('a2', datatype=BoolType(), default=True),