########################################################################################################################### # @file Proptocols between SICS and High Voltage Controller # # This is a driver for SICS to make following communication with the High Voltage Controller # # # 1. SICS uses TCP/IP protocol to interact with the HV component who shall provide an IP address # together with an port number. # # 2. Commands From SICS to HV component, # 1. HV_START hv1=xxx, i1=xxx, hv2=xxx, i2=xxx # :: Responses from HV component back to SICS are either # OK (if the system start correctly), or # Error Message (if the system does not start normally, the error message shall indicate # type of the errors) # # 2. HV_STOP (This will stop/shutdown the HV component totally) # # 3. HV_RESET (This will reset the HV component using the hv/i values specified in the Gumtree client GUI) # :: Responses from HV component back to SICS are either # OK (if the system start correctly), or # Error Message (if the system does not start normally, the error message will indicate type of the errors) # # 4. HV_STATUS (This command will send to HV component automatically and regularly, i.e. every 1 sec) # :: Responses from HV component back to SICS is "hv1=xxx, i1=xxx, hv2=xxx, i2=xxx, system=rampingup;\n", # SICS uses this information to update their values in the SICS system and on the Gumtree client as well. # # 3. HV parameters to be dsiaplyed on the Gumtree GUI are, hv1, i1, hv2, i2, system # # Author: Jing Chen (jgn@ansto.gov.au) July 2011 # # The HV Controller can be installed with the following command, # ::scobj::hv::mkHV { # name "hv" # 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::hv { } proc ::scobj::hv:setting {field basePath} { set newPara [sct target] switch $field { "voltage" {set comm "set hv=$newPara\r\n"} "pressure" {set comm "set pressure=$newPara\r\n"} "mode" {set comm "set mode=$newPara\r\n"} "date" {set comm "set date=$newPara\r\n"} "clear" {if {[string equal [string toupper $newPara] "OK"]!=1} { error "ERROR: please enter 'ok' to clear the error" return idle } else { set comm "clear error\r\n" } } "PowerUp" {if {[string equal [string toupper $newPara] "OK"]!=1} { error "ERROR: please enter 'ok' to set the Power Up" return idle } else { set comm "power up\r\n" } } "PowerDown" {if {[string equal [string toupper $newPara] "OK"]!=1} { error "ERROR: please enter 'ok' to set the Power Down" return idle } else { set comm "power down\r\n" } } "recording" {if {[string equal [string toupper [string trim $newPara " "]] "ON"]==1} { hset $basePath/dataRecording "ON" } elseif {[string equal [string toupper [string trim $newPara " "]] "OFF"]==1} { hset $basePath/dataRecording "OFF" } else { error "ERROR: please enter 'on' or 'off' to set the switch" } return idle } default {error "ERROR: illegal input command, type help for more info" return idle } } sct send $comm return checkReply } proc ::scobj::hv::checkReplyFunc {basePath} { set replyStr [sct result] hset $basePath/msg $replyStr return idle } ## # @brief send "get status" command to the HV device and obtain the latest status of the device proc ::scobj::hv::getHVStatusFunc {mode} { switch $mode { "state" {set comm "get status\r\n"} "config" {set comm "get config\r\n"} default {error "ERROR: illegal input command, type help for more info" return idle } } sct send $comm #after 500 return rdHVStatus } ## # @brief Read and record the HV status from the HV device proc ::scobj::hv::rdHVStatusFunc {basePath mode} { set replyStr [sct result] hset $basePath/msg $replyStr #broadcast "Reply from get $mode: $replyStr" if {[string first "Error" $replyStr] != -1} { error "ERROR: cannot get the current parameters setting from the HV device, check again!" } else { set replyText [split [string trimright $replyStr "\r\n "] ","] if {$mode == "state"} { hset $basePath/status/state "[lindex $replyText 3] [lindex $replyText 4]" hset $basePath/status/voltage [lindex $replyText 5] hsetprop $basePath/status/voltage units [lindex $replyText 6] hset $basePath/status/current [lindex $replyText 7] hsetprop $basePath/status/current units [lindex $replyText 8] hset $basePath/status/DetectorHighPressure [lindex $replyText 10] hsetprop $basePath/status/DetectorHighPressure units [lindex $replyText 11] hset $basePath/status/SampleHighPressure [lindex $replyText 13] hsetprop $basePath/status/SampleHighPressure units [lindex $replyText 14] hset $basePath/status/DetectorLowPressure [lindex $replyText 16] hsetprop $basePath/status/DetectorLowPressure units [lindex $replyText 17] hset $basePath/status/SampleLowPressure [lindex $replyText 19] hsetprop $basePath/status/SampleLowPressure units [lindex $replyText 20] hset $basePath/status/pressure5 [lindex $replyText 22] hsetprop $basePath/status/pressure5 units [lindex $replyText 23] hset $basePath/status/pressure6 [lindex $replyText 25] hsetprop $basePath/status/pressure6 units [lindex $replyText 26] hset $basePath/status/PLC-S "[lindex $replyText 28]" hset $basePath/status/PLC-H "[lindex $replyText 30]" hset $basePath/status/Presr-S "[lindex $replyText 32]" hset $basePath/status/Presr-H "[lindex $replyText 34]" hset $basePath/status/Soft-S "[lindex $replyText 36]" hset $basePath/status/Hard-S "[lindex $replyText 38]" set logdata "[lindex $replyText 10] [lindex $replyText 13] [lindex $replyText 16] [lindex $replyText 19] [lindex $replyText 22] [lindex $replyText 25] \ [lindex $replyText 5] [lindex $replyText 7] \ [lindex $replyText 28] [lindex $replyText 30] [lindex $replyText 32] [lindex $replyText 34] [lindex $replyText 36] [lindex $replyText 38] \ [lindex $replyText 4] [lindex $replyText 3]" if {[string equal [hval $basePath/dataRecording] "ON"] == 1} { debug_log $logdata } } elseif {$mode == "config"} { hset $basePath/config/mode "[lindex $replyText 3] [lindex $replyText 4]" hset $basePath/config/hv [lindex $replyText 5] hset $basePath/config/pressure_threshold [lindex $replyText 6] hsetprop $basePath/config/pressure_threshold units [lindex $replyText 7] } else { #return idle } } if {$replyStr != [sct oldval]} { sct oldval $replyStr sct update $replyStr sct utime readtime } return idle } ## # @brief Make a HV Controller # # @param argList, {name "hv" IP localhost PORT 65123 tuning 1 interval 1} # # name: name of hv 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::hv::mkHV {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 instrument sicslist setatt $pa(NAME) long_name $pa(NAME) set hvPath /sics/$pa(NAME) foreach {hPath type priv datatype init } { msg plain user text UNKNOW dataRecording plain user text ON status plain user none UNKNOW status/voltage plain user float 0 status/current plain user float 0 status/DetectorHighPressure plain user float 0 status/SampleHighPressure plain user float 0 status/DetectorLowPressure plain user float 0 status/SampleLowPressure plain user float 0 status/pressure5 plain user float 0 status/pressure6 plain user float 0 status/state plain user text UNKNOW status/PLC-S plain user text UNKNOW status/PLC-H plain user text UNKNOW status/Presr-S plain user text UNKNOW status/Presr-H plain user text UNKNOW status/Soft-S plain user text UNKNOW status/Hard-S plain user text UNKNOW config plain user none UNKNOW config/hv plain user float 0 config/mode plain user text UNKNOW config/pressure_threshold plain user float 0 } { hfactory $hvPath/$hPath $type $priv $datatype hset $hvPath/$hPath $init } hsetprop $hvPath/status oldval UNKNOWN hsetprop $hvPath/config oldval UNKNOWN #makesctcontroller sct_hv rfamp $pa(IP):$pa(PORT) makesctcontroller sct_hv std $pa(IP):$pa(PORT) hsetprop $hvPath/status read ::scobj::hv::getHVStatusFunc "state" hsetprop $hvPath/status rdHVStatus ::scobj::hv::rdHVStatusFunc $hvPath "state" hsetprop $hvPath/config read ::scobj::hv::getHVStatusFunc "config" hsetprop $hvPath/config rdHVStatus ::scobj::hv::rdHVStatusFunc $hvPath "config" if {[SplitReply [environment_simulation]]=="false"} { sct_hv poll $hvPath/status $pa(INTERVAL) sct_hv poll $hvPath/config $pa(INTERVAL) } hsetprop $hvPath tuning $pa(TUNING) if {$pa(TUNING)} { foreach {hpath type priv datatype mark} { set_hv plain user float voltage set_pressure plain user float pressure set_mode plain user text mode set_date plain user text date clear_error plain user text clear set_PowerUp plain user text PowerUp set_PowerDown plain user text PowerDown set_dataRecording plain user text recording } { hfactory $hvPath/$hpath $type $priv $datatype hsetprop $hvPath/$hpath write ::scobj::hv:setting $mark $hvPath hsetprop $hvPath/$hpath checkReply ::scobj::hv::checkReplyFunc $hvPath if {[SplitReply [environment_simulation]]=="false"} { sct_hv write $hvPath/$hpath $pa(INTERVAL) } } } foreach {hpath klass control data priv type} { /sics/hv instrument true true spy part /sics/hv/status NXsensor true true user NXsensor } { hsetprop $hpath klass $klass hsetprop $hpath privilege $priv hsetprop $hpath type $type hsetprop $hpath control $control hsetprop $hpath data $data } foreach {hpath klass control data nxsave mutable priv alias} { /sics/hv/status/voltage NXsensor true true true true user hv-voltage /sics/hv/status/current NXsensor true true true true user hv-current /sics/hv/status/DetectorHighPressure NXsensor true true true true user hv-DetectorHighPressure /sics/hv/status/DetectorLowPressure NXsensor true true true true user hv-DetectorLowPressure /sics/hv/status/SampleHighPressure NXsensor true true true true user hv-SampleHighPressure /sics/hv/status/SampleLowPressure NXsensor true true true true user hv-SampleLowPressure /sics/hv/status/pressure5 NXsensor true true true true user hv-pressure5 /sics/hv/status/pressure6 NXsensor true true true true user hv-pressure6 } { hsetprop $hpath nxalias $alias hsetprop $hpath klass $klass hsetprop $hpath privilege $priv hsetprop $hpath control $control hsetprop $hpath data $data hsetprop $hpath nxsave $nxsave hsetprop $hpath mutable $mutable hsetprop $hpath sdsinfo ::nexus::scobj::sdsinfo } # Initialise properties required for generating the API for GumTree and to save data ::scobj::hinitprops $pa(NAME) } proc hv_status {} { set cmd "get status\r\n" sct_hv send $cmd } proc hv_config {} { set cmd "get config\r\n" sct_hv send $cmd } proc hv_clear_error {} { set cmd "clear error\r\n" sct_hv send $cmd } proc hv_vol {{vol ""} args} { if {$vol == ""} { hget /instrument/hv/config/hv } else { set cmd "set hv=$vol\r\n" sct_hv send $cmd } } proc hv_pressure {{pressure ""} args} { if {$pressure == ""} { hget /instrument/hv/config/pressure_threshold } else { set cmd "set pressure=$pressure\r\n" sct_hv send $cmd } } proc hv_mode {{mode ""} args} { if {$mode == ""} { hget /instrument/hv/config/mode } else { set cmd "set mode=$mode\r\n" sct_hv send $cmd } } proc hv_date {{date ""} args} { if {$date == ""} { } else { set cmd "set date=$date\r\n" sct_hv send $cmd } } proc hv_powerup {} { set cmd "power up\r\n" sct_hv send $cmd } proc hv_powerdown {} { set cmd "power down\r\n" sct_hv send $cmd } proc hv_help {} { set cmd "help\r\n" sct_hv send $cmd } proc set_data_record {args} { switch $args { "ON" {hset /instrument/hv/dataRecording "ON"} "on" {hset /instrument/hv/dataRecording "ON"} "OFF" {hset /instrument/hv/dataRecording "OFF"} "off" {hset /instrument/hv/dataRecording "OFF"} default {error "ERROR: please enter 'on' or 'off' to set the switch"} } } publish hv_status user publish hv_config user publish hv_clear_error user publish hv_vol user publish hv_pressure user publish hv_mode user publish hv_date user publish hv_powerup user publish hv_powerdown user publish hv_help user publish set_data_record user # Main process call ::scobj::hv::mkHV { name "hv" IP 137.157.202.215 PORT 55011 tuning 1 interval 5 }