DIL5: improved version after tests 2026-08-12

This commit is contained in:
2026-08-12 16:46:06 +02:00
parent 2c389082f2
commit 6fa4698648
2 changed files with 46 additions and 114 deletions
+15 -5
View File
@@ -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,
+31 -109
View File
@@ -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():