diff --git a/secop_psi/ips_mercury.py b/secop_psi/ips_mercury.py index ebd07e4..f74972a 100644 --- a/secop_psi/ips_mercury.py +++ b/secop_psi/ips_mercury.py @@ -20,6 +20,7 @@ # ***************************************************************************** """oxford instruments mercury IPS power supply""" +import time from secop.core import Parameter, EnumType, FloatRange, BoolType from secop.lib.enum import Enum from secop.errors import BadValueError, HardwareError @@ -51,6 +52,7 @@ class Field(MercuryChannel, Magfield): nslaves = 3 slave_currents = None __init = True + __reset_switch_time = False def doPoll(self): super().doPoll() @@ -62,7 +64,7 @@ class Field(MercuryChannel, Magfield): if self.__init: self.__init = False 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._field_mismatch = False return self.current @@ -94,7 +96,18 @@ class Field(MercuryChannel, Magfield): return self.change('PSU:ACTN', value, hold_rtoz_rtos_clmp) 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): return self.change('PSU:SIG:SWHT', value, off_on) diff --git a/secop_psi/magfield.py b/secop_psi/magfield.py index 1d800b2..ef90bc2 100644 --- a/secop_psi/magfield.py +++ b/secop_psi/magfield.py @@ -44,6 +44,9 @@ Status = Enum( FINALIZING=390, ) +OFF = 0 +ON = 1 + class Magfield(HasLimits, Drivable): 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) tolerance = Parameter( '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) persistent_field = Parameter( 'persistent field', FloatRange(unit='$'), readonly=False) @@ -87,8 +90,7 @@ class Magfield(HasLimits, Drivable): _state = None __init = True _last_target = None - switch_on_time = None - switch_off_time = None + switch_time = None, None def doPoll(self): if self.__init: @@ -185,14 +187,11 @@ class Magfield(HasLimits, Drivable): def update_switch_heater(self, value): """is called whenever switch heater was changed""" - if value != 0: - self.switch_off_time = None - if self.switch_on_time is None: - self.switch_on_time = time.time() - else: - self.switch_on_time = None - if self.switch_off_time is None: - self.switch_off_time = time.time() + switch_time = self.switch_time[value] + if switch_time is None: + switch_time = time.time() + self.switch_time = [None, None] + self.switch_time[value] = switch_time def start_switch_on(self, state): """switch heater on""" @@ -213,12 +212,10 @@ class Magfield(HasLimits, Drivable): abs(self.target - self.persistent_field) <= self.tolerance): # short cut return self.check_switch_off self.read_switch_heater() - if self.switch_on_time is None: - if state.now - self.switch_off_time > 10: - self.log.warning('switch turned off manually?') - return self.start_switch_on - return Retry() - if state.now - self.switch_on_time < self.wait_switch_on: + if self.switch_time[ON] is None: + self.log.warning('switch turned off manually?') + return self.start_switch_on + if state.now - self.switch_time[ON] < self.wait_switch_on: return Retry() self._last_target = self.target return self.start_ramp_to_target @@ -279,12 +276,10 @@ class Magfield(HasLimits, Drivable): return self.start_switch_on self.persistent_field = self.value self.read_switch_heater() - if self.switch_off_time is None: - if state.now - self.switch_on_time > 10: - self.log.warning('switch turned on manually?') - return self.start_switch_off - return Retry() - if state.now - self.switch_off_time < self.wait_switch_off: + if self.switch_time[OFF] is None: + self.log.warning('switch turned on manually?') + return self.start_switch_off + if state.now - self.switch_time[OFF] < self.wait_switch_off: return Retry() if abs(self.value) > self.persistent_limit: self.status = Status.IDLE, 'leads current at field, switch off'