From c765c33f6db9ed6e98e78c9163ada5fad1d3aae5 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Mon, 22 Aug 2011 11:30:20 +1000 Subject: [PATCH] Make instance data properties of a params node instead of namespace global variables This is to allow multiple instance of the same device type without clashing of persistent data r3248 | dcl | 2011-08-22 11:30:20 +1000 (Mon, 22 Aug 2011) | 3 lines --- .../temperature/sct_lakeshore_336.tcl | 283 ++++++++++-------- 1 file changed, 152 insertions(+), 131 deletions(-) diff --git a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_336.tcl b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_336.tcl index 734fb5aa..c6f4e35f 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_336.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_336.tcl @@ -25,6 +25,10 @@ # Workaround: use 2 copies of this source code which are identical except for # the literal name of the proc add_ls336 vs.340 and the # namespace eval ::scobj::ls336 vs 340 +# Remediation: Move all of the "global" variables into properties of the "params" +# node so they can exist as "instance" variables and not clash for multiple +# instances of identical devices (e.g. two Lakeshore 336 temperature controllers) +# # ----------------------------------------------------------------------------*/ # Notes @@ -45,6 +49,21 @@ # Default temperature controller parameters namespace eval ::scobj::ls336 { + # Convenience function to replace global variables with properties of the "params" node. + proc set_param { tc_root param value } { + hsetprop $tc_root/params $param "$value" + } + # Convenience function to replace global variables with properties of the "params" node. + proc get_param { tc_root param } { + if { ![hpropexists $tc_root/params $param] } { + broadcast "Getting non-existent parameter $param" + return "" + } + set result "[SplitReply [hgetprop $tc_root/params $param]]" + return $result + } + # Initialize instance-local "global" variables. Needed since replacing with per-instance properties. + proc init_params { tc_root } { # Some global variables that are useful as default initilisation values or for tracking # Name of the scriptcontext object created from calling this driver - an instrument may use more than one # What Lakeshore model are we dealing with? 336 or 340? @@ -55,49 +74,47 @@ namespace eval ::scobj::ls336 { # Variables that are identical to node names but are needed internally as well # temperature difference between setpoint and actual temperature at which the # heater changes from idle to driving - set ls336_driveTolerance1 2 - set ls336_driveTolerance2 2 + set_param $tc_root ls336_driveTolerance1 2 + set_param $tc_root ls336_driveTolerance2 2 # Next 2 parameters are supported by LS model 340 only # ctrl loop 1 settle parameter, threshold=allowable band around setpoint (0,..,100) - set ls340_settleThr 30 + set_param $tc_root ls340_settleThr 30 # ctrl loop 1 settle parameter, settle time in seconds - set ls340_settleTime 30 + set_param $tc_root ls340_settleTime 30 # default Heater Range (0,..,5) zero is off, hence the least dangerous - set ls336_range 0 + set_param $tc_root ls336_range 0 # upper and lower temperature limit in Kelvin - set ls336_upperlimit 500.0 - set ls336_lowerlimit 4.0 + set_param $tc_root ls336_upperlimit 500.0 + set_param $tc_root ls336_lowerlimit 4.0 # temperature units are Kelvin - set ls336_tempUnits "K" + set_param $tc_root ls336_tempUnits "K" # ls336 status byte # enable extra logging - can produce huge stout****.log file in /usr/local/sics/log/ - set ls336_verbose 0 + set_param $tc_root ls336_verbose 0 # a list of available sensors (not all may be connected/active) - set this_sensorlist [list A B C D] + set_param $tc_root this_sensorlist [list A B C D] # a list of controler loops - set this_controlerlist [list 1 2] + set_param $tc_root this_controlerlist [list 1 2] # set device ID to unknown # set self-test result to unknown - set this_selfTestResult -1 + set_param $tc_root this_selfTestResult -1 # status of input channels - unknown at startup - set ls336_sampleSensor "UNKNOWN" - set timeInSecsSince2000 0 + set_param $tc_root ls336_sampleSensor "UNKNOWN" + set_param $tc_root timeInSecsSince2000 0 - set alarm_Limit_LoA $ls336_lowerlimit - set alarm_Limit_LoB $ls336_lowerlimit - set alarm_Limit_LoC $ls336_lowerlimit - set alarm_Limit_LoD $ls336_lowerlimit - set alarm_Limit_HiA $ls336_upperlimit - set alarm_Limit_HiB $ls336_upperlimit - set alarm_Limit_HiC $ls336_upperlimit - set alarm_Limit_HiD $ls336_upperlimit - set checkAlarmLimitsA 1 - set checkAlarmLimitsB 1 - set checkAlarmLimitsC 1 - set checkAlarmLimitsD 1 - - set tc_dfltURL ca5-[instname] - array set moxaPortMap {1 4001 2 4002 3 4003 4 4004} + set_param $tc_root alarm_Limit_LoA [get_param $tc_root ls336_lowerlimit] + set_param $tc_root alarm_Limit_LoB [get_param $tc_root ls336_lowerlimit] + set_param $tc_root alarm_Limit_LoC [get_param $tc_root ls336_lowerlimit] + set_param $tc_root alarm_Limit_LoD [get_param $tc_root ls336_lowerlimit] + set_param $tc_root alarm_Limit_HiA [get_param $tc_root ls336_upperlimit] + set_param $tc_root alarm_Limit_HiB [get_param $tc_root ls336_upperlimit] + set_param $tc_root alarm_Limit_HiC [get_param $tc_root ls336_upperlimit] + set_param $tc_root alarm_Limit_HiD [get_param $tc_root ls336_upperlimit] + set_param $tc_root checkAlarmLimitsA 1 + set_param $tc_root checkAlarmLimitsB 1 + set_param $tc_root checkAlarmLimitsC 1 + set_param $tc_root checkAlarmLimitsD 1 + } ########### Initialisation ############################# @@ -113,8 +130,8 @@ proc ls336_init {sct_controller tc_root} { # Define a constant time offset for later logging of data with timStamp # counting from 1st Jan 2000 00:00hrs # clock command does not work in tcl8.5 ?! - set ::scobj::ls336::timeInSecsSince2000 [clock scan 20000101T000000A] - # set ::scobj::ls336::timeInSecsSince2000 1000 + set_param $tc_root timeInSecsSince2000 [clock scan 20000101T000000A] + # set_param $tc_root timeInSecsSince2000 1000 # set the communication protocol: terminator , bps 9600 baud, 7 data bits + # 1 stop bit + odd parity bit # Query the device ID - are we talking to a Lakeshore 340 or 336? @@ -135,22 +152,22 @@ proc ls336_init {sct_controller tc_root} { # $sct_controller queue $tc_root/other/statusByte progress read # Was the self-test successful? $sct_controller queue $tc_root/other/selftest progress read - set ::scobj::ls336::this_selfTestResult [hval $tc_root/other/selftest] - if {$::scobj::ls336::this_selfTestResult == 0} { + set_param $tc_root this_selfTestResult [hval $tc_root/other/selftest] + if {[get_param $tc_root this_selfTestResult] == 0} { puts "sct_lakeshore336.tcl: Lakeshore 336 self-test ok." } else { puts "sct_lakeshore336.tcl: The Lakeshore 336 failed its self-test." } # Set the default upper and lower temperature alarm limits in Kelvin - foreach iSensor $::scobj::ls336::this_sensorlist { + foreach iSensor [get_param $tc_root this_sensorlist] { hsetprop $tc_root/input/alarm_Limits_$iSensor units "K" hsetprop $tc_root/input/alarm_Limits_$iSensor units "K" } # Set the default heater range (1,..,5) # Set the default settle parameters # Set the default tolerances for the setpoint temperatures - hset $tc_root/control/tolerance1 $::scobj::ls336::ls336_driveTolerance1 - hset $tc_root/control/tolerance2 $::scobj::ls336::ls336_driveTolerance2 + hset $tc_root/control/tolerance1 [get_param $tc_root ls336_driveTolerance1] + hset $tc_root/control/tolerance2 [get_param $tc_root ls336_driveTolerance2] } message ]} { return -code error "in ls336_init: $message" } @@ -177,7 +194,7 @@ proc getValue {tc_root nextState cmd idx} { # we are reading from a pseudo-node where there is no direct representation # in the device # puts "getValue(InpSample)" - #sct send $cmd$::scobj::ls336::ls336_term + #sct send $cmd[get_param $tc_root ls336_term] } elseif { 0 == [string compare -length 7 $cmd "CRVHDR?"] } { # In the case of calCurveHdr we need an extra parameter with the command sent set nodename $tc_root/input/inpCalCurve_$idx @@ -205,7 +222,7 @@ proc getValue {tc_root nextState cmd idx} { # rdValue is the default nextState for getValue() and setValue() # @param idx indicates which control loop or which input channel the command belongs to # @return idle Always returns system state idle - command sequence completed. - proc rdValue {tcroot rdCmd idx} { + proc rdValue {tc_root rdCmd idx} { if {[ catch { set data [sct result] # puts "rdValue(): result is $data" @@ -224,7 +241,7 @@ proc getValue {tc_root nextState cmd idx} { } } if {$idx == "A" || $idx == "B" || $idx == "C" || $idx == "D"} { - set nodename $tcroot/input/calCurveHdr_$idx + set nodename $tc_root/input/calCurveHdr_$idx hset $nodename "noCurve" } } @@ -264,14 +281,14 @@ proc getValue {tc_root nextState cmd idx} { set aT "T" set timeString $ayear$amonth$aday$aT$ahour$amin$asec$aA set timeInSecs [clock scan $timeString] - set timeInSecs [expr {$timeInSecs - $::scobj::ls336::timeInSecsSince2000}] - hset $tcroot/sensor/timStamp $timeInSecs + set timeInSecs [expr {$timeInSecs - [get_param $tc_root timeInSecsSince2000]}] + hset $tc_root/sensor/timStamp $timeInSecs if {1==0} { # if we could write a string value to NXsensor, then this date-time format would be nicer... set sColon ":" set sSpace " " set isoTimeString $ayear$amonth$aday$sSpace$ahour$sColon$amin$sColon$asec - hset $tcroot/sensor/timStamp $isoTimeString + hset $tc_root/sensor/timStamp $isoTimeString } } } @@ -289,7 +306,7 @@ proc getValue {tc_root nextState cmd idx} { # It is preceeded by a call to getValue() and a replacement for rdValue. # @param idx indicates which control loop or which input channel the command belongs to # @return idle Always returns system state idle - command sequence completed. -proc rdAlarmVal {tcroot rdCmd iSensor} { +proc rdAlarmVal {tc_root rdCmd iSensor} { if {[ catch { set data [sct result] switch -glob -- $data { @@ -318,24 +335,24 @@ proc rdAlarmVal {tcroot rdCmd iSensor} { switch $iSensor { "A" { - set ::scobj::ls336::checkAlarmLimitsA $onOff - if {$loVal >= 0} {set ::scobj::ls336::alarm_Limit_LoA $loVal} - if {$hiVal >= 0} {set ::scobj::ls336::alarm_Limit_HiA $hiVal} + set_param $tc_root checkAlarmLimitsA $onOff + if {$loVal >= 0} {set_param $tc_root alarm_Limit_LoA $loVal} + if {$hiVal >= 0} {set_param $tc_root alarm_Limit_HiA $hiVal} } "B" { - set ::scobj::ls336::checkAlarmLimitsB $onOff - if {$loVal >= 0} {set ::scobj::ls336::alarm_Limit_LoB $loVal} - if {$hiVal >= 0} {set ::scobj::ls336::alarm_Limit_HiB $hiVal} + set_param $tc_root checkAlarmLimitsB $onOff + if {$loVal >= 0} {set_param $tc_root alarm_Limit_LoB $loVal} + if {$hiVal >= 0} {set_param $tc_root alarm_Limit_HiB $hiVal} } "C" { - set ::scobj::ls336::checkAlarmLimitsC $onOff - if {$loVal >= 0} {set ::scobj::ls336::alarm_Limit_LoC $loVal} - if {$hiVal >= 0} {set ::scobj::ls336::alarm_Limit_HiC $hiVal} + set_param $tc_root checkAlarmLimitsC $onOff + if {$loVal >= 0} {set_param $tc_root alarm_Limit_LoC $loVal} + if {$hiVal >= 0} {set_param $tc_root alarm_Limit_HiC $hiVal} } "D" { - set ::scobj::ls336::checkAlarmLimitsD $onOff - if {$loVal >= 0} {set ::scobj::ls336::alarm_Limit_LoD $loVal} - if {$hiVal >= 0} {set ::scobj::ls336::alarm_Limit_HiD $hiVal} + set_param $tc_root checkAlarmLimitsD $onOff + if {$loVal >= 0} {set_param $tc_root alarm_Limit_LoD $loVal} + if {$hiVal >= 0} {set_param $tc_root alarm_Limit_HiD $hiVal} } } } @@ -354,7 +371,7 @@ proc rdAlarmVal {tcroot rdCmd iSensor} { # function is called for the CSET* and OUTMODE* commands. # @param idx indicates which control channel the command acts upon # @return idle Always returns system state idle - command sequence completed. - proc rdCfgValue {tcroot rdCmd idx} { + proc rdCfgValue {tc_root rdCmd idx} { if {[ catch { set data [sct result] switch -glob -- $data { @@ -403,15 +420,15 @@ proc rdAlarmVal {tcroot rdCmd iSensor} { append ctrl_Loop_Txt $mode # puts "rdCfgValue() idx: $idx, data: $data, output: $idx, ctrl_Loop_Txt: $ctrl_Loop_Txt" # puts "rdCfgValue setting ls336_input4CtrlLp idx:$idx, input:$input, myInp:$myInp" - set nodename $tcroot/sensor/ctrl_Loop_$idx + set nodename $tc_root/sensor/ctrl_Loop_$idx hset $nodename $ctrl_Loop_Txt # Keep track of which inputs are used for the control loops # puts "rdCfgValue() idx: $idx, data: $data, input:$input, ctrl_Loop_Txt: $ctrl_Loop_Txt" switch $idx { - "1" {hsetprop $tcroot/sensor/ctrl_Loop_1 ls336_input4CtrlLp1 $input} - "2" {hsetprop $tcroot/sensor/ctrl_Loop_2 ls336_input4CtrlLp2 $input} - "3" {hsetprop $tcroot/sensor/ctrl_Loop_3 ls336_input4CtrlLp3 $input} - "4" {hsetprop $tcroot/sensor/ctrl_Loop_4 ls336_input4CtrlLp4 $input} + "1" {hsetprop $tc_root/sensor/ctrl_Loop_1 ls336_input4CtrlLp1 $input} + "2" {hsetprop $tc_root/sensor/ctrl_Loop_2 ls336_input4CtrlLp2 $input} + "3" {hsetprop $tc_root/sensor/ctrl_Loop_3 ls336_input4CtrlLp3 $input} + "4" {hsetprop $tc_root/sensor/ctrl_Loop_4 ls336_input4CtrlLp4 $input} } } } @@ -430,7 +447,7 @@ proc rdAlarmVal {tcroot rdCmd iSensor} { # It is preceeded by a call to getValue() and is a replacement for rdValue(). # @param iSensor indicates which input channel the command belongs to # @return idle Always returns system state idle - command sequence completed. -proc rdBitValue {tcroot rdCmd iSensor} { +proc rdBitValue {tc_root rdCmd iSensor} { if {[ catch { set data [sct result] switch -glob -- $data { @@ -497,7 +514,7 @@ proc rdBitValue {tcroot rdCmd iSensor} { # with the message from RDGST? if the input is invalid. # @param idx indicates which input channel the command acts upon # @return idle Always returns system state idle - command sequence completed. - proc rdInpValue {tcroot rdCmd idx} { + proc rdInpValue {tc_root rdCmd idx} { if {[ catch { set data [sct result] switch -glob -- $data { @@ -510,8 +527,8 @@ proc rdBitValue {tcroot rdCmd iSensor} { # update only once per poll cycle needed # Read the sics node sampleSensor to # determine which input represents the sample temperature - set nodename $tcroot/sensor/sampleSensor - set ::scobj::ls336::ls336_sampleSensor [hval $nodename] + set nodename $tc_root/sensor/sampleSensor + set_param $tc_root ls336_sampleSensor [hval $nodename] } if { $data != [sct oldval] } { sct oldval $data @@ -522,19 +539,19 @@ proc rdBitValue {tcroot rdCmd iSensor} { # RDGST? is 'ok' or 'UNKNOWN' -> it is okay to show the Kelvin reading we have set value $data - if {$idx == $::scobj::ls336::ls336_sampleSensor} { - hset $tcroot/sensor/Tsample $value + if {$idx == [get_param $tc_root ls336_sampleSensor]} { + hset $tc_root/sensor/Tsample $value } # Switch command did not work reliably below, hence a less elegant but # functional if-elseif-else contruct is implemented instead - if {$idx == [hgetpropval $tcroot/sensor/ctrl_Loop_1 ls336_input4CtrlLp1]} { - hset $tcroot/sensor/ctrlLp1_value $value - } elseif {$idx == [hgetpropval $tcroot/sensor/ctrl_Loop_2 ls336_input4CtrlLp2]} { - hset $tcroot/sensor/ctrlLp2_value $value - } elseif {$idx == [hgetpropval $tcroot/sensor/ctrl_Loop_3 ls336_input4CtrlLp3]} { - hset $tcroot/sensor/ctrlLp3_value $value - } elseif {$idx == [hgetpropval $tcroot/sensor/ctrl_Loop_4 ls336_input4CtrlLp4]} { - hset $tcroot/sensor/ctrlLp4_value $value + if {$idx == [hgetpropval $tc_root/sensor/ctrl_Loop_1 ls336_input4CtrlLp1]} { + hset $tc_root/sensor/ctrlLp1_value $value + } elseif {$idx == [hgetpropval $tc_root/sensor/ctrl_Loop_2 ls336_input4CtrlLp2]} { + hset $tc_root/sensor/ctrlLp2_value $value + } elseif {$idx == [hgetpropval $tc_root/sensor/ctrl_Loop_3 ls336_input4CtrlLp3]} { + hset $tc_root/sensor/ctrlLp3_value $value + } elseif {$idx == [hgetpropval $tc_root/sensor/ctrl_Loop_4 ls336_input4CtrlLp4]} { + hset $tc_root/sensor/ctrlLp4_value $value } } } @@ -555,9 +572,9 @@ proc rdBitValue {tcroot rdCmd iSensor} { # for reasoning). # @param CtrlLoopIdx indicates which control loop the command acts upon # @return idle Always returns system state idle - command sequence completed. -proc inTolerance {tcroot rdCmd CtrlLoopIdx} { +proc inTolerance {tc_root rdCmd CtrlLoopIdx} { if {[ catch { - set tc_root $tcroot + set tc_root $tc_root set data [sct result] set oldvalue [sct oldval] switch -glob -- $data { @@ -616,10 +633,10 @@ proc inTolerance {tcroot rdCmd CtrlLoopIdx} { set nodename $tc_root/sensor/sensorValue$iSensor set temp [hval $nodename] set diff [expr {abs($setpt - $temp)}] - # $::scobj::ls336::ls336_driveTolerance = 0.2 Kelvin - set tol $::scobj::ls336::ls336_driveTolerance1 + # [get_param $tc_root ls336_driveTolerance] = 0.2 Kelvin + set tol [get_param $tc_root ls336_driveTolerance1] if {$CtrlLoopIdx == 2} { - set tol $::scobj::ls336::ls336_driveTolerance2 + set tol [get_param $tc_root ls336_driveTolerance2] } # if $diff > $tol if {$intol==0} { @@ -627,10 +644,10 @@ proc inTolerance {tcroot rdCmd CtrlLoopIdx} { hset $nodename "drive" if {$CtrlLoopIdx == 1} { hset $tc_root/status "busy" - if {$::scobj::ls336::ls336_verbose==1} {puts "hset $nodename drive; hset $tc_root/status busy"} + if {[get_param $tc_root ls336_verbose]==1} {puts "hset $nodename drive; hset $tc_root/status busy"} } else { hset $tc_root/status_Ctrl_Lp2 "busy" - if {$::scobj::ls336::ls336_verbose==1} {puts "hset $nodename drive; hset $tc_root/status_Ctrl_Lp2 busy"} + if {[get_param $tc_root ls336_verbose]==1} {puts "hset $nodename drive; hset $tc_root/status_Ctrl_Lp2 busy"} } } else { set nodename $tc_root/sensor/setpoint$CtrlLoopIdx @@ -639,10 +656,10 @@ proc inTolerance {tcroot rdCmd CtrlLoopIdx} { hset $nodename "monitor" if {$CtrlLoopIdx == 1} { hset $tc_root/status "idle" - if {$::scobj::ls336::ls336_verbose==1} {puts "hset $nodename idle; hset $tc_root/status monitor"} + if {[get_param $tc_root ls336_verbose]==1} {puts "hset $nodename idle; hset $tc_root/status monitor"} } else { hset $tc_root/status_Ctrl_Lp2 "idle" - if {$::scobj::ls336::ls336_verbose==1} {puts "hset $nodename idle; hset $tc_root/status_Ctrl_Lp2 monitor"} + if {[get_param $tc_root ls336_verbose]==1} {puts "hset $nodename idle; hset $tc_root/status_Ctrl_Lp2 monitor"} } } } @@ -666,7 +683,7 @@ proc inTolerance {tcroot rdCmd CtrlLoopIdx} { # @brief rdCalValue()) does what rdValue() does plus it resets the value /input/calCurveHdr_$idx forcing that node to refresh # @param idx indicates which control loop or which input channel the command belongs to # @return idle Always returns system state idle - command sequence completed. -proc rdCrvValue {tcroot rdCmd idx} { +proc rdCrvValue {tc_root rdCmd idx} { if {[ catch { set data [sct result] switch -glob -- $data { @@ -681,7 +698,7 @@ proc rdCrvValue {tcroot rdCmd idx} { sct utime readtime # The calibration curve has changed. # Set the curve header name to unknown, thus forcing the respective node to refresh - set tc_root $tcroot + set tc_root $tc_root set nodename $tc_root/input/calCurveHdr_$idx hset $nodename "request refresh" #puts "hset $nodename request refresh" @@ -771,7 +788,7 @@ proc setPoint {tc_root nextState cmd whichCtrlLoop} { if {[ catch { #puts "executing setPoint ($tc_root $nextState $cmd $whichCtrlLoop)" #broadcast setPoint "executing setPoint ($tc_root $nextState $cmd $whichCtrlLoop)" - set ns ::scobj::lh45 + set ns "[namespace current]" set par [sct target] # determine the corresponding input sensor @@ -916,13 +933,13 @@ proc sendCmd {tc_root nextState cmd {idx ""}} { # @brief determines which input sensor corresponds to this control loop or output # @param CtrlLoopIdx the control loop (valid values 1,2) or output (1,2,3,4) # @return iSensor returns A,B,C or D or None or Unknown -proc getCorrespondingInputSensor {tcroot CtrlLoopIdx} { +proc getCorrespondingInputSensor {tc_root CtrlLoopIdx} { # LS 336, device command outMode_* if {$CtrlLoopIdx < 1 || $CtrlLoopIdx > 4} { set iSensor "UNKOWN" return $iSensor } - set nodename $tcroot/control/outMode_$CtrlLoopIdx + set nodename $tc_root/control/outMode_$CtrlLoopIdx set data [hval $nodename] set input [::scobj::ls336::getValFromString $data 1 ","] switch -glob -- $input { @@ -963,28 +980,28 @@ proc checktol {tc_root currtime timecheck iLoop iSensor} { } set lotemp [expr {$setpt - $tol}] set hitemp [expr {$setpt + $tol}] - if {$::scobj::ls336::ls336_verbose==1} { + if {[get_param $tc_root ls336_verbose]==1} { puts "checktol(): setpt $isetp=$setpt lotemp=$lotemp, current $sensorValue=$temp, hitemp=$hitemp, tol=$tol, iLoop=$iLoop, timecheck=$timecheck, currtime=$currtime" } if { $temp < $lotemp || $temp > $hitemp} { hset $tc_root/emon/isInTolerance_Lp$iLoop "outsideTolerance" - if {$::scobj::ls336::ls336_verbose==1} {puts "hset $tc_root/emon/isInTolerance_Lp$iLoop outsideTolerance"} + if {[get_param $tc_root ls336_verbose]==1} {puts "hset $tc_root/emon/isInTolerance_Lp$iLoop outsideTolerance"} if {$iLoop==1} { sct utime timecheck } if {$iLoop==2} { sct utime timecheck2 } return 0 } else { - set timeout $::scobj::ls336::ls340_settleTime + set timeout [get_param $tc_root ls340_settleTime] set elapsedTime [expr {$currtime - $timecheck}] if {$elapsedTime > $timeout} { hset $tc_root/emon/isInTolerance_Lp$iLoop "inTolerance" - if {$::scobj::ls336::ls336_verbose==1} { + if {[get_param $tc_root ls336_verbose]==1} { puts "hset $tc_root/emon/isInTolerance_Lp$iLoop inTolerance (elapsedTime=$elapsedTime greater than settleTime=$timeout)" } return 1 } else { # Temperature has not been within tolerance for enough time - (overshoots, oscillations,..) hset $tc_root/emon/isInTolerance_Lp$iLoop "outsideTolerance" - if {$::scobj::ls336::ls336_verbose==1} { + if {[get_param $tc_root ls336_verbose]==1} { puts "hset $tc_root/emon/isInTolerance_Lp$iLoop outsideTolerance (elapsedTime=$elapsedTime less than settleTime=$timeout)" } return 0 @@ -1007,29 +1024,29 @@ proc check {tc_root whichCtrlLoop} { # determine the corresponding input sensor set whichSensor [getCorrespondingInputSensor $tc_root $whichCtrlLoop] # puts "check(): whichCtrlLoop=$whichCtrlLoop whichSensor= $whichSensor" - set lolimit $::scobj::ls336::alarm_Limit_LoA - set hilimit $::scobj::ls336::alarm_Limit_HiA - set bCheckLimits $::scobj::ls336::checkAlarmLimitsA + set lolimit [get_param $tc_root alarm_Limit_LoA] + set hilimit [get_param $tc_root alarm_Limit_HiA] + set bCheckLimits [get_param $tc_root checkAlarmLimitsA] switch $whichSensor { "A" { - set lolimit $::scobj::ls336::alarm_Limit_LoA - set hilimit $::scobj::ls336::alarm_Limit_HiA - set bCheckLimits $::scobj::ls336::checkAlarmLimitsA + set lolimit [get_param $tc_root alarm_Limit_LoA] + set hilimit [get_param $tc_root alarm_Limit_HiA] + set bCheckLimits [get_param $tc_root checkAlarmLimitsA] } "B" { - set lolimit $::scobj::ls336::alarm_Limit_LoB - set hilimit $::scobj::ls336::alarm_Limit_HiB - set bCheckLimits $::scobj::ls336::checkAlarmLimitsB + set lolimit [get_param $tc_root alarm_Limit_LoB] + set hilimit [get_param $tc_root alarm_Limit_HiB] + set bCheckLimits [get_param $tc_root checkAlarmLimitsB] } "C" { - set lolimit $::scobj::ls336::alarm_Limit_LoC - set hilimit $::scobj::ls336::alarm_Limit_HiC - set bCheckLimits $::scobj::ls336::checkAlarmLimitsC + set lolimit [get_param $tc_root alarm_Limit_LoC] + set hilimit [get_param $tc_root alarm_Limit_HiC] + set bCheckLimits [get_param $tc_root checkAlarmLimitsC] } "D" { - set lolimit $::scobj::ls336::alarm_Limit_LoD - set hilimit $::scobj::ls336::alarm_Limit_HiD - set bCheckLimits $::scobj::ls336::checkAlarmLimitsD + set lolimit [get_param $tc_root alarm_Limit_LoD] + set hilimit [get_param $tc_root alarm_Limit_HiD] + set bCheckLimits [get_param $tc_root checkAlarmLimitsD] } default { error "sct_ls336.tcl check(): Can't set setpoint. No valid input sensor specified for this output control loop." @@ -1508,7 +1525,7 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable p #puts "createing node for: $scobj_hpath $cmdGroup $varName $readable $writable $pollEnabled $drivable $idx $dataType $permission $rdCmd $rdFunc $wrCmd $wrFunc" # It is a command that is supported by the device if {[ catch { - set ns ::scobj::ls336 + set ns "[namespace current]" set nodeName "$scobj_hpath/$cmdGroup/$varName" if {1 > [string length $cmdGroup]} { set nodeName "$scobj_hpath/$varName" @@ -1564,23 +1581,27 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable p # @return nothing (well, the sct object) proc mk_sct_lakeshore_336 {sct_controller klasse tempobj tol1 tol2 verbose} { if {[ catch { - set ::scobj::ls336::ls336_driveTolerance1 $tol1 - set ::scobj::ls336::ls336_driveTolerance2 $tol2 - set ::scobj::ls336::ls336_verbose $verbose - set ns ::scobj::ls336 - - # terminator string for serial communication (empty for ls340, taken care of with the COMM command) - #set CR "\r" - #set LF "\n" - #Wombat uses only CR not CRLF - #set ::scobj::ls336::ls336_term "" ! obsolete - MakeSICSObj $tempobj SCT_OBJECT sicslist setatt $tempobj klass $klasse sicslist setatt $tempobj long_name $tempobj # Create a base node for all the state machines of this sics object set scobj_hpath /sics/$tempobj + # Initialise the per-instance "global" parameters + hfactory $scobj_hpath/params plain spy none + init_params $scobj_hpath + set_param $scobj_hpath ls336_driveTolerance1 $tol1 + set_param $scobj_hpath ls336_driveTolerance2 $tol2 + set_param $scobj_hpath ls336_verbose $verbose + + set ns "[namespace current]" + + # terminator string for serial communication (empty for ls340, taken care of with the COMM command) + #set CR "\r" + #set LF "\n" + #Wombat uses only CR not CRLF + #set_param $scobj_hpath ls336_term "" ! obsolete + # Create state machines for the following device commands (non-polled entries are place-holders # for manually maintained nodes, like the selector for the input that provides the sample temperature # 'sampleSensor', the sample tempreature reading 'Tsample', the input that provides for the controlLoop @@ -1712,10 +1733,10 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable p # helpNotes4user $scobj_hpath $cmdGroup $varName } - hsetprop $scobj_hpath/input/alarm_Limits_A units $::scobj::ls336::ls336_tempUnits - hsetprop $scobj_hpath/input/alarm_Limits_B units $::scobj::ls336::ls336_tempUnits - hsetprop $scobj_hpath/input/alarm_Limits_C units $::scobj::ls336::ls336_tempUnits - hsetprop $scobj_hpath/input/alarm_Limits_D units $::scobj::ls336::ls336_tempUnits + hsetprop $scobj_hpath/input/alarm_Limits_A units [get_param $scobj_hpath ls336_tempUnits] + hsetprop $scobj_hpath/input/alarm_Limits_B units [get_param $scobj_hpath ls336_tempUnits] + hsetprop $scobj_hpath/input/alarm_Limits_C units [get_param $scobj_hpath ls336_tempUnits] + hsetprop $scobj_hpath/input/alarm_Limits_D units [get_param $scobj_hpath ls336_tempUnits] # Create state machines for the following required nodes that do not correspond # to device commands. So far we only provide one tolerance for both control loops. @@ -1725,22 +1746,22 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable p helpNotes4user $scobj_hpath "control" "apply_tolerance" hfactory $scobj_hpath/control/tolerance1 plain user float - hsetprop $scobj_hpath/control/tolerance1 units $::scobj::ls336::ls336_tempUnits + hsetprop $scobj_hpath/control/tolerance1 units [get_param $scobj_hpath ls336_tempUnits] # hsetprop $scobj_hpath/control/tolerance units "K" hset $scobj_hpath/control/tolerance1 $tol1 helpNotes4user $scobj_hpath "control" "tolerance1" hfactory $scobj_hpath/control/tolerance2 plain user float - hsetprop $scobj_hpath/control/tolerance2 units $::scobj::ls336::ls336_tempUnits + hsetprop $scobj_hpath/control/tolerance2 units [get_param $scobj_hpath ls336_tempUnits] hset $scobj_hpath/control/tolerance2 $tol2 helpNotes4user $scobj_hpath "control" "tolerance2" # hfactory $scobj_hpath/lowerlimit plain mugger float - # hsetprop $scobj_hpath/lowerlimit units $::scobj::ls336::ls336_tempUnits - # hset $scobj_hpath/lowerlimit $::scobj::ls336::ls336_lowerlimit + # hsetprop $scobj_hpath/lowerlimit units [get_param $scobj_hpath ls336_tempUnits] + # hset $scobj_hpath/lowerlimit [get_param $scobj_hpath ls336_lowerlimit] # hfactory $scobj_hpath/upperlimit plain mugger float - # hsetprop $scobj_hpath/upperlimit units $::scobj::ls336::ls336_tempUnits - # hset $scobj_hpath/upperlimit $::scobj::ls336::ls336_upperlimit + # hsetprop $scobj_hpath/upperlimit units [get_param $scobj_hpath ls336_tempUnits] + # hset $scobj_hpath/upperlimit [get_param $scobj_hpath ls336_upperlimit] # environment monitoring flags: shows if setpoints of loop 1 and 2 are in tolerance hfactory $scobj_hpath/emon/monMode_Lp1 plain user text