########################################################################################################################### # @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 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 /sics/hv/config/hv } else { set cmd "set hv=$vol\r\n" sct_hv send $cmd } } proc hv_pressure {{pressure ""} args} { if {$pressure == ""} { hget /sics/hv/config/pressure_threshold } else { set cmd "set pressure=$pressure\r\n" sct_hv send $cmd } } proc hv_mode {{mode ""} args} { if {$mode == ""} { hget /sics/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 /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 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 }