make return value 'Done' unneccessary
'Done' was introduced in order to suppress unneccessary duplicate updates. However, since super calls on access methods are allowed, it is not nice when such a method returns Done, as this is not automagically replaced by the current parameter value. As a consequence: - using Done is discouraged, but not (yet) removed in all code - the 'omit_unchanged_within' property is moved from Module to an internal Parameter property 'update_unchanged' - its default is moved from a SEC node property to generalConfig - the 'update_unchanged' parameter property may be set to 'never' for parameters where duplicate updates make no sense - this property might be set to 'always', for measurements, where even unchanged values taken from HW should be transmitted Change-Id: I2847c983ca09c2c4098e402edd08d0c96c3913f4 Reviewed-on: https://forge.frm2.tum.de/review/c/secop/frappy/+/30672 Tested-by: Jenkins Automated Tests <pedersen+jenkins@frm2.tum.de> Reviewed-by: Markus Zolliker <markus.zolliker@psi.ch>
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
# *****************************************************************************
|
||||
"""Andeen Hagerling capacitance bridge"""
|
||||
|
||||
from frappy.core import Done, FloatRange, HasIO, Parameter, Readable, StringIO, nopoll
|
||||
from frappy.core import FloatRange, HasIO, Parameter, Readable, StringIO, nopoll
|
||||
|
||||
|
||||
class Ah2700IO(StringIO):
|
||||
@@ -43,7 +43,7 @@ class Capacitance(HasIO, Readable):
|
||||
reply = self.communicate('SI')
|
||||
if not reply.startswith('F='): # this is probably an error message like "LOSS TOO HIGH"
|
||||
self.status = [self.Status.ERROR, reply]
|
||||
return
|
||||
return self.value
|
||||
self.status = [self.Status.IDLE, '']
|
||||
# examples of replies:
|
||||
# 'F= 1000.0 HZ C= 0.000001 PF L> 0.0 DS V= 15.0 V'
|
||||
@@ -55,7 +55,6 @@ class Capacitance(HasIO, Readable):
|
||||
_, freq, _, _, cap, _, _, loss, lossunit, _, volt = reply[:11]
|
||||
self.freq = freq
|
||||
self.voltage = volt
|
||||
self.value = cap
|
||||
if lossunit == 'DS':
|
||||
self.loss = loss
|
||||
else: # the unit was wrong, we want DS = tan(delta), not NS = nanoSiemens
|
||||
@@ -64,30 +63,30 @@ class Capacitance(HasIO, Readable):
|
||||
self.loss = reply[7]
|
||||
except IndexError:
|
||||
pass # don't worry, loss will be updated next time
|
||||
return cap
|
||||
|
||||
def read_value(self):
|
||||
self.parse_reply(self.communicate('SI')) # SI = single trigger
|
||||
return Done
|
||||
return self.parse_reply(self.communicate('SI')) # SI = single trigger
|
||||
|
||||
@nopoll
|
||||
def read_freq(self):
|
||||
self.read_value()
|
||||
return Done
|
||||
return self.freq
|
||||
|
||||
@nopoll
|
||||
def read_loss(self):
|
||||
self.read_value()
|
||||
return Done
|
||||
return self.loss
|
||||
|
||||
@nopoll
|
||||
def read_voltage(self):
|
||||
self.read_value()
|
||||
return Done
|
||||
return self.voltage
|
||||
|
||||
def write_freq(self, value):
|
||||
self.parse_reply(self.communicate('FR %g;SI' % value))
|
||||
return Done
|
||||
self.value = self.parse_reply(self.communicate('FR %g;SI' % value))
|
||||
return self.freq
|
||||
|
||||
def write_voltage(self, value):
|
||||
self.parse_reply(self.communicate('V %g;SI' % value))
|
||||
return Done
|
||||
self.value = self.parse_reply(self.communicate('V %g;SI' % value))
|
||||
return self.voltage
|
||||
|
||||
@@ -39,7 +39,7 @@ switcher=sw
|
||||
import time
|
||||
|
||||
from frappy.datatypes import IntRange, BoolType, FloatRange
|
||||
from frappy.core import Attached, Property, Drivable, Parameter, Readable, Done
|
||||
from frappy.core import Attached, Property, Drivable, Parameter, Readable
|
||||
|
||||
|
||||
class ChannelSwitcher(Drivable):
|
||||
@@ -55,6 +55,7 @@ class ChannelSwitcher(Drivable):
|
||||
"""
|
||||
value = Parameter('the current channel number', IntRange(), needscfg=False)
|
||||
target = Parameter('channel to select', IntRange(), needscfg=False)
|
||||
status = Parameter(update_unchanged='never')
|
||||
autoscan = Parameter('whether to scan automatically',
|
||||
BoolType(), readonly=False, default=True)
|
||||
pollinterval = Parameter(default=1, export=False)
|
||||
@@ -108,7 +109,7 @@ class ChannelSwitcher(Drivable):
|
||||
if self.status[0] == 'BUSY':
|
||||
chan = self._channels[self.target]
|
||||
if chan.is_switching(now, self._start_switch, self.switch_delay):
|
||||
return Done
|
||||
return self.status
|
||||
self.setFastPoll(False)
|
||||
self.status = 'IDLE', 'measure'
|
||||
self.value = self.target
|
||||
@@ -116,7 +117,7 @@ class ChannelSwitcher(Drivable):
|
||||
chan.read_value()
|
||||
chan.read_status()
|
||||
if self.measure_delay > self._time_tol:
|
||||
return Done
|
||||
return self.status
|
||||
else:
|
||||
chan = self._channels[self.value]
|
||||
self.read_value() # this might modify autoscan or deadline!
|
||||
@@ -129,7 +130,7 @@ class ChannelSwitcher(Drivable):
|
||||
chan.read_status()
|
||||
self._last_measure = next_measure
|
||||
if not self.autoscan or now + self._time_tol < self._start_measure + self.measure_delay:
|
||||
return Done
|
||||
return self.status
|
||||
next_channel = self.next_channel(self.value)
|
||||
if next_channel == self.value:
|
||||
return 'IDLE', 'single channel'
|
||||
|
||||
@@ -26,7 +26,7 @@ import re
|
||||
import time
|
||||
|
||||
from frappy.core import Drivable, HasIO, Writable, \
|
||||
Parameter, Property, Readable, StringIO, Attached, Done, IDLE, nopoll
|
||||
Parameter, Property, Readable, StringIO, Attached, IDLE, nopoll
|
||||
from frappy.datatypes import EnumType, FloatRange, StringType, StructOf, BoolType
|
||||
from frappy.errors import HardwareError
|
||||
from frappy_psi.convergence import HasConvergence
|
||||
@@ -70,7 +70,7 @@ class MercuryChannel(HasIO):
|
||||
example: DB6.T1,DB1.H1
|
||||
slot ids for sensor (and control output)''',
|
||||
StringType())
|
||||
channel_name = Parameter('mercury nick name', StringType(), default='')
|
||||
channel_name = Parameter('mercury nick name', StringType(), default='', update_unchanged='never')
|
||||
channel_type = '' #: channel type(s) for sensor (and control) e.g. TEMP,HTR or PRES,AUX
|
||||
|
||||
def _complete_adr(self, adr):
|
||||
@@ -158,7 +158,7 @@ class MercuryChannel(HasIO):
|
||||
|
||||
def read_channel_name(self):
|
||||
if self.channel_name:
|
||||
return Done # channel name will not change
|
||||
return self.channel_name # channel name will not change
|
||||
return self.query('0:NICK', as_string)
|
||||
|
||||
|
||||
@@ -189,14 +189,14 @@ class HasInput(MercuryChannel):
|
||||
|
||||
def write_controlled_by(self, value):
|
||||
if self.controlled_by == value:
|
||||
return Done
|
||||
return value
|
||||
self.controlled_by = value
|
||||
if value == SELF:
|
||||
self.log.warning('switch to manual mode')
|
||||
for input_module in self.input_modules:
|
||||
if input_module.control_active:
|
||||
input_module.write_control_active(False)
|
||||
return Done
|
||||
return value
|
||||
|
||||
|
||||
class Loop(HasConvergence, MercuryChannel, Drivable):
|
||||
@@ -261,7 +261,8 @@ class HeaterOutput(HasInput, MercuryChannel, Writable):
|
||||
"""
|
||||
channel_type = 'HTR'
|
||||
value = Parameter('heater output', FloatRange(unit='W'), readonly=False)
|
||||
target = Parameter('heater output', FloatRange(0, 100, unit='$'), readonly=False)
|
||||
status = Parameter(update_unchanged='never')
|
||||
target = Parameter('heater output', FloatRange(0, 100, unit='$'), readonly=False, update_unchanged='never')
|
||||
resistivity = Parameter('heater resistivity', FloatRange(10, 1000, unit='Ohm'),
|
||||
readonly=False)
|
||||
true_power = Parameter('calculate power from measured current', BoolType(), readonly=False, default=True)
|
||||
@@ -288,13 +289,10 @@ class HeaterOutput(HasInput, MercuryChannel, Writable):
|
||||
if not self.true_power:
|
||||
self._volt_target = math.sqrt(self._last_target * self.resistivity)
|
||||
self.change('HTR:SIG:VOLT', self._volt_target)
|
||||
return Done
|
||||
return self.resistivity
|
||||
|
||||
def read_status(self):
|
||||
status = IDLE, ('true power' if self.true_power else 'fixed resistivity')
|
||||
if self.status != status:
|
||||
return status
|
||||
return Done
|
||||
return IDLE, ('true power' if self.true_power else 'fixed resistivity')
|
||||
|
||||
def read_value(self):
|
||||
if self._last_target is None: # on init
|
||||
@@ -317,7 +315,7 @@ class HeaterOutput(HasInput, MercuryChannel, Writable):
|
||||
if self.controlled_by != 0 and self.target:
|
||||
return 0
|
||||
if self._last_target is not None:
|
||||
return Done
|
||||
return self.target
|
||||
self._volt_target = self.query('HTR:SIG:VOLT')
|
||||
self.resistivity = max(10, self.query('HTR:RES'))
|
||||
self._last_target = self._volt_target ** 2 / max(10, self.resistivity)
|
||||
@@ -389,7 +387,7 @@ class TemperatureLoop(TemperatureSensor, Loop, Drivable):
|
||||
self.set_target(value)
|
||||
else:
|
||||
self.set_target(target)
|
||||
return Done
|
||||
return self.target
|
||||
|
||||
def read_enable_ramp(self):
|
||||
return self.query('TEMP:LOOP:RENA', off_on)
|
||||
@@ -472,7 +470,7 @@ class PressureLoop(PressureSensor, Loop, Drivable):
|
||||
def write_target(self, value):
|
||||
target = self.change('PRES:LOOP:PRST', value)
|
||||
self.set_target(target)
|
||||
return Done
|
||||
return self.target
|
||||
|
||||
|
||||
class HeLevel(MercuryChannel, Readable):
|
||||
|
||||
@@ -44,7 +44,7 @@ lowspeed = 50 # speed for final closing / reference run
|
||||
"""
|
||||
|
||||
from frappy.core import Drivable, Parameter, EnumType, Attached, FloatRange, \
|
||||
Command, IDLE, BUSY, WARN, ERROR, Done, PersistentParam, PersistentMixin
|
||||
Command, IDLE, BUSY, WARN, ERROR, PersistentParam, PersistentMixin
|
||||
from frappy.errors import HardwareError
|
||||
from frappy_psi.trinamic import Motor
|
||||
from frappy.lib.statemachine import StateMachine, Retry, Stop
|
||||
@@ -53,7 +53,7 @@ from frappy.lib.statemachine import StateMachine, Retry, Stop
|
||||
class MotorValve(PersistentMixin, Drivable):
|
||||
motor = Attached(Motor)
|
||||
value = Parameter('current state', EnumType(
|
||||
closed=0, opened=1, undefined=-1), default=-1)
|
||||
closed=0, opened=1, undefined=-1), default=-1, update_unchanged='never')
|
||||
target = Parameter('target state', EnumType(close=0, open=1))
|
||||
turns = Parameter('number of turns to open', FloatRange(), readonly=False, group='settings')
|
||||
speed = Parameter('speed for far moves', FloatRange(), readonly=False, group='settings')
|
||||
@@ -75,7 +75,7 @@ class MotorValve(PersistentMixin, Drivable):
|
||||
raise HardwareError('%s: need refrun' % self.status[1])
|
||||
self.target = target
|
||||
self._state.start(self.goto_target, count=3)
|
||||
return Done
|
||||
return self.target
|
||||
|
||||
def goto_target(self, state):
|
||||
self.value = 'undefined'
|
||||
@@ -90,7 +90,7 @@ class MotorValve(PersistentMixin, Drivable):
|
||||
if self.status[0] == ERROR:
|
||||
return 'undefined'
|
||||
if self.motor.isBusy():
|
||||
return Done
|
||||
return self.value
|
||||
motpos = self.motor.read_value()
|
||||
if self.motor.read_home():
|
||||
if motpos > 360:
|
||||
|
||||
@@ -40,7 +40,7 @@ from frappy.datatypes import BoolType, EnumType, \
|
||||
from frappy.errors import HardwareError
|
||||
from frappy.lib import clamp
|
||||
from frappy.lib.enum import Enum
|
||||
from frappy.modules import Communicator, Done, \
|
||||
from frappy.modules import Communicator, \
|
||||
Drivable, Parameter, Property, Readable
|
||||
from frappy.io import HasIO
|
||||
from frappy.rwhandler import CommonReadHandler, CommonWriteHandler
|
||||
@@ -478,16 +478,14 @@ class Temp(PpmsDrivable):
|
||||
def write_approachmode(self, value):
|
||||
if self.isDriving():
|
||||
self._write_params(self.setpoint, self.ramp, value)
|
||||
return Done
|
||||
self.approachmode = value
|
||||
return Done # do not execute TEMP command, as this would trigger an unnecessary T change
|
||||
return self.approachmode
|
||||
return value # do not execute TEMP command, as this would trigger an unnecessary T change
|
||||
|
||||
def write_ramp(self, value):
|
||||
if self.isDriving():
|
||||
self._write_params(self.setpoint, value, self.approachmode)
|
||||
return Done
|
||||
self.ramp = value
|
||||
return Done # do not execute TEMP command, as this would trigger an unnecessary T change
|
||||
return self.ramp
|
||||
return value # do not execute TEMP command, as this would trigger an unnecessary T change
|
||||
|
||||
def calc_expected(self, target, ramp):
|
||||
self._expected_target_time = time.time() + abs(target - self.value) * 60.0 / max(0.1, ramp)
|
||||
@@ -606,7 +604,7 @@ class Field(PpmsDrivable):
|
||||
self._last_change = time.time()
|
||||
self.status = (self.Status.BUSY, 'changed target')
|
||||
self._write_params(target, self.ramp, self.approachmode, self.persistentmode)
|
||||
return Done
|
||||
return self.target
|
||||
|
||||
def write_persistentmode(self, mode):
|
||||
if abs(self.target - self.value) <= 2e-5 and mode == self.persistentmode:
|
||||
@@ -617,20 +615,18 @@ class Field(PpmsDrivable):
|
||||
self._stopped = False
|
||||
self.status = (self.Status.BUSY, 'changed persistent mode')
|
||||
self._write_params(self.target, self.ramp, self.approachmode, mode)
|
||||
return Done
|
||||
return self.persistentmode
|
||||
|
||||
def write_ramp(self, value):
|
||||
self.ramp = value
|
||||
if self.isDriving():
|
||||
self._write_params(self.target, value, self.approachmode, self.persistentmode)
|
||||
return Done
|
||||
return None # do not execute FIELD command, as this would trigger a ramp up of leads current
|
||||
return self.ramp
|
||||
return value # do not execute FIELD command, as this would trigger a ramp up of leads current
|
||||
|
||||
def write_approachmode(self, value):
|
||||
if self.isDriving():
|
||||
self._write_params(self.target, self.ramp, value, self.persistentmode)
|
||||
return Done
|
||||
return None # do not execute FIELD command, as this would trigger a ramp up of leads current
|
||||
# do not execute FIELD command, as this would trigger a ramp up of leads current
|
||||
|
||||
def stop(self):
|
||||
if not self.isDriving():
|
||||
@@ -728,14 +724,13 @@ class Position(PpmsDrivable):
|
||||
self._status_before_change = self.status
|
||||
self.status = (self.Status.BUSY, 'changed target')
|
||||
self._write_params(target, self.speed)
|
||||
return Done
|
||||
return self.target
|
||||
|
||||
def write_speed(self, value):
|
||||
if self.isDriving():
|
||||
self._write_params(self.target, value)
|
||||
return Done
|
||||
self.speed = value
|
||||
return None # do not execute MOVE command, as this would trigger an unnecessary move
|
||||
return self.speed
|
||||
return value # do not execute MOVE command, as this would trigger an unnecessary move
|
||||
|
||||
def stop(self):
|
||||
if not self.isDriving():
|
||||
|
||||
@@ -28,7 +28,7 @@ import numpy as np
|
||||
from scipy.interpolate import splev, splrep # pylint: disable=import-error
|
||||
|
||||
from frappy.core import Attached, BoolType, Parameter, Readable, StringType, \
|
||||
FloatRange, Done
|
||||
FloatRange
|
||||
|
||||
|
||||
def linear(x):
|
||||
@@ -95,7 +95,7 @@ class Parser340(StdParser):
|
||||
KINDS = {
|
||||
"340": (Parser340, {}), # lakeshore 340 format
|
||||
"inp": (StdParser, {}), # M. Zollikers *.inp calcurve format
|
||||
"caldat": (StdParser, dict(x=1, y=2)), # format from sea/tcl/startup/calib_ext.tcl
|
||||
"caldat": (StdParser, {'x': 1, 'y': 2}), # format from sea/tcl/startup/calib_ext.tcl
|
||||
"dat": (StdParser, {}), # lakeshore raw data *.dat format
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ class Sensor(Readable):
|
||||
abs = Parameter('True: take abs(raw) before calib', datatype=BoolType(), readonly=False, default=True)
|
||||
value = Parameter(datatype=FloatRange(unit='K'))
|
||||
pollinterval = Parameter(export=False)
|
||||
status = Parameter(default=(Readable.Status.ERROR, 'unintialized'))
|
||||
status = Parameter(default=(Readable.Status.ERROR, 'unintialized'), update_unchanged='never')
|
||||
|
||||
description = 'a calibrated sensor value'
|
||||
_value_error = None
|
||||
@@ -227,4 +227,4 @@ class Sensor(Readable):
|
||||
|
||||
def read_status(self):
|
||||
self.update_status(self.rawsensor.status)
|
||||
return Done
|
||||
return self.status
|
||||
|
||||
Reference in New Issue
Block a user