diff --git a/site_ansto/instrument/config/beamline/he3_polanal.sct b/site_ansto/instrument/config/beamline/he3_polanal.sct index b0f784c0..5352068d 100644 --- a/site_ansto/instrument/config/beamline/he3_polanal.sct +++ b/site_ansto/instrument/config/beamline/he3_polanal.sct @@ -1,6 +1,5 @@ # vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent driver he3_polanal = { - debug_threshold = 0; protocol = std; class = instrument; simulation_group = rfgen_simulation; diff --git a/site_ansto/instrument/config/beamline/he3_polanal_sct.tcl b/site_ansto/instrument/config/beamline/he3_polanal_sct.tcl index 26abaa4c..8b7ec570 100644 --- a/site_ansto/instrument/config/beamline/he3_polanal_sct.tcl +++ b/site_ansto/instrument/config/beamline/he3_polanal_sct.tcl @@ -3,7 +3,7 @@ # namespace eval ::scobj::he3_polanal { - set debug_threshold 0 + set debug_threshold 5 # preamble hook code starts proc do_update { node dlist idx } { if {[llength ${dlist}] > ${idx}} { @@ -595,7 +595,7 @@ proc ::scobj::he3_polanal::mkDriver { sct_controller name device_class simulatio } hsetprop ${scobj_hpath} klass ${device_class} hsetprop ${scobj_hpath} data true - hsetprop ${scobj_hpath} debug_threshold 0 + hsetprop ${scobj_hpath} debug_threshold 5 # mkDriver hook code goes here } catch_message ] handle_exception ${catch_status} ${catch_message} diff --git a/site_ansto/instrument/config/environment/knauer_pump.sct b/site_ansto/instrument/config/environment/knauer_pump.sct index 881caa4c..cd5b0baf 100644 --- a/site_ansto/instrument/config/environment/knauer_pump.sct +++ b/site_ansto/instrument/config/environment/knauer_pump.sct @@ -3,7 +3,6 @@ # vim: ft=tcl ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent # driver knauer_pump = { - debug_threshold = 0; vendor = knauer; device = pump40p; protocol = knauer_ap; class = environment; simulation_group = environment_simulation; diff --git a/site_ansto/instrument/config/environment/knauer_pump_sct.tcl b/site_ansto/instrument/config/environment/knauer_pump_sct.tcl index 136f2f65..4649bdb4 100644 --- a/site_ansto/instrument/config/environment/knauer_pump_sct.tcl +++ b/site_ansto/instrument/config/environment/knauer_pump_sct.tcl @@ -3,7 +3,7 @@ # namespace eval ::scobj::knauer_pump { - set debug_threshold 0 + set debug_threshold 5 } proc ::scobj::knauer_pump::debug_log {tc_root debug_level debug_string} { @@ -1176,7 +1176,7 @@ proc ::scobj::knauer_pump::mkDriver { sct_controller name device_class simulatio ansto_makesctdrive ${name}_pump_volume_setp ${scobj_hpath}/pump/volume/setp ${scobj_hpath}/pump/volume/pval ${sct_controller} hsetprop ${scobj_hpath} klass ${device_class} hsetprop ${scobj_hpath} data true - hsetprop ${scobj_hpath} debug_threshold 0 + hsetprop ${scobj_hpath} debug_threshold 5 # mkDriver hook code starts #hset ${scobj_hpath}/pump/remote 1 # mkDriver hook code ends diff --git a/site_ansto/instrument/config/environment/sct_knauer_pump.tcl b/site_ansto/instrument/config/environment/sct_knauer_pump.tcl deleted file mode 100644 index 47d7d8a5..00000000 --- a/site_ansto/instrument/config/environment/sct_knauer_pump.tcl +++ /dev/null @@ -1,1307 +0,0 @@ -# Generated driver for knauer_pump -# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent -# - -namespace eval ::scobj::knauer_pump { - set debug_threshold 0 -} - -proc ::scobj::knauer_pump::debug_log {tc_root debug_level debug_string} { - set catch_status [ catch { - set debug_threshold [hgetpropval ${tc_root} debug_threshold] - if {${debug_level} >= ${debug_threshold}} { - set now [clock seconds] - set ts [clock format ${now} -format "%Y%m%d"] - set log_file_name "../log/knauer_pump_[basename ${tc_root}]_${ts}.log" - set fd [open "${log_file_name}" "a"] - set ts [clock format ${now} -format "%T"] - puts ${fd} "${ts} ${debug_string}" - close ${fd} - } - } catch_message ] -} - -proc ::scobj::knauer_pump::sics_log {debug_level debug_string} { - set catch_status [ catch { - set debug_threshold ${::scobj::knauer_pump::debug_threshold} - if {${debug_level} >= ${debug_threshold}} { - sicslog "::scobj::knauer_pump::${debug_string}" - } - } catch_message ] -} - -# checklimits function for driveable interface -proc ::scobj::knauer_pump::checklimits {tc_root} { - set catch_status [ catch { - debug_log ${tc_root} 1 "checklimits tc_root=${tc_root} sct=[sct] target=[sct target]" - set setpoint [sct target] - if { [hpropexists [sct] lowerlimit] } { - set lolimit [sct lowerlimit] - } else { - # lowerlimit not set, use target - set lolimit [sct target] - } - if { [hpropexists [sct] upperlimit] } { - set hilimit [sct upperlimit] - } else { - # upperlimit not set, use target - set hilimit [sct target] - } -# checklimits hook code goes here - if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } { - sct driving 0 - error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]" - } - return OK - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# check function for hset change -proc ::scobj::knauer_pump::checkrange {tc_root} { - set catch_status [ catch { - debug_log ${tc_root} 1 "checkrange tc_root=${tc_root} sct=[sct] target=[sct target]" - set setpoint [sct target] - if { [hpropexists [sct] lowerlimit] } { - set lolimit [sct lowerlimit] - } else { - # lowerlimit not set, use target - set lolimit [sct target] - } - if { [hpropexists [sct] upperlimit] } { - set hilimit [sct upperlimit] - } else { - # upperlimit not set, use target - set hilimit [sct target] - } -# checkrange hook code goes here - if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } { - error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]" - } - return OK - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to request the read of a parameter on a device -proc ::scobj::knauer_pump::flow_fetch {tc_root nextState cmd_str} { - set catch_status [ catch { - debug_log ${tc_root} 1 "flow_fetch tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set cmd "${cmd_str}" -# flow_fetch hook code starts - set index 4 - set data [hgetpropval ${tc_root}/dummy/status real_data] - set dlist [split ${data} ","] - if { [llength ${dlist}] > ${index} } { - set flow_pv [lindex ${dlist} 4] - } else { - set flow_pv 0.0 - } - sct result [expr {0.001 * ${flow_pv}}] - set cmd "@@NOSEND@@" -# flow_fetch hook code ends - if { [hpropexists [sct] geterror] } { - debug_log ${tc_root} 9 "[sct] error: [sct geterror]" - error "[sct geterror]" - } - debug_log ${tc_root} 1 "flow_fetch sct send ${cmd}" - if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { - sct send "${cmd}" - } - return ${nextState} - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to write a parameter value on a device -proc ::scobj::knauer_pump::flow_write {tc_root nextState cmd_str} { - set catch_status [ catch { - debug_log ${tc_root} 1 "flow_write tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set par [sct target] - set cmd "${cmd_str}${par}" -# flow_write hook code starts - set data [sct target] - set cmd "@@NOSEND@@" - set nextState idle - if { ${data} != [sct oldval] } { - debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]" - sct oldval ${data} - sct update ${data} - sct utime readtime - } -# flow_write hook code ends - if { [hpropexists [sct] geterror] } { - debug_log ${tc_root} 9 "[sct] error: [sct geterror]" - error "[sct geterror]" - } - if { [hpropexists [sct] driving] } { - if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } { - sct driving 1 - } - } - debug_log ${tc_root} 1 "flow_write sct send ${cmd}" - if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { - sct send "${cmd}" - } - return ${nextState} - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to request the read of a parameter on a device -proc ::scobj::knauer_pump::getValue {tc_root nextState cmd_str} { - set catch_status [ catch { - debug_log ${tc_root} 1 "getValue tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set cmd "${cmd_str}" -# getValue hook code goes here - debug_log ${tc_root} 1 "getValue sct send ${cmd}" - if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { - sct send "${cmd}" - } - return ${nextState} - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to check the write parameter on a device -proc ::scobj::knauer_pump::noResponse {tc_root} { - set catch_status [ catch { - debug_log ${tc_root} 1 "noResponse tc_root=${tc_root} sct=[sct] resp=[sct result]" -# noResponse hook code goes here - return "idle" - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# check function for hset change -proc ::scobj::knauer_pump::ratio_check {tc_root} { - set catch_status [ catch { - debug_log ${tc_root} 1 "ratio_check tc_root=${tc_root} sct=[sct] target=[sct target]" - set setpoint [sct target] - if { [hpropexists [sct] lowerlimit] } { - set lolimit [sct lowerlimit] - } else { - # lowerlimit not set, use target - set lolimit [sct target] - } - if { [hpropexists [sct] upperlimit] } { - set hilimit [sct upperlimit] - } else { - # upperlimit not set, use target - set hilimit [sct target] - } -# ratio_check hook code starts - set rlist [split ${setpoint} /] - if { [llength ${rlist}] != 4 } { - sct geterror "${setpoint} has [llength ${rlist}] components, needs 4" - error [sct geterror] - } - set sum 0 - for {set i 0} {$i < 4} {incr i} { - set cmp [lindex ${rlist} ${i}] - if { ![string is integer -strict ${cmp}] } { - sct geterror "component [expr {${i} + 1}] is not integer: \"${cmp}\"" - error [sct geterror] - } - if { !(${cmp} >= 0 && ${cmp} <= 100) } { - sct geterror "component [expr {${i} + 1}] is not between 0 and 100: \"${cmp}\"" - error [sct geterror] - } - set sum [expr {${sum} + ${cmp}}] - } - if { ${sum} != 100 } { - sct geterror "sum of components is ${sum}, must be 100" - error [sct geterror] - } -# ratio_check hook code ends - if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } { - error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]" - } - return OK - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to request the read of a parameter on a device -proc ::scobj::knauer_pump::ratio_fetch {tc_root nextState cmd_str} { - set catch_status [ catch { - debug_log ${tc_root} 1 "ratio_fetch tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set cmd "${cmd_str}" -# ratio_fetch hook code starts - set data [hgetpropval ${tc_root}/dummy/status real_data] - set dlist [split ${data} ","] - set ratio_vals "[lindex ${dlist} 5]/[lindex ${dlist} 6]/[lindex ${dlist} 7]/[lindex ${dlist} 8]" - sct result ${ratio_vals} - set cmd "@@NOSEND@@" -# ratio_fetch hook code ends - if { [hpropexists [sct] geterror] } { - debug_log ${tc_root} 9 "[sct] error: [sct geterror]" - error "[sct geterror]" - } - debug_log ${tc_root} 1 "ratio_fetch sct send ${cmd}" - if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { - sct send "${cmd}" - } - return ${nextState} - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to write a parameter value on a device -proc ::scobj::knauer_pump::ratio_write {tc_root nextState cmd_str} { - set catch_status [ catch { - debug_log ${tc_root} 1 "ratio_write tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set par [sct target] - set cmd "${cmd_str}${par}" -# ratio_write hook code starts - set data [sct target] - set cmd "@@NOSEND@@" - set nextState idle - if { ${data} != [sct oldval] } { - debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]" - sct oldval ${data} - sct update ${data} - sct utime readtime - } -# ratio_write hook code ends - if { [hpropexists [sct] geterror] } { - debug_log ${tc_root} 9 "[sct] error: [sct geterror]" - error "[sct geterror]" - } - if { [hpropexists [sct] driving] } { - if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } { - sct driving 1 - } - } - debug_log ${tc_root} 1 "ratio_write sct send ${cmd}" - if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { - sct send "${cmd}" - } - return ${nextState} - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to parse the read of a parameter on a device -proc ::scobj::knauer_pump::rdValue {tc_root} { - set catch_status [ catch { - debug_log ${tc_root} 1 "rdValue tc_root=${tc_root} sct=[sct] result=[sct result]" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set data [sct result] - set nextState "idle" - if {[string equal -nocase -length 7 ${data} "ASCERR:"]} { - # the protocol driver has reported an error - sct geterror "${data}" - error "[sct geterror]" - } -# rdValue hook code goes here - if { ${data} != [sct oldval] } { - debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]" - sct oldval ${data} - sct update ${data} - sct utime readtime - } - return ${nextState} - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to parse the read of a parameter on a device -proc ::scobj::knauer_pump::read_glp {tc_root} { - set catch_status [ catch { - debug_log ${tc_root} 1 "read_glp tc_root=${tc_root} sct=[sct] result=[sct result]" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set data [sct result] - set nextState "idle" - if {[string equal -nocase -length 7 ${data} "ASCERR:"]} { - # the protocol driver has reported an error - sct geterror "${data}" - error "[sct geterror]" - } -# read_glp hook code starts - if { [string equal -nocase -length 6 ${data} "ERROR:"] } { - } else { - set dlist [split [lindex [split ${data} ":"] 1] ","] - sct real_data "[join [lrange ${dlist} 0 end] ,]" - set data "Hidden in real_data property" - } -# read_glp hook code ends - if { [hpropexists [sct] geterror] } { - debug_log ${tc_root} 9 "[sct] error: [sct geterror]" - error "[sct geterror]" - } - if { ${data} != [sct oldval] } { - debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]" - sct oldval ${data} - sct update ${data} - sct utime readtime - } - return ${nextState} - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to parse the read of a parameter on a device -proc ::scobj::knauer_pump::read_status {tc_root} { - set catch_status [ catch { - debug_log ${tc_root} 1 "read_status tc_root=${tc_root} sct=[sct] result=[sct result]" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set data [sct result] - set nextState "idle" - if {[string equal -nocase -length 7 ${data} "ASCERR:"]} { - # the protocol driver has reported an error - sct geterror "${data}" - error "[sct geterror]" - } -# read_status hook code starts - set dlist [split [lindex [split ${data} ":"] 1] ","] - sct real_data "[join [lrange ${dlist} 0 end] ,]" - set data "Hidden in real_data property" -# read_status hook code ends - if { [hpropexists [sct] geterror] } { - debug_log ${tc_root} 9 "[sct] error: [sct geterror]" - error "[sct geterror]" - } - if { ${data} != [sct oldval] } { - debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]" - sct oldval ${data} - sct update ${data} - sct utime readtime - } - return ${nextState} - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to parse the read of a parameter on a device -proc ::scobj::knauer_pump::remote_read {tc_root} { - set catch_status [ catch { - debug_log ${tc_root} 1 "remote_read tc_root=${tc_root} sct=[sct] result=[sct result]" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set data [sct result] - set nextState "idle" - if {[string equal -nocase -length 7 ${data} "ASCERR:"]} { - # the protocol driver has reported an error - sct geterror "${data}" - error "[sct geterror]" - } -# remote_read hook code starts - if { [string equal -length 7 ${data} "REMOTE:"] } { - set data [lindex [split ${data} :] 1] - } else { - sct geterror "bad response" - error "[sct geterror]" - } -# remote_read hook code ends - if { [hpropexists [sct] geterror] } { - debug_log ${tc_root} 9 "[sct] error: [sct geterror]" - error "[sct geterror]" - } - if { ${data} != [sct oldval] } { - debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]" - sct oldval ${data} - sct update ${data} - sct utime readtime - } - return ${nextState} - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to write a parameter value on a device -proc ::scobj::knauer_pump::remote_write {tc_root nextState cmd_str} { - set catch_status [ catch { - debug_log ${tc_root} 1 "remote_write tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set par [sct target] - set cmd "${cmd_str}${par}" -# remote_write hook code starts - if { ${par} == 0 } { - set cmd "LOCAL" - } else { - set cmd "REMOTE" - } -# remote_write hook code ends - if { [hpropexists [sct] geterror] } { - debug_log ${tc_root} 9 "[sct] error: [sct geterror]" - error "[sct geterror]" - } - if { [hpropexists [sct] driving] } { - if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } { - sct driving 1 - } - } - debug_log ${tc_root} 1 "remote_write sct send ${cmd}" - if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { - sct send "${cmd}" - } - return ${nextState} - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to write a parameter value on a device -proc ::scobj::knauer_pump::setValue {tc_root nextState cmd_str} { - set catch_status [ catch { - debug_log ${tc_root} 1 "setValue tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set par [sct target] - set cmd "${cmd_str}${par}" -# setValue hook code goes here - if { [hpropexists [sct] driving] } { - if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } { - sct driving 1 - } - } - debug_log ${tc_root} 1 "setValue sct send ${cmd}" - if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { - sct send "${cmd}" - } - return ${nextState} - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to request the read of a parameter on a device -proc ::scobj::knauer_pump::state_fetch {tc_root nextState cmd_str} { - set catch_status [ catch { - debug_log ${tc_root} 1 "state_fetch tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set cmd "${cmd_str}" -# state_fetch hook code starts - set index 1 - set data [hgetpropval ${tc_root}/dummy/status real_data] - set dlist [split ${data} ","] - if { [llength ${dlist}] > ${index} } { - set state_code [lindex ${dlist} ${index}] - } else { - set state_code "0" - } - set cmd "@@NOSEND@@" - if { ${state_code} < 0 || ${state_code} > 9 } { - sct geterror "Invalid device_state ${state_code}" - error "[sct geterror]" - } - set slist [list "SYS_ST_INITIALIZING" \ - "SYS_ST_OFF" \ - "SYS_ST_IDLE" \ - "SYS_ST_RUN" \ - "SYS_ST_HOLD" \ - "SYS_ST_PURGE" \ - "SYS_ST_STANDBY" \ - "SYS_ST_SEVEN" \ - "SYS_ST_FAILED" \ - "SYS_ST_RUNATEND" \ - ] - sct result [lindex ${slist} ${state_code}] -# state_fetch hook code ends - if { [hpropexists [sct] geterror] } { - debug_log ${tc_root} 9 "[sct] error: [sct geterror]" - error "[sct geterror]" - } - debug_log ${tc_root} 1 "state_fetch sct send ${cmd}" - if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { - sct send "${cmd}" - } - return ${nextState} - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to request the read of a parameter on a device -proc ::scobj::knauer_pump::status_fetch {tc_root nextState cmd_str} { - set catch_status [ catch { - debug_log ${tc_root} 1 "status_fetch tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set cmd "${cmd_str}" -# status_fetch hook code starts - set index 1 - set data [hgetpropval ${tc_root}/dummy/status real_data] - set dlist [split ${data} ","] - set status_code [lindex ${dlist} ${index}] - set cmd "@@NOSEND@@" - if { ${status_code} == 3 } { - sct result "PUMPING" - } else { - sct result "IDLE" - } -# status_fetch hook code ends - if { [hpropexists [sct] geterror] } { - debug_log ${tc_root} 9 "[sct] error: [sct geterror]" - error "[sct geterror]" - } - debug_log ${tc_root} 1 "status_fetch sct send ${cmd}" - if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { - sct send "${cmd}" - } - return ${nextState} - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to check the write parameter on a device -proc ::scobj::knauer_pump::volume_check {tc_root} { - set catch_status [ catch { - debug_log ${tc_root} 1 "volume_check tc_root=${tc_root} sct=[sct] resp=[sct result]" -# volume_check hook code goes here - return "idle" - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# checkstatus function for driveable interface -proc ::scobj::knauer_pump::volume_checkstatus {tc_root} { - set catch_status [ catch { -# volume_checkstatus hook code goes here - if {[sct driving]} { - set sp "[sct target]" - if {[hpropexists [sct] simulated] && [sct simulated] == "true"} { - set pv "${sp}" - hupdateif ${tc_root}/[sct driveable] ${sp} - } else { - set pv "[hval ${tc_root}/[sct driveable]]" - } - if { abs(${pv} - ${sp}) <= [sct tolerance] } { - if { [hpropexists [sct] settle_time] } { - if { [hpropexists [sct] settle_time_start] } { - if { [sct utime] - [sct settle_time_start] >= [sct settle_time]} { - sct driving 0 - return "idle" - } - return "busy" - } else { - sct utime settle_time_start - return "busy" - } - } - sct driving 0 - return "idle" - } - if { [hpropexists [sct] settle_time_start] } { - hdelprop [sct] settle_time_start - } - return "busy" - } else { - return "idle" - } - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to request the read of a parameter on a device -proc ::scobj::knauer_pump::volume_fetch {tc_root nextState cmd_str} { - set catch_status [ catch { - debug_log ${tc_root} 1 "volume_fetch tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set cmd "${cmd_str}" -# volume_fetch hook code starts - set data [hgetpropval ${tc_root}/dummy/glp real_data] - set dlist [split ${data} ","] - if { [llength ${dlist}] > 11 } { - set pump_volm [lindex ${dlist} 10] - set pump_voln [lindex ${dlist} 11] - set pump_volume [expr {${pump_volm} + 0.000001 * ${pump_voln}}] - } else { - set pump_volume 0.0 - } - sct raw_volume ${pump_volume} - if { [hpropexists [sct] base_volume] } { - set pump_volume [expr {${pump_volume} - [sct base_volume]}] - } elseif { [hpropexists [sct] raw_volume] } { - sct base_volume [sct raw_volume] - } - sct result [format "%.2f" ${pump_volume}] - set cmd "@@NOSEND@@" -# volume_fetch hook code ends - if { [hpropexists [sct] geterror] } { - debug_log ${tc_root} 9 "[sct] error: [sct geterror]" - error "[sct geterror]" - } - debug_log ${tc_root} 1 "volume_fetch sct send ${cmd}" - if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { - sct send "${cmd}" - } - return ${nextState} - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to request the read of a parameter on a device -proc ::scobj::knauer_pump::volume_fsm {tc_root nextState cmd_str} { - set catch_status [ catch { - debug_log ${tc_root} 1 "volume_fsm tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set cmd "${cmd_str}" -# volume_fsm hook code starts - if { [sct this_state] > 0 } { - set flow_tgt [expr {int(1000.0 * [hval ${tc_root}/pump/flow/setp])}] - set ratio_tgt [join [split [hval ${tc_root}/pump/ratio/setp] /] ,] - set time_tgt [expr {int(60000.0 * 1000.0 * [sct target] / ${flow_tgt})}] - set time_1 [expr {${time_tgt} - 500}] - set time_2 [expr {${time_tgt} + 500}] - set saveState ${nextState} - set nextState "noResponse" - if { [sct this_state] == 1 } { - set cmd "GLP?" - set nextState ${saveState} - sct this_state [expr {[sct this_state] + 1}] - } elseif { [sct this_state] == 2 } { - set cmd "TT_LOAD:1" - sct this_state [expr {[sct this_state] + 1}] - } elseif { [sct this_state] == 3 } { - set cmd "TT_SET:0,0,${flow_tgt},${ratio_tgt},0,0,0,0,0,0,0,0" - sct this_state [expr {[sct this_state] + 1}] - } elseif { [sct this_state] == 4 } { - set cmd "TT_SET:1,${time_1},${flow_tgt},${ratio_tgt},0,0,0,0,0,0,0,0" - sct this_state [expr {[sct this_state] + 1}] - } elseif { [sct this_state] == 5 } { - set cmd "TT_SET:2,${time_2},0,${ratio_tgt},0,0,0,0,0,0,0,0" - sct this_state [expr {[sct this_state] + 1}] - } elseif { [sct this_state] == 6 } { - set cmd "START:1,0" - sct this_state 0 - } elseif { [sct this_state] == 91 } { - set cmd "STOP:1,0" - sct this_state 92 - } elseif { [sct this_state] == 92 } { - set cmd "STOP:0,0" - sct this_state 93 - } elseif { [sct this_state] == 93 } { - if { !([hpropexists ${tc_root}/pump/remote target] && [hgetpropval ${tc_root}/pump/remote target] == 1) } { - set cmd "LOCAL" - } else { - set cmd "@@NOSEND@@" - } - sct this_state 0 - } else { - sct this_state 0 - set cmd "@@NOSEND@@" - set nextState idle - } - } else { - set cmd "@@NOSEND@@" - set nextState idle - if { [hpropexists [sct] pumping] && [sct pumping] } { - set new_value [hval ${tc_root}/pump/status] - set old_value [sct oldval] - if {${new_value} != ${old_value}} { - sct oldval ${new_value} - if {${old_value} == "PUMPING" && ${new_value} == "IDLE"} { - set cmd "STOP:0,0" - sct this_state 91 - set nextState noResponse - sct result "" - sct driving 0 - sct pumping 0 - } - } - } - } -# volume_fsm hook code ends - if { [hpropexists [sct] geterror] } { - debug_log ${tc_root} 9 "[sct] error: [sct geterror]" - error "[sct geterror]" - } - debug_log ${tc_root} 1 "volume_fsm sct send ${cmd}" - if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { - sct send "${cmd}" - } - return ${nextState} - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# halt function for driveable interface -proc ::scobj::knauer_pump::volume_halt {tc_root} { - set catch_status [ catch { - debug_log ${tc_root} 1 "volume_halt tc_root=${tc_root} sct=[sct] driving=[sct driving]" - ### TODO hset [sct] [hval [sct]] -# volume_halt hook code starts - set cmd "STOP:0,0" - sct this_state 91 - debug_log ${tc_root} 1 "volume_halt sct send ${cmd}" - sct send ${cmd} -# volume_halt hook code ends - sct driving 0 - return "idle" - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to parse the read of a parameter on a device -proc ::scobj::knauer_pump::volume_read {tc_root} { - set catch_status [ catch { - debug_log ${tc_root} 1 "volume_read tc_root=${tc_root} sct=[sct] result=[sct result]" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set data [sct result] - set nextState "idle" - if {[string equal -nocase -length 7 ${data} "ASCERR:"]} { - # the protocol driver has reported an error - sct geterror "${data}" - error "[sct geterror]" - } -# volume_read hook code goes here - if { ${data} != [sct oldval] } { - debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]" - sct oldval ${data} - sct update ${data} - sct utime readtime - } - return ${nextState} - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to parse the read of a parameter on a device -proc ::scobj::knauer_pump::volume_store {tc_root} { - set catch_status [ catch { - debug_log ${tc_root} 1 "volume_store tc_root=${tc_root} sct=[sct] result=[sct result]" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set data [sct result] - set nextState "idle" - if {[string equal -nocase -length 7 ${data} "ASCERR:"]} { - # the protocol driver has reported an error - sct geterror "${data}" - error "[sct geterror]" - } -# volume_store hook code starts - if { [sct this_state] == 2 } { - set ns [namespace current] - # store the GLP result - hsetprop ${tc_root}/dummy/glp result "${data}" - sct with ${tc_root}/dummy/glp "${ns}::read_glp ${tc_root}" - # extract the volume - sct with ${tc_root}/[sct driveable] "${ns}::volume_fetch ${tc_root} ${nextState} @@NOSEND@@" - sct with ${tc_root}/[sct driveable] "${ns}::volume_read ${tc_root}" - # copy it to base_volume - hsetprop ${tc_root}/[sct driveable] base_volume [hgetpropval ${tc_root}/[sct driveable] raw_volume] - } - if { [hpropexists [sct] target] } { - set data [sct target] - } else { - set data 0.0 - } -# volume_store hook code ends - if { [hpropexists [sct] geterror] } { - debug_log ${tc_root} 9 "[sct] error: [sct geterror]" - error "[sct geterror]" - } - if { ${data} != [sct oldval] } { - debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]" - sct oldval ${data} - sct update ${data} - sct utime readtime - } - return ${nextState} - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -# function to write a parameter value on a device -proc ::scobj::knauer_pump::volume_write {tc_root nextState cmd_str} { - set catch_status [ catch { - debug_log ${tc_root} 1 "volume_write tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set par [sct target] - set cmd "${cmd_str}${par}" -# volume_write hook code starts - hset ${tc_root}/[sct driveable] 0.0 - set cmd "REMOTE" - sct this_state 1 - sct pumping 1 - set data ${par} - if { ${data} != [sct oldval] } { - debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]" - sct oldval ${data} - sct update ${data} - sct utime readtime - } -# volume_write hook code ends - if { [hpropexists [sct] geterror] } { - debug_log ${tc_root} 9 "[sct] error: [sct geterror]" - error "[sct geterror]" - } - if { [hpropexists [sct] driving] } { - if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } { - sct driving 1 - } - } - debug_log ${tc_root} 1 "volume_write sct send ${cmd}" - if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { - sct send "${cmd}" - } - return ${nextState} - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -proc ::scobj::knauer_pump::mkDriver { sct_controller name device_class simulation_flag ip_address tcp_port } { - ::scobj::knauer_pump::sics_log 9 "::scobj::knauer_pump::mkDriver ${sct_controller} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port}" - set ns "[namespace current]" - set catch_status [ catch { - - MakeSICSObj ${name} SCT_OBJECT - - sicslist setatt ${name} klass ${device_class} - sicslist setatt ${name} long_name ${name} - - set scobj_hpath /sics/${name} - - hfactory ${scobj_hpath}/dummy plain spy none - - hfactory ${scobj_hpath}/dummy/glp plain user text - hsetprop ${scobj_hpath}/dummy/glp read ${ns}::getValue ${scobj_hpath} read_glp {GLP?} - hsetprop ${scobj_hpath}/dummy/glp read_glp ${ns}::read_glp ${scobj_hpath} - hsetprop ${scobj_hpath}/dummy/glp control false - hsetprop ${scobj_hpath}/dummy/glp data false - hsetprop ${scobj_hpath}/dummy/glp mutable true - hsetprop ${scobj_hpath}/dummy/glp nxsave false - hsetprop ${scobj_hpath}/dummy/glp oldval UNKNOWN - hsetprop ${scobj_hpath}/dummy/glp real_data " " - hsetprop ${scobj_hpath}/dummy/glp sdsinfo "::nexus::scobj::sdsinfo" - hsetprop ${scobj_hpath}/dummy/glp type "part" - hsetprop ${scobj_hpath}/dummy/glp nxalias "${name}_dummy_glp" - - if {[string equal -nocase "${simulation_flag}" "false"]} { - ${sct_controller} poll ${scobj_hpath}/dummy/glp 1 - hsetprop ${scobj_hpath}/dummy/glp simulated false - } else { - ::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump" - hsetprop ${scobj_hpath}/dummy/glp simulated true - } - - hfactory ${scobj_hpath}/dummy/status plain user text - hsetprop ${scobj_hpath}/dummy/status read ${ns}::getValue ${scobj_hpath} read_status {STATUS?} - hsetprop ${scobj_hpath}/dummy/status read_status ${ns}::read_status ${scobj_hpath} - hsetprop ${scobj_hpath}/dummy/status control false - hsetprop ${scobj_hpath}/dummy/status data false - hsetprop ${scobj_hpath}/dummy/status mutable true - hsetprop ${scobj_hpath}/dummy/status nxsave false - hsetprop ${scobj_hpath}/dummy/status oldval UNKNOWN - hsetprop ${scobj_hpath}/dummy/status real_data " " - hsetprop ${scobj_hpath}/dummy/status sdsinfo "::nexus::scobj::sdsinfo" - hsetprop ${scobj_hpath}/dummy/status type "part" - hsetprop ${scobj_hpath}/dummy/status nxalias "${name}_dummy_status" - - if {[string equal -nocase "${simulation_flag}" "false"]} { - ${sct_controller} poll ${scobj_hpath}/dummy/status 1 - hsetprop ${scobj_hpath}/dummy/status simulated false - } else { - ::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump" - hsetprop ${scobj_hpath}/dummy/status simulated true - } - hsetprop ${scobj_hpath}/dummy data "false" - hsetprop ${scobj_hpath}/dummy klass "@none" - hsetprop ${scobj_hpath}/dummy type "part" - - hfactory ${scobj_hpath}/pump plain spy none - - hfactory ${scobj_hpath}/pump/remote plain user int - hsetprop ${scobj_hpath}/pump/remote read ${ns}::getValue ${scobj_hpath} remote_read {REMOTE?} - hsetprop ${scobj_hpath}/pump/remote remote_read ${ns}::remote_read ${scobj_hpath} - hsetprop ${scobj_hpath}/pump/remote write ${ns}::remote_write ${scobj_hpath} noResponse {} - hsetprop ${scobj_hpath}/pump/remote noResponse ${ns}::noResponse ${scobj_hpath} - hsetprop ${scobj_hpath}/pump/remote check ${ns}::checkrange ${scobj_hpath} - hsetprop ${scobj_hpath}/pump/remote control true - hsetprop ${scobj_hpath}/pump/remote data true - hsetprop ${scobj_hpath}/pump/remote mutable true - hsetprop ${scobj_hpath}/pump/remote nxsave true - hsetprop ${scobj_hpath}/pump/remote values 0,1 - hsetprop ${scobj_hpath}/pump/remote oldval 0 - hsetprop ${scobj_hpath}/pump/remote klass "parameter" - hsetprop ${scobj_hpath}/pump/remote sdsinfo "::nexus::scobj::sdsinfo" - hsetprop ${scobj_hpath}/pump/remote type "part" - hsetprop ${scobj_hpath}/pump/remote nxalias "${name}_pump_remote" - - if {[string equal -nocase "${simulation_flag}" "false"]} { - ${sct_controller} poll ${scobj_hpath}/pump/remote 1 - ${sct_controller} write ${scobj_hpath}/pump/remote - hsetprop ${scobj_hpath}/pump/remote simulated false - } else { - ::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump" - hsetprop ${scobj_hpath}/pump/remote simulated true - } - - hfactory ${scobj_hpath}/pump/state plain user text - hsetprop ${scobj_hpath}/pump/state read ${ns}::state_fetch ${scobj_hpath} rdValue { } - hsetprop ${scobj_hpath}/pump/state rdValue ${ns}::rdValue ${scobj_hpath} - hsetprop ${scobj_hpath}/pump/state control true - hsetprop ${scobj_hpath}/pump/state data true - hsetprop ${scobj_hpath}/pump/state mutable true - hsetprop ${scobj_hpath}/pump/state nxsave true - hsetprop ${scobj_hpath}/pump/state oldval UNKNOWN - hsetprop ${scobj_hpath}/pump/state klass "parameter" - hsetprop ${scobj_hpath}/pump/state sdsinfo "::nexus::scobj::sdsinfo" - hsetprop ${scobj_hpath}/pump/state type "part" - hsetprop ${scobj_hpath}/pump/state nxalias "${name}_pump_state" - - if {[string equal -nocase "${simulation_flag}" "false"]} { - ${sct_controller} poll ${scobj_hpath}/pump/state 1 - hsetprop ${scobj_hpath}/pump/state simulated false - } else { - ::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump" - hsetprop ${scobj_hpath}/pump/state simulated true - } - - hfactory ${scobj_hpath}/pump/status plain user text - hsetprop ${scobj_hpath}/pump/status read ${ns}::status_fetch ${scobj_hpath} rdValue { } - hsetprop ${scobj_hpath}/pump/status rdValue ${ns}::rdValue ${scobj_hpath} - hsetprop ${scobj_hpath}/pump/status control true - hsetprop ${scobj_hpath}/pump/status data true - hsetprop ${scobj_hpath}/pump/status mutable true - hsetprop ${scobj_hpath}/pump/status nxsave true - hsetprop ${scobj_hpath}/pump/status oldval UNKNOWN - hsetprop ${scobj_hpath}/pump/status klass "parameter" - hsetprop ${scobj_hpath}/pump/status sdsinfo "::nexus::scobj::sdsinfo" - hsetprop ${scobj_hpath}/pump/status type "part" - hsetprop ${scobj_hpath}/pump/status nxalias "${name}_pump_status" - - if {[string equal -nocase "${simulation_flag}" "false"]} { - ${sct_controller} poll ${scobj_hpath}/pump/status 1 - hsetprop ${scobj_hpath}/pump/status simulated false - } else { - ::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump" - hsetprop ${scobj_hpath}/pump/status simulated true - } - hsetprop ${scobj_hpath}/pump data "true" - hsetprop ${scobj_hpath}/pump klass "@none" - hsetprop ${scobj_hpath}/pump type "part" - - hfactory ${scobj_hpath}/pump/flow plain spy none - - hfactory ${scobj_hpath}/pump/flow/pval plain user float - hsetprop ${scobj_hpath}/pump/flow/pval read ${ns}::flow_fetch ${scobj_hpath} rdValue { } - hsetprop ${scobj_hpath}/pump/flow/pval rdValue ${ns}::rdValue ${scobj_hpath} - hsetprop ${scobj_hpath}/pump/flow/pval control true - hsetprop ${scobj_hpath}/pump/flow/pval data true - hsetprop ${scobj_hpath}/pump/flow/pval mutable true - hsetprop ${scobj_hpath}/pump/flow/pval nxsave true - hsetprop ${scobj_hpath}/pump/flow/pval oldval 0.0 - hsetprop ${scobj_hpath}/pump/flow/pval klass "parameter" - hsetprop ${scobj_hpath}/pump/flow/pval sdsinfo "::nexus::scobj::sdsinfo" - hsetprop ${scobj_hpath}/pump/flow/pval type "part" - hsetprop ${scobj_hpath}/pump/flow/pval units "mL/min" - hsetprop ${scobj_hpath}/pump/flow/pval nxalias "${name}_pump_flow_pval" - - if {[string equal -nocase "${simulation_flag}" "false"]} { - ${sct_controller} poll ${scobj_hpath}/pump/flow/pval 1 - hsetprop ${scobj_hpath}/pump/flow/pval simulated false - } else { - ::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump" - hsetprop ${scobj_hpath}/pump/flow/pval simulated true - } - - hfactory ${scobj_hpath}/pump/flow/setp plain user float - hsetprop ${scobj_hpath}/pump/flow/setp write ${ns}::flow_write ${scobj_hpath} noResponse { } - hsetprop ${scobj_hpath}/pump/flow/setp noResponse ${ns}::noResponse ${scobj_hpath} - hsetprop ${scobj_hpath}/pump/flow/setp check ${ns}::checkrange ${scobj_hpath} - hsetprop ${scobj_hpath}/pump/flow/setp control true - hsetprop ${scobj_hpath}/pump/flow/setp data true - hsetprop ${scobj_hpath}/pump/flow/setp mutable true - hsetprop ${scobj_hpath}/pump/flow/setp nxsave true - hsetprop ${scobj_hpath}/pump/flow/setp lowerlimit 0 - hsetprop ${scobj_hpath}/pump/flow/setp upperlimit 9.999 - hsetprop ${scobj_hpath}/pump/flow/setp oldval 1.0 - hset ${scobj_hpath}/pump/flow/setp 1.0 - hsetprop ${scobj_hpath}/pump/flow/setp klass "parameter" - hsetprop ${scobj_hpath}/pump/flow/setp sdsinfo "::nexus::scobj::sdsinfo" - hsetprop ${scobj_hpath}/pump/flow/setp type "part" - hsetprop ${scobj_hpath}/pump/flow/setp units "mL/min" - hsetprop ${scobj_hpath}/pump/flow/setp nxalias "${name}_pump_flow_setp" - - if {[string equal -nocase "${simulation_flag}" "false"]} { - ${sct_controller} write ${scobj_hpath}/pump/flow/setp - hsetprop ${scobj_hpath}/pump/flow/setp simulated false - } else { - ::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump" - hsetprop ${scobj_hpath}/pump/flow/setp simulated true - } - hsetprop ${scobj_hpath}/pump/flow data "true" - hsetprop ${scobj_hpath}/pump/flow klass "@none" - hsetprop ${scobj_hpath}/pump/flow type "part" - - hfactory ${scobj_hpath}/pump/ratio plain spy none - - hfactory ${scobj_hpath}/pump/ratio/pval plain user text - hsetprop ${scobj_hpath}/pump/ratio/pval read ${ns}::ratio_fetch ${scobj_hpath} rdValue { } - hsetprop ${scobj_hpath}/pump/ratio/pval rdValue ${ns}::rdValue ${scobj_hpath} - hsetprop ${scobj_hpath}/pump/ratio/pval control true - hsetprop ${scobj_hpath}/pump/ratio/pval data true - hsetprop ${scobj_hpath}/pump/ratio/pval mutable true - hsetprop ${scobj_hpath}/pump/ratio/pval nxsave true - hsetprop ${scobj_hpath}/pump/ratio/pval oldval UNKNOWN - hsetprop ${scobj_hpath}/pump/ratio/pval klass "parameter" - hsetprop ${scobj_hpath}/pump/ratio/pval sdsinfo "::nexus::scobj::sdsinfo" - hsetprop ${scobj_hpath}/pump/ratio/pval type "part" - hsetprop ${scobj_hpath}/pump/ratio/pval units "percent" - hsetprop ${scobj_hpath}/pump/ratio/pval nxalias "${name}_pump_ratio_pval" - - if {[string equal -nocase "${simulation_flag}" "false"]} { - ${sct_controller} poll ${scobj_hpath}/pump/ratio/pval 1 - hsetprop ${scobj_hpath}/pump/ratio/pval simulated false - } else { - ::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump" - hsetprop ${scobj_hpath}/pump/ratio/pval simulated true - } - - hfactory ${scobj_hpath}/pump/ratio/setp plain user text - hsetprop ${scobj_hpath}/pump/ratio/setp write ${ns}::ratio_write ${scobj_hpath} noResponse { } - hsetprop ${scobj_hpath}/pump/ratio/setp noResponse ${ns}::noResponse ${scobj_hpath} - hsetprop ${scobj_hpath}/pump/ratio/setp check ${ns}::ratio_check ${scobj_hpath} - hsetprop ${scobj_hpath}/pump/ratio/setp control true - hsetprop ${scobj_hpath}/pump/ratio/setp data true - hsetprop ${scobj_hpath}/pump/ratio/setp mutable true - hsetprop ${scobj_hpath}/pump/ratio/setp nxsave true - hsetprop ${scobj_hpath}/pump/ratio/setp oldval 25/25/25/25 - hset ${scobj_hpath}/pump/ratio/setp 25/25/25/25 - hsetprop ${scobj_hpath}/pump/ratio/setp klass "parameter" - hsetprop ${scobj_hpath}/pump/ratio/setp sdsinfo "::nexus::scobj::sdsinfo" - hsetprop ${scobj_hpath}/pump/ratio/setp type "part" - hsetprop ${scobj_hpath}/pump/ratio/setp units "percent" - hsetprop ${scobj_hpath}/pump/ratio/setp nxalias "${name}_pump_ratio_setp" - - if {[string equal -nocase "${simulation_flag}" "false"]} { - ${sct_controller} write ${scobj_hpath}/pump/ratio/setp - hsetprop ${scobj_hpath}/pump/ratio/setp simulated false - } else { - ::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump" - hsetprop ${scobj_hpath}/pump/ratio/setp simulated true - } - hsetprop ${scobj_hpath}/pump/ratio data "true" - hsetprop ${scobj_hpath}/pump/ratio klass "@none" - hsetprop ${scobj_hpath}/pump/ratio type "part" - - hfactory ${scobj_hpath}/pump/volume plain spy none - - hfactory ${scobj_hpath}/pump/volume/pval plain user float - hsetprop ${scobj_hpath}/pump/volume/pval read ${ns}::volume_fetch ${scobj_hpath} volume_read { } - hsetprop ${scobj_hpath}/pump/volume/pval volume_read ${ns}::volume_read ${scobj_hpath} - hsetprop ${scobj_hpath}/pump/volume/pval control true - hsetprop ${scobj_hpath}/pump/volume/pval data true - hsetprop ${scobj_hpath}/pump/volume/pval mutable true - hsetprop ${scobj_hpath}/pump/volume/pval nxsave true - hsetprop ${scobj_hpath}/pump/volume/pval oldval 0.0 - hsetprop ${scobj_hpath}/pump/volume/pval klass "parameter" - hsetprop ${scobj_hpath}/pump/volume/pval sdsinfo "::nexus::scobj::sdsinfo" - hsetprop ${scobj_hpath}/pump/volume/pval type "part" - hsetprop ${scobj_hpath}/pump/volume/pval units "mL" - hsetprop ${scobj_hpath}/pump/volume/pval nxalias "${name}_pump_volume_pval" - - if {[string equal -nocase "${simulation_flag}" "false"]} { - ${sct_controller} poll ${scobj_hpath}/pump/volume/pval 1 - hsetprop ${scobj_hpath}/pump/volume/pval simulated false - } else { - ::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump" - hsetprop ${scobj_hpath}/pump/volume/pval simulated true - } - - hfactory ${scobj_hpath}/pump/volume/setp plain user float - hsetprop ${scobj_hpath}/pump/volume/setp read ${ns}::volume_fsm ${scobj_hpath} volume_store { } - hsetprop ${scobj_hpath}/pump/volume/setp volume_store ${ns}::volume_store ${scobj_hpath} - hsetprop ${scobj_hpath}/pump/volume/setp write ${ns}::volume_write ${scobj_hpath} volume_check { } - hsetprop ${scobj_hpath}/pump/volume/setp volume_check ${ns}::volume_check ${scobj_hpath} - hsetprop ${scobj_hpath}/pump/volume/setp check ${ns}::checkrange ${scobj_hpath} - hsetprop ${scobj_hpath}/pump/volume/setp driving 0 - hsetprop ${scobj_hpath}/pump/volume/setp checklimits ${ns}::checklimits ${scobj_hpath} - hsetprop ${scobj_hpath}/pump/volume/setp checkstatus ${ns}::volume_checkstatus ${scobj_hpath} - hsetprop ${scobj_hpath}/pump/volume/setp halt ${ns}::volume_halt ${scobj_hpath} - hsetprop ${scobj_hpath}/pump/volume/setp driveable pump/volume/pval - hsetprop ${scobj_hpath}/pump/volume/setp control true - hsetprop ${scobj_hpath}/pump/volume/setp data true - hsetprop ${scobj_hpath}/pump/volume/setp mutable true - hsetprop ${scobj_hpath}/pump/volume/setp nxsave true - hsetprop ${scobj_hpath}/pump/volume/setp lowerlimit 0 - hsetprop ${scobj_hpath}/pump/volume/setp upperlimit 100 - hsetprop ${scobj_hpath}/pump/volume/setp tolerance 0.01 - hsetprop ${scobj_hpath}/pump/volume/setp oldval 0.0 - hsetprop ${scobj_hpath}/pump/volume/setp klass "parameter" - hsetprop ${scobj_hpath}/pump/volume/setp sdsinfo "::nexus::scobj::sdsinfo" - hsetprop ${scobj_hpath}/pump/volume/setp this_state "0" - hsetprop ${scobj_hpath}/pump/volume/setp type "drivable" - hsetprop ${scobj_hpath}/pump/volume/setp units "mL" - hsetprop ${scobj_hpath}/pump/volume/setp nxalias "${name}_pump_volume_setp" - - if {[string equal -nocase "${simulation_flag}" "false"]} { - ${sct_controller} poll ${scobj_hpath}/pump/volume/setp 1 - ${sct_controller} write ${scobj_hpath}/pump/volume/setp - hsetprop ${scobj_hpath}/pump/volume/setp simulated false - } else { - ::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump" - hsetprop ${scobj_hpath}/pump/volume/setp simulated true - } - hsetprop ${scobj_hpath}/pump/volume data "true" - hsetprop ${scobj_hpath}/pump/volume klass "@none" - hsetprop ${scobj_hpath}/pump/volume type "part" - ansto_makesctdrive ${name}_pump_volume_setp ${scobj_hpath}/pump/volume/setp ${scobj_hpath}/pump/volume/pval ${sct_controller} - hsetprop ${scobj_hpath} klass ${device_class} - hsetprop ${scobj_hpath} data true - hsetprop ${scobj_hpath} debug_threshold 0 -# mkDriver hook code starts - #hset ${scobj_hpath}/pump/remote 1 -# mkDriver hook code ends - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -proc ::scobj::knauer_pump::add_driver {name device_class simulation_flag ip_address tcp_port} { - set catch_status [ catch { - ::scobj::knauer_pump::sics_log 9 "::scobj::knauer_pump::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port}" - if {[string equal -nocase "${simulation_flag}" "false"]} { - if {[string equal -nocase "aqadapter" "${ip_address}"]} { - ::scobj::knauer_pump::sics_log 9 "makesctcontroller sct_${name} aqadapter ${tcp_port}" - makesctcontroller sct_${name} aqadapter ${tcp_port} - } else { - ::scobj::knauer_pump::sics_log 9 "makesctcontroller sct_${name} knauer_ap ${ip_address}:${tcp_port}" - makesctcontroller sct_${name} knauer_ap ${ip_address}:${tcp_port} - } - } else { - ::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => Null sctcontroller for knauer_pump" - ::scobj::knauer_pump::sics_log 9 "makesctcontroller sct_${name} aqadapter NULL" - makesctcontroller sct_${name} aqadapter NULL - } - ::scobj::knauer_pump::sics_log 1 "::scobj::knauer_pump::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port}" - ::scobj::knauer_pump::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -namespace eval ::scobj::knauer_pump { - namespace export debug_threshold - namespace export debug_log - namespace export sics_log - namespace export mkDriver - namespace export add_driver -} - -proc add_knauer_pump {name ip_address tcp_port} { - set simulation_flag "[string tolower [SplitReply [environment_simulation]]]" - ::scobj::knauer_pump::add_driver ${name} "environment" ${simulation_flag} ${ip_address} ${tcp_port} -} - -clientput "file evaluation of sct_knauer_pump.tcl" -::scobj::knauer_pump::sics_log 9 "file evaluation of sct_knauer_pump.tcl" - -proc ::scobj::knauer_pump::read_config {} { - set catch_status [ catch { - set ns "::scobj::knauer_pump" - dict for {k u} $::config_dict { - if { [dict exists $u "implementation"] } { - set simulation_flag "[string tolower [SplitReply [environment_simulation]]]" - set device_class "environment" - if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { - continue - } - set enabled [string tolower [dict get $u "enabled"]] - if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { - continue - } - if { [dict exists $u "simulation_group"] } { - set simulation_flag [SplitReply [[string tolower [dict get $u "simulation_group"]]]] - } - if { [dict exists $u "device_class"] } { - set device_class "[dict get $u "device_class"]" - } - set name [dict get $u name] - set implementation [dict get $u "implementation"] - if { !([dict exists $::config_dict $implementation]) } { - continue - } - set v [dict get $::config_dict $implementation] - if { !([dict exists $v "driver"]) } { - continue - } - if { [string equal -nocase [dict get $v "driver"] "knauer_pump"] } { - if { ![string equal -nocase "${simulation_flag}" "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "simulation_flag=${simulation_flag} => using null asyncqueue" - ${ns}::sics_log 9 "makesctcontroller sct_${name} aqadapter NULL" - makesctcontroller sct_${name} aqadapter NULL - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - if { [string equal -nocase ${asyncqueue} "sct"] } { - set ip_address [dict get $v ip] - set tcp_port [dict get $v port] - makesctcontroller sct_${name} knauer_ap ${ip_address}:${tcp_port} - } else { - makesctcontroller sct_${name} aqadapter ${asyncqueue} - } - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "sendterminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "sendterminator"]" - } elseif { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - } - if { [dict exists $v "replyterminator"] } { - ${asyncprotocol} replyterminator "[dict get $v "replyterminator"]" - } elseif { [dict exists $v "terminator"] } { - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue - set ip_address [dict get $v ip] - set tcp_port [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${ip_address} ${tcp_port} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" - } - makesctcontroller sct_${name} aqadapter ${asyncqueue} - } - ${ns}::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} - } - } - } - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -if { [info exists ::config_dict] } { - ::scobj::knauer_pump::read_config -} else { - ::scobj::knauer_pump::sics_log 5 "No config dict" -} diff --git a/site_ansto/instrument/config/environment/temperature/lakeshore_218.sct b/site_ansto/instrument/config/environment/temperature/lakeshore_218.sct index 64a87296..d16b9647 100644 --- a/site_ansto/instrument/config/environment/temperature/lakeshore_218.sct +++ b/site_ansto/instrument/config/environment/temperature/lakeshore_218.sct @@ -1,6 +1,11 @@ +# +# Template driver for the Lakeshore 218 Temperature Monitor +# vim: ft=tcl ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent +# driver lakeshore_218 = { vendor = lakeshore; device = ls218; protocol = std; class = NXdetector; simulation_group = detector_simulation; + make_args = '{num_chans 8}'; group = { data = false; @@ -11,28 +16,34 @@ driver lakeshore_218 = { var krdg = { type = text; read_command = "KRDG? 0"; - value = "0,0,0,0,0,0,0,0"; + read_function = read_krdg; + value = '"Hidden in real_data property"'; + property real_data = '0,0,0,0,0,0,0,0'; } } group sensor = { priv = user; mutable = true; type = float; - readable = 1; + readable = 15; fetch_function = getTemp; - var ch1 = { read_command = '0'; } - var ch2 = { read_command = '1'; } - var ch3 = { read_command = '2'; } - var ch4 = { read_command = '3'; } - var ch5 = { read_command = '4'; } - var ch6 = { read_command = '5'; } - var ch7 = { read_command = '6'; } - var ch8 = { read_command = '7'; } + var ch1 = { read_command = '0'; conditional = '${num_chans} > 0'; } + var ch2 = { read_command = '1'; conditional = '${num_chans} > 1'; } + var ch3 = { read_command = '2'; conditional = '${num_chans} > 2'; } + var ch4 = { read_command = '3'; conditional = '${num_chans} > 3'; } + var ch5 = { read_command = '4'; conditional = '${num_chans} > 4'; } + var ch6 = { read_command = '5'; conditional = '${num_chans} > 5'; } + var ch7 = { read_command = '6'; conditional = '${num_chans} > 6'; } + var ch8 = { read_command = '7'; conditional = '${num_chans} > 7'; } } code fetch_function getTemp = {%% - set temps [split "[hval ${tc_root}/krdg]" ","] + set temps [split "[hgetpropval ${tc_root}/krdg real_data]" ","] sct result [lindex ${temps} ${cmd_str}] set cmd "@@NOSEND@@" %%} + code read_krdg = {%% + sct real_data "${data}" + set data "Hidden in real_data property" + %%} } diff --git a/site_ansto/instrument/config/environment/temperature/lakeshore_218_sct.tcl b/site_ansto/instrument/config/environment/temperature/lakeshore_218_sct.tcl index 6c771dc4..0ae69644 100644 --- a/site_ansto/instrument/config/environment/temperature/lakeshore_218_sct.tcl +++ b/site_ansto/instrument/config/environment/temperature/lakeshore_218_sct.tcl @@ -65,7 +65,7 @@ proc ::scobj::lakeshore_218::getTemp {tc_root nextState cmd_str} { } set cmd "${cmd_str}" # getTemp hook code starts - set temps [split "[hval ${tc_root}/krdg]" ","] + set temps [split "[hgetpropval ${tc_root}/krdg real_data]" ","] sct result [lindex ${temps} ${cmd_str}] set cmd "@@NOSEND@@" # getTemp hook code ends @@ -136,6 +136,39 @@ proc ::scobj::lakeshore_218::rdValue {tc_root} { handle_exception ${catch_status} ${catch_message} } +# function to parse the read of a parameter on a device +proc ::scobj::lakeshore_218::read_krdg {tc_root} { + set catch_status [ catch { + debug_log ${tc_root} 1 "read_krdg tc_root=${tc_root} sct=[sct] result=[sct result]" + if { [hpropexists [sct] geterror] } { + hdelprop [sct] geterror + } + set data [sct result] + set nextState "idle" + if {[string equal -nocase -length 7 ${data} "ASCERR:"]} { + # the protocol driver has reported an error + sct geterror "${data}" + error "[sct geterror]" + } +# read_krdg hook code starts + sct real_data "${data}" + set data "Hidden in real_data property" +# read_krdg hook code ends + if { [hpropexists [sct] geterror] } { + debug_log ${tc_root} 9 "[sct] error: [sct geterror]" + error "[sct geterror]" + } + if { ${data} != [sct oldval] } { + debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]" + sct oldval ${data} + sct update ${data} + sct utime readtime + } + return ${nextState} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + # function to write a parameter value on a device proc ::scobj::lakeshore_218::setValue {tc_root nextState cmd_str} { set catch_status [ catch { @@ -160,8 +193,8 @@ proc ::scobj::lakeshore_218::setValue {tc_root nextState cmd_str} { handle_exception ${catch_status} ${catch_message} } -proc ::scobj::lakeshore_218::mkDriver { sct_controller name device_class simulation_flag ip_address tcp_port } { - ::scobj::lakeshore_218::sics_log 9 "::scobj::lakeshore_218::mkDriver ${sct_controller} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port}" +proc ::scobj::lakeshore_218::mkDriver { sct_controller name device_class simulation_flag ip_address tcp_port {num_chans 8} } { + ::scobj::lakeshore_218::sics_log 9 "::scobj::lakeshore_218::mkDriver ${sct_controller} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${num_chans}" set ns "[namespace current]" set catch_status [ catch { @@ -173,14 +206,15 @@ proc ::scobj::lakeshore_218::mkDriver { sct_controller name device_class simulat set scobj_hpath /sics/${name} hfactory ${scobj_hpath}/krdg plain user text - hsetprop ${scobj_hpath}/krdg read ${ns}::getValue ${scobj_hpath} rdValue {KRDG? 0} - hsetprop ${scobj_hpath}/krdg rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/krdg read ${ns}::getValue ${scobj_hpath} read_krdg {KRDG? 0} + hsetprop ${scobj_hpath}/krdg read_krdg ${ns}::read_krdg ${scobj_hpath} hsetprop ${scobj_hpath}/krdg control false hsetprop ${scobj_hpath}/krdg data false hsetprop ${scobj_hpath}/krdg mutable true hsetprop ${scobj_hpath}/krdg nxsave false - hsetprop ${scobj_hpath}/krdg oldval 0,0,0,0,0,0,0,0 - hset ${scobj_hpath}/krdg 0,0,0,0,0,0,0,0 + hsetprop ${scobj_hpath}/krdg oldval "Hidden in real_data property" + hset ${scobj_hpath}/krdg "Hidden in real_data property" + hsetprop ${scobj_hpath}/krdg real_data "0,0,0,0,0,0,0,0" hsetprop ${scobj_hpath}/krdg sdsinfo "::nexus::scobj::sdsinfo" hsetprop ${scobj_hpath}/krdg type "part" hsetprop ${scobj_hpath}/krdg nxalias "${name}_krdg" @@ -199,172 +233,188 @@ proc ::scobj::lakeshore_218::mkDriver { sct_controller name device_class simulat hfactory ${scobj_hpath}/sensor plain spy none - hfactory ${scobj_hpath}/sensor/ch1 plain user float - hsetprop ${scobj_hpath}/sensor/ch1 read ${ns}::getTemp ${scobj_hpath} rdValue {0} - hsetprop ${scobj_hpath}/sensor/ch1 rdValue ${ns}::rdValue ${scobj_hpath} - hsetprop ${scobj_hpath}/sensor/ch1 control true - hsetprop ${scobj_hpath}/sensor/ch1 data true - hsetprop ${scobj_hpath}/sensor/ch1 mutable true - hsetprop ${scobj_hpath}/sensor/ch1 nxsave true - hsetprop ${scobj_hpath}/sensor/ch1 oldval 0.0 - hsetprop ${scobj_hpath}/sensor/ch1 klass "parameter" - hsetprop ${scobj_hpath}/sensor/ch1 sdsinfo "::nexus::scobj::sdsinfo" - hsetprop ${scobj_hpath}/sensor/ch1 type "part" - hsetprop ${scobj_hpath}/sensor/ch1 nxalias "${name}_sensor_ch1" + if {${num_chans} > 0} { + hfactory ${scobj_hpath}/sensor/ch1 plain user float + hsetprop ${scobj_hpath}/sensor/ch1 read ${ns}::getTemp ${scobj_hpath} rdValue {0} + hsetprop ${scobj_hpath}/sensor/ch1 rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/sensor/ch1 control true + hsetprop ${scobj_hpath}/sensor/ch1 data true + hsetprop ${scobj_hpath}/sensor/ch1 mutable true + hsetprop ${scobj_hpath}/sensor/ch1 nxsave true + hsetprop ${scobj_hpath}/sensor/ch1 oldval 0.0 + hsetprop ${scobj_hpath}/sensor/ch1 klass "parameter" + hsetprop ${scobj_hpath}/sensor/ch1 sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/sensor/ch1 type "part" + hsetprop ${scobj_hpath}/sensor/ch1 nxalias "${name}_sensor_ch1" - if {[string equal -nocase "${simulation_flag}" "false"]} { - ${sct_controller} poll ${scobj_hpath}/sensor/ch1 1 - hsetprop ${scobj_hpath}/sensor/ch1 simulated false - } else { - ::scobj::lakeshore_218::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for lakeshore_218" - hsetprop ${scobj_hpath}/sensor/ch1 simulated true + if {[string equal -nocase "${simulation_flag}" "false"]} { + ${sct_controller} poll ${scobj_hpath}/sensor/ch1 15 + hsetprop ${scobj_hpath}/sensor/ch1 simulated false + } else { + ::scobj::lakeshore_218::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for lakeshore_218" + hsetprop ${scobj_hpath}/sensor/ch1 simulated true + } } - hfactory ${scobj_hpath}/sensor/ch2 plain user float - hsetprop ${scobj_hpath}/sensor/ch2 read ${ns}::getTemp ${scobj_hpath} rdValue {1} - hsetprop ${scobj_hpath}/sensor/ch2 rdValue ${ns}::rdValue ${scobj_hpath} - hsetprop ${scobj_hpath}/sensor/ch2 control true - hsetprop ${scobj_hpath}/sensor/ch2 data true - hsetprop ${scobj_hpath}/sensor/ch2 mutable true - hsetprop ${scobj_hpath}/sensor/ch2 nxsave true - hsetprop ${scobj_hpath}/sensor/ch2 oldval 0.0 - hsetprop ${scobj_hpath}/sensor/ch2 klass "parameter" - hsetprop ${scobj_hpath}/sensor/ch2 sdsinfo "::nexus::scobj::sdsinfo" - hsetprop ${scobj_hpath}/sensor/ch2 type "part" - hsetprop ${scobj_hpath}/sensor/ch2 nxalias "${name}_sensor_ch2" + if {${num_chans} > 1} { + hfactory ${scobj_hpath}/sensor/ch2 plain user float + hsetprop ${scobj_hpath}/sensor/ch2 read ${ns}::getTemp ${scobj_hpath} rdValue {1} + hsetprop ${scobj_hpath}/sensor/ch2 rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/sensor/ch2 control true + hsetprop ${scobj_hpath}/sensor/ch2 data true + hsetprop ${scobj_hpath}/sensor/ch2 mutable true + hsetprop ${scobj_hpath}/sensor/ch2 nxsave true + hsetprop ${scobj_hpath}/sensor/ch2 oldval 0.0 + hsetprop ${scobj_hpath}/sensor/ch2 klass "parameter" + hsetprop ${scobj_hpath}/sensor/ch2 sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/sensor/ch2 type "part" + hsetprop ${scobj_hpath}/sensor/ch2 nxalias "${name}_sensor_ch2" - if {[string equal -nocase "${simulation_flag}" "false"]} { - ${sct_controller} poll ${scobj_hpath}/sensor/ch2 1 - hsetprop ${scobj_hpath}/sensor/ch2 simulated false - } else { - ::scobj::lakeshore_218::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for lakeshore_218" - hsetprop ${scobj_hpath}/sensor/ch2 simulated true + if {[string equal -nocase "${simulation_flag}" "false"]} { + ${sct_controller} poll ${scobj_hpath}/sensor/ch2 15 + hsetprop ${scobj_hpath}/sensor/ch2 simulated false + } else { + ::scobj::lakeshore_218::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for lakeshore_218" + hsetprop ${scobj_hpath}/sensor/ch2 simulated true + } } - hfactory ${scobj_hpath}/sensor/ch3 plain user float - hsetprop ${scobj_hpath}/sensor/ch3 read ${ns}::getTemp ${scobj_hpath} rdValue {2} - hsetprop ${scobj_hpath}/sensor/ch3 rdValue ${ns}::rdValue ${scobj_hpath} - hsetprop ${scobj_hpath}/sensor/ch3 control true - hsetprop ${scobj_hpath}/sensor/ch3 data true - hsetprop ${scobj_hpath}/sensor/ch3 mutable true - hsetprop ${scobj_hpath}/sensor/ch3 nxsave true - hsetprop ${scobj_hpath}/sensor/ch3 oldval 0.0 - hsetprop ${scobj_hpath}/sensor/ch3 klass "parameter" - hsetprop ${scobj_hpath}/sensor/ch3 sdsinfo "::nexus::scobj::sdsinfo" - hsetprop ${scobj_hpath}/sensor/ch3 type "part" - hsetprop ${scobj_hpath}/sensor/ch3 nxalias "${name}_sensor_ch3" + if {${num_chans} > 2} { + hfactory ${scobj_hpath}/sensor/ch3 plain user float + hsetprop ${scobj_hpath}/sensor/ch3 read ${ns}::getTemp ${scobj_hpath} rdValue {2} + hsetprop ${scobj_hpath}/sensor/ch3 rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/sensor/ch3 control true + hsetprop ${scobj_hpath}/sensor/ch3 data true + hsetprop ${scobj_hpath}/sensor/ch3 mutable true + hsetprop ${scobj_hpath}/sensor/ch3 nxsave true + hsetprop ${scobj_hpath}/sensor/ch3 oldval 0.0 + hsetprop ${scobj_hpath}/sensor/ch3 klass "parameter" + hsetprop ${scobj_hpath}/sensor/ch3 sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/sensor/ch3 type "part" + hsetprop ${scobj_hpath}/sensor/ch3 nxalias "${name}_sensor_ch3" - if {[string equal -nocase "${simulation_flag}" "false"]} { - ${sct_controller} poll ${scobj_hpath}/sensor/ch3 1 - hsetprop ${scobj_hpath}/sensor/ch3 simulated false - } else { - ::scobj::lakeshore_218::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for lakeshore_218" - hsetprop ${scobj_hpath}/sensor/ch3 simulated true + if {[string equal -nocase "${simulation_flag}" "false"]} { + ${sct_controller} poll ${scobj_hpath}/sensor/ch3 15 + hsetprop ${scobj_hpath}/sensor/ch3 simulated false + } else { + ::scobj::lakeshore_218::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for lakeshore_218" + hsetprop ${scobj_hpath}/sensor/ch3 simulated true + } } - hfactory ${scobj_hpath}/sensor/ch4 plain user float - hsetprop ${scobj_hpath}/sensor/ch4 read ${ns}::getTemp ${scobj_hpath} rdValue {3} - hsetprop ${scobj_hpath}/sensor/ch4 rdValue ${ns}::rdValue ${scobj_hpath} - hsetprop ${scobj_hpath}/sensor/ch4 control true - hsetprop ${scobj_hpath}/sensor/ch4 data true - hsetprop ${scobj_hpath}/sensor/ch4 mutable true - hsetprop ${scobj_hpath}/sensor/ch4 nxsave true - hsetprop ${scobj_hpath}/sensor/ch4 oldval 0.0 - hsetprop ${scobj_hpath}/sensor/ch4 klass "parameter" - hsetprop ${scobj_hpath}/sensor/ch4 sdsinfo "::nexus::scobj::sdsinfo" - hsetprop ${scobj_hpath}/sensor/ch4 type "part" - hsetprop ${scobj_hpath}/sensor/ch4 nxalias "${name}_sensor_ch4" + if {${num_chans} > 3} { + hfactory ${scobj_hpath}/sensor/ch4 plain user float + hsetprop ${scobj_hpath}/sensor/ch4 read ${ns}::getTemp ${scobj_hpath} rdValue {3} + hsetprop ${scobj_hpath}/sensor/ch4 rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/sensor/ch4 control true + hsetprop ${scobj_hpath}/sensor/ch4 data true + hsetprop ${scobj_hpath}/sensor/ch4 mutable true + hsetprop ${scobj_hpath}/sensor/ch4 nxsave true + hsetprop ${scobj_hpath}/sensor/ch4 oldval 0.0 + hsetprop ${scobj_hpath}/sensor/ch4 klass "parameter" + hsetprop ${scobj_hpath}/sensor/ch4 sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/sensor/ch4 type "part" + hsetprop ${scobj_hpath}/sensor/ch4 nxalias "${name}_sensor_ch4" - if {[string equal -nocase "${simulation_flag}" "false"]} { - ${sct_controller} poll ${scobj_hpath}/sensor/ch4 1 - hsetprop ${scobj_hpath}/sensor/ch4 simulated false - } else { - ::scobj::lakeshore_218::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for lakeshore_218" - hsetprop ${scobj_hpath}/sensor/ch4 simulated true + if {[string equal -nocase "${simulation_flag}" "false"]} { + ${sct_controller} poll ${scobj_hpath}/sensor/ch4 15 + hsetprop ${scobj_hpath}/sensor/ch4 simulated false + } else { + ::scobj::lakeshore_218::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for lakeshore_218" + hsetprop ${scobj_hpath}/sensor/ch4 simulated true + } } - hfactory ${scobj_hpath}/sensor/ch5 plain user float - hsetprop ${scobj_hpath}/sensor/ch5 read ${ns}::getTemp ${scobj_hpath} rdValue {4} - hsetprop ${scobj_hpath}/sensor/ch5 rdValue ${ns}::rdValue ${scobj_hpath} - hsetprop ${scobj_hpath}/sensor/ch5 control true - hsetprop ${scobj_hpath}/sensor/ch5 data true - hsetprop ${scobj_hpath}/sensor/ch5 mutable true - hsetprop ${scobj_hpath}/sensor/ch5 nxsave true - hsetprop ${scobj_hpath}/sensor/ch5 oldval 0.0 - hsetprop ${scobj_hpath}/sensor/ch5 klass "parameter" - hsetprop ${scobj_hpath}/sensor/ch5 sdsinfo "::nexus::scobj::sdsinfo" - hsetprop ${scobj_hpath}/sensor/ch5 type "part" - hsetprop ${scobj_hpath}/sensor/ch5 nxalias "${name}_sensor_ch5" + if {${num_chans} > 4} { + hfactory ${scobj_hpath}/sensor/ch5 plain user float + hsetprop ${scobj_hpath}/sensor/ch5 read ${ns}::getTemp ${scobj_hpath} rdValue {4} + hsetprop ${scobj_hpath}/sensor/ch5 rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/sensor/ch5 control true + hsetprop ${scobj_hpath}/sensor/ch5 data true + hsetprop ${scobj_hpath}/sensor/ch5 mutable true + hsetprop ${scobj_hpath}/sensor/ch5 nxsave true + hsetprop ${scobj_hpath}/sensor/ch5 oldval 0.0 + hsetprop ${scobj_hpath}/sensor/ch5 klass "parameter" + hsetprop ${scobj_hpath}/sensor/ch5 sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/sensor/ch5 type "part" + hsetprop ${scobj_hpath}/sensor/ch5 nxalias "${name}_sensor_ch5" - if {[string equal -nocase "${simulation_flag}" "false"]} { - ${sct_controller} poll ${scobj_hpath}/sensor/ch5 1 - hsetprop ${scobj_hpath}/sensor/ch5 simulated false - } else { - ::scobj::lakeshore_218::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for lakeshore_218" - hsetprop ${scobj_hpath}/sensor/ch5 simulated true + if {[string equal -nocase "${simulation_flag}" "false"]} { + ${sct_controller} poll ${scobj_hpath}/sensor/ch5 15 + hsetprop ${scobj_hpath}/sensor/ch5 simulated false + } else { + ::scobj::lakeshore_218::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for lakeshore_218" + hsetprop ${scobj_hpath}/sensor/ch5 simulated true + } } - hfactory ${scobj_hpath}/sensor/ch6 plain user float - hsetprop ${scobj_hpath}/sensor/ch6 read ${ns}::getTemp ${scobj_hpath} rdValue {5} - hsetprop ${scobj_hpath}/sensor/ch6 rdValue ${ns}::rdValue ${scobj_hpath} - hsetprop ${scobj_hpath}/sensor/ch6 control true - hsetprop ${scobj_hpath}/sensor/ch6 data true - hsetprop ${scobj_hpath}/sensor/ch6 mutable true - hsetprop ${scobj_hpath}/sensor/ch6 nxsave true - hsetprop ${scobj_hpath}/sensor/ch6 oldval 0.0 - hsetprop ${scobj_hpath}/sensor/ch6 klass "parameter" - hsetprop ${scobj_hpath}/sensor/ch6 sdsinfo "::nexus::scobj::sdsinfo" - hsetprop ${scobj_hpath}/sensor/ch6 type "part" - hsetprop ${scobj_hpath}/sensor/ch6 nxalias "${name}_sensor_ch6" + if {${num_chans} > 5} { + hfactory ${scobj_hpath}/sensor/ch6 plain user float + hsetprop ${scobj_hpath}/sensor/ch6 read ${ns}::getTemp ${scobj_hpath} rdValue {5} + hsetprop ${scobj_hpath}/sensor/ch6 rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/sensor/ch6 control true + hsetprop ${scobj_hpath}/sensor/ch6 data true + hsetprop ${scobj_hpath}/sensor/ch6 mutable true + hsetprop ${scobj_hpath}/sensor/ch6 nxsave true + hsetprop ${scobj_hpath}/sensor/ch6 oldval 0.0 + hsetprop ${scobj_hpath}/sensor/ch6 klass "parameter" + hsetprop ${scobj_hpath}/sensor/ch6 sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/sensor/ch6 type "part" + hsetprop ${scobj_hpath}/sensor/ch6 nxalias "${name}_sensor_ch6" - if {[string equal -nocase "${simulation_flag}" "false"]} { - ${sct_controller} poll ${scobj_hpath}/sensor/ch6 1 - hsetprop ${scobj_hpath}/sensor/ch6 simulated false - } else { - ::scobj::lakeshore_218::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for lakeshore_218" - hsetprop ${scobj_hpath}/sensor/ch6 simulated true + if {[string equal -nocase "${simulation_flag}" "false"]} { + ${sct_controller} poll ${scobj_hpath}/sensor/ch6 15 + hsetprop ${scobj_hpath}/sensor/ch6 simulated false + } else { + ::scobj::lakeshore_218::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for lakeshore_218" + hsetprop ${scobj_hpath}/sensor/ch6 simulated true + } } - hfactory ${scobj_hpath}/sensor/ch7 plain user float - hsetprop ${scobj_hpath}/sensor/ch7 read ${ns}::getTemp ${scobj_hpath} rdValue {6} - hsetprop ${scobj_hpath}/sensor/ch7 rdValue ${ns}::rdValue ${scobj_hpath} - hsetprop ${scobj_hpath}/sensor/ch7 control true - hsetprop ${scobj_hpath}/sensor/ch7 data true - hsetprop ${scobj_hpath}/sensor/ch7 mutable true - hsetprop ${scobj_hpath}/sensor/ch7 nxsave true - hsetprop ${scobj_hpath}/sensor/ch7 oldval 0.0 - hsetprop ${scobj_hpath}/sensor/ch7 klass "parameter" - hsetprop ${scobj_hpath}/sensor/ch7 sdsinfo "::nexus::scobj::sdsinfo" - hsetprop ${scobj_hpath}/sensor/ch7 type "part" - hsetprop ${scobj_hpath}/sensor/ch7 nxalias "${name}_sensor_ch7" + if {${num_chans} > 6} { + hfactory ${scobj_hpath}/sensor/ch7 plain user float + hsetprop ${scobj_hpath}/sensor/ch7 read ${ns}::getTemp ${scobj_hpath} rdValue {6} + hsetprop ${scobj_hpath}/sensor/ch7 rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/sensor/ch7 control true + hsetprop ${scobj_hpath}/sensor/ch7 data true + hsetprop ${scobj_hpath}/sensor/ch7 mutable true + hsetprop ${scobj_hpath}/sensor/ch7 nxsave true + hsetprop ${scobj_hpath}/sensor/ch7 oldval 0.0 + hsetprop ${scobj_hpath}/sensor/ch7 klass "parameter" + hsetprop ${scobj_hpath}/sensor/ch7 sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/sensor/ch7 type "part" + hsetprop ${scobj_hpath}/sensor/ch7 nxalias "${name}_sensor_ch7" - if {[string equal -nocase "${simulation_flag}" "false"]} { - ${sct_controller} poll ${scobj_hpath}/sensor/ch7 1 - hsetprop ${scobj_hpath}/sensor/ch7 simulated false - } else { - ::scobj::lakeshore_218::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for lakeshore_218" - hsetprop ${scobj_hpath}/sensor/ch7 simulated true + if {[string equal -nocase "${simulation_flag}" "false"]} { + ${sct_controller} poll ${scobj_hpath}/sensor/ch7 15 + hsetprop ${scobj_hpath}/sensor/ch7 simulated false + } else { + ::scobj::lakeshore_218::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for lakeshore_218" + hsetprop ${scobj_hpath}/sensor/ch7 simulated true + } } - hfactory ${scobj_hpath}/sensor/ch8 plain user float - hsetprop ${scobj_hpath}/sensor/ch8 read ${ns}::getTemp ${scobj_hpath} rdValue {7} - hsetprop ${scobj_hpath}/sensor/ch8 rdValue ${ns}::rdValue ${scobj_hpath} - hsetprop ${scobj_hpath}/sensor/ch8 control true - hsetprop ${scobj_hpath}/sensor/ch8 data true - hsetprop ${scobj_hpath}/sensor/ch8 mutable true - hsetprop ${scobj_hpath}/sensor/ch8 nxsave true - hsetprop ${scobj_hpath}/sensor/ch8 oldval 0.0 - hsetprop ${scobj_hpath}/sensor/ch8 klass "parameter" - hsetprop ${scobj_hpath}/sensor/ch8 sdsinfo "::nexus::scobj::sdsinfo" - hsetprop ${scobj_hpath}/sensor/ch8 type "part" - hsetprop ${scobj_hpath}/sensor/ch8 nxalias "${name}_sensor_ch8" + if {${num_chans} > 7} { + hfactory ${scobj_hpath}/sensor/ch8 plain user float + hsetprop ${scobj_hpath}/sensor/ch8 read ${ns}::getTemp ${scobj_hpath} rdValue {7} + hsetprop ${scobj_hpath}/sensor/ch8 rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/sensor/ch8 control true + hsetprop ${scobj_hpath}/sensor/ch8 data true + hsetprop ${scobj_hpath}/sensor/ch8 mutable true + hsetprop ${scobj_hpath}/sensor/ch8 nxsave true + hsetprop ${scobj_hpath}/sensor/ch8 oldval 0.0 + hsetprop ${scobj_hpath}/sensor/ch8 klass "parameter" + hsetprop ${scobj_hpath}/sensor/ch8 sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/sensor/ch8 type "part" + hsetprop ${scobj_hpath}/sensor/ch8 nxalias "${name}_sensor_ch8" - if {[string equal -nocase "${simulation_flag}" "false"]} { - ${sct_controller} poll ${scobj_hpath}/sensor/ch8 1 - hsetprop ${scobj_hpath}/sensor/ch8 simulated false - } else { - ::scobj::lakeshore_218::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for lakeshore_218" - hsetprop ${scobj_hpath}/sensor/ch8 simulated true + if {[string equal -nocase "${simulation_flag}" "false"]} { + ${sct_controller} poll ${scobj_hpath}/sensor/ch8 15 + hsetprop ${scobj_hpath}/sensor/ch8 simulated false + } else { + ::scobj::lakeshore_218::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for lakeshore_218" + hsetprop ${scobj_hpath}/sensor/ch8 simulated true + } } hsetprop ${scobj_hpath}/sensor data "true" hsetprop ${scobj_hpath}/sensor klass "@none" @@ -379,7 +429,7 @@ proc ::scobj::lakeshore_218::mkDriver { sct_controller name device_class simulat proc ::scobj::lakeshore_218::add_driver {name device_class simulation_flag ip_address tcp_port} { set catch_status [ catch { - ::scobj::lakeshore_218::sics_log 9 "::scobj::lakeshore_218::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port}" + ::scobj::lakeshore_218::sics_log 9 "::scobj::lakeshore_218::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${num_chans}" if {[string equal -nocase "${simulation_flag}" "false"]} { if {[string equal -nocase "aqadapter" "${ip_address}"]} { ::scobj::lakeshore_218::sics_log 9 "makesctcontroller sct_${name} aqadapter ${tcp_port}" @@ -393,8 +443,8 @@ proc ::scobj::lakeshore_218::add_driver {name device_class simulation_flag ip_ad ::scobj::lakeshore_218::sics_log 9 "makesctcontroller sct_${name} aqadapter NULL" makesctcontroller sct_${name} aqadapter NULL } - ::scobj::lakeshore_218::sics_log 1 "::scobj::lakeshore_218::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port}" - ::scobj::lakeshore_218::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} + ::scobj::lakeshore_218::sics_log 1 "::scobj::lakeshore_218::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${num_chans}" + ::scobj::lakeshore_218::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${num_chans} } catch_message ] handle_exception ${catch_status} ${catch_message} } @@ -485,7 +535,26 @@ proc ::scobj::lakeshore_218::read_config {} { } makesctcontroller sct_${name} aqadapter ${asyncqueue} } - ${ns}::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} + set arg_list [list] + set missing_list [list] + array unset default_map + array set default_map [list num_chans 8] + foreach arg {num_chans} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } elseif {[info exists default_map($arg)]} { + lappend arg_list $default_map($arg) + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + ${ns}::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} {*}$arg_list } } } diff --git a/site_ansto/instrument/config/environment/temperature/sct_oxford_mercury.tcl b/site_ansto/instrument/config/environment/temperature/sct_oxford_mercury.tcl deleted file mode 100644 index 22ebad6b..00000000 --- a/site_ansto/instrument/config/environment/temperature/sct_oxford_mercury.tcl +++ /dev/null @@ -1,891 +0,0 @@ -# vim: ts=8 sw=2 sta sts=2 et ai si -# This is a template driver for a mercury temperaure controller from Oxford Instruments -# -# Author: Douglas Clowes -# Date: August 2012 -# -if { "[lindex [split [info nameofexecutable] "/"] end]" == "tclsh"} { -# This block is to suppress spurious error/warning messages when loaded in Nagelfar - set catch_status [ catch { - puts "TCLSH" - proc environment_simulation {} { return "" } - proc SplitReply {str} { return "" } - proc makesctcontroller {args} { } - proc MakeSICSObj {args} { } - proc sicslist {args} { } - proc hfactory {args} { } - proc hdelprop {args} { } - proc hsetprop {args} { } - proc hgetprop {args} { } - proc hpropexists {args} { } - proc hlistprop {args} { } - proc hset {args} { } - proc hget {args} { } - proc hval {args} { } - proc hinfo {args} { } - proc hlist {args} { } - proc sct {args} { } - proc debug_log {args} { } - proc pathname {args} { } - proc basename {args} { } - proc channel {args} { } - proc ns {args} { } - } catch_message ] - if {$catch_status != 0} { - puts "error in main $catch_message" - return -code error "in main $catch_message" - } -} - -set vendor "oxford" -set device "mercury" - -namespace eval ::scobj::[set vendor]_[set device] { - proc ns {} { - return "[namespace current]" - } - # All of this takes place in a namespace based on the vendor and device - # Debug prints and vendor/device save - clientput "Namespace: [namespace current]" - clientput "Vendor:[set vendor]" - clientput "Device:[set device]" - set [namespace current]::vendor [set ::vendor] - set [namespace current]::device [set ::device] - set [namespace current]::ven_dev "[set ::vendor]_[set ::device]" - clientput "[namespace current]::vendor [set [namespace current]::vendor]" - clientput "[namespace current]::device [set [namespace current]::device]" - clientput "[namespace current]::ven_dev [set [namespace current]::ven_dev]" - - proc debug_log {debug_level arg_string} { - # write a timestamped string message to a log file for debugging - set debug_threshold 0 - if {$debug_level >= $debug_threshold} { - set fd [open "[set [namespace current]::log_file]" "a"] - set line "[clock format [clock seconds] -format "%T"] $arg_string" - puts $fd "$line" - close $fd - } - } - - proc channel {arg} { - # strip the trailing digits from the arg and return them as a string - set result 0 - for { set i 0 } { $i < [string length $arg] } { incr i } { - if { ! [string match {[0-9]} [string index $arg end-$i]] } { - break - } - set result [string range "$arg" end-$i end] - } - debug_log 1 "Extract channel $result from argument $arg" - return $result - } - - proc setPoint {tc_root nextState cmd} { - # send a command to set a value - debug_log 1 "setPoint tc_root=$tc_root sct=[sct] $cmd [sct target]" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set par [sct target] - set command "$cmd:$par" - - debug_log 1 "setPoint tc_root=$tc_root sct=[sct] Write $command" - sct send "$command" - sct driving 1 - sct time_check [clock seconds] - if {$par != [sct oldval]} { - sct oldval $par - sct update $par - sct utime readtime - debug_log 1 "setPoint: new data for $tc_root [sct] result=$par" - } - return $nextState - } - - proc chkWrite {tc_root} { - # process the response to the write - # - not all devices will respond to writes - set data [sct result] - debug_log 1 "chkWrite tc_root=$tc_root sct=[sct] resp=$data" - if {[string equal -nocase -length 7 $data "ASCERR:"]} { - # the protocol driver has reported an error - sct geterror "$data" - } elseif {[string equal -nocase -length 1 $data "?"]} { - # the device has reported an error - sct geterror "Error: $data" - } else { - # the write was successful, record the data - set data [sct target] - if {$data != [sct oldval]} { - sct oldval $data - sct update $data - sct utime readtime - debug_log 1 "chkWrite new data for $tc_root [sct] result=$data" - } - } - return idle - } - - proc noResponse {tc_root} { - set data "[sct result]" - debug_log 1 "noResponse tc_root=$tc_root sct=[sct] resp=$data" - return idle - } - - proc getValue {tc_root nextState cmd} { - # send a command to request a value - debug_log 1 "getValue tc_root=$tc_root sct=[sct] $cmd" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - if { [string equal -nocase -length 4 "$cmd" "XXXX"] } { - set cmd "$cmd [channel [pathname [sct]]]" - } - debug_log 1 "getValue sct send $cmd" - sct send "$cmd" - return $nextState - } - - proc rdValue {tc_root} { - # process the received response to the read request - debug_log 1 "[ns]::rdValue tc_root=$tc_root sct=[sct] result=[sct result]" - set data [sct result] - if {[string equal -nocase -length 7 $data "ASCERR:"]} { - # the protocol driver has reported an error - sct geterror "$data" - } elseif {[string equal -nocase -length 1 $data "?"]} { - # the device has reported an error - sct geterror "Error: $data" - } else { - if { [string equal -nocase [basename [sct]] "XXXX"] } { - return "idle" - } - scan [lindex [split "$data" ":"] end] "%g" data - if {$data != [sct oldval]} { - debug_log 1 "[sct] changed to new:$data, from old:[sct oldval]" - sct oldval $data - sct update $data - sct utime readtime - } - } - return "idle" - } - - proc rdText {tc_root} { - # process the received response to the read request - debug_log 1 "[ns]::rdText tc_root=$tc_root sct=[sct] result=[sct result]" - set data [sct result] - if {[string equal -nocase -length 7 $data "ASCERR:"]} { - # the protocol driver has reported an error - sct geterror "$data" - } elseif {[string equal -nocase -length 1 $data "?"]} { - # the device has reported an error - sct geterror "Error: $data" - } else { - if { [string equal -nocase [basename [sct]] "XXXX"] } { - return "idle" - } - scan [lindex [split "$data" ":"] end] "%s" data - if {$data != [sct oldval]} { - debug_log 1 "[sct] changed to new:$data, from old:[sct oldval]" - sct oldval $data - sct update $data - sct utime readtime - } - } - return "idle" - } - - proc rdTextAll {tc_root} { - # process the received response to the read request - debug_log 1 "[ns]::rdText tc_root=$tc_root sct=[sct] result=[sct result]" - set data [sct result] - if {[string equal -nocase -length 7 $data "ASCERR:"]} { - # the protocol driver has reported an error - sct geterror "$data" - } elseif {[string equal -nocase -length 1 $data "?"]} { - # the device has reported an error - sct geterror "Error: $data" - } else { - if { [string equal -nocase [basename [sct]] "XXXX"] } { - return "idle" - } - #scan [lindex [split "$data" ":"] end] "%s" data - if {$data != [sct oldval]} { - debug_log 1 "[sct] changed to new:$data, from old:[sct oldval]" - sct oldval $data - sct update $data - sct utime readtime - } - } - return "idle" - } - - proc getTemp {tc_root nextState cmd} { - debug_log 1 "getTemp tc_root=$tc_root sct=[sct] $cmd" - if { ! [hpropexists [sct] my_state] } { - sct my_state 0 - } - if { [sct my_state] == 0 } { - set command "CSET?" - } else { - set command "RDGK? [sct channel]" - } - debug_log 1 "getTemp sct send $command" - sct send "$command" - return "$nextState" - } - - proc rdTemp {tc_root} { - debug_log 1 "rdTemp tc_root=$tc_root sct=[sct] result=[sct result]" - if { [sct my_state] == 0 } { - set response "[split [sct result] ","]" - sct channel [lindex $response 0] - sct filter [lindex $response 1] - sct my_state 1 - return "read" - } else { - set data "[sct result]" - if {$data != [sct oldval]} { - debug_log 1 "[sct] changed to new:$data, from old:[sct oldval]" - sct oldval $data - sct update $data - sct utime readtime - } - sct my_state 0 - return "idle" - } - } - - proc gtLoop {tc_root nextState cmd} { - debug_log 1 "gtLoop tc_root=$tc_root sct=[sct] nextState=$nextState cmd=$cmd" - debug_log 1 "gtLoop tc_root=$tc_root pathname=[pathname [sct]] basename=[basename [sct]]" - if { ! [hpropexists [sct] my_state] } { - debug_log 1 "gtLoop setting my_state to zero because it doesn't exist" - sct my_state 0 - } - if { [sct my_state] == 0 } { - set command "RAMP?" - } else { - set command "SETP?" - } - debug_log 1 "gtLoop sct=[sct] command=$command" - sct send "$command" - return "$nextState" - return idle - } - - proc rdLoop {tc_root} { - debug_log 1 "rdLoop tc_root=$tc_root sct=[sct] result=[sct result]" - debug_log 1 "rdLoop tc_root=$tc_root pathname=[pathname [sct]] basename=[basename [sct]]" - set nextState "read" - if { [sct my_state] == 0 } { - debug_log 1 "rdLoop sct=[sct] RAMP - result=[sct result]" - set nextState "read" - } else { - debug_log 1 "rdLoop sct=[sct] SETP - result=[sct result]" - set nextState "idle" - sct my_state -1 - } - sct my_state "[expr {[sct my_state] + 1}]" - return $nextState - } - - proc wrLoop {tc_root nextState cmd} { - debug_log 1 "wrLoop tc_root=$tc_root sct=[sct] nextState=$nextState cmd=$cmd" - if { ! [hpropexists [sct] my_state] } { - debug_log 1 "wrLoop setting my_state to zero because it doesn't exist" - sct my_state 0 - } - if { [sct writestatus] == "start" } { - debug_log 1 "wrLoop setting my_state to zero because writestatus is [sct writestatus]" - sct my_state 0 - } - debug_log 1 "wrLoop target=[sct target] writestatus=[sct writestatus] my_state=[sct my_state]" - if { [sct my_state] == 0 } { - set my_rate [hval [sct]/ramp_rate] - if { $my_rate > 0.0 } { - set command "RAMP 0,0;RAMP?" - } else { - set command "RAMP 1,$my_rate;RAMP?" - } - } else { - set command "SETP [hval [sct]/setpoint];SETP?" - } - debug_log 1 "wrLoop sct=[sct] command=$command" - sct send "$command" - return "$nextState" - } - - proc ckLoop {tc_root} { - debug_log 1 "ckLoop tc_root=$tc_root sct=[sct] result=[sct result]" - debug_log 1 "ckLoop target=[sct target] writestatus=[sct writestatus] my_state=[sct my_state]" - set nextState "write" - if { [sct my_state] == 0 } { - debug_log 1 "ckLoop sct=[sct] RAMP - result=[sct result]" - [ns]::rdValue $tc_root - set nextState "write" - } else { - debug_log 1 "ckLoop sct=[sct] SETP - result=[sct result]" - [ns]::rdValue $tc_root - sct my_state -1 - set nextState "idle" - } - sct my_state "[expr {[sct my_state] + 1}]" - return $nextState - } - - ## - # @brief getState() sends commands/requests to the device under control - # - # @param tc_root the path to the device_state node - # @param nextState the next sct state (rdState) - # @param cmd empty argument - # - # @return the next sct state (rdState) - # - proc getState {tc_root nextState cmd} { - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - debug_log 1 "getState $tc_root sct=[sct] state=[hval [sct]] substate=[sct substate] next=$nextState" - set my_state [hval [sct]] - set my_substate [sct substate] - if {$my_state == "STATE_INIT"} { - if { $my_substate == 0 } { - set command "*IDN?" - } elseif { $my_substate == 1 } { - set command "*TST?" - } - } elseif { $my_state == "STATE_CURVE"} { - if { $my_substate == 0 } { - set my_substate 1000 - sct substate $my_substate - } - if { ($my_substate % 1000) == 0 } { - set command "CRVHDR? [expr {int($my_substate / 1000)}]" - } else { - set command "CRVPT? [expr {int($my_substate / 1000)}],[expr {($my_substate % 1000)}]" - } - } elseif { $my_state == "STATE_IDLE"} { - if { $my_substate == 0 } { - set command "*ESE?" - } elseif { $my_substate == 1 } { - set command "*ESR?" - } elseif { $my_substate == 2 } { - set command "*STB?" - } - } - debug_log 1 "getState sct send $command" - sct send $command - return "$nextState" - } - - ## - # @brief rdState() handles events from the device under control - # - # @param tc_root the path to the device_state node - # - proc rdState {tc_root} { - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - debug_log 1 "rdState $tc_root sct=[sct] state=[hval [sct]] substate=[sct substate] response=\"[sct result]\"" - set nextState "read" - set my_state [hval [sct]] - set my_substate [sct substate] - if {$my_state == "STATE_INIT"} { - if { $my_substate == 0 } { # IDN - sct identity [sct result] - incr my_substate - } elseif { $my_substate == 1 } { - sct selftest [sct result] - incr my_substate - } - if { $my_substate > 1 } { - #hset [sct] "STATE_IDLE" - hset [sct] "STATE_CURVE" - set my_substate 0 - } - } elseif { $my_state == "STATE_CURVE"} { - if { ($my_substate % 1000) == 0 } { - debug_log 1 "Curve: [expr {$my_substate / 1000}] Header: [sct result]" - } else { - debug_log 1 "Curve: [expr {$my_substate / 1000}] Point: [expr {$my_substate % 1000}] Value: [sct result]" - set rslt [scan "[sct result]" "%f,%f" units temperature] - debug_log 1 "Curve: [expr {$my_substate / 1000}] Point: [expr {$my_substate % 1000}] Result: $rslt Units: $units Temp: $temperature" - if { $units == 0.0 && $temperature == 0.0 } { - set my_substate [expr { (($my_substate / 1000)) * 1000 + 999}] - } - } - if { ($my_substate % 1000) >= 200 } { - if { ($my_substate / 1000) >= 20 } { - hset [sct] "STATE_IDLE" - set my_substate 0 - } else { - set my_substate [expr { (($my_substate / 1000) + 1) * 1000 }] - } - } else { - set my_substate [expr { $my_substate + 1 }] - } - } elseif { $my_state == "STATE_IDLE"} { - if { $my_substate == 0 } { # ESE - sct the_ese [sct result] - incr my_substate - } elseif { $my_substate == 1 } { # ESR - sct the_esr [sct result] - incr my_substate - } elseif { $my_substate == 2 } { # STB - sct the_stb [sct result] - incr my_substate - } - if { $my_substate > 2 } { - set my_substate 0 - set nextState "idle" - } - } - sct substate $my_substate - if { $my_state != [hval [sct]] } { - debug_log 1 "device_state $my_state to [hval [sct]]" - } - return "$nextState" - } - - proc chkTarget {tc_root par} { - set target {} - if {[hpropexists [sct] values]} { - set values [split [SplitReply [sct values]] ","] - foreach value $values { - #sct print "Testing $par against $value" - set lo_hi [split $value ":"] - if {[llength $lo_hi] == 2} { - if {[lindex $lo_hi 0] <= $par && [lindex $lo_hi 1] >= $par} { - #sct print "Success $par between [lindex $lo_hi 0] and [lindex $lo_hi 1]" - set target "$par" - break - } - } else { - if {[string toupper "$par"] == [string toupper "$value"]} { - #sct print "Success $par matches $value" - set target "$par" - break - } - } - } - if {"$target" == ""} { - #sct print "Failure $par no matches in $values" - return -code error "Invalid value: \"$par\"" - } - } else { - set target "$par" - } - return $target - } - -## -# @brief Implement the checkstatus command for the drivable interface -# -# NOTE: The drive adapter initially sets the writestatus to "start" and will -# only call this when writestatus!="start" - proc drivestatus {tc_root} { - #debug_log 1 "drivestatus tc_root=$tc_root, sct=[sct], setpoint=[hval [sct]], temp=[hval [pathname [sct]]/sensor], driving=[sct driving]" - if {[sct driving]} { - # tolerance - set temp [hval [pathname [sct]]/sensor] - set loval [expr {[hval [sct]] - [sct tolerance]}] - set hival [expr {[hval [sct]] + [sct tolerance]}] - if {$loval <= $temp && $temp <= $hival} { - # settle time - set timeout [sct settletime] - set timecheck [sct time_check] - set currtime [clock seconds] - #debug_log 1 "drivestatus tc_root=$tc_root, sct=[sct], setpoint=[hval [sct]], temp=[hval [pathname [sct]]/sensor], temp=($loval, $temp, $hival), time=($timecheck, $currtime, $timeout)" - if { ($currtime - $timecheck) >= $timeout } { - debug_log 1 "drivestatus tc_root=$tc_root, sct=[sct], finished driving" - sct driving 0 - } - } else { - sct time_check [clock seconds] - } - return busy - } else { - debug_log 1 "drivestatus tc_root=$tc_root, sct=[sct], now idle" - return idle - } - } - - proc halt {tc_root} { - debug_log 1 "halt $tc_root" - foreach loop {Loop1 Loop2 Loop3 Loop4} { - set catch_status [ catch { - hset $tc_root/$loop/setpoint [hval $tc_root/$loop/sensor] - hsetprop $tc_root/$loop/setpoint driving 0 - } catch_message ] - } - debug_log 1 "halt $tc_root done driving" - return idle - } - - proc check {tc_root} { - debug_log 1 "check tc_root=$tc_root, sct=[sct], target=[sct target]" - set catch_status [ catch { - set target [chkTarget $tc_root [sct target]] - if { "$target" == "" } { - error "setpoint violates limits" - } - } catch_message ] - if {$catch_status != 0} { - return -code error $catch_message - } - return OK - } - - proc wrNode {tc_root cmd level} { - set space [string repeat " " $level] - set val [hval $tc_root] - if {"$val" == ""} { - set line "$tc_root ([hinfo $tc_root])" - } else { - set line "$tc_root ([hinfo $tc_root]) = $val" - } - sct print "$space* $line" - if {"[string tolower "$cmd"]" == "-prop"} { - set props [hlistprop $tc_root] - #sct print "<<$props>>" - foreach prop $props { - #sct print "prop: $prop" - set flds [split $prop "="] - #sct print "flds: $flds" - if {[llength $flds] > 1} { - set fld0 [lindex $flds 0] - #sct print "fld0: $fld0" - if {[hpropexists $tc_root $fld0]} { - sct print "$space - [hgetprop $tc_root $fld0]" - } - } - } - } - foreach node [hlist $tc_root] { - [ns]::wrNode $tc_root/$node "$cmd" [expr {$level + 1}] - } - } - - proc wrTree {tc_root nextState cmd} { - debug_log 1 "wrTree root=$tc_root sct=[sct] cmd=$cmd target=[sct target]" - sct print "$tc_root" - [ns]::wrNode $tc_root "[sct target]" 1 - return idle - } - - ## - # @brief createNode() creates a node for the given nodename with the properties given - # - # @param scobj_hpath string variable holding the path to the object's base node in sics (/sample/tc1) - # @param sct_controller name of the scriptcontext object (typically sct_xxx_yyy) - # @param cmdGroup subdirectory (below /sample/tc*/) in which the node is to be created - # @param varName name of the actual node typically representing one device command - # @param readable set to 1 if the node represents a query command, 0 if it is not - # @param writable set to 1 if the node represents a request for a change in settings sent to the device - # @param drivable if set to 1 it prepares the node to provide a drivable interface - # @param dataType data type of the node, must be one of none, int, float, text - # @param permission defines what user group may read/write to this node (is one of spy, user, manager) - # @param rdCmd actual device query command to be sent to the device - # @param rdFunc nextState Function to be called after the getValue function, typically rdValue() - # @param wrCmd actual device write command to be sent to the device - # @param wrFunc Function to be called to send the wrCmd to the device, typically setValue() - # @param allowedValues allowed values for the node data - does not permit other - # @param klass Nexus class name (?) - # @return OK - proc createNode {scobj_hpath sct_controller\ - cmdGroup varName\ - readable writable drivable\ - dataType permission\ - rdCmd rdFunc\ - wrCmd wrFunc\ - allowedValues klass} { - - set catch_status [ catch { - set ns "[ns]" - set nodeName "$scobj_hpath/$cmdGroup/$varName" - if {1 > [string length $cmdGroup]} { - set nodeName "$scobj_hpath/$varName" - } - debug_log 1 "Creating node $nodeName" - hfactory $nodeName plain $permission $dataType - if {$readable > 0} { - # the node is readable so set it up to be polled using the rdFunc - # rdFunc is getValueFunc.rdValueFunc with both explicit functions - # or rdValueFunc where "getValue" is the implied getValueFunc - set parts [split "$rdFunc" "."] - if { [llength $parts] == 2 } { - set func_name [lindex $parts 0] - set next_state [lindex $parts 1] - } else { - set func_name "getValue" - set next_state [lindex $parts 0] - } - hsetprop $nodeName read ${ns}::$func_name $scobj_hpath $next_state $rdCmd - hsetprop $nodeName $next_state ${ns}::$next_state $scobj_hpath - # set the poll rate as a period in seconds - # TODO allow directly settable value in seconds - set poll_period 5 - if { $readable >= 0 && $readable <= 300 } { - set poll_period [expr {int($readable)}] - } - debug_log 1 "Registering node $nodeName for poll at $poll_period seconds" - $sct_controller poll $nodeName $poll_period - } - if {$writable == 1} { - # the node is writable so set it up to invoke a callback when written - # rdFunc is putValueFunc.chkWriteFunc with both explicit functions - # or putValueFunc where "noResponse" is the implied chkWriteFunc - set parts [split "$wrFunc" "."] - if { [llength $parts] == 2 } { - set func_name [lindex $parts 0] - set next_state [lindex $parts 1] - } else { - set func_name [lindex $parts 0] - set next_state "noResponse" - } - hsetprop $nodeName write ${ns}::$func_name $scobj_hpath $next_state $wrCmd - hsetprop $nodeName $next_state ${ns}::$next_state $scobj_hpath - hsetprop $nodeName writestatus UNKNOWN - debug_log 1 "Registering node $nodeName for write callback" - $sct_controller write $nodeName - } - # Initialise the previous value to test against - switch -exact $dataType { - "none" { } - "int" { hsetprop $nodeName oldval -1 } - "float" { hsetprop $nodeName oldval -1.0 } - default { hsetprop $nodeName oldval UNKNOWN } - } - # Set the allowed values property - if {1 < [string length $allowedValues]} { - hsetprop $nodeName values $allowedValues - } - # Drive adapter interface - # TODO make it a separate function and pass in all this stuff - if {$drivable == 1} { - hsetprop $nodeName check ${ns}::check $scobj_hpath - hsetprop $nodeName driving 0 - hsetprop $nodeName checklimits ${ns}::check $scobj_hpath - hsetprop $nodeName checkstatus ${ns}::drivestatus $scobj_hpath - hsetprop $nodeName halt ${ns}::halt $scobj_hpath - } else { - hsetprop $nodeName driving 0 - } - } catch_message ] - if {$catch_status != 0} { - debug_log 5 "error in [ns]::createNode $catch_message" - return -code error "in [ns]::createNode $catch_message" - } - return OK - } - - proc mk_sct_driver {sct_controller the_klass the_name tol CID CTYPE} { - debug_log 1 "mk_sct_driver $sct_controller $the_klass $the_name $tol $CID $CTYPE" - set catch_status [ catch { - - MakeSICSObj $the_name SCT_OBJECT - sicslist setatt $the_name klass $the_klass - sicslist setatt $the_name long_name $the_name - - set scobj_hpath /sics/$the_name - - hfactory $scobj_hpath/Loop1 plain spy none - hfactory $scobj_hpath/Loop2 plain spy none - hfactory $scobj_hpath/Loop3 plain spy none - hfactory $scobj_hpath/Loop4 plain spy none - hfactory $scobj_hpath/Level plain spy none - - set deviceCommand {\ - Loop1 setpoint 5 1 1 float user {READ:DEV:MB1.T1:TEMP:LOOP:TSET} {rdValue} {SET:DEV:MB1.T1:TEMP:LOOP:TSET} {setPoint} {1:333}\ - Loop1 sensor 1 0 0 float user {READ:DEV:MB1.T1:TEMP:SIG:TEMP} {rdValue} {} {} {}\ - Loop1 nick 5 0 0 text user {READ:DEV:MB1.T1:TEMP:NICK} {rdText} {} {} {}\ - Loop1 temp 0 0 0 text user {READ:DEV:MB1.T1:TEMP} {rdTextAll} {} {} {}\ - Loop1 loop 0 0 0 text user {READ:DEV:MB1.T1:TEMP:LOOP} {rdTextAll} {} {} {}\ - Loop1 heater 0 0 0 text user {READ:DEV:MB0.H1:HTR} {rdTextAll} {} {} {}\ - Loop1 power 5 0 0 float user {READ:DEV:MB0.H1:HTR:SIG:POWR} {rdValue} {} {} {}\ - Loop2 setpoint 5 1 1 float user {READ:DEV:DB6.T1:TEMP:LOOP:TSET} {rdValue} {SET:DEV:DB6.T1:TEMP:LOOP:TSET} {setPoint} {1:333}\ - Loop2 sensor 1 0 0 float user {READ:DEV:DB6.T1:TEMP:SIG:TEMP} {rdValue} {} {} {}\ - Loop2 nick 5 0 0 text user {READ:DEV:DB6.T1:TEMP:NICK} {rdText} {} {} {}\ - Loop2 temp 0 0 0 text user {READ:DEV:DB6.T1:TEMP} {rdTextAll} {} {} {}\ - Loop2 loop 0 0 0 text user {READ:DEV:DB6.T1:TEMP:LOOP} {rdTextAll} {} {} {}\ - Loop2 heater 0 0 0 text user {READ:DEV:DB1.H1:HTR} {rdTextAll} {} {} {}\ - Loop2 power 5 0 0 float user {READ:DEV:DB1.H1:HTR:SIG:POWR} {rdValue} {} {} {}\ - Loop3 setpoint 5 1 1 float user {READ:DEV:DB7.T1:TEMP:LOOP:TSET} {rdValue} {SET:DEV:DB7.T1:TEMP:LOOP:TSET} {setPoint} {1:333}\ - Loop3 sensor 1 0 0 float user {READ:DEV:DB7.T1:TEMP:SIG:TEMP} {rdValue} {} {} {}\ - Loop3 nick 5 0 0 text user {READ:DEV:DB7.T1:TEMP:NICK} {rdText} {} {} {}\ - Loop3 temp 0 0 0 text user {READ:DEV:DB7.T1:TEMP} {rdTextAll} {} {} {}\ - Loop3 loop 0 0 0 text user {READ:DEV:DB7.T1:TEMP:LOOP} {rdTextAll} {} {} {}\ - Loop3 heater 0 0 0 text user {READ:DEV:DB2.H1:HTR} {rdTextAll} {} {} {}\ - Loop3 power 5 0 0 float user {READ:DEV:DB2.H1:HTR:SIG:POWR} {rdValue} {} {} {}\ - Loop4 setpoint 5 1 1 float user {READ:DEV:DB8.T1:TEMP:LOOP:TSET} {rdValue} {SET:DEV:DB8.T1:TEMP:LOOP:TSET} {setPoint} {1:333}\ - Loop4 sensor 1 0 0 float user {READ:DEV:DB8.T1:TEMP:SIG:TEMP} {rdValue} {} {} {}\ - Loop4 nick 5 0 0 text user {READ:DEV:DB8.T1:TEMP:NICK} {rdText} {} {} {}\ - Loop4 temp 0 0 0 text user {READ:DEV:DB8.T1:TEMP} {rdTextAll} {} {} {}\ - Loop4 loop 0 0 0 text user {READ:DEV:DB7.T1:TEMP:LOOP} {rdTextAll} {} {} {}\ - Loop4 heater 0 0 0 text user {READ:DEV:DB3.H1:HTR} {rdTextAll} {} {} {}\ - Loop4 power 5 0 0 float user {READ:DEV:DB3.H1:HTR:SIG:POWR} {rdValue} {} {} {}\ - Level Nitrogen 15 0 0 float user {READ:DEV:DB5.L1:LVL:SIG:NIT:LEV} {rdValue} {} {} {}\ - Level Helium 15 0 0 float user {READ:DEV:DB5.L1:LVL:SIG:HEL:LEV} {rdValue} {} {} {}\ - } - - foreach {cmdGroup varName\ - readable writable drivable\ - dataType permission\ - rdCmd rdFunc\ - wrCmd wrFunc\ - allowedValues} $deviceCommand { - [ns]::createNode $scobj_hpath $sct_controller\ - $cmdGroup $varName\ - $readable $writable $drivable\ - $dataType $permission\ - $rdCmd $rdFunc\ - $wrCmd $wrFunc\ - $allowedValues $the_klass - } - - foreach cmdGroup { Loop1 Loop2 Loop3 Loop4 } { - set pathName "$scobj_hpath/$cmdGroup" - hsetprop $pathName type part - hsetprop $pathName klass NXsensor - hsetprop $pathName privilege spy - hsetprop $pathName control true - hsetprop $pathName data true - hsetprop $pathName nxsave true - hsetprop $pathName/setpoint tolerance $tol - hsetprop $pathName/setpoint settletime 5 - foreach varName { setpoint sensor nick } { - set nodeName "$pathName/$varName" - hsetprop $nodeName nxalias ${the_name}_${cmdGroup}_${varName}_value - hsetprop $nodeName long_name $varName - hsetprop $nodeName klass sensor - hsetprop $nodeName priviledge user - hsetprop $nodeName control true - hsetprop $nodeName data true - hsetprop $nodeName nxsave true - hsetprop $nodeName mutable true - hsetprop $nodeName sdsinfo ::nexus::scobj::sdsinfo - } - } - - foreach cmdGroup { Level } { - set pathName "$scobj_hpath/$cmdGroup" - hsetprop $pathName type part - hsetprop $pathName klass NXsensor - hsetprop $pathName privilege spy - hsetprop $pathName control true - hsetprop $pathName data true - hsetprop $pathName nxsave true - foreach varName { Nitrogen Helium } { - set nodeName "$pathName/$varName" - hsetprop $nodeName long_name $varName - hsetprop $nodeName klass sensor - hsetprop $nodeName priviledge user - hsetprop $nodeName control true - hsetprop $nodeName data true - hsetprop $nodeName nxsave true - hsetprop $nodeName nxalias ${the_name}_${cmdGroup}_${varName}_value - hsetprop $nodeName mutable true - hsetprop $nodeName sdsinfo ::nexus::scobj::sdsinfo - } - } - - hfactory $scobj_hpath/device_state plain spy none - hset $scobj_hpath/device_state "STATE_INIT" - hsetprop $scobj_hpath/device_state substate 0 - - set point 0 - set catch_status_2 [ catch { - hsetprop $scobj_hpath privilege spy - hsetprop $scobj_hpath long_name $the_name - hsetprop $scobj_hpath sicsdev $the_name - hsetprop $scobj_hpath nxalias $the_name - hsetprop $scobj_hpath control true - hsetprop $scobj_hpath data true - hsetprop $scobj_hpath nxsave true - hsetprop $scobj_hpath mutable true - hsetprop $scobj_hpath klass parameter - hsetprop $scobj_hpath sdsinfo ::nexus::scobj::sdsinfo - set point 1 -if {0} { - ::scobj::hinitprops $the_name Loop1 - set point 2 - ::scobj::hinitprops $the_name Loop2/setpoint - set point 3 - ::scobj::hinitprops $the_name Loop3/setpoint - set point 4 - ::scobj::hinitprops $the_name Loop4/setpoint - set point 5 -} - } catch_message_2 ] - if {$catch_status_2 != 0} { - debug_log 5 "error in [ns]::mk_sct_driver($point) $catch_message_2" - return -code error "in [ns]::mk_sct_driver($point) $catch_message_2" - } - hsetprop $scobj_hpath/Loop1/setpoint permlink data_set ${CTYPE}${CID}SP1 - hsetprop $scobj_hpath/Loop1/setpoint @description ${CTYPE}${CID}SP1 - hsetprop $scobj_hpath/Loop1/setpoint permlink data_set ${CTYPE}${CID}SP1 - hsetprop $scobj_hpath/Loop1/setpoint @description ${CTYPE}${CID}SP1 - hsetprop $scobj_hpath/Loop2/setpoint permlink data_set ${CTYPE}${CID}SP2 - hsetprop $scobj_hpath/Loop2/setpoint @description ${CTYPE}${CID}SP2 - hsetprop $scobj_hpath/Loop3/setpoint permlink data_set ${CTYPE}${CID}SP3 - hsetprop $scobj_hpath/Loop3/setpoint @description ${CTYPE}${CID}SP3 - hsetprop $scobj_hpath/Loop4/setpoint permlink data_set ${CTYPE}${CID}SP4 - hsetprop $scobj_hpath/Loop4/setpoint @description ${CTYPE}${CID}SP4 - - hsetprop $scobj_hpath/Loop1/sensor permlink data_set ${CTYPE}${CID}S1 - hsetprop $scobj_hpath/Loop1/sensor @description ${CTYPE}${CID}S1 - hsetprop $scobj_hpath/Loop2/sensor permlink data_set ${CTYPE}${CID}S2 - hsetprop $scobj_hpath/Loop2/sensor @description ${CTYPE}${CID}S2 - hsetprop $scobj_hpath/Loop3/sensor permlink data_set ${CTYPE}${CID}S3 - hsetprop $scobj_hpath/Loop3/sensor @description ${CTYPE}${CID}S3 - hsetprop $scobj_hpath/Loop4/sensor permlink data_set ${CTYPE}${CID}S4 - hsetprop $scobj_hpath/Loop4/sensor @description ${CTYPE}${CID}S4 - - if {[SplitReply [environment_simulation]]=="false"} { - hsetprop $scobj_hpath/Loop1/setpoint type drivable - hsetprop $scobj_hpath/Loop2/setpoint type drivable - hsetprop $scobj_hpath/Loop3/setpoint type drivable - hsetprop $scobj_hpath/Loop4/setpoint type drivable - ansto_makesctdrive ${the_name}_loop1 $scobj_hpath/Loop1/setpoint $scobj_hpath/Loop1/sensor $sct_controller - ansto_makesctdrive ${the_name}_loop2 $scobj_hpath/Loop2/setpoint $scobj_hpath/Loop2/sensor $sct_controller - ansto_makesctdrive ${the_name}_loop3 $scobj_hpath/Loop3/setpoint $scobj_hpath/Loop3/sensor $sct_controller - ansto_makesctdrive ${the_name}_loop4 $scobj_hpath/Loop4/setpoint $scobj_hpath/Loop4/sensor $sct_controller - } - } catch_message ] - if {$catch_status != 0} { - debug_log 5 "error in [ns]::mk_sct_driver $catch_message" - return -code error "in [ns]::mk_sct_driver $catch_message" - } - } - - proc add_[set vendor]_[set device] {the_name IP port CID CTYPE terminator {_tol 5.0}} { - set [ns]::log_file "../log/[set [ns]::ven_dev]_[set the_name].log" - set fd [open [set [ns]::log_file] "w"] - close $fd - debug_log 1 "add_[set [ns]::vendor]_[set [ns]::device] ${the_name} ${IP} ${port} ${_tol}" - clientput "Namespace: [namespace current]" - clientput "::vendor $::vendor" - clientput "::device $::device" - clientput "[namespace current]::vendor [set [namespace current]::vendor]" - clientput "[namespace current]::device [set [namespace current]::device]" - clientput "[namespace current]::ven_dev [set [namespace current]::ven_dev]" - clientput "[namespace current]::log_file [set [namespace current]::log_file]" - if {[SplitReply [environment_simulation]]=="false"} { - debug_log 1 "makesctcontroller sct_${the_name} std ${IP}:${port} $terminator" - makesctcontroller sct_${the_name} std ${IP}:${port} $terminator - } - debug_log 1 "::scobj::oxford_mercury::mk_sct_driver sct_${the_name} environment ${the_name} ${_tol} $CID $CTYPE" - ::scobj::oxford_mercury::mk_sct_driver sct_${the_name} environment ${the_name} ${_tol} $CID $CTYPE - } - - - namespace export add_[set vendor]_[set device] -} - -namespace import ::scobj::[set vendor]_[set device]::* - -