diff --git a/.pylintrc b/.pylintrc index 72011d6..5bfa170 100644 --- a/.pylintrc +++ b/.pylintrc @@ -134,7 +134,7 @@ variable-rgx=[a-z_][a-zA-Z0-9_]{0,30}$ inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ # Good variable names which should always be accepted, separated by a comma -good-names=i,j,k,ex,Run,_,a,b,c,d,m,n,u,v,w,x,y,z,e +good-names=i,j,k,ex,Run,_,a,b,c,d,m,n,u,v,w,x,y,z,e,CMDS,PARAMS,OVERRIDES,DISPATCHER,PROPERTIES # Bad variable names which should always be refused, separated by a comma bad-names=foo,bar,baz,toto,tutu,tata diff --git a/etc/amagnet.cfg b/etc/amagnet.cfg index 9736cec..344a588 100644 --- a/etc/amagnet.cfg +++ b/etc/amagnet.cfg @@ -23,7 +23,7 @@ encoding=secop [device enable] class=secop_mlz.entangle.NamedDigitalOutput -tangodevice='tango://amagnet.antares.frm2:10000/box/plc/_enable' +tangodevice='tango://localhost:10000/box/plc/_enable' value.datatype=["enum", {'On':1,'Off':0}] target.datatype=["enum", {'On':1,'Off':0}] .description='Enables to Output of the Powersupply' @@ -31,7 +31,7 @@ target.datatype=["enum", {'On':1,'Off':0}] [device polarity] class=secop_mlz.entangle.NamedDigitalOutput -tangodevice=tango://amagnet.antares.frm2:10000/box/plc/_polarity +tangodevice=tango://localhost:10000/box/plc/_polarity value.datatype=["enum", {'+1':1,'0':0,'-1':-1}] target.datatype=["enum", {'+1':1,'0':0,'-1':-1}] .description=polarity (+/-) switch @@ -45,7 +45,7 @@ comtries=50 [device symmetry] class=secop_mlz.entangle.NamedDigitalOutput -tangodevice=tango://amagnet.antares.frm2:10000/box/plc/_symmetric +tangodevice=tango://localhost:10000/box/plc/_symmetric value.datatype=["enum",{'symmetric':1,'short':0, 'asymmetric':-1}] target.datatype=["enum",{'symmetric':1,'short':0, 'asymmetric':-1}] .description=par/ser switch selecting (a)symmetric mode @@ -55,35 +55,35 @@ target.datatype=["enum",{'symmetric':1,'short':0, 'asymmetric':-1}] [device T1] class=secop_mlz.entangle.AnalogInput -tangodevice=tango://amagnet.antares.frm2:10000/box/plc/_t1 +tangodevice=tango://localhost:10000/box/plc/_t1 .description=Temperature1 of the coils system #warnlimits=(0, 50) value.unit='degC' [device T2] class=secop_mlz.entangle.AnalogInput -tangodevice=tango://amagnet.antares.frm2:10000/box/plc/_t2 +tangodevice=tango://localhost:10000/box/plc/_t2 .description=Temperature2 of the coils system #warnlimits=(0, 50) value.unit='degC' [device T3] class=secop_mlz.entangle.AnalogInput -tangodevice=tango://amagnet.antares.frm2:10000/box/plc/_t3 +tangodevice=tango://localhost:10000/box/plc/_t3 .description=Temperature3 of the coils system #warnlimits=(0, 50) value.unit='degC' [device T4] class=secop_mlz.entangle.AnalogInput -tangodevice=tango://amagnet.antares.frm2:10000/box/plc/_t4 +tangodevice=tango://localhost:10000/box/plc/_t4 .description=Temperature4 of the coils system #warnlimits=(0, 50) value.unit='degC' [device currentsource] class=secop_mlz.entangle.PowerSupply -tangodevice=tango://amagnet.antares.frm2:10000/box/lambda/curr +tangodevice=tango://localhost:10000/box/lambda/curr .description=Device for the magnet power supply (current mode) abslimits=(0,200) speed=1 diff --git a/secop/modules.py b/secop/modules.py index 66149f2..87d0a82 100644 --- a/secop/modules.py +++ b/secop/modules.py @@ -142,11 +142,11 @@ class OVERRIDE(object): # storage for CMDs settings (description + call signature...) class CMD(object): - def __init__(self, description, arguments=[], result=None): + def __init__(self, description, arguments=None, result=None): # descriptive text for humans self.description = description # list of datatypes for arguments - self.arguments = arguments + self.arguments = arguments or [] # datatype for result self.resulttype = result @@ -210,18 +210,16 @@ class ModuleMeta(type): if rfunc: self.log.debug("rfunc(%s): call %r" % (pname, rfunc)) value = rfunc(self, maxage) - setattr(self, pname, value) - return value else: # return cached value self.log.debug("rfunc(%s): return cached value" % pname) value = self.PARAMS[pname].value - setattr(self, pname, value) - return value + setattr(self, pname, value) # important! trigger the setter + return value if rfunc: wrapped_rfunc.__doc__ = rfunc.__doc__ - if getattr(rfunc, '__wrapped__', False) == False: + if getattr(rfunc, '__wrapped__', False) is False: setattr(newtype, 'read_' + pname, wrapped_rfunc) wrapped_rfunc.__wrapped__ = True @@ -246,7 +244,7 @@ class ModuleMeta(type): if wfunc: wrapped_wfunc.__doc__ = wfunc.__doc__ - if getattr(wfunc, '__wrapped__', False) == False: + if getattr(wfunc, '__wrapped__', False) is False: setattr(newtype, 'write_' + pname, wrapped_wfunc) wrapped_wfunc.__wrapped__ = True @@ -268,16 +266,16 @@ class ModuleMeta(type): # also collect/update information about CMD's setattr(newtype, 'CMDS', getattr(newtype, 'CMDS', {})) - for name in attrs: - if name.startswith('do_'): - if name[3:] in newtype.CMDS: + for attrname in attrs: + if attrname.startswith('do_'): + if attrname[3:] in newtype.CMDS: continue - value = getattr(newtype, name) + value = getattr(newtype, attrname) if isinstance(value, types.MethodType): argspec = inspect.getargspec(value) if argspec[0] and argspec[0][0] == 'self': del argspec[0][0] - newtype.CMDS[name[3:]] = CMD( + newtype.CMDS[attrname[3:]] = CMD( getattr(value, '__doc__'), argspec.args, None) # XXX: how to find resulttype? attrs['__constructed__'] = True @@ -400,11 +398,11 @@ class Module(object): # only check if datatype given try: v = datatype.validate(v) - except (ValueError, TypeError) as e: + except (ValueError, TypeError): self.log.exception(formatExtendedStack()) raise - raise ConfigError('Module %s: config parameter %r:\n%r' % - (self.name, k, e)) +# raise ConfigError('Module %s: config parameter %r:\n%r' % +# (self.name, k, e)) setattr(self, k, v) self._requestLock = threading.RLock() @@ -431,7 +429,7 @@ class Readable(Module): datatype=TupleOf( EnumType(**{ 'IDLE': status.OK, -# 'BUSY': status.BUSY, + 'BUSY': status.BUSY, 'WARN': status.WARN, 'UNSTABLE': status.UNSTABLE, 'ERROR': status.ERROR, @@ -475,7 +473,7 @@ class Readable(Module): # status was already polled above continue if ((int(pobj.poll) < 0) and fastpoll) or ( - 0 == nr % abs(int(pobj.poll))): + nr % abs(int(pobj.poll))) == 0: # poll always if pobj.poll is negative and fastpoll (i.e. Module is busy) # otherwise poll every 'pobj.poll' iteration rfunc = getattr(self, 'read_' + pname, None) @@ -511,18 +509,6 @@ class Drivable(Writable): Also status gets extended with a BUSY state indicating a running action. """ - OVERRIDES = { - "status" : OVERRIDE(datatype=TupleOf( - EnumType(**{ - 'IDLE': status.OK, - 'BUSY': status.BUSY, - 'WARN': status.WARN, - 'UNSTABLE': status.UNSTABLE, - 'ERROR': status.ERROR, - 'UNKNOWN': status.UNKNOWN - }), StringType())), - } - def do_stop(self): """default implementation of the stop command @@ -536,7 +522,7 @@ class Communicator(Module): """ CMDS = { - "communicate" : CMD("provides the simplest mean to communication", + "communicate" : CMD("provides the simplest mean to communication", arguments=[StringType()], result=StringType() ), diff --git a/secop_mlz/amagnet.py b/secop_mlz/amagnet.py index 9c0f0ec..8e71378 100644 --- a/secop_mlz/amagnet.py +++ b/secop_mlz/amagnet.py @@ -28,12 +28,11 @@ Supporting classes for FRM2 magnets, currently only Garfield (amagnet). import math -from secop.lib import lazy_property, mkthread from secop.lib.sequence import SequencerMixin, Step from secop.protocol import status -from secop.datatypes import * -from secop.errors import SECoPServerError, ConfigError, ProgrammingError, CommunicationError, HardwareError, DisabledError -from secop.modules import PARAM, CMD, OVERRIDE, Readable, Drivable +from secop.datatypes import StringType, TupleOf, FloatRange, ArrayOf, StructOf +from secop.errors import DisabledError, ConfigError +from secop.modules import PARAM, Drivable class GarfieldMagnet(SequencerMixin, Drivable): @@ -132,7 +131,7 @@ class GarfieldMagnet(SequencerMixin, Drivable): trycurr = (maxcurr - mincurr) * ratio + mincurr self.log.debug('current for %g T is %g A', field, trycurr) return trycurr # interpolated - raise ConfigurationError(self, + raise ConfigError(self, '_current2field polynome not monotonic!') def init(self): @@ -195,6 +194,7 @@ class GarfieldMagnet(SequencerMixin, Drivable): def _set_field_polarity(self, polarity): current_pol = self._get_field_polarity() + polarity = int(polarity) if current_pol == polarity: return if polarity == 0: @@ -202,7 +202,7 @@ class GarfieldMagnet(SequencerMixin, Drivable): if current_pol == 0: # safe to switch self._polswitch.write_target( - '+1' if polarity == 1 else str(polarity)) + '+1' if polarity > 0 else str(polarity)) return 0 if self._currentsource.value < 0.1: self._polswitch.write_target('0') @@ -222,8 +222,7 @@ class GarfieldMagnet(SequencerMixin, Drivable): if self._enable.read_status(maxage)[0] != status.OK: return self._enable.status if self._polswitch.value in ['0', 0]: - return self._currentsource.status[ - 0], 'Shorted, ' + self._currentsource.status[1] + return status.OK, 'Shorted, ' + self._currentsource.status[1] if self._symmetry.value in ['short', 0]: return self._currentsource.status[ 0], 'Shorted, ' + self._currentsource.status[1] @@ -236,7 +235,7 @@ class GarfieldMagnet(SequencerMixin, Drivable): wanted_current = self._field2current(abs(target)) wanted_polarity = -1 if target < 0 else (+1 if target else 0) - current_polarity = self._get_field_polarity() + current_polarity = int(self._get_field_polarity()) # generate Step sequence and start it seq = [] @@ -320,7 +319,7 @@ class GarfieldMagnet(SequencerMixin, Drivable): def _set_polarity(self, store, target): if self._polswitch.read_status(0)[0] == status.BUSY: return True - if self._polswitch.value == target: + if int(self._polswitch.value) == int(target): return False # done with this step if self._polswitch.read_value(0) != 0: self._polswitch.write_target(0)