diff --git a/site_ansto/instrument/kookaburra/config/counter/sct_bm.tcl b/site_ansto/instrument/kookaburra/config/counter/sct_bm.tcl new file mode 100644 index 00000000..f3b73095 --- /dev/null +++ b/site_ansto/instrument/kookaburra/config/counter/sct_bm.tcl @@ -0,0 +1,386 @@ +########################################################################################################################### +# +# file Proptocols between SICS and Embedded I/O device in Kookoburra +# +# This is a driver for SICS to communicate with the embedded I/O box on Kookoburra +# +# Author: Jing Chen (jgn@ansto.gov.au) June 2013 +# +# The driver can be installed with the following command, +# +# ::scobj::emHV::mkEmHV { +# name "emHV" +# IP localhost +# PORT 55010 +# tuning 1 +# interval 1 +# +############################################################################################################################## + + +proc debug_log {args} { + set d1 [clock format [clock seconds] -format %d%h%Y] + set fd [open "../log/pressure$d1.log" a] + puts $fd "[clock format [clock seconds] -format "%D %T "] [string trim $args "{}"]" + close $fd +} + + +namespace eval ::scobj::emHV { +} + +proc ::scobj::emHV::getEmStatusFunc {chan} { + + if {[hpropexists [sct] geterror]} { + hdelprop [sct] geterror + } + + set comm "get hvstatus$chan" + sct send $comm + + return rdEmStatus$chan +} + +proc ::scobj::emHV::rdEmStatusFunc {basePath chan} { + set replyStr [sct result] + + if {[string first "ASCERR" $replyStr] != -1} { + sct geterror $replyStr + return -code error "Error in emHV Response: $replyStr" + } elseif {[string length $replyStr] < 1} { + return -code error "Error in emHV: no message returned from device" + } else { + hset $basePath/hv$chan [lindex [split $replyStr ","] 3] + hset $basePath/rate$chan [lindex [split $replyStr ","] 5] + hset $basePath/uA$chan [lindex [split $replyStr ","] 7] + hset $basePath/status$chan [lindex [split $replyStr ","] 9] + } + + if {$chan == 1} { + return getEmStatus2 + } else { + return idle + } +} + +proc ::scobj::emHV::setCounterFunc {basePath} { + set countermode [sct target] + clientput "$countermode" + sct send "$countermode\r\n" + return ckCounterState +} + +proc ::scobj::emHV::ckCounterStateFunc {basePath} { + set replyStr [sct result] + + if {[string first "ASCERR" $replyStr] != -1} { + sct geterror $replyStr + return -code error "Error in emHV Response: $replyStr" + } elseif {[string first "Invalid Cmd" $replyStr] != -1} { + sct geterror $replyStr + return -code error "Error in emHV Response: $replyStr" + } elseif {[string length $replyStr] < 1} { + return -code error "Error in emHV: no message returned from device" + } else { + hset $basePath/count1 [lindex [split $replyStr ","] 5] + hset $basePath/count2 [lindex [split $replyStr ","] 7] + hset $basePath/countstate [lindex [split $replyStr ","] 3] + + if {[hval $basePath/countstate] == "stopped"} { + clientput "Counter stops" + return idle + } elseif {[hval $basePath/countstate] == "paused"} { + clientput "Counter pause" + return idle + } else { + clientput "Counter progressing ..." + set comm "get counter\r\n" + sct send $comm + return ckCounterState + } + } +} + +proc ::scobj::emHV::setPointFunc {basePath chan} { + set vol [sct target] + hset $basePath/target$chan $vol + + sct send "set hv$chan=$vol\r\n" + return ckVolStatus$chan +} + +proc ::scobj::emHV::ckVolStatusFunc {basePath chan} { + set replyStr [sct result] + + if {[string first "ASCERR" $replyStr] != -1} { + sct geterror $replyStr + return -code error "Error in emHV Response: $replyStr" + } elseif {[string length $replyStr] < 1} { + return -code error "Error in emHV: no message returned from device" + } else { + hset $basePath/hv$chan [lindex [split $replyStr ","] 3] + hset $basePath/rate$chan [lindex [split $replyStr ","] 5] + hset $basePath/uA$chan [lindex [split $replyStr ","] 7] + hset $basePath/status$chan [lindex [split $replyStr ","] 9] + } + + if {[hval $basePath/hv$chan] == [hval $basePath/target$chan]} { + return idle + } else { + if {[hval $basePath/status$chan] != "OK"} { + clientput "Voltage channel $chan is busy, wait ..." + sct send "get hvstatus$chan\r\n" + return ckVolStatus$chan + } else { + clientput "Start ramping voltage$chan to target [hval $basePath/target$chan] ..." + sct send "set poweruphv$chan\r\n" + return rampVol$chan + } + } +} + +proc ::scobj::emHV::rampVolFunc {basePath chan} { + set replyStr [sct result] + + if {[string first "ASCERR" $replyStr] != -1} { + sct geterror $replyStr + return -code error "Error in emHV Response: $replyStr" + } elseif {[string length $replyStr] < 1} { + return -code error "Error in emHV: no message returned from device" + } else { + hset $basePath/hv$chan [lindex [split $replyStr ","] 3] + hset $basePath/rate$chan [lindex [split $replyStr ","] 5] + hset $basePath/uA$chan [lindex [split $replyStr ","] 7] + hset $basePath/status$chan [lindex [split $replyStr ","] 9] + + if {[hval $basePath/status$chan] == "OK"} { + clientput "Finished ramping voltage$chan to [hval $basePath/target$chan]" + return idle + } else { + clientput "Ramping voltage$chan to [hval $basePath/hv$chan] ..." + sct send "get hvstatus$chan\r\n" + return rampVol$chan + } + } +} + +## +# @brief Make a emHV Controller +# +# @param argList, {name "emHV" IP localhost PORT 65123 tuning 1 interval 1} +# +# name: name of emHV controller object +# IP: IP address of RF generator moxa box +# PORT: Port number assigned to the generator on the moxa-box +# tuning: boolean, set tuning=1 to allow instrument scientists to set the axe positions +# interval: polling and ramping interval in seconds. + +proc ::scobj::emHV::mkEmHV {argList} { +# Generate parameter array from the argument list + foreach {k v} $argList { + set KEY [string toupper $k] + set pa($KEY) $v + } + + MakeSICSObj $pa(NAME) SCT_OBJECT + sicslist setatt $pa(NAME) klass environment + sicslist setatt $pa(NAME) long_name $pa(NAME) + sicslist setatt $pa(NAME) privilege spy + + set scobj_hpath /sics/$pa(NAME) + + makesctcontroller sct_$pa(NAME) std $pa(IP):$pa(PORT) + + # High Voltage Component + hfactory $scobj_hpath/hv1 plain user int + hfactory $scobj_hpath/rate1 plain user int + hfactory $scobj_hpath/uA1 plain user int + hfactory $scobj_hpath/status1 plain user text + hfactory $scobj_hpath/target1 plain user int + hfactory $scobj_hpath/hv2 plain user int + hfactory $scobj_hpath/rate2 plain user int + hfactory $scobj_hpath/uA2 plain user int + hfactory $scobj_hpath/status2 plain user text + hfactory $scobj_hpath/target2 plain user int + + # Counter Component + hfactory $scobj_hpath/count1 plain user int + hfactory $scobj_hpath/count2 plain user int + hfactory $scobj_hpath/countstate plain user text + + hset $scobj_hpath/hv1 0 + hset $scobj_hpath/rate1 0 + hset $scobj_hpath/uA1 0 + hset $scobj_hpath/status1 UNKNOWN + hset $scobj_hpath/target1 0 + hset $scobj_hpath/hv2 0 + hset $scobj_hpath/rate2 0 + hset $scobj_hpath/uA2 0 + hset $scobj_hpath/status2 UNKNOWN + hset $scobj_hpath/target2 0 + + hset $scobj_hpath/count1 0 + hset $scobj_hpath/count2 0 + hset $scobj_hpath/countstate UNKNOWN + + hsetprop $scobj_hpath read ::scobj::emHV::getEmStatusFunc 1 + hsetprop $scobj_hpath rdEmStatus1 ::scobj::emHV::rdEmStatusFunc $scobj_hpath 1 + hsetprop $scobj_hpath getEmStatus2 ::scobj::emHV::getEmStatusFunc 2 + hsetprop $scobj_hpath rdEmStatus2 ::scobj::emHV::rdEmStatusFunc $scobj_hpath 2 + + if {[SplitReply [environment_simulation]]=="false"} { + sct_emHV poll $scobj_hpath $pa(INTERVAL) + #sct_emHV queue $scobj_hpath progress read + } + + hfactory $scobj_hpath/setpoint1 plain user int + hsetprop $scobj_hpath/setpoint1 write ::scobj::emHV::setPointFunc $scobj_hpath 1 + hsetprop $scobj_hpath/setpoint1 ckVolStatus1 ::scobj::emHV::ckVolStatusFunc $scobj_hpath 1 + hsetprop $scobj_hpath/setpoint1 rampVol1 ::scobj::emHV::rampVolFunc $scobj_hpath 1 + + hfactory $scobj_hpath/setpoint2 plain user int + hsetprop $scobj_hpath/setpoint2 write ::scobj::emHV::setPointFunc $scobj_hpath 2 + hsetprop $scobj_hpath/setpoint2 ckVolStatus2 ::scobj::emHV::ckVolStatusFunc $scobj_hpath 2 + hsetprop $scobj_hpath/setpoint2 rampVol2 ::scobj::emHV::rampVolFunc $scobj_hpath 2 + + hfactory $scobj_hpath/counter plain user text + hsetprop $scobj_hpath/counter write ::scobj::emHV::setCounterFunc $scobj_hpath + hsetprop $scobj_hpath/counter ckCounterState ::scobj::emHV::ckCounterStateFunc $scobj_hpath + + if {[SplitReply [environment_simulation]]=="false"} { + sct_emHV write $scobj_hpath/setpoint1 + sct_emHV write $scobj_hpath/setpoint2 + sct_emHV write $scobj_hpath/counter + } + + # add HDB structure here + ::scobj::hinitprops $pa(NAME) + ::scobj::set_required_props $scobj_hpath + + hsetprop $scobj_hpath klass environment + hsetprop $scobj_hpath type part + hsetprop $scobj_hpath privilege spy + hsetprop $scobj_hpath control true + hsetprop $scobj_hpath data true + + foreach {hPath klass control data priv type} { + ch1 NXsensor true true user NXsensor + ch2 NXsensor true true user NXsensor + } { + hsetprop $scobj_hpath/$hPath klass $klass + hsetprop $scobj_hpath/$hPath privilege $priv + hsetprop $scobj_hpath/$hPath type $type + hsetprop $scobj_hpath/$hPath control $control + hsetprop $scobj_hpath/$hPath data $data + } + + foreach {hpath klass control data nxsave mutable priv alias} { + hv1 sensor true true true true user emHV-hv1 + rate1 sensor true true true true user emHV-rate1 + uA1 sensor true true true true user emHV-uA1 + status1 sensor true true true true user emHV-status1 + hv2 sensor true true true true user emHV-hv2 + rate2 sensor true true true true user emHV-rate2 + uA2 sensor true true true true user emHV-uA2 + status2 sensor true true true true user emHV-status2 + count1 sensor true true true true user emHV-count1 + count2 sensor true true true true user emHV-count2 + countstate sensor true true true true user emHV-countstate + } { + hsetprop $scobj_hpath/$hpath klass $klass + hsetprop $scobj_hpath/$hpath privilege $priv + hsetprop $scobj_hpath/$hpath control $control + hsetprop $scobj_hpath/$hpath data $data + hsetprop $scobj_hpath/$hpath nxsave $nxsave + hsetprop $scobj_hpath/$hpath mutable $mutable + hsetprop $scobj_hpath/$hpath nxalias $alias + hsetprop $scobj_hpath/$hpath sdsinfo ::nexus::scobj::sdsinfo + } +} + +proc emHV1 {{vol ""} args} { + if {$vol == ""} { + hval /sample/emHV/hv1 + } else { + hset /sample/emHV/setpoint1 $vol + } +} + +proc emHV2 {{vol ""} args} { + if {$vol == ""} { + hval /sample/emHV/hv2 + } else { + hset /sample/emHV/setpoint2 $vol + #set cmd "set hv2=$vol\r\n" + #sct_emHV transact $cmd + } +} + +proc hvramp1 {amp} { + set cmd "set hvramp1=$amp\r\n" + sct_emHV transact $cmd +} + +proc hvramp2 {amp} { + set cmd "set hvramp2=$amp\r\n" + sct_emHV transact $cmd +} + +proc poweruphv1 {} { + set cmd "set poweruphv1\r\n" + sct_emHV transact $cmd +} + +proc poweruphv2 {} { + set cmd "set poweruphv2\r\n" + sct_emHV transact $cmd +} + +proc powerdownhv1 {} { + set cmd "set powerdownhv1\r\n" + sct_emHV transact $cmd +} + +proc powerdownhv2 {} { + set cmd "set powerdownhv2\r\n" + sct_emHV transact $cmd +} + +proc bmthreshold {{vol ""} args} { + if {$vol == ""} { + set cmd "get bmthreshold\r\n" + } else { + set cmd "set bmthreshold=$vol\r\n" + } + sct_emHV transact $cmd +} + +proc setcounter {args} { + set cmd "set counter" + foreach arg $args { + lappend cmd $arg + } + hset /sample/emHV/counter $cmd +} + +publish emHV1 user +publish emHV2 user +publish hvramp1 user +publish hvramp2 user +publish poweruphv1 user +publish poweruphv2 user +publish powerdownhv1 user +publish powerdownhv2 user +publish bmthreshold user +publish setcounter user + +# Main process call to create the driver +#IP 137.157.205.22 +#IP for SIS PLC 137.157.205.21 30000 +::scobj::emHV::mkEmHV { + name "emHV" + IP 137.157.205.22 + PORT 30000 + tuning 1 + interval 1 +}