########################################################################################################################### # @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] [lindex $replyText 6]" hset $basePath/status/current "[lindex $replyText 7] [lindex $replyText 8]" hset $basePath/status/DetectorHighPressure "[lindex $replyText 10] [lindex $replyText 11]" hset $basePath/status/SampleHighPressure "[lindex $replyText 13] [lindex $replyText 14]" hset $basePath/status/DetectorLowPressure "[lindex $replyText 16] [lindex $replyText 17]" hset $basePath/status/SampleLowPressure "[lindex $replyText 19] [lindex $replyText 20]" hset $basePath/status/pressure5 "[lindex $replyText 22] [lindex $replyText 23]" hset $basePath/status/pressure6 "[lindex $replyText 25] [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] [lindex $replyText 7]" } else { return idle } 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) hfactory /sics/$pa(NAME)/msg plain user text hfactory /sics/$pa(NAME)/dataRecording plain user text hset /sics/$pa(NAME)/dataRecording "ON" hfactory /sics/$pa(NAME)/status plain user none hfactory /sics/$pa(NAME)/status/voltage plain user text hfactory /sics/$pa(NAME)/status/current plain user text hfactory /sics/$pa(NAME)/status/DetectorHighPressure plain user text hfactory /sics/$pa(NAME)/status/SampleHighPressure plain user text hfactory /sics/$pa(NAME)/status/DetectorLowPressure plain user text hfactory /sics/$pa(NAME)/status/SampleLowPressure plain user text hfactory /sics/$pa(NAME)/status/pressure5 plain user text hfactory /sics/$pa(NAME)/status/pressure6 plain user text hfactory /sics/$pa(NAME)/status/state plain user text hfactory /sics/$pa(NAME)/status/PLC-S plain user text hfactory /sics/$pa(NAME)/status/PLC-H plain user text hfactory /sics/$pa(NAME)/status/Presr-S plain user text hfactory /sics/$pa(NAME)/status/Presr-H plain user text hfactory /sics/$pa(NAME)/status/Soft-S plain user text hfactory /sics/$pa(NAME)/status/Hard-S plain user text hfactory /sics/$pa(NAME)/config plain user none hfactory /sics/$pa(NAME)/config/hv plain user text hfactory /sics/$pa(NAME)/config/mode plain user text hfactory /sics/$pa(NAME)/config/pressure_threshold plain user text #makesctcontroller sct_hv rfamp $pa(IP):$pa(PORT) makesctcontroller sct_hv std $pa(IP):$pa(PORT) hsetprop /sics/$pa(NAME)/status read ::scobj::hv::getHVStatusFunc "state" hsetprop /sics/$pa(NAME)/status rdHVStatus ::scobj::hv::rdHVStatusFunc /sics/$pa(NAME) "state" hsetprop /sics/$pa(NAME)/config read ::scobj::hv::getHVStatusFunc "config" hsetprop /sics/$pa(NAME)/config rdHVStatus ::scobj::hv::rdHVStatusFunc /sics/$pa(NAME) "config" # Initialise properties required for generating the API for GumTree and to save data ::scobj::hinitprops $pa(NAME) status config ::scobj::hinitprops $pa(NAME) status/voltage status/current status/state ::scobj::hinitprops $pa(NAME) status/DetectorHighPressure status/SampleHighPressure status/DetectorLowPressure status/SampleLowPressure status/pressure5 status/pressure6 ::scobj::hinitprops $pa(NAME) status/PLC-S status/PLC-H status/Presr-S status/Presr-H status/Soft-S status/Hard-S ::scobj::hinitprops $pa(NAME) config/hv config/pressure_threshold config/mode if {[SplitReply [environment_simulation]]=="false"} { sct_hv poll /sics/$pa(NAME)/status $pa(INTERVAL) sct_hv poll /sics/$pa(NAME)/config $pa(INTERVAL) } hsetprop /sics/$pa(NAME) tuning $pa(TUNING) if {$pa(TUNING)} { hfactory /sics/$pa(NAME)/set_hv plain user int hfactory /sics/$pa(NAME)/set_pressure plain user int hfactory /sics/$pa(NAME)/set_mode plain user text hfactory /sics/$pa(NAME)/set_date plain user text hfactory /sics/$pa(NAME)/clear_error plain user text hfactory /sics/$pa(NAME)/set_PowerUp plain user text hfactory /sics/$pa(NAME)/set_PowerDown plain user text hfactory /sics/$pa(NAME)/set_dataRecording plain user text ::scobj::hinitprops $pa(NAME) set_hv set_pressure set_mode set_date clear_error set_PowerUp set_PowerDown set_dataRecording hsetprop /sics/$pa(NAME)/set_hv write ::scobj::hv:setting "voltage" /sics/$pa(NAME) hsetprop /sics/$pa(NAME)/set_hv checkReply ::scobj::hv::checkReplyFunc /sics/$pa(NAME) hsetprop /sics/$pa(NAME)/set_pressure write ::scobj::hv:setting "pressure" /sics/$pa(NAME) hsetprop /sics/$pa(NAME)/set_pressure checkReply ::scobj::hv::checkReplyFunc /sics/$pa(NAME) hsetprop /sics/$pa(NAME)/set_mode write ::scobj::hv:setting "mode" /sics/$pa(NAME) hsetprop /sics/$pa(NAME)/set_mode checkReply ::scobj::hv::checkReplyFunc /sics/$pa(NAME) hsetprop /sics/$pa(NAME)/set_date write ::scobj::hv:setting "date" /sics/$pa(NAME) hsetprop /sics/$pa(NAME)/set_date checkReply ::scobj::hv::checkReplyFunc /sics/$pa(NAME) hsetprop /sics/$pa(NAME)/clear_error write ::scobj::hv:setting "clear" /sics/$pa(NAME) hsetprop /sics/$pa(NAME)/clear_error checkReply ::scobj::hv::checkReplyFunc /sics/$pa(NAME) hsetprop /sics/$pa(NAME)/set_PowerUp write ::scobj::hv:setting "PowerUp" /sics/$pa(NAME) hsetprop /sics/$pa(NAME)/set_PowerUp checkReply ::scobj::hv::checkReplyFunc /sics/$pa(NAME) hsetprop /sics/$pa(NAME)/set_PowerDown write ::scobj::hv:setting "PowerDown" /sics/$pa(NAME) hsetprop /sics/$pa(NAME)/set_PowerDown checkReply ::scobj::hv::checkReplyFunc /sics/$pa(NAME) hsetprop /sics/$pa(NAME)/set_dataRecording write ::scobj::hv:setting "recording" /sics/$pa(NAME) if {[SplitReply [environment_simulation]]=="false"} { sct_hv write /sics/$pa(NAME)/set_hv $pa(INTERVAL) sct_hv write /sics/$pa(NAME)/set_pressure $pa(INTERVAL) sct_hv write /sics/$pa(NAME)/set_mode $pa(INTERVAL) sct_hv write /sics/$pa(NAME)/set_date $pa(INTERVAL) sct_hv write /sics/$pa(NAME)/clear_error $pa(INTERVAL) sct_hv write /sics/$pa(NAME)/set_PowerUp $pa(INTERVAL) sct_hv write /sics/$pa(NAME)/set_PowerDown $pa(INTERVAL) sct_hv write /sics/$pa(NAME)/set_dataRecording $pa(INTERVAL) } } } proc hvGetStatus {} { set cmd "get status\r\n" sct_hv send $cmd } proc hvGetConfig {} { set cmd "get config\r\n" sct_hv send $cmd } proc hvClearError {} { set cmd "clear error\r\n" sct_hv send $cmd } proc hvSetHV {vol} { set cmd "set hv=$vol\r\n" sct_hv send $cmd } proc hvSetPressure {pressure} { set cmd "set pressure=$pressure\r\n" sct_hv send $cmd } proc hvSetMode {mode} { set cmd "set mode=$mode\r\n" sct_hv send $cmd } proc hvSetDate {date} { set cmd "set date=$date\r\n" sct_hv send $cmd } proc hvPowerUp {} { set cmd "power up\r\n" sct_hv send $cmd } proc hvPowerDown {} { set cmd "power down\r\n" sct_hv send $cmd } proc hvHelp {} { set cmd "help\r\n" sct_hv send $cmd } proc setDataRecord {args} { switch $args { "ON" {hset /sics/hv/dataRecording "ON"} "on" {hset /sics/hv/dataRecording "ON"} "OFF" {hset /sics/hv/dataRecording "OFF"} "off" {hset /sics/hv/dataRecording "OFF"} default {error "ERROR: please enter 'on' or 'off' to set the switch"} } } publish hvGetStatus user publish hvGetConfig user publish hvClearError user publish hvSetHV user publish hvSetPressure user publish hvSetMode user publish hvSetDate user publish hvPowerUp user publish hvPowerDown user publish hvHelp user publish setDataRecord user # Main process call ::scobj::hv::mkHV { name "hv" IP 137.157.202.215 PORT 55011 tuning 1 interval 5 }