# ***************************************************************************** # # 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 # # ***************************************************************************** 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')