dil5: fixes with checking valves
This commit is contained in:
1 parent
87d0b44f86
commit
5d6dd95405
2 files changed
+55
-34
No files matched your search
+1
-1
@@ -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
@@ -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 = {
|
||||
|
||||
Reference in new issue
Block a user