rework switch timing

- specific things in ips_mercury.py
- general things in magfield.py

Change-Id: I7c2bae815b9a80a17803b44b8941ef3dea3adb60
This commit is contained in:
zolliker 2022-09-14 13:58:12 +02:00
parent c3f55435da
commit b0315e133b
2 changed files with 33 additions and 25 deletions

View File

@ -20,6 +20,7 @@
# ***************************************************************************** # *****************************************************************************
"""oxford instruments mercury IPS power supply""" """oxford instruments mercury IPS power supply"""
import time
from secop.core import Parameter, EnumType, FloatRange, BoolType from secop.core import Parameter, EnumType, FloatRange, BoolType
from secop.lib.enum import Enum from secop.lib.enum import Enum
from secop.errors import BadValueError, HardwareError from secop.errors import BadValueError, HardwareError
@ -51,6 +52,7 @@ class Field(MercuryChannel, Magfield):
nslaves = 3 nslaves = 3
slave_currents = None slave_currents = None
__init = True __init = True
__reset_switch_time = False
def doPoll(self): def doPoll(self):
super().doPoll() super().doPoll()
@ -62,7 +64,7 @@ class Field(MercuryChannel, Magfield):
if self.__init: if self.__init:
self.__init = False self.__init = False
self.persistent_field = pf self.persistent_field = pf
if self.switch_heater != 0 or self._field_mismatch is None: if self.switch_heater == self.switch_heater.on or self._field_mismatch is None:
self.forced_persistent_field = False self.forced_persistent_field = False
self._field_mismatch = False self._field_mismatch = False
return self.current return self.current
@ -94,7 +96,18 @@ class Field(MercuryChannel, Magfield):
return self.change('PSU:ACTN', value, hold_rtoz_rtos_clmp) return self.change('PSU:ACTN', value, hold_rtoz_rtos_clmp)
def read_switch_heater(self): def read_switch_heater(self):
return self.query('PSU:SIG:SWHT', off_on) value = self.query('PSU:SIG:SWHT', off_on)
now = time.time()
switch_time = self.switch_time[self.switch_heater]
if value != self.switch_heater:
self.__reset_switch_time = True
if now < (switch_time or 0) + 10:
# probably switch heater was changed, but IPS reply is not yet updated
return self.switch_heater
elif self.__reset_switch_time:
self.__reset_switch_time = False
self.switch_time = [None, None]
return value
def write_switch_heater(self, value): def write_switch_heater(self, value):
return self.change('PSU:SIG:SWHT', value, off_on) return self.change('PSU:SIG:SWHT', value, off_on)

View File

@ -44,6 +44,9 @@ Status = Enum(
FINALIZING=390, FINALIZING=390,
) )
OFF = 0
ON = 1
class Magfield(HasLimits, Drivable): class Magfield(HasLimits, Drivable):
value = Parameter('magnetic field', datatype=FloatRange(unit='T')) value = Parameter('magnetic field', datatype=FloatRange(unit='T'))
@ -52,7 +55,7 @@ class Magfield(HasLimits, Drivable):
'persistent mode', EnumType(Mode), readonly=False, default=Mode.PERSISTENT) 'persistent mode', EnumType(Mode), readonly=False, default=Mode.PERSISTENT)
tolerance = Parameter( tolerance = Parameter(
'tolerance', FloatRange(0, unit='$'), readonly=False, default=0.0002) 'tolerance', FloatRange(0, unit='$'), readonly=False, default=0.0002)
switch_heater = Parameter('switch heater', EnumType(off=0, on=1), switch_heater = Parameter('switch heater', EnumType(off=OFF, on=ON),
readonly=False, default=0) readonly=False, default=0)
persistent_field = Parameter( persistent_field = Parameter(
'persistent field', FloatRange(unit='$'), readonly=False) 'persistent field', FloatRange(unit='$'), readonly=False)
@ -87,8 +90,7 @@ class Magfield(HasLimits, Drivable):
_state = None _state = None
__init = True __init = True
_last_target = None _last_target = None
switch_on_time = None switch_time = None, None
switch_off_time = None
def doPoll(self): def doPoll(self):
if self.__init: if self.__init:
@ -185,14 +187,11 @@ class Magfield(HasLimits, Drivable):
def update_switch_heater(self, value): def update_switch_heater(self, value):
"""is called whenever switch heater was changed""" """is called whenever switch heater was changed"""
if value != 0: switch_time = self.switch_time[value]
self.switch_off_time = None if switch_time is None:
if self.switch_on_time is None: switch_time = time.time()
self.switch_on_time = time.time() self.switch_time = [None, None]
else: self.switch_time[value] = switch_time
self.switch_on_time = None
if self.switch_off_time is None:
self.switch_off_time = time.time()
def start_switch_on(self, state): def start_switch_on(self, state):
"""switch heater on""" """switch heater on"""
@ -213,12 +212,10 @@ class Magfield(HasLimits, Drivable):
abs(self.target - self.persistent_field) <= self.tolerance): # short cut abs(self.target - self.persistent_field) <= self.tolerance): # short cut
return self.check_switch_off return self.check_switch_off
self.read_switch_heater() self.read_switch_heater()
if self.switch_on_time is None: if self.switch_time[ON] is None:
if state.now - self.switch_off_time > 10: self.log.warning('switch turned off manually?')
self.log.warning('switch turned off manually?') return self.start_switch_on
return self.start_switch_on if state.now - self.switch_time[ON] < self.wait_switch_on:
return Retry()
if state.now - self.switch_on_time < self.wait_switch_on:
return Retry() return Retry()
self._last_target = self.target self._last_target = self.target
return self.start_ramp_to_target return self.start_ramp_to_target
@ -279,12 +276,10 @@ class Magfield(HasLimits, Drivable):
return self.start_switch_on return self.start_switch_on
self.persistent_field = self.value self.persistent_field = self.value
self.read_switch_heater() self.read_switch_heater()
if self.switch_off_time is None: if self.switch_time[OFF] is None:
if state.now - self.switch_on_time > 10: self.log.warning('switch turned on manually?')
self.log.warning('switch turned on manually?') return self.start_switch_off
return self.start_switch_off if state.now - self.switch_time[OFF] < self.wait_switch_off:
return Retry()
if state.now - self.switch_off_time < self.wait_switch_off:
return Retry() return Retry()
if abs(self.value) > self.persistent_limit: if abs(self.value) > self.persistent_limit:
self.status = Status.IDLE, 'leads current at field, switch off' self.status = Status.IDLE, 'leads current at field, switch off'