
for autodevice to work, it is not necessary to be unplugged for 60 seconds, only for a short time. fixed this behaviour
724 lines
17 KiB
Tcl
724 lines
17 KiB
Tcl
# CCU 4
|
|
namespace eval ccu4 {} {
|
|
# 1=remote
|
|
variable deviceaction 1
|
|
variable newdevice ""
|
|
}
|
|
|
|
proc stdConfig::ccu4 {{title CCU4} args} {
|
|
variable name
|
|
variable node
|
|
|
|
set ins [string toupper [result instrument]]
|
|
if {$ins eq "SEAMAN"} {
|
|
set ins free
|
|
}
|
|
controller std "\n" 5
|
|
prop startcmd "cid csf cir cic=$ins"
|
|
hsetprop $node/tasks complete "ccu4::completeStart $name"
|
|
prop write ccu4::write
|
|
prop commerror ccu4::errorScript
|
|
prop freelist 0
|
|
prop obj /$name
|
|
|
|
pollperiod 0.5 0.5 5
|
|
obj ccu4 rd -int
|
|
prop enum 1
|
|
prop label on
|
|
prop read ccu4::read
|
|
prop cfgtablefile config/ccu4device.list
|
|
prop layoutpos 99
|
|
# if {[info exists ::rack_in_use]} {
|
|
prop instrument $ins
|
|
# }
|
|
default 1
|
|
kids $title {
|
|
node autodevice par -int [expr [llength $args] == 0]
|
|
prop enum 1
|
|
|
|
node fav out -int
|
|
prop newline 1
|
|
prop enum 1
|
|
prop label "flow available"
|
|
|
|
node f upd
|
|
prop label flow
|
|
prop avnode fav
|
|
|
|
node fs out -int
|
|
prop enum ok,no_sens
|
|
prop avnode fav
|
|
|
|
node mav out -int
|
|
prop newline 1
|
|
prop enum 1
|
|
prop label "n.v. motor available"
|
|
|
|
node fm upd -int
|
|
prop enum idle,opening,closing,opened,closed,no_motor
|
|
prop avnode mav
|
|
|
|
node fa out -int
|
|
prop enum fixed,controlled,automatic,offline
|
|
prop avnode mav
|
|
|
|
node mp out
|
|
prop label "motor pulse"
|
|
prop avnode mav
|
|
|
|
node msp upd
|
|
prop label "motor speed"
|
|
prop avnode mav
|
|
|
|
node mmp upd
|
|
prop label "measured pulse"
|
|
prop avnode mav
|
|
|
|
node mc out
|
|
prop label "motor current"
|
|
prop avnode mav
|
|
|
|
node mfc out
|
|
prop label "free current"
|
|
prop avnode mav
|
|
|
|
#obsolete
|
|
node moc out
|
|
prop label "overrun const"
|
|
prop avnode mav
|
|
|
|
node mtc out
|
|
prop label "torque const"
|
|
prop avnode mav
|
|
|
|
node mtl upd
|
|
prop label "torque limit"
|
|
prop avnode mav
|
|
|
|
node mft out
|
|
prop label "flow target"
|
|
prop avnode mav
|
|
|
|
node mt upd
|
|
prop label "torque"
|
|
prop avnode mav
|
|
|
|
#obsolete
|
|
node mo upd
|
|
prop label "overrun"
|
|
prop avnode mav
|
|
|
|
node mcr upd
|
|
prop label "read current"
|
|
prop avnode mav
|
|
|
|
node mot upd
|
|
prop label "open time"
|
|
prop avnode mav
|
|
|
|
node mw out
|
|
prop label "wiggle"
|
|
prop help "correction pulse after automatic open"
|
|
prop avnode mav
|
|
|
|
node hav out
|
|
prop newline 1
|
|
prop enum none,int,ext
|
|
prop label "He lev. available"
|
|
|
|
node h upd -secop=helev
|
|
prop label "he level"
|
|
prop avnode hav
|
|
prop errvar hsf
|
|
|
|
node hr upd
|
|
prop label "he sensor mm"
|
|
prop avnode hav
|
|
|
|
node hc upd
|
|
prop label "He meas. current"
|
|
prop avnode hav
|
|
|
|
node hu upd
|
|
prop label "He meas. volt"
|
|
prop avnode hav
|
|
|
|
node hh out
|
|
prop label "He full level"
|
|
prop avnode hav
|
|
|
|
node hl out
|
|
prop label "He fill level"
|
|
prop avnode hav
|
|
|
|
node htf out
|
|
prop label "fast period"
|
|
prop help "meas. period in fast mode"
|
|
prop avnode hav
|
|
|
|
node hts out
|
|
prop label "slow period"
|
|
prop help "meas. period in slow mode"
|
|
prop avnode hav
|
|
|
|
node hd out
|
|
prop label "He driv. current"
|
|
prop avnode hav
|
|
|
|
node hwr out
|
|
prop label "He wire res."
|
|
prop avnode hav
|
|
|
|
node hem out
|
|
prop label "empty"
|
|
prop help "sensor length in mm from top to empty pos."
|
|
prop avnode hav
|
|
|
|
node hfu out
|
|
prop label "full"
|
|
prop help "sensor length in mm from top to full pos."
|
|
prop avnode hav
|
|
|
|
node hcd out -int
|
|
prop enum stop,fill,off,auto,manual=7
|
|
prop avnode hav
|
|
|
|
node hv upd -int
|
|
prop enum fill_valve_off,filling,no_fill_valve,timeout,timeout1
|
|
prop avnode hav
|
|
|
|
node hsf upd -int
|
|
prop enum sens_ok,sens_warm,no_sens,timeout,not_yet_read,disabled
|
|
prop avnode hav
|
|
|
|
node ha out -int
|
|
prop enum 1
|
|
prop label "He auto fill"
|
|
prop avnode hav
|
|
|
|
node hm upd -int
|
|
prop enum 1
|
|
prop label measure
|
|
prop avnode hav
|
|
|
|
node hf out -int
|
|
prop enum slow,fast
|
|
prop avnode hav
|
|
|
|
node hbe out -int
|
|
prop enum 1
|
|
prop label LHe 48V enabled
|
|
prop avnode hav
|
|
|
|
node hmf upd
|
|
prop label "meas first"
|
|
prop avnode hav
|
|
|
|
node hms upd
|
|
prop label "meas speed"
|
|
prop avnode hav
|
|
|
|
node hit out
|
|
prop label "increase tolerance"
|
|
prop avnode hav
|
|
|
|
node hft out -int
|
|
prop label "fast/fill timeout"
|
|
prop avnode hav
|
|
|
|
node hea out
|
|
prop label "add. He channels"
|
|
prop enum 0,1,6=6
|
|
|
|
node hch out -int
|
|
prop label "LHe channel"
|
|
prop avnode hea
|
|
|
|
node hwr0 out
|
|
prop label "ext. He wire res."
|
|
prop avnode hea
|
|
|
|
node hem0 out
|
|
prop label "ext. empty"
|
|
prop help "sensor length in mm from top to empty pos."
|
|
prop avnode hea
|
|
|
|
node hfu0 out
|
|
prop label "ext. full"
|
|
prop help "sensor length in mm from top to full pos."
|
|
prop avnode hea
|
|
|
|
node hd0 out
|
|
prop label "ext. drive"
|
|
prop help "external sensor drive current (mA)"
|
|
prop avnode hea
|
|
|
|
for {set ch 0} {$ch < 6} {incr ch} {
|
|
node h$ch upd
|
|
prop errvar hs$ch
|
|
prop newline 1
|
|
prop avnode hea
|
|
|
|
node hs$ch upd -int
|
|
prop enum sens_ok,sens_warm,no_sens,timeout,not_yet_read,disabled
|
|
prop nonewline 1
|
|
prop avnode hea
|
|
|
|
}
|
|
|
|
node hfb upd
|
|
prop label He v. feedb.
|
|
prop avnode hav
|
|
|
|
node nav out -int
|
|
prop newline 1
|
|
prop enum 1
|
|
prop label "N2 available"
|
|
|
|
node nu upd -secop=n2upper
|
|
prop label "N2 upper"
|
|
prop avnode nav
|
|
|
|
node nl upd -secop=n2lower
|
|
prop label "N2 lower"
|
|
prop avnode nav
|
|
|
|
node nth out
|
|
prop label "N2 threshold"
|
|
prop avnode nav
|
|
|
|
node ntc out
|
|
prop label "N2 tube cool delay"
|
|
prop avnode nav
|
|
|
|
node ntm out
|
|
prop label "N2 fill timeout"
|
|
prop avnode nav
|
|
|
|
node ns upd -int
|
|
prop enum sens_ok,no_sens,short_circuit,upside_down,sens_warm,empty
|
|
prop avnode nav
|
|
|
|
node na out -int
|
|
prop enum 1
|
|
prop label "N2 auto fill"
|
|
prop avnode nav
|
|
|
|
node nv upd -int
|
|
prop enum fill_valve_off,filling,no_fill_valve,timeout,timeout1,boost
|
|
prop avnode nav
|
|
|
|
node nc out -int
|
|
prop enum stop,fill,off,auto
|
|
prop avnode nav
|
|
|
|
node nfb upd
|
|
prop label LN2 v. feedb.
|
|
prop avnode nav
|
|
|
|
node cda upd
|
|
prop newline 1
|
|
prop label "code res. a"
|
|
|
|
node cdb upd
|
|
prop label "code res. b"
|
|
|
|
node cba upd
|
|
prop label "code a invalid"
|
|
|
|
node cbb upd
|
|
prop label "code b invalid"
|
|
|
|
node cvs -int upd
|
|
prop label "config version"
|
|
|
|
node csp -int upd
|
|
prop label "hardware type"
|
|
|
|
node cdv out -text
|
|
prop label "device"
|
|
|
|
node cic out -text
|
|
prop label "connected to"
|
|
|
|
node cin upd -text
|
|
prop label "connect to"
|
|
|
|
node cds out
|
|
prop label "device state"
|
|
prop enum local,remote,loading,by_code,by_touch
|
|
|
|
node timing par 0
|
|
prop newline 1
|
|
prop enum 1
|
|
|
|
node tc upd
|
|
prop avnode timing
|
|
|
|
node tn upd
|
|
prop avnode timing
|
|
|
|
node th upd
|
|
prop avnode timing
|
|
|
|
node tf upd
|
|
prop avnode timing
|
|
|
|
node tm upd
|
|
prop avnode timing
|
|
|
|
node tv upd
|
|
prop avnode timing
|
|
|
|
node tq upd
|
|
prop avnode timing
|
|
|
|
node bdl out
|
|
prop label "valve boost delay"
|
|
|
|
foreach a $args {
|
|
if {$a eq "aux"} {
|
|
node axa upd -int
|
|
node ax upd
|
|
node axs upd
|
|
node axd upd -int
|
|
} elseif {[string match valve* $a]} {
|
|
set nvalve [string range $a 5 end]
|
|
for {set ch 1} {$ch <= 12} {incr ch} {
|
|
node v$ch rd -int 10
|
|
prop read ccu4::readValve v$ch
|
|
prop enum valve_off,valve_on,no_valve,timeout,timeout1,boost
|
|
if {$ch > $nvalve} {
|
|
prop visible false
|
|
}
|
|
node vc$ch out -int
|
|
prop write ccu4::writeValve v$ch
|
|
prop enum valve_off,valve_on
|
|
if {$ch > $nvalve} {
|
|
prop visible false
|
|
}
|
|
}
|
|
} elseif {$a ne "multiHe"} {
|
|
error "ERROR: unknown argument '$a' to ccu4"
|
|
}
|
|
}
|
|
}
|
|
return "CCU4"
|
|
}
|
|
|
|
proc ccu4::readValve {valve} {
|
|
# for some strange reason, v... are not queried with '?'
|
|
# we have to do it here
|
|
sct send $valve
|
|
return ccu4::complete
|
|
}
|
|
|
|
proc ccu4::writeValve {valve} {
|
|
set res [ccu4::write]
|
|
# update readback value immediately
|
|
hupdate [sct parent]/$valve [sct target]
|
|
return $res
|
|
}
|
|
|
|
proc ccu4::completeStart {name} {
|
|
set resval(cid) 0
|
|
set resval(cir) ""
|
|
set resval(csf) ""
|
|
foreach res [split [sct result]] {
|
|
lassign [split $res =] cmd val
|
|
set resval($cmd) $val
|
|
}
|
|
sct result $resval(cid)
|
|
if {$name eq "cc"} {
|
|
hsetprop [sct parent] freelist ""
|
|
set old [silent 0 result device ccu4version]
|
|
if {$old ne $resval(csf)} {
|
|
catch {device makeitem ccu4version $resval(csf)}
|
|
error "WARNING: CCU4 version has changed from $old to $resval(csf), please make 'samenv reload'"
|
|
}
|
|
set rack [silent other result device rack]
|
|
if {$rack ne "other" && $resval(cir) ne $rack && $resval(cir) ne "undef"} {
|
|
# force config download (including rack name 'cir')
|
|
hupdate [hgetpropval [sct parent] obj]/cvs 1
|
|
}
|
|
}
|
|
return [stdSct::completeStart]
|
|
}
|
|
|
|
proc ccu4::errorScript {} {
|
|
if {[sct result] eq "ASCERR: disconnected"} {
|
|
hupdate [sct obj]/status disconnected
|
|
return idle
|
|
} else {
|
|
hupdate [sct obj]/status [sct result]
|
|
stdSct::errorScript
|
|
}
|
|
}
|
|
|
|
proc ccu4::read {} {
|
|
if {![silent 1 hvali [sct]]} {
|
|
sct update 0
|
|
return idle
|
|
}
|
|
sct update 1
|
|
sct send "?"
|
|
return ccu4::update
|
|
}
|
|
|
|
proc ccu4::loadcodes {} {
|
|
if {[sct codeidx] >= [sct codelen]} {
|
|
# set version and save
|
|
sct send "cir=[silent {} result device rack] cvs=[sct codeversion] c=s"
|
|
clientput "CCU4: updated cfgtable to version from [clock format [sct codeversion] -format {%Y-%m-%d %H:%M}]"
|
|
if {[hvali [sct]/hea]} {
|
|
set hv a
|
|
} else {
|
|
set hv no
|
|
}
|
|
clientput "CCU4: this CCU has $hv He vessel channel"
|
|
return ccu4::loadcomplete
|
|
}
|
|
# add item to device list
|
|
sct send "c=[lindex [sct codelist] [sct codeidx]]"
|
|
sct codeidx [expr [sct codeidx] + 1]
|
|
return stdSct::complete
|
|
}
|
|
|
|
proc ccu4::loadcomplete {} {
|
|
hupdate [sct]/cvs [sct codeversion]
|
|
return unpoll
|
|
}
|
|
|
|
proc ccu4::update {} {
|
|
variable deviceaction
|
|
variable newdevice
|
|
|
|
hupdate [sct]/status ""
|
|
set fdone 0
|
|
set hidecmd ""
|
|
foreach item [sct result] {
|
|
set item [split $item "="]
|
|
|
|
set name [lindex $item 0]
|
|
set value [lindex $item 1]
|
|
hsetprop [sct]/$name done 1
|
|
switch $name {
|
|
f {
|
|
set fdone 1
|
|
}
|
|
cds {
|
|
if {$value >= 3 || $value == 0} { # device changed (local, by_code, by_touch)
|
|
set deviceaction $value
|
|
}
|
|
set newdevice ""
|
|
}
|
|
cdv {
|
|
if {$deviceaction >= 3} { # by_code, by_touch
|
|
set newdevice $value
|
|
}
|
|
}
|
|
cin {
|
|
if {[info exists ::rack_in_use] && $value eq "free"} {
|
|
clientput "disconnect requested from CCU touch display"
|
|
sct send "cic="
|
|
return "ccu4::completeDisconnect"
|
|
}
|
|
}
|
|
csp {
|
|
# check for not updated nodes
|
|
foreach node [hlist [sct]] {
|
|
set avnode [silent 0 hgetpropval [sct]/$node avnode]
|
|
if {$avnode ne "0"} {
|
|
set vis [hvali [sct]/$avnode]
|
|
if {$vis} {
|
|
set vistxt true
|
|
} else {
|
|
set vistxt false
|
|
}
|
|
if {[silent true hgetpropval [sct]/$node visible] ne $vistxt} {
|
|
hsetprop [sct]/$node visible $vistxt
|
|
if {! $vis} {
|
|
logsetup [sct]/$node clear
|
|
}
|
|
}
|
|
if {$vis && [silent 1 hgetpropval [sct]/$node done] == 0} {
|
|
append hidecmd "$node "
|
|
}
|
|
hsetprop [sct]/$node done 0
|
|
}
|
|
}
|
|
}
|
|
cda - cdb {
|
|
set cda [hval [sct]/cda]
|
|
set cdb [hval [sct]/cdb]
|
|
set $name $value
|
|
if {$cda == 999999 && $cdb == 999999} {
|
|
device makeitem was_unplugged 1
|
|
}
|
|
}
|
|
}
|
|
set visible [silent true hgetpropval [sct]/$name visible]
|
|
if {[silent notFound hlist [sct]/$name] eq "notFound"} {
|
|
if {[silent notFound sct notFound_$name] eq "notFound"} {
|
|
clientput "ERROR: [sct]/$name not found"
|
|
sct notFound_$name 1
|
|
}
|
|
} elseif {$visible eq "false"} {
|
|
append hidecmd "$name:"
|
|
logsetup [sct]/$name clear
|
|
} else {
|
|
set errvar [silent "" hgetpropval [sct]/$name errvar]
|
|
if {$errvar ne ""} {
|
|
set errval [hvali [sct]/$errvar]
|
|
if {$errval == 1} {
|
|
# sens warm
|
|
updateval [sct]/$name -11
|
|
} elseif {$errval == 3} {
|
|
# timeout
|
|
updateval [sct]/$name 111
|
|
} elseif {$errval > 0} {
|
|
hsetprop [sct]/$name geterror [lindex [split [hgetpropval [sct]/$errvar enum] ,] $errval]
|
|
hupdate [sct]/$name $value
|
|
} else {
|
|
updateval [sct]/$name $value
|
|
}
|
|
} else {
|
|
updateval [sct]/$name $value
|
|
}
|
|
}
|
|
}
|
|
# update flow anyway, as this triggers control
|
|
if {!$fdone && [silent true hgetpropval [sct]/f visible] ne "false"} {
|
|
hupdate [sct]/f [hvali [sct]/f]
|
|
}
|
|
hdelprop [sct] geterror
|
|
set cvs [hvali [sct]/cvs]
|
|
if {$cvs != 0 && [file exists [sct cfgtablefile]]} {
|
|
sct codeversion [file mtime [sct cfgtablefile]]
|
|
|
|
if {$cvs != [sct codeversion]} {
|
|
clientput "CCU4: replace cfgtable version from [clock format $cvs -format {%Y-%m-%d %H:%M}]"
|
|
hupdate [sct]/cvs 0
|
|
set cfgtbl [split [read_file [sct cfgtablefile]] \n]
|
|
set codelist [list ]
|
|
foreach line $cfgtbl {
|
|
if {[string index $line 0] ne "#" && [string length $line] > 1} {
|
|
set lline [split $line "\t"]
|
|
while {[llength $lline] < 6} {
|
|
lappend lline {}
|
|
}
|
|
lappend codelist [join $lline ","]
|
|
}
|
|
}
|
|
sct codelist $codelist
|
|
sct codeidx 0
|
|
sct codelen [llength [sct codelist]]
|
|
sct send "cvs=0 c=c"
|
|
[sct controller] poll [sct] 0.1 slow ccu4::loadcodes
|
|
return stdSct::complete
|
|
}
|
|
}
|
|
if {$deviceaction == 0} {
|
|
# CCU4 was restarted
|
|
# if {[info exists instrument]} {
|
|
# set ins [string toupper [sct instrument]]
|
|
# if {$instrument eq $ins} {
|
|
# clientput "this rack is ours"
|
|
# } elseif {$instrument eq ""} {
|
|
# clientput "assume this rack is ours"
|
|
# }
|
|
clientlog RENEW
|
|
device makeitem action renew
|
|
set deviceaction 1
|
|
sct send cds=1
|
|
return stdSct::complete
|
|
}
|
|
}
|
|
if {$deviceaction >= 3} {
|
|
if {$newdevice eq ""} {
|
|
# get new device name
|
|
sct send cdv
|
|
return ccu4::update
|
|
}
|
|
if {[sctval [sct]/autodevice]} {
|
|
set newdevice [string tolower $newdevice]
|
|
if {![file exists ${newdevice}.config]} {
|
|
set guess [glob ${newdevice}*.config]
|
|
if {[llength $guess] == 1} {
|
|
set newdevice [lindex [split $guess .] 0]
|
|
}
|
|
}
|
|
if {$newdevice eq "none"} {
|
|
device makeitem was_unplugged 1
|
|
}
|
|
device makeitem newdevice $newdevice
|
|
if {$deviceaction == 3} {
|
|
clientlog "PLUGGED $newdevice"
|
|
device makeitem action "plugged"
|
|
} else {
|
|
clientlog "SELECTED $newdevice"
|
|
device makeitem action "selected on touch display"
|
|
}
|
|
# set device state to "loading"
|
|
sct send cds=2
|
|
} elseif {$deviceaction == 3} {
|
|
# clientput "plugged [string tolower $newdevice] but autodevice off"
|
|
# set device state to "remote"
|
|
sct send cds=1
|
|
} else {
|
|
# clientput "[string tolower $newdevice] selected on CCU4, but autodevice off"
|
|
# set device state to "remote"
|
|
sct send cds=1
|
|
}
|
|
set deviceaction 1
|
|
return stdSct::complete
|
|
}
|
|
if {$hidecmd ne ""} {
|
|
sct send [lrange $hidecmd 0 10]
|
|
return stdSct::complete
|
|
}
|
|
# on seaman:
|
|
set fi [string toupper [silent 0 free_instruments]]
|
|
if {$fi ne "0"} {
|
|
if {[silent 0 sct freelist] ne $fi} {
|
|
sct freelist $fi
|
|
sct send cil=$fi
|
|
return stdSct::complete
|
|
}
|
|
}
|
|
return idle
|
|
}
|
|
|
|
proc ccu4::getdevice {old} {
|
|
variable deviceaction
|
|
catch {
|
|
set cdv [string toupper [hval /cc/cdv]]
|
|
set old [string toupper $old]
|
|
if {$cdv ne "NONE" && $cdv ne $old} {
|
|
set deviceaction 3
|
|
}
|
|
}
|
|
}
|
|
|
|
proc ccu4::write {} {
|
|
if {![hvali [sct parent]]} {
|
|
sct update [sct target]
|
|
return idle
|
|
}
|
|
set name [lindex [split [sct] "/"] 2]
|
|
#clientput "[expr [clock seconds] % 60] $name=[sct target]"
|
|
sct send "$name=[sct target]"
|
|
return ccu4::complete
|
|
}
|
|
|
|
proc ccu4::complete {} {
|
|
set res [split [sct result] "="]
|
|
sct update [lindex $res 1]
|
|
return idle
|
|
}
|
|
|
|
proc ccu4::completeDisconnect args {
|
|
dolater 0 rack_disconnect
|
|
return idle
|
|
}
|