dil5: fixes with checking valves

This commit is contained in:
DIL5 committed 2026-10-19 10:52:20 +02:00
1 parent 87d0b44f86
commit 5d6dd95405
2 files changed
+55 -34

No files matched your search

+1 -1
View File
@@ -12,7 +12,7 @@ logo_ip = '192.168.0.3'
Node('dil5.linse@psi.ch',
'dil5 on linse-dil5',
interface='tcp://5000',
secondary = ['ws://8010']
secondary = ['ws://8051']
)
Mod('logo',
+54 -33
View File
@@ -20,6 +20,7 @@
#
# *****************************************************************************
import time
from frappy.core import Readable, Drivable, Parameter, Attached, FloatRange, \
Command, IDLE, BUSY, WARN, ERROR, Property
from frappy.datatypes import EnumType, IntRange, BoolType, StructOf, StringType
@@ -86,14 +87,14 @@ class Dilution(HasStates, Drivable):
_start_time = 0
init = True
_warn_manual_work = None
_valve_warnings = None
def write_target(self, target):
self.log.info('start %s', target)
if target == 'condense':
self.start_machine(self.start_condense)
self.condense()
elif target == 'remove':
self.start_machine(self.start_remove)
self.remove()
else:
raise RangeError(r'invalid command {target!r}')
self.log.info('started %s', target)
@@ -102,11 +103,15 @@ class Dilution(HasStates, Drivable):
@Command
def condense(self):
"""condense mixture"""
self._valve_warnings = None
self.handle_valves(self.condense_valves)
self.start_machine(self.start_condense)
@Command
def remove(self):
"""remove mixture"""
self._valve_warnings = None
self.handle_valves(self.remove_valves)
self.start_machine(self.start_remove)
@status_code(BUSY)
@@ -116,14 +121,13 @@ class Dilution(HasStates, Drivable):
pumpstate = self.forepump.read_value()
if self.turbopump:
self.turbopump.write_target(0)
self.handle_valves(**self.condense_valves)
self.handle_valves(self.condense_valves)
self._start_time = state.now
if not pumpstate: # wait longer for starting fore pump
self._start_time += 10
return Retry
if self.wait_valves():
return Retry
self.check_valve_result()
return self.condensing
@status_code(BUSY)
@@ -174,10 +178,9 @@ class Dilution(HasStates, Drivable):
def circulate(self, state):
"""Zirkuliert die Mischung."""
if state.init:
self.handle_valves(**self.condense_valves)
self.handle_valves(self.condense_valves)
if self.wait_valves():
return Retry
self.check_valve_result()
return Finish
@status_code(BUSY, 'remove (wait for turbo shut down)')
@@ -185,7 +188,7 @@ class Dilution(HasStates, Drivable):
"""Entfernt die Mischung."""
if state.init:
self.handle_valves(**self.remove_valves)
self.handle_valves(self.remove_valves)
if self.turbopump is not None:
self._start_time = state.now
self.turbopump.write_target(0)
@@ -226,39 +229,40 @@ 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)
self.log.warn('V %r %r', state.init, self.valves_after_remove)
if state.init:
self.handle_valves(**self.valves_after_remove)
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._valve_warnings = self.check_after_remove
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)
self._warn_manual_work = False
except ImpossibleError:
return WARN, f'please close manual valves {",".join(self._valves_failed[False])}'
if status[0] < ERROR and self._valve_warnings:
valves_failed = self.inner_handle_valves(**self._valve_warnings)
if valves_failed[False]:
return WARN, f'please close manual valves {",".join(valves_failed[False])}'
self._valve_warnings = None
return status
def handle_valves(self, check_closed=(), check_open=(), close=(), open=()):
"""check ot set given valves
def inner_handle_valves(self, check_closed=(), check_open=(), close=(), open=()):
"""check or set given valves
raises ImpossibleError, when checks fails
returns failed valves raises ImpossibleError, when checks fails
"""
self._valves_to_wait_for = {}
self._valves_failed = {True: [], False: []}
self._valve_change_time = time.monotonic()
valves_failed = {True: [], False: []}
for flag, valves in enumerate([check_closed, check_open]):
for vname in valves.split():
if self.secNode.modules[vname].read_value() != flag:
self._valves_failed[flag].append(vname)
valves_failed[flag].append(vname)
if valves_failed:
return valves_failed
for flag, valves in enumerate([close, open]):
for vname in valves.split():
valve = self.secNode.modules[vname]
@@ -268,28 +272,45 @@ class Dilution(HasStates, Drivable):
elif valve.read_value() != flag:
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)
return {}
def handle_valves(self, valveset):
"""check or set given valves
raises ImpossibleError, when checks fails
busy valves are stored in self._valves_to_wait_for
and handled in :meth:wait_valves later
"""
valves_failed = self.inner_handle_valves(**valveset)
self.check_failed_valves(valves_failed)
def check_failed_valves(self, valves_failed, addtext=''):
result = []
for flag, valves in valves_failed.items():
if valves:
result.append(f"{','.join(valves)} not {'open' if flag else 'closed'}")
if result:
raise ImpossibleError(f"failed: {', '.join(result)}{addtext}")
def wait_valves(self):
busy = False
valves_failed = {True: [], False: []}
timedout = time.monotonic() > self._valve_change_time + 10
for vname, (valve, flag) in dict(self._valves_to_wait_for.items()):
statuscode = valve.read_status()[0]
if statuscode == BUSY:
if statuscode == BUSY and not timedout:
busy = True
continue
if valve.read_value() == flag and statuscode == IDLE:
self._valves_to_wait_for.pop(vname)
else:
self._valves_failed[flag].append(vname)
valves_failed[flag].append(vname)
if not busy:
self.check_failed_valves(valves_failed)
elif timedout:
self.check_failed_valves(valves_failed, ' after 10 sec')
return busy
def check_valve_result(self):
result = []
for flag, valves in self._valves_failed.items():
if valves:
result.append(f"{','.join(valves)} not {'open' if flag else 'closed'}")
if result:
raise ImpossibleError(f"failed: {', '.join(result)}")
class DIL5(Dilution):
condense_valves = {