fix inheritance order

+ hide pollperiod on PPMS Modules

Change-Id: I77ad5502884360bf6babfd226de0675ee06a6196
Reviewed-on: https://forge.frm2.tum.de/review/c/sine2020/secop/playground/+/25054
Tested-by: Jenkins Automated Tests <pedersen+jenkins@frm2.tum.de>
Reviewed-by: Enrico Faulhaber <enrico.faulhaber@frm2.tum.de>
Reviewed-by: Markus Zolliker <markus.zolliker@psi.ch>
This commit is contained in:
zolliker 2021-02-24 15:04:55 +01:00
parent 1588703f99
commit 9071a5bcf7
2 changed files with 36 additions and 20 deletions

View File

@ -40,7 +40,7 @@ Done = object() #: a special return value for a read/write function indicating
class HasAccessibles(HasProperties): class HasAccessibles(HasProperties):
"""base class of Module """base class of module
joining the class's properties, parameters and commands dicts with joining the class's properties, parameters and commands dicts with
those of base classes. those of base classes.
@ -53,7 +53,7 @@ class HasAccessibles(HasProperties):
# merge accessibles from all sub-classes, treat overrides # merge accessibles from all sub-classes, treat overrides
# for now, allow to use also the old syntax (parameters/commands dict) # for now, allow to use also the old syntax (parameters/commands dict)
accessibles = {} accessibles = {}
for base in cls.__bases__: for base in reversed(cls.__bases__):
accessibles.update(getattr(base, 'accessibles', {})) accessibles.update(getattr(base, 'accessibles', {}))
newaccessibles = {k: v for k, v in cls.__dict__.items() if isinstance(v, Accessible)} newaccessibles = {k: v for k, v in cls.__dict__.items() if isinstance(v, Accessible)}
for aname, aobj in accessibles.items(): for aname, aobj in accessibles.items():
@ -445,6 +445,19 @@ class Module(HasAccessibles):
pass pass
def registerCallbacks(self, modobj, autoupdate=()): def registerCallbacks(self, modobj, autoupdate=()):
"""register callbacks to another module <modobj>
- whenever a self.<param> changes:
<modobj>.update_<param> is called with the new value as argument.
If this method raises an exception, <modobj>.<param> gets into an error state.
If the method does not exist and <param> is in autoupdate,
<modobj>.<param> is updated to self.<param>
- whenever <self>.<param> gets into an error state:
<modobj>.error_update_<param> is called with the exception as argument.
If this method raises an error, <modobj>.<param> gets into an error state.
If this method does not exist, and <param> is in autoupdate,
<modobj>.<param> gets into the same error state as self.<param>
"""
for pname in self.parameters: for pname in self.parameters:
errfunc = getattr(modobj, 'error_update_' + pname, None) errfunc = getattr(modobj, 'error_update_' + pname, None)
if errfunc: if errfunc:

View File

