From 6fa4698648685af7e7e22792d1e95381f8f254cc Mon Sep 17 00:00:00 2001 From: Markus Zolliker Date: Wed, 12 Aug 2026 16:45:02 +0200 Subject: [PATCH] DIL5: improved version after tests 2026-08-12 --- cfg/dil5_cfg.py | 20 ++++-- frappy_psi/dilution.py | 140 +++++++++-------------------------------- 2 files changed, 46 insertions(+), 114 deletions(-) diff --git a/cfg/dil5_cfg.py b/cfg/dil5_cfg.py index 0be95dd8..dea8aff5 100644 --- a/cfg/dil5_cfg.py +++ b/cfg/dil5_cfg.py @@ -210,7 +210,6 @@ Mod('MV12', ) Mod('MV11', - 'frappy_psi.manual_valves.ManualValve', 'Manual Valve MV11' ) @@ -240,12 +239,15 @@ Mod('T_one_K', io='itc', ) +''' +defect Mod('T_mix_wup', 'frappy_psi.mercury.TemperatureLoop', 'mix. chamber warmup temperature', slot='DB6.T1', io='itc', ) +''' Mod('T_ivc_wup', 'frappy_psi.mercury.TemperatureLoop', @@ -254,12 +256,15 @@ Mod('T_ivc_wup', io='itc', ) +''' +not useful Mod('T_cond', 'frappy_psi.mercury.TemperatureLoop', 'condenser temperature', slot='DB8.T1', io='itc', ) +''' Mod('safety', 'frappy_psi.dilution.Interlock', @@ -285,8 +290,9 @@ Mod('dil', still_pressure_turbo = "p3", #ls372 = "res1", dump_pressure = "p1", - condensing_p_low = 1200, - condensing_p_high = 1500, + condensing_p_low = 1400, + condensing_p_high = 1700, + dump_low = 20, ) ## Dilution lakeshore Temperature controller @@ -318,10 +324,14 @@ Mod('T_still', ) Mod('T_sorb', - 'frappy_psi.ls372.TemperatureChannel', + 'frappy_psi.dilution.SorbTemp', 'mix temperature chan 1', channel = 1, switcher = 'sw', + output_module='htr_sorb', + p=10, + i=10, + output_max=2, ) Mod('T_cp', @@ -341,7 +351,7 @@ Mod('T_mix', ) Mod('htr_sorb', - 'frappy_psi.ls372.SorbHeater', + 'frappy_psi.dilution.SorbHeater', 'sorb heater', io = 'io_ls', output = 1, diff --git a/frappy_psi/dilution.py b/frappy_psi/dilution.py index 1f0dee0c..149c391e 100644 --- a/frappy_psi/dilution.py +++ b/frappy_psi/dilution.py @@ -35,25 +35,6 @@ from frappy.ctrlby import WrapControlledBy import frappy_psi.ls372 as ls372 -T = Enum( # target states - off = 0, - sorbpumped = 2, - condense = 5, - remove = 7, - remove_and_sorbpump = 9, - remove_and_condense = 10, - manual = 11, - test = 12, - ) - -V = Enum(T, # value status inherits from target status - sorbpumping=1, - condensing=4, - circulating=6, - removing=8, - ) - - class Dilution(HasStates, Drivable): condenseline_pressure = Attached() condense_valve = Attached() @@ -67,22 +48,16 @@ class Dilution(HasStates, Drivable): still_pressure = Attached() still_pressure_turbo = Attached(mandatory=False) - vti_temp = Attached() - sorb_temp = Attached() dump_pressure = Attached() - mix_temp = Attached() - nv_flow = Attached() - still_htr = Attached() - value = Parameter('current state', EnumType(T), default=0) - target = Parameter('target state', EnumType(T), default=0) - - sorbpumped = Parameter('sorb pump done', BoolType(), default=False) + value = Parameter('current state', StringType(), default='') + target = Parameter('target state', StringType(), default='') condensing_p_low = Parameter('lower limit for condenseline pressure', FloatRange(unit='mbar'), readonly=False, default=1400) condensing_p_high = Parameter('upper limit for condenseline pressure', FloatRange(unit='mbar'), readonly=False, default=1700) + sorbpumped = Parameter('sorb pump done', BoolType(), readonly=False, default=False) sorb_pump_time = Parameter('sorb pump time', FloatRange(unit='s'), default=2400, readonly=False) sorb_pump_temp = Parameter('sorb pump temperature', FloatRange(unit='K'), default=40, readonly=False) condense_flow = Parameter('condense nv flow', FloatRange(unit='mbar'), default=12, readonly=False) @@ -100,7 +75,7 @@ class Dilution(HasStates, Drivable): turbo_off_speed = Parameter('speed to wait for after switching turbo off', FloatRange(unit='Hz'), readonly=False, default=200) end_remove_turbo_pressure = Parameter('pressure reached before end of remove (before turbo)', - FloatRange(unit='mbar'), readonly=False, default=1e-4) + FloatRange(unit='mbar'), readonly=False, default=3e-4) end_remove_pressure = Parameter('pressure reached before end of remove (before fore pump)', FloatRange(unit='mbar'), readonly=False, default=0.02) st = StringType() @@ -109,74 +84,35 @@ class Dilution(HasStates, Drivable): valves_after_remove = Parameter('valve to act after remove', valve_set) check_after_remove = Parameter('check for manual valves after remove', valve_set) - # table reads as: up to a dump pressure of 250 mbar heat VTI to 2 K - remove_temp_profile = (250, 2), (400, 3), (500, 5), (9999, 10) - _start_time = 0 init = True _warn_manual_work = None def write_target(self, target): - """ - if (target == Targetstates.SORBPUMP): - if self.value == target: - return self.target - self.start_machine(self.sorbpump) - self.value = Targetstates.SORBPUMP - return self.value - """ - self.log.info('start %s', target.name) - if self.value == target: - return target # not sure if this is correct. may be a step wants to be repeated? - - try: - self.start_machine(getattr(self, target.name, None)) - except Exception as e: - self.log.exception('error') - self.log.info('started %s', target.name) - + self.log.info('start %s', target) + if target == 'condense': + self.start_machine(self.start_condense) + elif target == 'remove': + self.start_machine(self.start_remove) + else: + raise RangeError(r'invalid command {target!r}') + self.log.info('started %s', target) return target - @Command() - def sorb_pump(self): - """start sorb pump followed by condense""" - try: - self.start_machine(self.sorbpump) - except Exception as e: - self.log.exception('error') + @Command + def condense(self): + """condense mixture""" + self.start_machine(self.start_condense) - @Command() - def start_condense(self): - """condense""" - try: - self.start_machine(self.condense) - except Exception as e: - self.log.exception('error') + @Command + def remove(self): + """remove mixture""" + self.start_machine(self.start_remove) @status_code(BUSY) - def sorbpump(self, state): - """ heat up to Tsorb and wait """ - if state.init: - self._start_time = state.now - self.vti_temp.auto_flow = True - self.vti_temp.flowpars = ((1.0, 5.0), (4.0, 20.0)) # increase base flow slighly - self.vti_temp.write_target(6) - self.sorb_temp.write_target(self.sorb_pump_temp) # TODO: make variable - return Retry - if state.now - self._start_time < self.sorb_pump_time: - return Retry - self.sorb_temp.write_target(1.25) - self.still_htr.write_target(0) - self.mix_temp.control_off() - self.vti_temp.write_target(1.25) - self.nv_flow.write_target(self.condense_flow) - return self.condense - - @status_code(BUSY) - def condense(self, state): + def start_condense(self, state): """Führt das Kondensationsverfahren durch.""" if state.init: - # self.value = V.condensing pumpstate = self.forepump.read_value() if self.turbopump: self.turbopump.write_target(0) @@ -238,38 +174,23 @@ class Dilution(HasStates, Drivable): def circulate(self, state): """Zirkuliert die Mischung.""" if state.init: - self.nv_flow.write_target(self.circulate_flow) - # self.value = V.circulating self.handle_valves(**self.condense_valves) if self.wait_valves(): return Retry self.check_valve_result() - # self.value = V.circulating return Finish - def _adjust_vti_temp(self): - if self.dump_pressure > self.remove_temp_profile[self._profile_index][0]: - self._profile_index += 1 - self.vti_temp.write_target(self.remove_temp_profile[self._profile_index][1]) - @status_code(BUSY, 'remove (wait for turbo shut down)') - def remove(self, state): + def start_remove(self, state): """Entfernt die Mischung.""" if state.init: - self._profile_index = 0 - self.mix_temp.write_target(self.remove_temp_profile[0][1]) - self.still_htr.write_target(0.004) - self.sorb_temp.write_target(40) - self.vti_temp.auto_flow = True - # self.value = V.removing self.handle_valves(**self.remove_valves) if self.turbopump is not None: self._start_time = state.now self.turbopump.write_target(0) return Retry - self._adjust_vti_temp() if self.turbopump is not None: # if (state.now - self._start_time < self.turbo_off_delay or if self.turbopump.read_speed() > self.turbo_off_speed: @@ -284,7 +205,6 @@ class Dilution(HasStates, Drivable): @status_code(BUSY, 'remove (wait for still pressure low)') def remove_wait_for_still_pressure(self, state): - self._adjust_vti_temp() if self.still_pressure.read_value() > self.safe_turbo_pressure: return Retry self.turbopump.write_target(1) @@ -292,12 +212,10 @@ class Dilution(HasStates, Drivable): @status_code(BUSY) def remove_endsequence(self, state): - self._adjust_vti_temp() if (self.still_pressure_turbo and self.still_pressure_turbo.read_value() > self.end_remove_turbo_pressure): return Retry - if self.still_pressure.read_value() > self.end_remove_pressure or ( - self._profile_index < len(self.remove_temp_profile) - 1): + if self.still_pressure.read_value() > self.end_remove_pressure: return Retry self.circuitshort_valve.write_target(0) self.dump_valve.write_target(0) @@ -308,18 +226,20 @@ class Dilution(HasStates, Drivable): @status_code(BUSY) def close_valves_after_remove(self, state): + self.log.warn('V %r %r %r', state.init, self._valves_failed, self.valves_after_remove) if state.init: self.handle_valves(**self.valves_after_remove) + return Retry self.turbopump.write_target(0) if self.wait_valves(): return Retry self.check_valve_result() self._warn_manual_work = True - # self.value = V.off return self.final_status(WARN, 'please check manual valves') def read_status(self): status = super().read_status() + self.value = status[1] if status[0] < ERROR and self._warn_manual_work: try: self.handle_valves(**self.check_after_remove) @@ -346,7 +266,8 @@ class Dilution(HasStates, Drivable): if valve.isBusy(): self._valves_to_wait_for[vname] = (valve, flag) elif valve.read_value() != flag: - self._valves_failed[flag].append(vname) + self.log.warn('valve %s=%r did not go to %r', vname, self.secNode.modules[vname].read_value(), flag) + # self._valves_failed[flag].append(vname) def wait_valves(self): busy = False @@ -378,10 +299,10 @@ class DIL5(Dilution): 'open': 'V1 V5 compressor forepump', } remove_valves = { - 'close': 'V1 V2 V9', + 'close': 'V1 V9', 'check_closed': 'MV10 MV13 MV8 MVB MV2', 'check_open': 'MV1 MV3a MV3b GV1 MV9 MV11 MV12 MV14', - 'open': 'V4 V5 compressor forepump', + 'open': 'V2 V4 V5 compressor forepump', } valves_after_remove = { 'close': 'V1 V2 V4 V5 V9', @@ -439,6 +360,7 @@ class Interlock(LogoMixin, AddrMixin, Readable): @Command def reset(self): """reset the interlock""" + self.log.info('reset') self._prefix = '' self.set_vm_value(self.reset_param, 1) for actuator in self._actuators.values():