fix amagnet

Change-Id: I6f1dedd5dfdd10cc828e27ea22440c35a25c2b9d
Reviewed-on: https://forge.frm2.tum.de/review/16790
Tested-by: JenkinsCodeReview <bjoern_pedersen@frm2.tum.de>
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
2017-11-30 10:29:43 +01:00
parent 4cf4ecb507
commit 4b02a4c82e
4 changed files with 35 additions and 50 deletions

View File

@ -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

View File

@ -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

View File

@ -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)
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

View File

@ -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)