321 lines
8.5 KiB
Tcl
321 lines
8.5 KiB
Tcl
namespace eval heliox {
|
|
}
|
|
|
|
source drivers/trun.tcl
|
|
|
|
proc stdConfig::heliox {} {
|
|
variable name
|
|
controller syncedprot
|
|
|
|
obj Heliox -drive out
|
|
prop layoutpos -10
|
|
prop check heliox::check_set
|
|
prop write stdSct::complete
|
|
# prop label set
|
|
|
|
tdrive $name -log 1
|
|
kids heliox {
|
|
node mode -int wr
|
|
prop enum undefined=0,hiT=1,midT=2,lowT=3,condense=4
|
|
prop read heliox::read
|
|
prop check heliox::check_mode
|
|
prop write heliox::complete
|
|
|
|
node lasts_until -text upd
|
|
prop visible False
|
|
default 0
|
|
|
|
node pot_state -text upd
|
|
|
|
node target_hours par 48
|
|
prop help "how many hours the pot should last (< 75)"
|
|
|
|
node holdflow out
|
|
default 1.5
|
|
prop check heliox::check_holdflow
|
|
prop help "flow for holding pressure"
|
|
prop write stdSct::complete
|
|
|
|
node condenseflow out
|
|
default 3
|
|
prop check heliox::check_condenseflow
|
|
prop help "flow for condensing"
|
|
prop write stdSct::complete
|
|
}
|
|
catch {
|
|
hsetprop /tt getsample hvali /th/pot
|
|
} msg
|
|
clientput $msg
|
|
}
|
|
|
|
proc heliox::check_set {} {
|
|
# save for later
|
|
sct goto [sct target]
|
|
if {[sct target] < 1.6} {
|
|
set condense_text ""
|
|
if {[hvali [sct]/lasts_until] > [DoubleTime]} {
|
|
if {[hvali [sct]/mode] < 3} {
|
|
hupdate [sct]/mode 3
|
|
}
|
|
} elseif {[hvali [sct]/mode] == 4} {
|
|
set condense_text "running"
|
|
} else {
|
|
hupdate [sct]/mode 4
|
|
set condense_text "started"
|
|
}
|
|
# sct goto [sct target]
|
|
if {$condense_text ne ""} {
|
|
sct print "going to [sct target] K might take a while - condense process is $condense_text"
|
|
}
|
|
} else {
|
|
if {[sct target] > 25} {
|
|
hupdate [sct]/mode 1
|
|
} elseif {[sct target] < 22} {
|
|
hupdate [sct]/mode 2
|
|
} elseif {[hval [sct]/mode] < 1 || [hval [sct]/mode] > 2} {
|
|
hupdate [sct]/mode 1
|
|
}
|
|
}
|
|
set mainsensor /th/pot
|
|
switch [sctval [sct]/mode] {
|
|
1 {
|
|
nv set [hvali [sct]/holdflow]
|
|
th setsorb/channel C
|
|
th setsorb 20
|
|
th mainloop set
|
|
tt dblctrl 1
|
|
run tt [sct target]
|
|
}
|
|
2 {
|
|
nv set [hvali [sct]/holdflow]
|
|
th setsorb/channel C
|
|
th setsorb 20
|
|
th mainloop set
|
|
tt dblctrl 0
|
|
tt set 1.25
|
|
th set [sct target]
|
|
}
|
|
3 {
|
|
nv set [hvali [sct]/holdflow]
|
|
th setsorb/channel B
|
|
th mainloop setsorb
|
|
th set 0
|
|
if {[sct target] != [hvali [sct]]} {
|
|
th setsorb [sct target]
|
|
}
|
|
set mainsensor /th/low
|
|
tt dblctrl 0
|
|
tt set 1.25
|
|
set state "low-T mode"
|
|
}
|
|
4 {
|
|
th setsorb/channel C
|
|
th setsorb 40
|
|
th set 0
|
|
th mainloop setsorb
|
|
tt dblctrl 0
|
|
tt set 1.25
|
|
catch {hdelprop /ts/mode soft_deadline}
|
|
}
|
|
default {
|
|
error "bad mode"
|
|
}
|
|
}
|
|
setmainsensor $mainsensor
|
|
sct update [sct target]
|
|
hsetprop /ts target [silent 0 sct goto]
|
|
hsetprop /th target [silent 0 sct goto]
|
|
}
|
|
|
|
proc heliox::setmainsensor {mainsensor} {
|
|
if {$mainsensor eq "/th/low"} {
|
|
set old /th/pot
|
|
} else {
|
|
set old /th/low
|
|
}
|
|
catch {[sct controller] killupdatescript $old "updateval [sct objectPath]"}
|
|
[sct controller] updatescript $mainsensor "updateval [sct objectPath]"
|
|
hsetprop [sct objectPath] mainsensor $mainsensor
|
|
}
|
|
|
|
proc heliox::check_mode {} {
|
|
set mainsensor /th/pot
|
|
switch [sct target] {
|
|
0 {
|
|
}
|
|
1 {
|
|
nv set [hvali [sct parent]/holdflow]
|
|
if {[sct target] != [hvali [sct]]} {
|
|
th set [hvali /th/target]
|
|
}
|
|
th setsorb/channel C
|
|
th setsorb 20
|
|
th mainloop set
|
|
set state "hi-T mode"
|
|
}
|
|
2 {
|
|
nv set [hvali [sct parent]/holdflow]
|
|
if {[sct target] != [hvali [sct]]} {
|
|
th set [hvali /th/target]
|
|
}
|
|
th setsorb/channel C
|
|
th setsorb 20
|
|
th mainloop set
|
|
set state "mid-T mode"
|
|
}
|
|
3 {
|
|
nv set [hvali [sct parent]/holdflow]
|
|
if {[hvali [sct parent]/lasts_until] > [DoubleTime]} {
|
|
th set 0
|
|
th setsorb/channel B
|
|
th mainloop setsorb
|
|
if {[sct target] != [hvali [sct]]} {
|
|
th setsorb [expr min(1.8, [hvali /th/target])]
|
|
}
|
|
tt set 1.25
|
|
tt dblctrl 0
|
|
} else {
|
|
clientput "the 3He pot is probably empty"
|
|
error "condense needed before lowT mode"
|
|
}
|
|
set mainsensor /th/low
|
|
set state "low-T mode"
|
|
}
|
|
4 {
|
|
th set 0
|
|
th setsorb/channel C
|
|
th mainloop set
|
|
th setsorb 40
|
|
tt set 1.25
|
|
tt dblctrl 0
|
|
set state "-> condense"
|
|
hsetprop /th target 0.25
|
|
hsetprop /ts target 0.25
|
|
catch {hdelprop /ts/mode soft_deadline}
|
|
}
|
|
}
|
|
setmainsensor $mainsensor
|
|
clientput "the 3He pot [hvali [sct parent]/pot_state]"
|
|
sct update [sct target]
|
|
}
|
|
|
|
proc heliox::check_condenseflow {} {
|
|
if {[sctval [sct parent]/mode] == 4} {
|
|
nv set [sct target]
|
|
}
|
|
sct update [sct target]
|
|
}
|
|
|
|
proc heliox::check_holdflow {} {
|
|
if {[sctval [sct parent]/mode] != 4} {
|
|
nv set [sct target]
|
|
}
|
|
sct update [sct target]
|
|
}
|
|
|
|
proc heliox::complete {} {
|
|
sct print [lindex {undefined "hi-T mode" "mid-T mode" "low-T mode" "-> condense"} [sct target]]
|
|
return idle
|
|
}
|
|
|
|
proc heliox::read {} {
|
|
set now [DoubleTime]
|
|
set lasts_until [hvali [sct parent]/lasts_until]
|
|
|
|
# calculate additional losses
|
|
set lasttime [silent 0 sct lasttime]
|
|
if {$lasttime == 0} {
|
|
set delay 5
|
|
} else {
|
|
set delay [expr min(30, $now - $lasttime)]
|
|
}
|
|
set ts [result th pot]
|
|
set tsorb [result th sorb]
|
|
sct lasttime $now
|
|
set mode [hvali [sct]]
|
|
if {(($mode == 3 && $ts > 2) || ($ts > 3)) && $tsorb < 10} {
|
|
if {$lasts_until} {
|
|
clientput "3He pot went empty"
|
|
}
|
|
set lasts_until 0
|
|
} else { # check losses through heating
|
|
# factor 30000 is a rough guess (measured 25000 for regulation th pot at 1 K)
|
|
set loss [expr $delay * ([silent 0 result th set/power] + [silent 0 result tt set/power]) * 30000]
|
|
set lasts_until [expr $lasts_until - $loss]
|
|
if {$loss > 0 && $lasts_until < $now} {
|
|
if {$lasts_until > 0} {
|
|
clientput "guess 3He pot went empty"
|
|
}
|
|
set lasts_until 0
|
|
}
|
|
}
|
|
if {$mode == 4} {
|
|
if {$ts > 3} {
|
|
# above 3 K: set deadline
|
|
nv set [hvali [sct parent]/condenseflow]
|
|
set lasts_until 0
|
|
sct condense_deadline [expr $now + 3600]
|
|
} elseif {[result th sorb] > 39} {
|
|
nv set [hvali [sct parent]/condenseflow]
|
|
# 3He vapor pressure: 200 mbar at 2 K, power law
|
|
set p [expr 200 * ($ts / 2.0) ** 3.5]
|
|
# dump pressure at condensation start
|
|
set p_max 410
|
|
# the amount of 3He corresponding to 1 mbar in the dump lasts that many hours
|
|
set hours_per_mbar 0.3
|
|
# the condensation does not stop immediately -> add 8 hours
|
|
set hours [expr max(0, $hours_per_mbar * ($p_max - $p)) + 8]
|
|
set target_hours [hvali [sct parent]/target_hours]
|
|
set lasts_until [expr int($now + $hours * 3600)]
|
|
calc_pot $lasts_until
|
|
sct condense_deadline [silent [expr $now + 3600] sct condense_deadline]
|
|
if {$hours > 8} {
|
|
set dl [expr $now + ($target_hours - $hours) * 30]
|
|
set sdl [silent $dl sct soft_deadline]
|
|
if {$dl <= $sdl} {
|
|
sct soft_deadline $dl
|
|
} elseif {$now > $sdl + 300} {
|
|
clientput "stop condensing - target_hours is probably too high - expect only [expr round($hours)] h hold time"
|
|
set target_hours $hours
|
|
}
|
|
} elseif {$now > [sct condense_deadline]} {
|
|
clientput "condense timeout - hold time is probably very low"
|
|
set target_hours $hours
|
|
}
|
|
if {$hours >= $target_hours} {
|
|
th setsorb 0
|
|
th setsorb/channel B
|
|
th mainloop setsorb
|
|
th setsorb [silent 0.25 hgetpropval [sct parent] goto]
|
|
# switch to lowT and trigger check_mode
|
|
hset [sct] 3
|
|
nv set [hvali [sct parent]/holdflow]
|
|
clientput "the 3He pot [hvali [sct parent]/pot_state]"
|
|
}
|
|
}
|
|
}
|
|
calc_pot $lasts_until
|
|
sct update [hvali [sct]]
|
|
return idle
|
|
}
|
|
|
|
proc heliox::calc_pot {lasts_until} {
|
|
set now [clock seconds]
|
|
set lasts_until [expr int($lasts_until)]
|
|
hupdate [sct parent]/lasts_until $lasts_until
|
|
if {$lasts_until == 0} {
|
|
hupdate [sct parent]/pot_state "is empty"
|
|
} elseif {$lasts_until > 0} {
|
|
set dynow [clock format $now -format "%j"]
|
|
set dayofyear [clock format $lasts_until -format "%j"]
|
|
if {$dayofyear == $dynow} {
|
|
set day today
|
|
} elseif {$dayofyear == $dynow + 1} {
|
|
set day tomorrow
|
|
} else {
|
|
set day [clock format $lasts_until -format %Y-%m-%d]
|
|
}
|
|
hupdate [sct parent]/pot_state "lasts until $day [clock format $lasts_until -format %H:%M]"
|
|
}
|
|
}
|