proc makeCCU4 {args} { if {[sicsdescriptor cc] ne "ccu4"} { if {[sicsdescriptor cc] ne "notfound"} { error "object cc must be CCU4 but is [sicsdescriptor cc]" } set ver [silent 0 result device ccu4version] if {$ver < 7.0 && $ver != 0} { clientput "WARNING: old ccu4 version $ver" makenv cc ccu4_6 catch {cc hea 0} } else { makenv cc ccu4 if {$ver < 7.3} { cc hea 0 } } } device_layout makeitem /cc 99 set badargs [list] set cfgdev "0" set hepump 0 set sensirion [silent 0 result instconfig sensirion] foreach arg $args { switch $arg { nv - nv_release_blocked { if {$arg eq "nv_release_blocked"} { makenv nv -driver ccu4flow release_blocked $sensirion } else { makenv nv -driver ccu4flow $sensirion } # GraphAdd cc.f mbar nv_flow red GraphAdd nv.flow ln/min nv_flow magenta GraphAdd nv.autoflow.flowtarget ln/min nv_set green if {[silent 0 result instconfig sensirion]} { GraphAdd nv.flowp ln/min nv_pres gray } # GraphAdd cc.mp i pulse green # GraphAdd cc.mo i overrun blue # GraphAdd cc.mt i torque yellow set hepump 1 } nvstep { makenv nv -driver nvstep $sensirion GraphAdd nv.flow ln/min nv_flow magenta GraphAdd nv.autoflow.flowtarget ln/min nv_set green if {[silent 0 result instconfig sensirion]} { GraphAdd nv.flowp ln/min nv_pres gray } makenv nvmot trinamic -base /nv/ hepump GraphAdd nv.nvmot.pos deg GraphAdd nv.nvmot.encoder deg # nvmot maxcurrent 128 # nvmot maxspeed 200 # nvmot acceleration 50 # nvmot freewheeling 1 # nvmot lowerlimit -110 # nvmot upperlimit 110 # nvmot zero -90 # nvmot maxencdif 1.8 nvmot precision 1.8 set hepump 1 } n2 { makenv ln2fill ccu4n2 GraphAdd cc.nu K_2 N2_upper red GraphAdd cc.nl K_2 N2_lower green } he { makenv hefill ccu4he GraphAdd cc.h % He_Level brown set vessel [silent 0 result instconfig hevessel] if {$vessel eq "ami136"} { makenv vhe -driver ami136 cm GraphAdd vhe % HeVessel blue } else { GraphAdd cc.h0 % HeVessel blue helium_register _cc /cc/h0 vessel if {$vessel ne "0"} { catch {cc hea 1} catch {cc hem0 475} catch {cc hfu0 0} } } helium_register _cc /cc/h } he_ilm { makenv hefill -driver ccu4ext he lev set vessel [silent 0 result instconfig hevessel] if {$vessel ne "0"} { catch {cc hea 1} catch {cc hav 2} catch {cc hem0 475} catch {cc hfu0 0} } GraphAdd lev % He_Level brown GraphAdd cc.h0 % HeVessel blue hsetprop /hefill fast_cmd "lev mode 1\ncc hf 1" hsetprop /hefill slow_cmd "lev mode 0\ncc hf 0" hsetprop /hefill vessel_cmd "cc h0" } default { if {$cfgdev eq "0"} { set cfgdev $arg } else { lappend badargs $arg } } } # the following lines are to allow only new syntax # makeCCU4 device module ... instead of ccu4_device if {$cfgdev eq "0"} { set cfgdev "" } } if {$hepump} { makeHePump hsetprop /nv hepump /hepump } set cfg [ccu4_get_device_config $cfgdev codesfile] if {$cfg eq "" || [llength $badargs] > 0} { error "ERROR: bad args: $badargs ERROR: Usage: makeCCU4 ... ERROR: must be a device defined in $codesfile ERROR: must be one of: nv n2 he he_ilm" } ccu4_config_device $cfg } proc ccu4_get_device_config {device codesfilename} { upvar $codesfilename codesfile set codesfile config/ccu4device.list catch { set fil [open $codesfile] set lines [list] catch { set lines [split [::read $fil] \n] } close $fil } set ldevice [string tolower $device] foreach line $lines { set lline [split $line "\t"] set fdevice [string tolower [lindex $lline 0]] # clientput "$ldevice $fdevice" if {$ldevice eq $fdevice} { return $line } } return "" } proc ccu4_config_device {devcfg} { set lline [split $devcfg "\t"] # send device name first cc cdv [lindex $lline 0] cc hav 0 cc fav 0 cc nav 0 cc mav 0 set opt [lindex $lline 3] foreach o [split $opt ""] { switch $o { f { cc fav 1 cc mav 1 } n { cc nav 1 } N { cc nav 2 } a { cc hav 1 cc hd 75 cc hwr 460 } o { cc hav 1 cc hd 130 cc hwr 166 } h { cc hav 1 if {[catch { cc hd [lindex $lline 6] cc hwr [lindex $lline 7] }]} { error "config/ccu4device.list: need current and resistivity of wire in column 6 and 7 (or use a/o instead of h)" } } H { cc hav 2 } } } if {[sctval /cc/hav] == 1} { if {[catch { cc hem [lindex $lline 4] cc hfu [lindex $lline 5] }]} { error "config/ccu4device.list: need empty and full resistivity of wire in column 4 and 5" } } # set to remote cc cds 1 } proc ccu4_device {device} { global device_name if {$device eq "0"} { device makeitem ccu4_device 0 return } set c4d [silent 0 result device ccu4_device] if {$device eq "renew"} { if {$c4d eq "blank"} { ccu4_show_device $device_name return } set device $c4d } elseif {$device eq "default"} { if {$c4d eq "blank"} { ccu4_show_device $device_name return } if {$c4d ne "0"} { return } set device $device_name } device makeitem ccu4_device $device if {$device eq "blank" || $device eq "special"} { return } set cfgdev [ccu4_get_device_config [string tolower $device] codesfile] if {$cfgdev ne ""} { ccu4_config_device $cfgdev } else { error "$device not found in $codesfile" } } proc ccu4_show_device {device} { cc cdv $device cc hav 0 cc fav 0 cc nav 0 cc mav 0 cc cds 1 } proc makeNone {} { if {[rack] ne "no"} { set ver [silent 0 result device ccu4version] if {$ver < 7.0} { makenv cc ccu4_6 } else { makenv cc ccu4 } ccu4_device none makeHePump } else { ccu4_device 0 } } proc rackGroup args { # source config/rack.list Label "select rack (with T-controller and CCU):" RadioGroup rack Newline NarrowColumn 3 set racks [get_rack] if {[lindex $racks 0] eq "!"} { Style warning Label "[lrange $racks 1 end]" Newline set racks [concat no other] } else { set racks [concat no $racks other] } foreach key $racks { RadioButton $key } Newline Label "a list of racks can be found as $::env(HOME)/sea/tcl/config/rack.list" } proc rack {{rack ""} {forced 0}} { global rack_in_use rack_was_active rack_request set oldrack [silent UNDEF result device rack] if {$oldrack eq "UNDEF"} { if {[cfg_env exists _cc]} { set oldrack other } else { set oldrack no } } set now [DoubleTime] if {$rack eq ""} { if {[info exists rack_request]} { lassign $rack_request rackset req_time if {$req_time < $now + 10} { return $rackset } unset rack_request } return $oldrack } set rack_request [list $rack $now] set rack_was_active $now if {$rack eq "other"} { device rack other clientlog "other rack: define ports with cfgenv _cc / cfgenv _tt" return } source config/rack.list if {$rack eq "no"} { install_rack no $forced return } set cfglist no foreach {key val} $racklist { if {[string equal -nocase $rack $key]} { set rack $key set cfglist $val break } } if {$cfglist eq "no"} { error "illegal rack: $rack" } if {![info exists rack_in_use]} { install_rack $rack return } set racks [get_rack] if {$racks eq $rack} { install_rack $rack 1 } else { clientlog "ask_for_rack $rack [result instrument]" seaman / ask_for_rack $rack [result instrument] } } proc install_rack {rack {forced 0}} { global inside_samenv global rack_in_use if {$rack eq ""} { set rack no } clientlog "install_rack $rack" set oldrack [silent UNDEF result device rack] if {$rack eq "no"} { if {[silent 1 result device rack_used]} { if {$forced || $oldrack eq "no"} { samenv -q none } else { clientlog "ERROR: rack $oldrack is in use" clientlog "ERROR: use" clientlog "ERROR: samenv none" clientlog "ERROR: to release it" error "above error" } } else { device makeitem rack no remove_these_objects {cc _cc} cfg_env makeitem _cc unconnected cfg_env makeitem _tt unconnected cfg_env makeitem _nvmot unconnected cfg_env makeitem _hemot unconnected # catch {_cc disconnect} # catch {_tt disconnect} } seaman / rack_owner $oldrack free return } source config/rack.list array set racks $racklist if {![info exists racks($rack)]} { error "undefined rack: $rack" } set cfglist $racks($rack) device makeitem rack $rack set reload 0 foreach {dev hostport} $cfglist { if {[silent 0 result cfg_env $dev] ne $hostport} { cfg_env makeitem $dev $hostport set reload 1 } } if {$rack ne "other"} { seaman / rack_owner $rack [result instrument] [result device rack_used] } if {$reload} { dolater 3 reload_device_later } elseif {[sicsdescriptor cc] eq "notfound"} { if {[info exists rack_in_use]} { do_as_manager { set inside_samenv 1 makenv cc ccu4 set inside_samenv 0 } } catch {ccu4::getdevice [result device name]} } else { dolater 3 _cc reconnect catch {ccu4::getdevice [result device name]} } } proc reload_device_later {} { samenv -q reload if {[result device name] eq "none"} { # auto device: cc cdv * } # cc send cin= } proc set_free_instruments {cc fi} { $cc send cil=[string toupper $fi] } proc rack_check_connection {} { global rack_was_active set now [DoubleTime] if {[sicsdescriptor cc] eq "notfound" || ![string match "CC*" [silent no result device rack]]} { seaman_rack_in_use [result device rack] 0 return } set last [silent 0 hgetpropval /cc read_time] set last2 [silent 0 hgetpropval /tt read_time] if {$last2 > $last} { # let's take the last read time of /tt, in case the ccu (/cc) is not working set last $last2 } if {[info exists rack_was_active]} { if {$last > $rack_was_active} { set rack_was_active $last } if {[silent 0 result device rack_used] == 0} { set inuse 0 } else { set inuse [expr $now < $rack_was_active + 10] } seaman_rack_in_use [result device rack] $inuse } else { set rack_was_active $now } if {$last == 0} { set rack_expires [expr $rack_was_active + 300] } elseif {[result device name] eq "none"} { set rack_expires [expr $rack_was_active + 300] } else { set rack_expires [expr $rack_was_active + 3600 * 12] } if {$now > $rack_expires} { clientlog "no rack connected - no device" rack no 1 } } proc seaman_rack_in_use {rack inuse} { global rack_in_use # if {![info exists rack_in_use]} { # # no rack management # return # } if {$rack eq ""} { set rack no } if {$rack eq "no"} { # should not happen set inuse 0 } set old [silent "" set rack_in_use] set rack_in_use "$inuse $rack" if {$rack_in_use ne $old} { seaman / rack_in_use_on $rack [result instrument] $inuse } } proc rack_disconnect args { install_rack no 1 seaman / move_rack_to [result device rack] free } proc rack_in_use {rack} { global rack_in_use if {![info exists rack_in_use]} { # no rack management return 0 } if {[silent 0 result device rack_used] == 0} { return 0 } set inuse [lindex $rack_in_use 0] set r [lindex $rack_in_use 1] if {$r ne $rack} { set inuse 2 } return $inuse } proc release_rack_for {rack instrument} { switch [rack_in_use $rack] { 1 { seaman / rack_not_available_for $rack $instrument [result instrument] return } 0 { rack no clientlog "rack no" seaman / rack_available_for $rack $instrument } 2 { clientlog "rack $rack not in use here" seaman / rack_available_for $rack $instrument force } } } proc rack_not_available {rack old} { broadcast "ERROR: $rack not available (used on $old)" } publishLazy rack publishLazy rack_disconnect publishLazy rack_with_confirm publishLazy seaman_rack_in_use publishLazy reload_device_later publishLazy set_free_instruments publishLazy release_rack_for publishLazy rack_not_available publishLazy install_rack publishLazy rack_in_use