@ -41,7 +41,7 @@ from secop.errors import HardwareError
from secop.lib import clamp from secop.lib import clamp
from secop.lib.enum import Enum from secop.lib.enum import Enum
from secop.modules import Attached, Communicator, Done, \ from secop.modules import Attached, Communicator, Done, \
Drivable, HasAccessibles, Parameter, Property, Readable Drivable, Parameter, Property, Readable
from secop.poller import Poller from secop.poller import Poller
from secop.stringio import HasIodev from secop.stringio import HasIodev
@ -128,8 +128,8 @@ class Main(Communicator):
return data # return data as string return data # return data as string
class PpmsMixin(HasIodev, HasAccessibles): class PpmsBase(HasIodev, Readable):
"""common methods for ppms modules""" """common base for all ppms modules"""
iodev = Attached() iodev = Attached()
pollerClass = Poller pollerClass = Poller
@ -137,6 +137,10 @@ class PpmsMixin(HasIodev, HasAccessibles):
_last_settings = None # used by several modules _last_settings = None # used by several modules
slow_pollfactor = 1 slow_pollfactor = 1
# as this pollinterval affects only the polling of settings
# it would be confusing to export it.
pollinterval = Parameter(export=False)
def initModule(self): def initModule(self):
self._iodev.register(self) self._iodev.register(self)
@ -168,13 +172,12 @@ class PpmsMixin(HasIodev, HasAccessibles):
self.status = (self.Status.IDLE, '') self.status = (self.Status.IDLE, '')
class Channel(PpmsMixin, Readable): class Channel(PpmsBase):
"""channel base class""" """channel base class"""
value = Parameter('main value of channels', poll=True) value = Parameter('main value of channels', poll=True)
enabled = Parameter('is this channel used?', readonly=False, poll=False, enabled = Parameter('is this channel used?', readonly=False, poll=False,
datatype=BoolType(), default=False) datatype=BoolType(), default=False)
pollinterval = Parameter(visibility=3)
channel = Property('channel name', channel = Property('channel name',
datatype=StringType(), export=False, default='') datatype=StringType(), export=False, default='')
@ -193,7 +196,7 @@ class Channel(PpmsMixin, Readable):
class UserChannel(Channel): class UserChannel(Channel):
"""user channel""" """user channel"""
pollinterval = Parameter(visibility=3) # pollinterval = Parameter(visibility=3)
no = Property('channel number', no = Property('channel number',
datatype=IntRange(0, 0), export=False, default=0) datatype=IntRange(0, 0), export=False, default=0)
@ -216,7 +219,7 @@ class DriverChannel(Channel):
datatype=FloatRange(0., 5000., unit='uA')) datatype=FloatRange(0., 5000., unit='uA'))
powerlimit = Parameter('power limit', readonly=False, handler=drvout, powerlimit = Parameter('power limit', readonly=False, handler=drvout,
datatype=FloatRange(0., 1000., unit='uW')) datatype=FloatRange(0., 1000., unit='uW'))
pollinterval = Parameter(visibility=3) # pollinterval = Parameter(visibility=3)
def analyze_drvout(self, no, current, powerlimit): def analyze_drvout(self, no, current, powerlimit):
if self.no != no: if self.no != no:
@ -246,7 +249,7 @@ class BridgeChannel(Channel):
datatype=EnumType(ReadingMode)) datatype=EnumType(ReadingMode))
voltagelimit = Parameter('voltage limit', readonly=False, handler=bridge, voltagelimit = Parameter('voltage limit', readonly=False, handler=bridge,
datatype=FloatRange(0.0001, 100., unit='mV')) datatype=FloatRange(0.0001, 100., unit='mV'))
pollinterval = Parameter(visibility=3) # pollinterval = Parameter(visibility=3)
def analyze_bridge(self, no, excitation, powerlimit, dcflag, readingmode, voltagelimit): def analyze_bridge(self, no, excitation, powerlimit, dcflag, readingmode, voltagelimit):
if self.no != no: if self.no != no:
@ -267,14 +270,14 @@ class BridgeChannel(Channel):
return self.no, 0, 0, change.dcflag, change.readingmode, 0 return self.no, 0, 0, change.dcflag, change.readingmode, 0
class Level(PpmsMixin, Readable): class Level(PpmsBase):
"""helium level""" """helium level"""
level = IOHandler('level', 'LEVEL?', '%g,%d') level = IOHandler('level', 'LEVEL?', '%g,%d')
value = Parameter(datatype=FloatRange(unit='%'), handler=level) value = Parameter(datatype=FloatRange(unit='%'), handler=level)
status = Parameter(handler=level) status = Parameter(handler=level)
pollinterval = Parameter(visibility=3) # pollinterval = Parameter(visibility=3)
channel = 'level' channel = 'level'
@ -290,7 +293,7 @@ class Level(PpmsMixin, Readable):
return dict(value=level, status=(self.Status.IDLE, '')) return dict(value=level, status=(self.Status.IDLE, ''))
class Chamber(PpmsMixin, Drivable): class Chamber(PpmsBase, Drivable):
"""sample chamber handling """sample chamber handling
value is an Enum, which is redundant with the status text value is an Enum, which is redundant with the status text
@ -328,7 +331,7 @@ class Chamber(PpmsMixin, Drivable):
datatype=EnumType(StatusCode)) datatype=EnumType(StatusCode))
target = Parameter(description='chamber command', handler=chamber, target = Parameter(description='chamber command', handler=chamber,
datatype=EnumType(Operation)) datatype=EnumType(Operation))
pollinterval = Parameter(visibility=3) # pollinterval = Parameter(visibility=3)
STATUS_MAP = { STATUS_MAP = {
StatusCode.purged_and_sealed: (Status.IDLE, 'purged and sealed'), StatusCode.purged_and_sealed: (Status.IDLE, 'purged and sealed'),
@ -365,7 +368,7 @@ class Chamber(PpmsMixin, Drivable):
return (change.target,) return (change.target,)
class Temp(PpmsMixin, Drivable): class Temp(PpmsBase, Drivable):
"""temperature""" """temperature"""
temp = IOHandler('temp', 'TEMP?', '%g,%g,%d') temp = IOHandler('temp', 'TEMP?', '%g,%g,%d')
@ -388,7 +391,7 @@ class Temp(PpmsMixin, Drivable):
datatype=FloatRange(0, 20, unit='K/min'), handler=temp) datatype=FloatRange(0, 20, unit='K/min'), handler=temp)
approachmode = Parameter('how to approach target!', readonly=False, handler=temp, approachmode = Parameter('how to approach target!', readonly=False, handler=temp,
datatype=EnumType(ApproachMode)) datatype=EnumType(ApproachMode))
pollinterval = Parameter(visibility=3) # pollinterval = Parameter(visibility=3)
timeout = Parameter('drive timeout, in addition to ramp time', readonly=False, timeout = Parameter('drive timeout, in addition to ramp time', readonly=False,
datatype=FloatRange(0, unit='sec'), default=3600) datatype=FloatRange(0, unit='sec'), default=3600)
@ -550,7 +553,7 @@ class Temp(PpmsMixin, Drivable):
self._stopped = True self._stopped = True
class Field(PpmsMixin, Drivable): class Field(PpmsBase, Drivable):
"""magnetic field""" """magnetic field"""
field = IOHandler('field', 'FIELD?', '%g,%g,%d,%d') field = IOHandler('field', 'FIELD?', '%g,%g,%d,%d')
@ -574,7 +577,7 @@ class Field(PpmsMixin, Drivable):
datatype=EnumType(ApproachMode)) datatype=EnumType(ApproachMode))
persistentmode = Parameter('what to do after changing field', readonly=False, handler=field, persistentmode = Parameter('what to do after changing field', readonly=False, handler=field,
datatype=EnumType(PersistentMode)) datatype=EnumType(PersistentMode))
pollinterval = Parameter(visibility=3) # pollinterval = Parameter(visibility=3)
STATUS_MAP = { STATUS_MAP = {
1: (Status.IDLE, 'persistent mode'), 1: (Status.IDLE, 'persistent mode'),
@ -687,7 +690,7 @@ class Field(PpmsMixin, Drivable):
self._stopped = True self._stopped = True
class Position(PpmsMixin, Drivable): class Position(PpmsBase, Drivable):
"""rotator position""" """rotator position"""
move = IOHandler('move', 'MOVE?', '%g,%g,%g') move = IOHandler('move', 'MOVE?', '%g,%g,%g')
@ -699,7 +702,7 @@ class Position(PpmsMixin, Drivable):
datatype=BoolType(), default=True) datatype=BoolType(), default=True)
speed = Parameter('motor speed', readonly=False, handler=move, speed = Parameter('motor speed', readonly=False, handler=move,
datatype=FloatRange(0.8, 12, unit='deg/sec')) datatype=FloatRange(0.8, 12, unit='deg/sec'))
pollinterval = Parameter(visibility=3) # pollinterval = Parameter(visibility=3)
STATUS_MAP = { STATUS_MAP = {
1: (Status.IDLE, 'at target'), 1: (Status.IDLE, 'at target'),