301 lines
10 KiB
Python
301 lines
10 KiB
Python
# *****************************************************************************
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify it under
|
|
# the terms of the GNU General Public License as published by the Free Software
|
|
# Foundation; either version 2 of the License, or (at your option) any later
|
|
# version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
# details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along with
|
|
# this program; if not, write to the Free Software Foundation, Inc.,
|
|
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
#
|
|
# Module authors:
|
|
# Andrea Plank <andrea.plank@psi.ch>
|
|
#
|
|
# *****************************************************************************
|
|
|
|
from frappy.core import Drivable, Parameter, EnumType, Attached, FloatRange, \
|
|
Command, IDLE, BUSY, WARN, ERROR, Property
|
|
from frappy.datatypes import StatusType, EnumType, ArrayOf, BoolType, IntRange
|
|
from frappy.states import StateMachine, Retry, Finish, status_code, HasStates
|
|
from frappy.lib.enum import Enum
|
|
from frappy.errors import ImpossibleError
|
|
import time
|
|
Targetstates = Enum(
|
|
SORBPUMP = 0,
|
|
CONDENSE = 1,
|
|
CIRCULATE = 2,
|
|
REMOVE = 3,
|
|
MANUAL = 4,
|
|
TEST = 5,
|
|
STOP = 6,
|
|
)
|
|
|
|
class Dilution(HasStates, Drivable):
|
|
|
|
condenseline_pressure = Attached()
|
|
condense_valve = Attached()
|
|
dump_valve = Attached()
|
|
|
|
circulate_pump = Attached()
|
|
compressor = Attached(mandatory=(False))
|
|
turbopump = Attached(mandatory=(False))
|
|
condenseline_valve = Attached()
|
|
circuitshort_valve = Attached()
|
|
still_pressure = Attached()
|
|
#ls372 = Attached()
|
|
V5 = Attached() #Name noch ändern!!!
|
|
p1 = Attached() #Name noch ändern!!!
|
|
|
|
condensing_p_low = Property('Lower limit for condenseline pressure', IntRange())
|
|
|
|
condensing_p_high = Property('Lower limit for condenseline pressure', IntRange())
|
|
|
|
target = Parameter('target state', EnumType(Targetstates))
|
|
|
|
value = Parameter('target state', EnumType(Targetstates))
|
|
|
|
init = True
|
|
|
|
def earlyInit(self):
|
|
super().earlyInit()
|
|
|
|
def read_value(self):
|
|
return self.value
|
|
|
|
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
|
|
"""
|
|
if (target == Targetstates.TEST):
|
|
self.value = Targetstates.TEST
|
|
self.init = True
|
|
self.start_machine(self.test)
|
|
|
|
if (target == Targetstates.REMOVE):
|
|
if self.value == target:
|
|
return target
|
|
if self.value != Teststates.CIRCULATE:
|
|
self.final_status(WARN, "state before is not circulate")
|
|
return self.value
|
|
self.value = Targetstates.REMOVE
|
|
self.init = True
|
|
self.start_machine(self.remove)
|
|
|
|
elif (target == Targetstates.CIRCULATE):
|
|
if self.value == target:
|
|
return target
|
|
self.value = Targetstates.CIRCULATE
|
|
self.init = True
|
|
self.start_machine(self.circulate)
|
|
|
|
elif (target == Targetstates.CONDENSE):
|
|
if self.value == target:
|
|
return target
|
|
self.value = Targetstates.CONDENSE
|
|
self.init = True
|
|
self.start_machine(self.condense)
|
|
|
|
elif(target == Targetstates.MANUAL):
|
|
self.value = Targetstates.MANUAL
|
|
self.stop_machine()
|
|
|
|
elif (target == Targetstates.STOP):
|
|
self.value = Targetstates.STOP
|
|
self.stop_machine()
|
|
return self.value
|
|
|
|
"""
|
|
@status_code(BUSY, 'sorbpump state')
|
|
def sorbpump(self, state):
|
|
#Heizt Tsorb auf und wartet ab.
|
|
if self.init:
|
|
self.ls372.write_target(40) #Setze Tsorb auf 40K
|
|
self.start_time = self.now
|
|
self.init = false
|
|
return Retry
|
|
|
|
if self.now - self.start_time < 2400: # 40 Minuten warten
|
|
return Retry
|
|
|
|
self.ls372.write_target(0)
|
|
|
|
if self.ls372.read_value() > 10: # Warten bis Tsorb unter 10K
|
|
return Retry
|
|
|
|
return self.condense
|
|
"""
|
|
|
|
@status_code(BUSY, 'test mode')
|
|
def test(self, state):
|
|
"Nur zum testen, ob UI funktioniert"
|
|
self.init = False
|
|
self.condense_valve.write_target(1)
|
|
time.sleep(1)
|
|
self.condense_valve.write_target(0)
|
|
self.dump_valve.write_target(1)
|
|
time.sleep(1)
|
|
self.dump_valve.write_target(0)
|
|
self.compressor.write_target(1)
|
|
return True
|
|
|
|
@status_code(BUSY, 'condense mode')
|
|
def wait_for_condense_line_pressure(self, state):
|
|
if (self.condenseline_pressure.read_value > 500):
|
|
return Retry
|
|
|
|
return self.circulate
|
|
|
|
|
|
def initialize_condense_valves(self):
|
|
return True
|
|
|
|
@status_code(BUSY, 'condense state')
|
|
def condense(self, state):
|
|
"""Führt das Kondensationsverfahren durch."""
|
|
if self.init:
|
|
self.initialize_condense_valves()
|
|
self.circuitshort_valve.write_target(0)
|
|
self.dump_valve.write_target(0)
|
|
self.condense_valve.write_target(0)
|
|
|
|
self.condenseline_valve.write_target(1)
|
|
self.V5.write_target(1)
|
|
|
|
if (self.compressor is not None):
|
|
self.compressor.write_target(1)
|
|
|
|
self.circulate_pump.write_target(1)
|
|
self.init = False
|
|
return Retry
|
|
|
|
if self.condenseline_pressure.read_value() < self.condensing_p_low:
|
|
self.condense_valve.write_target(1)
|
|
elif (self.condenseline_pressure.read_value() > self.condensing_p_high):
|
|
self.condense_valve.write_target(0)
|
|
|
|
if (self.p1.read_value() > 20):
|
|
return Retry
|
|
|
|
self.condense_valve.write_target(1)
|
|
|
|
if (self.turbopump is not None):
|
|
if (self.condenseline_pressure.read_value() > 900 and self.still_pressure.read_value() > 10):
|
|
return Retry
|
|
else:
|
|
self.turbopump.write_target(1)
|
|
|
|
return self.wait_for_condense_line_pressure
|
|
|
|
|
|
def initialize_circulation_valves(self):
|
|
return True
|
|
|
|
@status_code(BUSY, 'circulate state')
|
|
def circulate(self):
|
|
"""Zirkuliert die Mischung."""
|
|
return self.initialize_circulation_valves()
|
|
|
|
|
|
@status_code(BUSY, 'remove state')
|
|
def remove(self):
|
|
"""Entfernt die Mischung."""
|
|
|
|
if self.init:
|
|
self.condenseline_valve.write_target(0)
|
|
self.dump_valve.write_target(1)
|
|
self.start_time = self.now
|
|
self.init = False
|
|
return Retry
|
|
|
|
if self.turbopump is not None:
|
|
self.turbopump.write_target(0)
|
|
|
|
if (self.now - self.start_time < 300 or self.turbopump.read_speed() > 60):
|
|
return Retry
|
|
|
|
self.circuitshort_valve.write_target(1)
|
|
|
|
if self.turbopump is not None:
|
|
if self.still_pressure.read_value() > 20:
|
|
return Retry
|
|
self.turbopump.write_target(1)
|
|
|
|
if self.still_pressure.read_value() > 1e-4:
|
|
return Retry
|
|
|
|
self.circuitshort_valve.write_target(0)
|
|
self.dump_valve.write_target(0)
|
|
|
|
if self.compressor is not None:
|
|
self.compressor.write_target(0)
|
|
|
|
for valve in self.remove_closed_valves:
|
|
valve.write_target(0)
|
|
|
|
self.circulate_pump.write_target(0)
|
|
|
|
return Finish
|
|
|
|
class DIL5(Dilution):
|
|
|
|
MV10 = Attached()
|
|
MV13 = Attached()
|
|
MV8 = Attached()
|
|
MVB = Attached()
|
|
MV2 = Attached()
|
|
MV1 = Attached()
|
|
MV3a = Attached()
|
|
MV3b = Attached()
|
|
GV1 = Attached()
|
|
MV14 = Attached()
|
|
MV12 = Attached()
|
|
MV11 = Attached()
|
|
MV9 = Attached()
|
|
GV2 = Attached()
|
|
|
|
def earlyInit(self):
|
|
self.circulate_closed_valves = [self.condense_valve, self.dump_valve, self.circuitshort_valve, self.MV10, self.MV13, self.MV8, self.MVB, self.MV2]
|
|
self.circulate_open_valves = [self.MV11, self.circulate_pump, self.GV2, self.V5, self.compressor, self.condenseline_valve, self.MV1, self.MV3a, self.MV3b, self.GV1, self.MV9, self.MV14]
|
|
self.condense_closed_valves = [self.MV10, self.MV13, self.MV8, self.MVB, self.MV2]
|
|
self.condense_open_valves = [self.MV1, self.MV3a, self.MV3b, self.GV1, self.MV9, self.MV14, self.MV12, self.MV11]
|
|
super().earlyInit()
|
|
|
|
def initialize_condense_valves(self):
|
|
#Anfangszustand der Ventile überprüfen
|
|
for valve in self.condense_open_valves:
|
|
if valve.read_value() == 0:
|
|
self.stop_machine()
|
|
raise ImpossibleError(f'valve {valve.name} must be open')
|
|
|
|
for valve in self.condense_closed_valves:
|
|
if valve.read_value == 1:
|
|
self.stop_machine()
|
|
return ImpossibleError(f'valve {valve.name} must be closed')
|
|
|
|
def initialize_circulation_valves(self):
|
|
#Anfangszustand der Ventile überprüfen
|
|
self.value = Targetstates.CIRCULATE
|
|
for valve in self.circulate_closed_valves:
|
|
if (valve.read_value() == 1):
|
|
self.stop_machine()
|
|
raise ImpossibleError(f'valve {valve.name} must be open')
|
|
|
|
for valve in self.circulate_open_valves:
|
|
if (valve.read_value() == 0):
|
|
valve.write_target(1)
|
|
self.stop_machine()
|
|
raise ImpossibleError(f'valve {valve.name} must be open')
|
|
|
|
|