initial commit
This commit is contained in:
273
tcl/drivers/heliox.tcl
Normal file
273
tcl/drivers/heliox.tcl
Normal file
@@ -0,0 +1,273 @@
|
||||
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 60
|
||||
prop help "how many hours the pot should last (< 75)"
|
||||
}
|
||||
catch {
|
||||
hsetprop /tt getsample hvali /ts/pot
|
||||
} msg
|
||||
clientput $msg
|
||||
}
|
||||
|
||||
proc heliox::check_set {} {
|
||||
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 2.5
|
||||
th setsorb/channel C
|
||||
th setsorb 20
|
||||
th mainloop set
|
||||
tt dblctrl 1
|
||||
run tt [sct target]
|
||||
}
|
||||
2 {
|
||||
nv set 2.5
|
||||
th setsorb/channel C
|
||||
th setsorb 20
|
||||
th mainloop set
|
||||
tt dblctrl 0
|
||||
tt set 1.25
|
||||
th set [sct target]
|
||||
}
|
||||
3 {
|
||||
nv set 2.5
|
||||
th setsorb/channel B
|
||||
th mainloop setsorb
|
||||
th set 0
|
||||
if {[sct target] != [hvali [sct]]} {
|
||||
th setsorb [sct target]
|
||||
}
|
||||
set mainsensor /th/low
|
||||
tt set 1.25
|
||||
set state "low-T mode"
|
||||
}
|
||||
4 {
|
||||
th setsorb/channel C
|
||||
th setsorb 40
|
||||
th set 0
|
||||
th mainloop setsorb
|
||||
tt set 1.25
|
||||
}
|
||||
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} {
|
||||
set old [silent "" hgetpropval [sct objectPath] mainsensor]
|
||||
if {$mainsensor ne $old} {
|
||||
if {$old ne ""} {
|
||||
catch {[sct controller] killupdatescript $old "updateval [sct objectPath]"}
|
||||
}
|
||||
[sct controller] updatescript $mainsensor "updateval [sct objectPath]"
|
||||
}
|
||||
}
|
||||
|
||||
proc heliox::check_mode {} {
|
||||
set mainsensor /th/pot
|
||||
switch [sct target] {
|
||||
0 {
|
||||
}
|
||||
1 {
|
||||
nv set 2.5
|
||||
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 2.5
|
||||
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 2.5
|
||||
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
|
||||
} 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
|
||||
set state "-> condense"
|
||||
hsetprop /th target 0.25
|
||||
hsetprop /ts target 0.25
|
||||
}
|
||||
}
|
||||
setmainsensor $mainsensor
|
||||
clientput "the 3He pot [hvali [sct parent]/pot_state]"
|
||||
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
|
||||
if {$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 {[hvali [sct]] == 4} {
|
||||
if {$ts > 3} {
|
||||
nv set 4
|
||||
set lasts_until 0
|
||||
sct condense_deadline [expr $now + 36000] # timeout: should be 3600
|
||||
} elseif {[result th sorb] > 39} {
|
||||
nv set 4
|
||||
# 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 {$now > [sct condense_deadline]} {
|
||||
clientput "condense timeout - cannot fill pot for lasting $target_hours hours"
|
||||
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]
|
||||
sct update 3
|
||||
nv set 2.5
|
||||
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]"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user