First Working Version against "SCPI" protocol Mercury

r3733 | dcl | 2012-09-11 11:40:48 +1000 (Tue, 11 Sep 2012) | 1 line
This commit is contained in:
Douglas Clowes
2012-09-11 11:40:48 +10:00
parent 81605a11a1
commit 62d894b9e7

View File

@@ -100,20 +100,25 @@ namespace eval ::scobj::[set vendor]_[set device] {
return "[join [lrange [split $node '/'] 0 end-1] '/']"
}
proc setValue {tc_root nextState cmd} {
proc setPoint {tc_root nextState cmd} {
# send a command to set a value
debug_log 1 "setValue tc_root=$tc_root sct=[sct] $cmd [sct target]"
debug_log 1 "setPoint tc_root=$tc_root sct=[sct] $cmd [sct target]"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set par [sct target]
if { "$cmd" == "XXXX" } {
set command "$cmd $par;$cmd?"
} else {
set command "$cmd $par"
}
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
}
@@ -175,6 +180,57 @@ namespace eval ::scobj::[set vendor]_[set device] {
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
@@ -415,96 +471,94 @@ namespace eval ::scobj::[set vendor]_[set device] {
return "$nextState"
}
proc loadCurve_XXX {fname} {
sct print "loading curve [sct target] into [sct]"
set lines [list]
if {[file exists "[sct target]"] && [file readable "[sct target]"]} {
sct print "opening [file normalize "[sct target]"]"
set f [open "[sct target]"]
while {1} {
set line [gets $f]
if {[eof $f]} {
close $f
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
}
# TODO - parse lines and build database
}
close $f
}
}
proc loadCurve_34A {fname} {
sct print "loading curve [sct target] into [sct]"
set profile_index 0
set lines [list]
if {[file exists "[sct target]"] && [file readable "[sct target]"]} {
sct print "opening [file normalize "[sct target]"]"
set f [open "[sct target]"]
while {1} {
set line [gets $f]
if {[eof $f]} {
#close $f
} else {
if {[string toupper "$par"] == [string toupper "$value"]} {
#sct print "Success $par matches $value"
set target "$par"
break
}
if { [string equal -nocase -length 5 "$line" "Name:"] } {
sct profile_name "[string range "$line" 6 end]"
} elseif { [string equal -nocase -length 14 "$line" "Serial number:"] } {
sct profile_number "[string range "$line" 15 end]"
} elseif { [string equal -nocase -length 7 "$line" "Format:"] } {
sct profile_format [lindex [split "$line"] 1]
} elseif { [string equal -nocase -length 6 "$line" "Limit:"] } {
sct profile_limit [lindex [split "$line"] 1]
} elseif { [string equal -nocase -length 12 "$line" "Coefficient:"] } {
sct profile_coeff [lindex [split "$line"] 1]
} elseif { [string equal -nocase -length 6 "$line" "Point "] } {
set rslt [scan "$line" "Point %d: %f,%f" idx r t]
if { $rslt != 3 } {
debug_log 1 "Profile error ($rslt) for: $line"
} else {
incr profile_index 1
sct profile_line_[format "%03d" $profile_index] "[list $idx $r $t]"
debug_log 1 "Profile line $profile_index: [sct profile_line_[format "%03d" $profile_index]]"
}
}
if {"$target" == ""} {
#sct print "Failure $par no matches in $values"
return -code error "Invalid value: \"$par\""
}
} else {
debug_log 1 "Profile error unknown for: $line"
}
}
close $f
set target "$par"
}
return $target
}
proc ldCurve { tc_root nextState cmd } {
if { ! [hpropexists [sct] index] } {
sct index 0
##
# @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
}
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
if { "[sct index]" <= 0 } {
[ns]::loadCurve_34A "[sct target]"
# TODO send curve header
debug_log 1 "Curve header: "
sct index [expr {[sct index] + 1}]
return write
} else {
# write curve to device
if { [hpropexists [sct] profile_line_[format "%03d" [sct index]]] } {
set profile_line [sct profile_line_[format "%03d" [sct index]]]
debug_log 1 "Profile line $profile_line"
sct time_check [clock seconds]
}
return "$nextState"
}
return "$nextState"
}
proc ackCurve {tc_root} {
sct index [expr {[sct index] + 1}]
if { [hpropexists [sct] profile_line_[format "%03d" [sct index]]] } {
return "write"
}
sct index 0
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]
@@ -660,55 +714,42 @@ namespace eval ::scobj::[set vendor]_[set device] {
set scobj_hpath /sics/$the_name
hfactory $scobj_hpath/Loop1 plain spy none
hfactory $scobj_hpath/Heater plain spy none
hfactory $scobj_hpath/Chan1 plain spy none
hfactory $scobj_hpath/Curve1 plain spy none
hfactory $scobj_hpath/Analog1 plain spy none
hfactory $scobj_hpath/Analog2 plain spy none
hfactory $scobj_hpath/Sensor 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 {\
Sensor value 1 0 0 float user {RDGK?} {rdValue} {} {} {}\
{} setpoint 1 1 0 float user {SETP?} {rdValue} {SETP} {setValue} {}\
{} device_state 1 0 0 text user {NULL} {getState.rdState} {} {} {}\
{} alarm_reset 0 1 0 text user {} {} {ALMRST} {setValue} {}\
{} device_reset 0 1 0 text user {} {} {*RST} {setValue} {}\
{} mnmx_reset 0 1 0 text user {} {} {MNMXRST} {setValue} {}\
{} Tree 0 1 0 text user {} {} {} {wrTree} {}\
Loop1 ramp 1 1 0 text user {RAMP?} {rdValue} {RAMP} {setValue} {}\
Loop1 ramp_enable 0 0 0 float user {} {} {} {} {}\
Loop1 ramp_rate 0 0 0 float user {} {} {} {} {}\
Loop1 setpoint 1 1 0 float user {SETP?} {rdValue} {SETP} {setValue} {}\
Loop1 cset 1 1 0 text user {CSET?} {rdValue} {CSET} {setValue} {}\
Loop1 sensor_channel 0 0 0 int user {} {} {} {} {}\
Loop1 filter_enable 0 0 0 int user {} {} {} {} {}\
Loop1 units 0 0 0 int user {} {} {} {} {}\
Loop1 delay 0 0 0 int user {} {} {} {} {}\
Loop1 current_or_power 0 0 0 int user {} {} {} {} {}\
Loop1 htr_limit 0 0 0 int user {} {} {} {} {}\
Loop1 htr_resistance 0 0 0 float user {} {} {} {} {}\
Analog1 analog 1 1 0 text user {ANALOG?} {rdValue} {ANALOG} {setValue} {}\
Analog1 aout 1 0 0 float user {AOUT?} {rdValue} {} {} {}\
Analog2 analog 1 1 0 text user {ANALOG?} {rdValue} {ANALOG} {setValue} {}\
Analog2 aout 1 0 0 float user {AOUT?} {rdValue} {} {} {}\
Heater htr 1 0 0 float user {HTR?} {rdValue} {} {} {}\
Heater htrrng 1 1 0 int user {HTRRNG?} {rdValue} {HTRRNG} {setValue} {}\
Heater htrst 1 0 0 int user {HTRST?} {rdValue} {} {} {}\
Chan1 alarm 1 1 0 text user {ALARM?} {rdValue} {ALARM} {setValue} {}\
Chan1 alarmst 1 0 0 text user {ALARMST?} {rdValue} {} {} {}\
Chan1 filter 1 1 0 text user {FILTER?} {rdValue} {FILTER} {setValue} {}\
Chan1 inset 1 1 0 text user {INSET?} {rdValue} {INSET} {setValue} {}\
Chan1 ldat 1 0 0 float user {LDAT?} {rdValue} {} {} {}\
Chan1 linear 1 1 0 text user {LINEAR?} {rdValue} {LINEAR} {setValue} {}\
Chan1 mdat 1 0 0 text user {MDAT?} {rdValue} {} {} {}\
Chan1 mnmx 1 1 0 text user {MNMX?} {rdValue} {MNMX} {setValue} {}\
Chan1 rdgk 1 0 0 float user {RDGK?} {rdValue} {} {} {}\
Chan1 rdgpwr 1 0 0 float user {RDGPWR?} {rdValue} {} {} {}\
Chan1 rdgr 1 0 0 float user {RDGR?} {rdValue} {} {} {}\
Chan1 rdgrng 1 1 0 text user {RDGRNG?} {rdValue} {RDGRNG} {setValue} {}\
Chan1 rdgst 1 0 0 int user {RDGST?} {rdValue} {} {} {}\
Curve1 header 1 0 0 text user {CRVHDR?} {rdValue} {} {} {}\
Curve1 profile 0 1 0 text user {} {} {XX} {ldCurve.ackCurve} {}\
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\
@@ -726,9 +767,90 @@ namespace eval ::scobj::[set vendor]_[set device] {
$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"
}
if {[SplitReply [environment_simulation]]=="false"} {
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"
@@ -738,6 +860,8 @@ namespace eval ::scobj::[set vendor]_[set device] {
proc add_[set vendor]_[set device] {the_name IP port {_tol 5.0}} {
set [ns]::log_file "/tmp/[set [ns]::ven_dev]_[set the_name].log"
set fd [open [ns]::log_file "w"]
close $fd
debug_log 1 "add_[set [ns]::vendor]_[set [ns]::device] ${the_name} ${IP} ${port} ${_tol}"
puts "Namespace: [namespace current]"
puts "::vendor $::vendor"