Files
sea/tcl/startup/n2cool.tcl
2022-08-18 15:04:28 +02:00

180 lines
4.7 KiB
Tcl

# new version modified Aug 2018.
#
# for next cooldown:
# - test offset feature (this is something like integral part in PI control)
# - reg is max(MagTop - 100, target)
proc makeN2cool {{temp "tcoil ta"} {topTemp "tcoil tc"}} {
makeobject n2coolPar array logged
n2coolPar makeitem temp $temp
n2coolPar makeitem topTemp $topTemp
n2coolPar makeitem state inactive
n2coolPar makeitem istate 0
# date and hour when to finish (set to tomorrow at start)
n2coolPar makeitem day [clock format [expr [clock seconds] + 24*3600] -format %d]
n2coolPar makeitem time 6
n2coolPar makeitem last 0
n2coolPar makeitem target 85
n2coolPar makeitem interval 600
n2coolPar makeitem maxDif 100
# filtered temperature
n2coolPar makeitem tfil 0
# regulation temperature
n2coolPar makeitem reg 0
n2coolPar makeitem offset 0
n2coolPar makeitem prop 3
obj_list makeitem n2coolPar "LN2 cooldown parameters"
Layout n2cool
makenv n2valve n2cool_ccu -controller _lnv -port ma15-ts:3004
}
proc n2coolLayout args {
RadioGroup n2cool [result n2coolPar state]
Label "LN2 cooldown (plug valve to CCU on MA15 rack)"
NoNewline
RadioButton inactive
NoNewline
RadioButton start
Newline
RadioButton opened
NoNewline
RadioButton closed
Newline
Tip "Name of bottom coil sensor temperature (MagBot)"
Input "coil sensor" "n2coolPar temp"
Tip "Name of top coil sensor temperature (MagTop)"
Input "coil sensor" "n2coolPar topTemp"
Input "coil sensor target" "n2coolPar target"
Newline
Tip "finish day \[day of month\]"
Input "finish day" "n2coolPar day"
Tip "finish hour \[decimal fractions possible\]"
Input "finish hour" "n2coolPar time"
Newline
Tip "max. difference MagTop - MagBot"
Input "max dif" "n2coolPar maxDif"
Tip "regulation interval"
Input "interval" "n2coolPar interval"
Tip "Kelvin / min."
Input "prop" "n2coolPar prop"
Input "T_reg" "n2coolPar reg"
Input "T_offset" "n2coolPar offset"
}
#
# Automatic N2 Precooling for Cryomagnets (tested for MA15 only)
#
#Typical usage:
# sicscron 1 n2cool
#
# the temperature of MagBot is regulated at the maximum of MagTop - maxDif and
# target
# Every 10 minutes (interval) the valve is opened and closed again
# it is closed again after a time proportional to the the difference between
# T_filtered and T_reg - offset. This time is calculated live from T_filtered.
# The valve is then kept closed until the next 10 min interval.
#
proc n2cool {{arg none}} {
switch $arg {
start {
if {[result n2coolPar istate] != 0} {
error "started already"
}
n2coolPar state start
n2coolPar day [clock format [expr [clock seconds] + 24*3600] -format %d]
n2coolPar last 0
sicscron 1 n2cool
return
}
inactive {
clientput "close and finish"
n2coolPar state inactive
n2valve 2
n2coolPar istate 0
return
}
none { }
default {
clientput "ERROR: n2cool $arg not allowed"
error stop
return
}
}
if {[result n2coolPar state] eq "inactive"} {
error stop
}
set now [clock seconds]
set today [clock format $now -format %d]
set seconds [expr $now - [clock scan 00:00]]
if {$today == [result n2coolPar day] && $seconds/3600.0 > [result n2coolPar time]} {
n2coolPar state inactive
n2valve 2
n2coolPar istate 0
clientput "finished at [clock format $now]"
error stop
}
set state [result n2coolPar state]
set oldState $state
set t [result [result n2coolPar temp]]
set ttop [result [result n2coolPar topTemp]]
set last [result n2coolPar last]
set offset [result n2coolPar offset]
set tfil [result n2coolPar tfil]
set interval [result n2coolPar interval]
set target [result n2coolPar target]
set maxDif [result n2coolPar maxDif]
set reg [format %.1f [expr max($ttop - $maxDif, $target)]]
n2coolPar reg $reg
set prop [result n2coolPar prop]
if {$tfil == 0} {
n2coolPar tfil $t
} else {
set w [expr 2.0 / $interval]
set tfil [expr $tfil + ($t - $tfil) * $w]
n2coolPar tfil $tfil
if {$now > $last + $interval} {
n2coolPar last $now
if {$tfil > $reg - $offset} {
n2valve 1
n2coolPar state opened
clientput open
} else {
n2valve 0
n2coolPar state closed
}
} elseif {$tfil < $reg + double($now - $last) / 60.0 * $prop - $offset} {
if {[sctval /n2valve] != 0} {
n2coolPar offset [expr 0.5 * ($offset + $tfil - $reg)]
clientput close
n2valve 0
n2coolPar state closed
}
}
}
switch [result n2coolPar state] {
opened {
n2valve 1
n2coolPar istate 1
}
closed - closedFast {
n2coolPar istate 2
}
inactive {
n2coolPar istate 0
clientput "n2cool deactivated"
error stop
}
}
return
}
publishLazy n2cool