Merge branch 'RELEASE-3_1'

Conflicts:
	sics/site_ansto/instrument/config/environment/hiden_xcs_sct.tcl
	sics/site_ansto/instrument/config/environment/temperature/sct_lakeshore_m370.tcl
	sics/site_ansto/instrument/hipd/wombat_configuration.tcl
	sics/site_ansto/instrument/kookaburra/kookaburra_configuration.tcl
	sics/site_ansto/instrument/pelican/pelican_configuration.tcl
	sics/site_ansto/instrument/reflectometer/platypus_configuration.tcl
	sics/site_ansto/instrument/util/gen_sct.py
This commit is contained in:
Douglas Clowes
2014-11-06 14:13:20 +11:00
52 changed files with 4133 additions and 3116 deletions

View File

@ -0,0 +1,106 @@
# 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;
group polariser = {
var spin = {
type = text;
readable = 900;
read_command = 'polariser';
read_function = rdValue;
writeable = 1;
write_command = 'polariser';
check_function = chkWrite;
allowed = "+,-,0"
}
var Amplitude = { type = text; }
var Freq = { type = text; units = 'Hertz'; }
var Phase = { type = text; units = 'Degree'; }
var Time2 = { type = text; units = 'Second'; }
var Field = { type = text; units = 'Oersted'; }
}
group analyser = {
var spin = {
type = text;
readable = 900;
read_command = 'analyser';
read_function = rdValue;
writeable = 1;
write_command = 'analyser';
check_function = chkWrite;
allowed = "+,-,0"
}
var Amplitude = { type = text; }
var Freq = { type = text; units = 'Hertz'; }
var Phase = { type = text; units = 'Degree'; }
var Time2 = { type = text; units = 'Second'; }
var Field = { type = text; units = 'Oersted'; }
}
code chkWrite = {%%
[namespace current]::rdValue ${tc_root}
%%}
code rdValue = {%%
set dlist [split [string trim ${data}]]
if {[llength ${dlist}] < 2} {
sct geterror "Syntax Error: '${data}'"
error "[sct geterror]"
}
set my_name [basename [pathname [sct]]]
if {![string equal -nocase "[lindex ${dlist} 0]" "${my_name}"]} {
error "[lindex ${dlist} 0] is not my name (${my_name})"
}
if {[string match "*Not Active*" "${data}"]} {
set data 0
} elseif {[string match -nocase "*Error:*" "${data}"]} {
sct geterror "${data}"
error "[sct geterror]"
} else {
set data [lindex ${dlist} 1]
}
set path [pathname [sct]]
if {[llength ${dlist}] > 2} {
set new_value [lindex ${dlist} 2]
if { "${new_value}" == "NaN" } {
set new_value 0
}
hupdateif ${path}/Amplitude "${new_value}"
}
if {[llength ${dlist}] > 3} {
hupdateif ${path}/Freq "[lindex ${dlist} 3]"
}
if {[llength ${dlist}] > 4} {
hupdateif ${path}/Phase "[lindex ${dlist} 4]"
}
if {[llength ${dlist}] > 5} {
hupdateif ${path}/Time2 "[lindex ${dlist} 5]"
}
if {[llength ${dlist}] > 6} {
hupdateif ${path}/Field "[lindex ${dlist} 6]"
}
%%}
code setValue = {%%
set cmd "${cmd_str}"
if {[string equal -nocase [sct target] "refresh"]} {
set cmd "${cmd_str}"
}
if {[string equal -nocase [sct target] "dn"]} {
set cmd "${cmd_str} -"
}
if {[string equal -nocase [sct target] "down"]} {
set cmd "${cmd_str} -"
}
if {[sct target] == "-" || [sct target] == -1} {
set cmd "${cmd_str} -"
}
if {[string equal -nocase [sct target] "up"]} {
set cmd "${cmd_str} +"
}
if {[sct target] == "+" || [sct target] == 1} {
set cmd "${cmd_str} +"
}
%%}
}

View File

@ -0,0 +1,517 @@
# Generated driver for he3_polanal
# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent
#
namespace eval ::scobj::he3_polanal {
set debug_threshold 0
}
proc ::scobj::he3_polanal::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 fd [open "../log/he3_polanal_[basename ${tc_root}].log" "a"]
set line "[clock format [clock seconds] -format "%T"] ${debug_string}"
puts ${fd} "${line}"
close ${fd}
}
} catch_message ]
}
proc ::scobj::he3_polanal::sics_log {debug_level debug_string} {
set catch_status [ catch {
set debug_threshold ${::scobj::he3_polanal::debug_threshold}
if {${debug_level} >= ${debug_threshold}} {
sicslog "::scobj::he3_polanal::${debug_string}"
}
} catch_message ]
}
# check function for hset change
proc ::scobj::he3_polanal::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 check the write parameter on a device
proc ::scobj::he3_polanal::chkWrite {tc_root} {
set catch_status [ catch {
debug_log ${tc_root} 1 "chkWrite tc_root=${tc_root} sct=[sct] resp=[sct result]"
# chkWrite hook code starts
[namespace current]::rdValue ${tc_root}
# chkWrite hook code ends
return "idle"
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to request the read of a parameter on a device
proc ::scobj::he3_polanal::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::he3_polanal::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}
}
# function to parse the read of a parameter on a device
proc ::scobj::he3_polanal::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 starts
set dlist [split [string trim ${data}]]
if {[llength ${dlist}] < 2} {
sct geterror "Syntax Error: '${data}'"
error "[sct geterror]"
}
set my_name [basename [pathname [sct]]]
if {![string equal -nocase "[lindex ${dlist} 0]" "${my_name}"]} {
error "[lindex ${dlist} 0] is not my name (${my_name})"
}
if {[string match "*Not Active*" "${data}"]} {
set data 0
} elseif {[string match -nocase "*Error:*" "${data}"]} {
sct geterror "${data}"
error "[sct geterror]"
} else {
set data [lindex ${dlist} 1]
}
set path [pathname [sct]]
if {[llength ${dlist}] > 2} {
set new_value [lindex ${dlist} 2]
if { "${new_value}" == "NaN" } {
set new_value 0
}
hupdateif ${path}/Amplitude "${new_value}"
}
if {[llength ${dlist}] > 3} {
hupdateif ${path}/Freq "[lindex ${dlist} 3]"
}
if {[llength ${dlist}] > 4} {
hupdateif ${path}/Phase "[lindex ${dlist} 4]"
}
if {[llength ${dlist}] > 5} {
hupdateif ${path}/Time2 "[lindex ${dlist} 5]"
}
if {[llength ${dlist}] > 6} {
hupdateif ${path}/Field "[lindex ${dlist} 6]"
}
# rdValue 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::he3_polanal::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 starts
set cmd "${cmd_str}"
if {[string equal -nocase [sct target] "refresh"]} {
set cmd "${cmd_str}"
}
if {[string equal -nocase [sct target] "dn"]} {
set cmd "${cmd_str} -"
}
if {[string equal -nocase [sct target] "down"]} {
set cmd "${cmd_str} -"
}
if {[sct target] == "-" || [sct target] == -1} {
set cmd "${cmd_str} -"
}
if {[string equal -nocase [sct target] "up"]} {
set cmd "${cmd_str} +"
}
if {[sct target] == "+" || [sct target] == 1} {
set cmd "${cmd_str} +"
}
# setValue 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 "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}
}
proc ::scobj::he3_polanal::mkDriver { sct_controller name device_class simulation_flag ip_address tcp_port } {
::scobj::he3_polanal::sics_log 9 "::scobj::he3_polanal::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}/analyser plain spy none
hsetprop ${scobj_hpath}/analyser data "true"
hsetprop ${scobj_hpath}/analyser klass "@none"
hsetprop ${scobj_hpath}/analyser type "part"
hfactory ${scobj_hpath}/analyser/Amplitude plain user text
hsetprop ${scobj_hpath}/analyser/Amplitude control true
hsetprop ${scobj_hpath}/analyser/Amplitude data true
hsetprop ${scobj_hpath}/analyser/Amplitude mutable true
hsetprop ${scobj_hpath}/analyser/Amplitude nxsave true
hsetprop ${scobj_hpath}/analyser/Amplitude oldval UNKNOWN
hsetprop ${scobj_hpath}/analyser/Amplitude klass "parameter"
hsetprop ${scobj_hpath}/analyser/Amplitude sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/analyser/Amplitude type "part"
hsetprop ${scobj_hpath}/analyser/Amplitude nxalias "${name}_analyser_Amplitude"
hfactory ${scobj_hpath}/analyser/Field plain user text
hsetprop ${scobj_hpath}/analyser/Field control true
hsetprop ${scobj_hpath}/analyser/Field data true
hsetprop ${scobj_hpath}/analyser/Field mutable true
hsetprop ${scobj_hpath}/analyser/Field nxsave true
hsetprop ${scobj_hpath}/analyser/Field units Oersted
hsetprop ${scobj_hpath}/analyser/Field oldval UNKNOWN
hsetprop ${scobj_hpath}/analyser/Field klass "parameter"
hsetprop ${scobj_hpath}/analyser/Field sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/analyser/Field type "part"
hsetprop ${scobj_hpath}/analyser/Field nxalias "${name}_analyser_Field"
hfactory ${scobj_hpath}/analyser/Freq plain user text
hsetprop ${scobj_hpath}/analyser/Freq control true
hsetprop ${scobj_hpath}/analyser/Freq data true
hsetprop ${scobj_hpath}/analyser/Freq mutable true
hsetprop ${scobj_hpath}/analyser/Freq nxsave true
hsetprop ${scobj_hpath}/analyser/Freq units Hertz
hsetprop ${scobj_hpath}/analyser/Freq oldval UNKNOWN
hsetprop ${scobj_hpath}/analyser/Freq klass "parameter"
hsetprop ${scobj_hpath}/analyser/Freq sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/analyser/Freq type "part"
hsetprop ${scobj_hpath}/analyser/Freq nxalias "${name}_analyser_Freq"
hfactory ${scobj_hpath}/analyser/Phase plain user text
hsetprop ${scobj_hpath}/analyser/Phase control true
hsetprop ${scobj_hpath}/analyser/Phase data true
hsetprop ${scobj_hpath}/analyser/Phase mutable true
hsetprop ${scobj_hpath}/analyser/Phase nxsave true
hsetprop ${scobj_hpath}/analyser/Phase units Degree
hsetprop ${scobj_hpath}/analyser/Phase oldval UNKNOWN
hsetprop ${scobj_hpath}/analyser/Phase klass "parameter"
hsetprop ${scobj_hpath}/analyser/Phase sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/analyser/Phase type "part"
hsetprop ${scobj_hpath}/analyser/Phase nxalias "${name}_analyser_Phase"
hfactory ${scobj_hpath}/analyser/Time2 plain user text
hsetprop ${scobj_hpath}/analyser/Time2 control true
hsetprop ${scobj_hpath}/analyser/Time2 data true
hsetprop ${scobj_hpath}/analyser/Time2 mutable true
hsetprop ${scobj_hpath}/analyser/Time2 nxsave true
hsetprop ${scobj_hpath}/analyser/Time2 units Second
hsetprop ${scobj_hpath}/analyser/Time2 oldval UNKNOWN
hsetprop ${scobj_hpath}/analyser/Time2 klass "parameter"
hsetprop ${scobj_hpath}/analyser/Time2 sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/analyser/Time2 type "part"
hsetprop ${scobj_hpath}/analyser/Time2 nxalias "${name}_analyser_Time2"
hfactory ${scobj_hpath}/analyser/spin plain user text
hsetprop ${scobj_hpath}/analyser/spin read ${ns}::getValue ${scobj_hpath} rdValue {analyser}
hsetprop ${scobj_hpath}/analyser/spin rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/analyser/spin write ${ns}::setValue ${scobj_hpath} chkWrite {analyser}
hsetprop ${scobj_hpath}/analyser/spin chkWrite ${ns}::chkWrite ${scobj_hpath}
hsetprop ${scobj_hpath}/analyser/spin check ${ns}::checkrange ${scobj_hpath}
hsetprop ${scobj_hpath}/analyser/spin control true
hsetprop ${scobj_hpath}/analyser/spin data true
hsetprop ${scobj_hpath}/analyser/spin mutable true
hsetprop ${scobj_hpath}/analyser/spin nxsave true
hsetprop ${scobj_hpath}/analyser/spin values +,-,0
hsetprop ${scobj_hpath}/analyser/spin oldval UNKNOWN
hsetprop ${scobj_hpath}/analyser/spin klass "parameter"
hsetprop ${scobj_hpath}/analyser/spin sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/analyser/spin type "part"
hsetprop ${scobj_hpath}/analyser/spin nxalias "${name}_analyser_spin"
if {[string equal -nocase "${simulation_flag}" "false"]} {
${sct_controller} poll ${scobj_hpath}/analyser/spin 900
${sct_controller} write ${scobj_hpath}/analyser/spin
} else {
::scobj::he3_polanal::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for he3_polanal"
}
hfactory ${scobj_hpath}/polariser plain spy none
hsetprop ${scobj_hpath}/polariser data "true"
hsetprop ${scobj_hpath}/polariser klass "@none"
hsetprop ${scobj_hpath}/polariser type "part"
hfactory ${scobj_hpath}/polariser/Amplitude plain user text
hsetprop ${scobj_hpath}/polariser/Amplitude control true
hsetprop ${scobj_hpath}/polariser/Amplitude data true
hsetprop ${scobj_hpath}/polariser/Amplitude mutable true
hsetprop ${scobj_hpath}/polariser/Amplitude nxsave true
hsetprop ${scobj_hpath}/polariser/Amplitude oldval UNKNOWN
hsetprop ${scobj_hpath}/polariser/Amplitude klass "parameter"
hsetprop ${scobj_hpath}/polariser/Amplitude sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/polariser/Amplitude type "part"
hsetprop ${scobj_hpath}/polariser/Amplitude nxalias "${name}_polariser_Amplitude"
hfactory ${scobj_hpath}/polariser/Field plain user text
hsetprop ${scobj_hpath}/polariser/Field control true
hsetprop ${scobj_hpath}/polariser/Field data true
hsetprop ${scobj_hpath}/polariser/Field mutable true
hsetprop ${scobj_hpath}/polariser/Field nxsave true
hsetprop ${scobj_hpath}/polariser/Field units Oersted
hsetprop ${scobj_hpath}/polariser/Field oldval UNKNOWN
hsetprop ${scobj_hpath}/polariser/Field klass "parameter"
hsetprop ${scobj_hpath}/polariser/Field sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/polariser/Field type "part"
hsetprop ${scobj_hpath}/polariser/Field nxalias "${name}_polariser_Field"
hfactory ${scobj_hpath}/polariser/Freq plain user text
hsetprop ${scobj_hpath}/polariser/Freq control true
hsetprop ${scobj_hpath}/polariser/Freq data true
hsetprop ${scobj_hpath}/polariser/Freq mutable true
hsetprop ${scobj_hpath}/polariser/Freq nxsave true
hsetprop ${scobj_hpath}/polariser/Freq units Hertz
hsetprop ${scobj_hpath}/polariser/Freq oldval UNKNOWN
hsetprop ${scobj_hpath}/polariser/Freq klass "parameter"
hsetprop ${scobj_hpath}/polariser/Freq sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/polariser/Freq type "part"
hsetprop ${scobj_hpath}/polariser/Freq nxalias "${name}_polariser_Freq"
hfactory ${scobj_hpath}/polariser/Phase plain user text
hsetprop ${scobj_hpath}/polariser/Phase control true
hsetprop ${scobj_hpath}/polariser/Phase data true
hsetprop ${scobj_hpath}/polariser/Phase mutable true
hsetprop ${scobj_hpath}/polariser/Phase nxsave true
hsetprop ${scobj_hpath}/polariser/Phase units Degree
hsetprop ${scobj_hpath}/polariser/Phase oldval UNKNOWN
hsetprop ${scobj_hpath}/polariser/Phase klass "parameter"
hsetprop ${scobj_hpath}/polariser/Phase sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/polariser/Phase type "part"
hsetprop ${scobj_hpath}/polariser/Phase nxalias "${name}_polariser_Phase"
hfactory ${scobj_hpath}/polariser/Time2 plain user text
hsetprop ${scobj_hpath}/polariser/Time2 control true
hsetprop ${scobj_hpath}/polariser/Time2 data true
hsetprop ${scobj_hpath}/polariser/Time2 mutable true
hsetprop ${scobj_hpath}/polariser/Time2 nxsave true
hsetprop ${scobj_hpath}/polariser/Time2 units Second
hsetprop ${scobj_hpath}/polariser/Time2 oldval UNKNOWN
hsetprop ${scobj_hpath}/polariser/Time2 klass "parameter"
hsetprop ${scobj_hpath}/polariser/Time2 sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/polariser/Time2 type "part"
hsetprop ${scobj_hpath}/polariser/Time2 nxalias "${name}_polariser_Time2"
hfactory ${scobj_hpath}/polariser/spin plain user text
hsetprop ${scobj_hpath}/polariser/spin read ${ns}::getValue ${scobj_hpath} rdValue {polariser}
hsetprop ${scobj_hpath}/polariser/spin rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/polariser/spin write ${ns}::setValue ${scobj_hpath} chkWrite {polariser}
hsetprop ${scobj_hpath}/polariser/spin chkWrite ${ns}::chkWrite ${scobj_hpath}
hsetprop ${scobj_hpath}/polariser/spin check ${ns}::checkrange ${scobj_hpath}
hsetprop ${scobj_hpath}/polariser/spin control true
hsetprop ${scobj_hpath}/polariser/spin data true
hsetprop ${scobj_hpath}/polariser/spin mutable true
hsetprop ${scobj_hpath}/polariser/spin nxsave true
hsetprop ${scobj_hpath}/polariser/spin values +,-,0
hsetprop ${scobj_hpath}/polariser/spin oldval UNKNOWN
hsetprop ${scobj_hpath}/polariser/spin klass "parameter"
hsetprop ${scobj_hpath}/polariser/spin sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/polariser/spin type "part"
hsetprop ${scobj_hpath}/polariser/spin nxalias "${name}_polariser_spin"
if {[string equal -nocase "${simulation_flag}" "false"]} {
${sct_controller} poll ${scobj_hpath}/polariser/spin 900
${sct_controller} write ${scobj_hpath}/polariser/spin
} else {
::scobj::he3_polanal::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for he3_polanal"
}
hsetprop ${scobj_hpath} klass ${device_class}
hsetprop ${scobj_hpath} data true
hsetprop ${scobj_hpath} debug_threshold 0
# mkDriver hook code goes here
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
proc ::scobj::he3_polanal::add_driver {name device_class simulation_flag ip_address tcp_port} {
set catch_status [ catch {
::scobj::he3_polanal::sics_log 9 "::scobj::he3_polanal::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::he3_polanal::sics_log 9 "makesctcontroller sct_${name} aqadapter ${tcp_port}"
makesctcontroller sct_${name} aqadapter ${tcp_port}
} else {
::scobj::he3_polanal::sics_log 9 "makesctcontroller sct_${name} std ${ip_address}:${tcp_port}"
makesctcontroller sct_${name} std ${ip_address}:${tcp_port}
}
} else {
::scobj::he3_polanal::sics_log 9 "simulation_flag={simulation_flag} => No sctcontroller for he3_polanal"
}
::scobj::he3_polanal::sics_log 1 "::scobj::he3_polanal::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port}"
::scobj::he3_polanal::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
namespace eval ::scobj::he3_polanal {
namespace export debug_threshold
namespace export debug_log
namespace export sics_log
namespace export mkDriver
namespace export add_driver
}
proc add_he3_polanal {name ip_address tcp_port} {
set simulation_flag "[string tolower [SplitReply [rfgen_simulation]]]"
::scobj::he3_polanal::add_driver ${name} "instrument" "${simulation_flag}" ${ip_address} ${tcp_port}
}
clientput "file evaluation of sct_he3_polanal.tcl"
::scobj::he3_polanal::sics_log 9 "file evaluation of sct_he3_polanal.tcl"
proc ::scobj::he3_polanal::read_config {} {
set catch_status [ catch {
set ns "::scobj::he3_polanal"
dict for {k u} $::config_dict {
if { [dict exists $u "implementation"] } {
set simulation_flag "[string tolower [SplitReply [rfgen_simulation]]]"
set device_class "instrument"
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"] "he3_polanal"] } {
if { ![string equal -nocase "${simulation_flag}" "false"] } {
set asyncqueue "null"
${ns}::sics_log 9 "simulation_flag=${simulation_flag} => using null asyncqueue"
} 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]
}
} else {
if { [dict exists $v "asyncprotocol"] } {
set asyncprotocol [dict get $v "asyncprotocol"]
} else {
set asyncprotocol ${name}_protocol
MakeAsyncProtocol ${asyncprotocol}
if { [dict exists $v "terminator"] } {
${asyncprotocol} sendterminator "[dict get $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"]"
}
}
if { [string equal -nocase ${asyncqueue} "sct"] } {
${ns}::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port}
} else {
${ns}::add_driver ${name} ${device_class} ${simulation_flag} "aqadapter" ${asyncqueue}
}
}
}
}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
if { [info exists ::config_dict] } {
::scobj::he3_polanal::read_config
} else {
::scobj::he3_polanal::sics_log 5 "No config dict"
}

View File

@ -7,7 +7,6 @@ namespace eval counter {
proc ::counter::transferscript {} { proc ::counter::transferscript {} {
variable isc_numchannels variable isc_numchannels
bm status
set val [SplitReply [bm1 gettime]] set val [SplitReply [bm1 gettime]]
for {set i 1} {$i <= $isc_numchannels} {incr i} { for {set i 1} {$i <= $isc_numchannels} {incr i} {
append val " [SplitReply [bm$i getcounts] ]" append val " [SplitReply [bm$i getcounts] ]"

View File

@ -20,6 +20,11 @@ driver hiden_xcs = {
group_property 'nxsave' = 'true' group_property 'nxsave' = 'true'
property 'klass' = 'environment' property 'klass' = 'environment'
property 'sdsinfo' = '::nexus::scobj::sdsinfo' property 'sdsinfo' = '::nexus::scobj::sdsinfo'
var auto = {
type = int;
allowed = '0,1';
value = 0;
}
var enabled = { var enabled = {
permlink = 'G.X02' permlink = 'G.X02'
type = int; type = int;
@ -64,12 +69,15 @@ driver hiden_xcs = {
property pid_error = 0 property pid_error = 0
property pid_deriv = 0 property pid_deriv = 0
property pid_integ = 0 property pid_integ = 0
property pid_pvalue = 0.2 property pid_pvalue = 0.1
property pid_ivalue = 0.1 property pid_ivalue = 0.1
property pid_dvalue = 0.0 property pid_dvalue = 0.0
property pid_imax = 30 property pid_imax = 50
} }
var setpoint = { var setpoint = {
readable = 1;
read_command = '@'
fetch_function = getTarget
permlink = 'G.SP01' permlink = 'G.SP01'
driveable = flow/sensor driveable = flow/sensor
write_function = write_flow write_function = write_flow
@ -96,19 +104,22 @@ driver hiden_xcs = {
property pid_error = 0 property pid_error = 0
property pid_deriv = 0 property pid_deriv = 0
property pid_integ = 0 property pid_integ = 0
property pid_pvalue = 0.2 property pid_pvalue = 1.0
property pid_ivalue = 0.1 property pid_ivalue = 0.10
property pid_dvalue = 0.0 property pid_dvalue = 0.0
property pid_imax = 30 property pid_imax = 20
} }
var setpoint = { var setpoint = {
readable = 1;
read_command = '@'
fetch_function = getTarget
permlink = 'G.SP02' permlink = 'G.SP02'
driveable = humidity/sensor driveable = humidity/sensor
write_function = write_humidity write_function = write_humidity
checkrange_function = chkrange_function checkrange_function = chkrange_function
value = 50 value = 50
lowerlimit = 10 lowerlimit = 0
upperlimit = 90 upperlimit = 100
tolerance = 1 tolerance = 1
} }
} }
@ -140,6 +151,14 @@ driver hiden_xcs = {
# Code lines start with '@' which is stripped before being emitted into generated driver # Code lines start with '@' which is stripped before being emitted into generated driver
# The code is emitted at the appropriate place in the given function # The code is emitted at the appropriate place in the given function
# #
code getTarget = {
@ if { [hpropexists [sct] target] } {
@ sct result [sct target]
@ } else {
@ sct result [hval [sct]]
@ }
@ set cmd "@@NOSEND@@"
}
code read_function read_digital = { code read_function read_digital = {
@ if { [string equal -nocase -length 5 "${data}" "DOUT ="] } { @ if { [string equal -nocase -length 5 "${data}" "DOUT ="] } {
@ set result [scan "${data}" "DOUT = %d OK" val] @ set result [scan "${data}" "DOUT = %d OK" val]
@ -222,6 +241,10 @@ driver hiden_xcs = {
} }
code pid_function pid_humidity = { code pid_function pid_humidity = {
@ if { ![hval ${tc_root}/auto] } {
@ set pid 0.0
@ sct pid_integ 0.0
@ }
@ set sign 1 @ set sign 1
@ foreach node [list ${tc_root}/analog/sp1 ${tc_root}/analog/sp2] { @ foreach node [list ${tc_root}/analog/sp1 ${tc_root}/analog/sp2] {
@ set sign [expr -${sign}] @ set sign [expr -${sign}]
@ -252,6 +275,10 @@ driver hiden_xcs = {
} }
code pid_function pid_flow = { code pid_function pid_flow = {
@ if { ![hval ${tc_root}/auto] } {
@ set pid 0.0
@ sct pid_integ 0.0
@ }
@ foreach node [list ${tc_root}/analog/sp1 ${tc_root}/analog/sp2] { @ foreach node [list ${tc_root}/analog/sp1 ${tc_root}/analog/sp2] {
@ if { !([hpropexists ${node} bias_flow] && [hgetpropval ${node} bias_flow] == ${pid}) } { @ if { !([hpropexists ${node} bias_flow] && [hgetpropval ${node} bias_flow] == ${pid}) } {
@ hsetprop ${node} bias_flow ${pid} @ hsetprop ${node} bias_flow ${pid}
@ -266,6 +293,7 @@ driver hiden_xcs = {
code write_function write_digital = { code write_function write_digital = {
} }
code write_function write_twelve = { code write_function write_twelve = {
@ if { [hpropexists [sct] base] } { @ if { [hpropexists [sct] base] } {
@ set base [sct base] @ set base [sct base]

View File

@ -181,6 +181,35 @@ proc ::scobj::hiden_xcs::fetch_flow {tc_root nextState cmd_str} {
handle_exception ${catch_status} ${catch_message} handle_exception ${catch_status} ${catch_message}
} }
# function to request the read of a parameter on a device
proc ::scobj::hiden_xcs::getTarget {tc_root nextState cmd_str} {
set catch_status [ catch {
debug_log ${tc_root} 1 "getTarget tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set cmd "${cmd_str}"
# getTarget hook code starts
if { [hpropexists [sct] target] } {
sct result [sct target]
} else {
sct result [hval [sct]]
}
set cmd "@@NOSEND@@"
# getTarget hook code ends
if { [hpropexists [sct] geterror] } {
debug_log ${tc_root} 9 "[sct] error: [sct geterror]"
error "[sct geterror]"
}
debug_log ${tc_root} 1 "getTarget 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 # function to request the read of a parameter on a device
proc ::scobj::hiden_xcs::getValue {tc_root nextState cmd_str} { proc ::scobj::hiden_xcs::getValue {tc_root nextState cmd_str} {
set catch_status [ catch { set catch_status [ catch {
@ -269,6 +298,10 @@ proc ::scobj::hiden_xcs::pid_flow {tc_root sp pv} {
set i_value [expr {[sct pid_ivalue] * [sct pid_integ]}] set i_value [expr {[sct pid_ivalue] * [sct pid_integ]}]
set pid [expr {${p_value} + ${i_value} + ${d_value}}] set pid [expr {${p_value} + ${i_value} + ${d_value}}]
# pid_flow hook code starts # pid_flow hook code starts
if { ![hval ${tc_root}/auto] } {
set pid 0.0
sct pid_integ 0.0
}
foreach node [list ${tc_root}/analog/sp1 ${tc_root}/analog/sp2] { foreach node [list ${tc_root}/analog/sp1 ${tc_root}/analog/sp2] {
if { !([hpropexists ${node} bias_flow] && [hgetpropval ${node} bias_flow] == ${pid}) } { if { !([hpropexists ${node} bias_flow] && [hgetpropval ${node} bias_flow] == ${pid}) } {
hsetprop ${node} bias_flow ${pid} hsetprop ${node} bias_flow ${pid}
@ -304,6 +337,10 @@ proc ::scobj::hiden_xcs::pid_humidity {tc_root sp pv} {
set i_value [expr {[sct pid_ivalue] * [sct pid_integ]}] set i_value [expr {[sct pid_ivalue] * [sct pid_integ]}]
set pid [expr {${p_value} + ${i_value} + ${d_value}}] set pid [expr {${p_value} + ${i_value} + ${d_value}}]
# pid_humidity hook code starts # pid_humidity hook code starts
if { ![hval ${tc_root}/auto] } {
set pid 0.0
sct pid_integ 0.0
}
set sign 1 set sign 1
foreach node [list ${tc_root}/analog/sp1 ${tc_root}/analog/sp2] { foreach node [list ${tc_root}/analog/sp1 ${tc_root}/analog/sp2] {
set sign [expr -${sign}] set sign [expr -${sign}]
@ -763,6 +800,20 @@ proc ::scobj::hiden_xcs::mkDriver { sct_controller name device_class simulation_
set scobj_hpath /sics/${name} set scobj_hpath /sics/${name}
# Start of unnamed group # Start of unnamed group
# Start of var: auto
hfactory ${scobj_hpath}/auto plain user int
hsetprop ${scobj_hpath}/auto control true
hsetprop ${scobj_hpath}/auto data true
hsetprop ${scobj_hpath}/auto mutable true
hsetprop ${scobj_hpath}/auto nxsave true
hsetprop ${scobj_hpath}/auto values 0,1
hsetprop ${scobj_hpath}/auto oldval 0
hset ${scobj_hpath}/auto 0
hsetprop ${scobj_hpath}/auto klass "environment"
hsetprop ${scobj_hpath}/auto sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/auto type "part"
hsetprop ${scobj_hpath}/auto nxalias "${name}_auto"
# Start of var: enabled # Start of var: enabled
hfactory ${scobj_hpath}/enabled plain user int hfactory ${scobj_hpath}/enabled plain user int
hsetprop ${scobj_hpath}/enabled read ${ns}::getValue ${scobj_hpath} read_digital {?DOUT,2} hsetprop ${scobj_hpath}/enabled read ${ns}::getValue ${scobj_hpath} read_digital {?DOUT,2}
@ -1103,10 +1154,10 @@ proc ::scobj::hiden_xcs::mkDriver { sct_controller name device_class simulation_
hsetprop ${scobj_hpath}/flow/sensor pid_deriv "0" hsetprop ${scobj_hpath}/flow/sensor pid_deriv "0"
hsetprop ${scobj_hpath}/flow/sensor pid_dvalue "0.0" hsetprop ${scobj_hpath}/flow/sensor pid_dvalue "0.0"
hsetprop ${scobj_hpath}/flow/sensor pid_error "0" hsetprop ${scobj_hpath}/flow/sensor pid_error "0"
hsetprop ${scobj_hpath}/flow/sensor pid_imax "30" hsetprop ${scobj_hpath}/flow/sensor pid_imax "50"
hsetprop ${scobj_hpath}/flow/sensor pid_integ "0" hsetprop ${scobj_hpath}/flow/sensor pid_integ "0"
hsetprop ${scobj_hpath}/flow/sensor pid_ivalue "0.1" hsetprop ${scobj_hpath}/flow/sensor pid_ivalue "0.1"
hsetprop ${scobj_hpath}/flow/sensor pid_pvalue "0.2" hsetprop ${scobj_hpath}/flow/sensor pid_pvalue "0.1"
hsetprop ${scobj_hpath}/flow/sensor sdsinfo "::nexus::scobj::sdsinfo" hsetprop ${scobj_hpath}/flow/sensor sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/flow/sensor type "part" hsetprop ${scobj_hpath}/flow/sensor type "part"
hsetprop ${scobj_hpath}/flow/sensor nxalias "${name}_flow_sensor" hsetprop ${scobj_hpath}/flow/sensor nxalias "${name}_flow_sensor"
@ -1121,6 +1172,8 @@ proc ::scobj::hiden_xcs::mkDriver { sct_controller name device_class simulation_
# Start of var: setpoint # Start of var: setpoint
hfactory ${scobj_hpath}/flow/setpoint plain user float hfactory ${scobj_hpath}/flow/setpoint plain user float
hsetprop ${scobj_hpath}/flow/setpoint read ${ns}::getTarget ${scobj_hpath} rdValue {@}
hsetprop ${scobj_hpath}/flow/setpoint rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/flow/setpoint write ${ns}::write_flow ${scobj_hpath} noResponse {} hsetprop ${scobj_hpath}/flow/setpoint write ${ns}::write_flow ${scobj_hpath} noResponse {}
hsetprop ${scobj_hpath}/flow/setpoint noResponse ${ns}::noResponse ${scobj_hpath} hsetprop ${scobj_hpath}/flow/setpoint noResponse ${ns}::noResponse ${scobj_hpath}
hsetprop ${scobj_hpath}/flow/setpoint check ${ns}::checkrange ${scobj_hpath} hsetprop ${scobj_hpath}/flow/setpoint check ${ns}::checkrange ${scobj_hpath}
@ -1146,6 +1199,7 @@ proc ::scobj::hiden_xcs::mkDriver { sct_controller name device_class simulation_
hsetprop ${scobj_hpath}/flow/setpoint nxalias "${name}_flow_setpoint" hsetprop ${scobj_hpath}/flow/setpoint nxalias "${name}_flow_setpoint"
if {[string equal -nocase "${simulation_flag}" "false"]} { if {[string equal -nocase "${simulation_flag}" "false"]} {
${sct_controller} poll ${scobj_hpath}/flow/setpoint 1
${sct_controller} write ${scobj_hpath}/flow/setpoint ${sct_controller} write ${scobj_hpath}/flow/setpoint
hsetprop ${scobj_hpath}/flow/setpoint simulated false hsetprop ${scobj_hpath}/flow/setpoint simulated false
} else { } else {
@ -1177,10 +1231,10 @@ proc ::scobj::hiden_xcs::mkDriver { sct_controller name device_class simulation_
hsetprop ${scobj_hpath}/humidity/sensor pid_deriv "0" hsetprop ${scobj_hpath}/humidity/sensor pid_deriv "0"
hsetprop ${scobj_hpath}/humidity/sensor pid_dvalue "0.0" hsetprop ${scobj_hpath}/humidity/sensor pid_dvalue "0.0"
hsetprop ${scobj_hpath}/humidity/sensor pid_error "0" hsetprop ${scobj_hpath}/humidity/sensor pid_error "0"
hsetprop ${scobj_hpath}/humidity/sensor pid_imax "30" hsetprop ${scobj_hpath}/humidity/sensor pid_imax "20"
hsetprop ${scobj_hpath}/humidity/sensor pid_integ "0" hsetprop ${scobj_hpath}/humidity/sensor pid_integ "0"
hsetprop ${scobj_hpath}/humidity/sensor pid_ivalue "0.1" hsetprop ${scobj_hpath}/humidity/sensor pid_ivalue "0.1"
hsetprop ${scobj_hpath}/humidity/sensor pid_pvalue "0.2" hsetprop ${scobj_hpath}/humidity/sensor pid_pvalue "1.0"
hsetprop ${scobj_hpath}/humidity/sensor sdsinfo "::nexus::scobj::sdsinfo" hsetprop ${scobj_hpath}/humidity/sensor sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/humidity/sensor type "part" hsetprop ${scobj_hpath}/humidity/sensor type "part"
hsetprop ${scobj_hpath}/humidity/sensor nxalias "${name}_humidity_sensor" hsetprop ${scobj_hpath}/humidity/sensor nxalias "${name}_humidity_sensor"
@ -1195,6 +1249,8 @@ proc ::scobj::hiden_xcs::mkDriver { sct_controller name device_class simulation_
# Start of var: setpoint # Start of var: setpoint
hfactory ${scobj_hpath}/humidity/setpoint plain user float hfactory ${scobj_hpath}/humidity/setpoint plain user float
hsetprop ${scobj_hpath}/humidity/setpoint read ${ns}::getTarget ${scobj_hpath} rdValue {@}
hsetprop ${scobj_hpath}/humidity/setpoint rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/humidity/setpoint write ${ns}::write_humidity ${scobj_hpath} noResponse {} hsetprop ${scobj_hpath}/humidity/setpoint write ${ns}::write_humidity ${scobj_hpath} noResponse {}
hsetprop ${scobj_hpath}/humidity/setpoint noResponse ${ns}::noResponse ${scobj_hpath} hsetprop ${scobj_hpath}/humidity/setpoint noResponse ${ns}::noResponse ${scobj_hpath}
hsetprop ${scobj_hpath}/humidity/setpoint check ${ns}::chkrange_function ${scobj_hpath} hsetprop ${scobj_hpath}/humidity/setpoint check ${ns}::chkrange_function ${scobj_hpath}
@ -1207,8 +1263,8 @@ proc ::scobj::hiden_xcs::mkDriver { sct_controller name device_class simulation_
hsetprop ${scobj_hpath}/humidity/setpoint data true hsetprop ${scobj_hpath}/humidity/setpoint data true
hsetprop ${scobj_hpath}/humidity/setpoint mutable true hsetprop ${scobj_hpath}/humidity/setpoint mutable true
hsetprop ${scobj_hpath}/humidity/setpoint nxsave true hsetprop ${scobj_hpath}/humidity/setpoint nxsave true
hsetprop ${scobj_hpath}/humidity/setpoint lowerlimit 10 hsetprop ${scobj_hpath}/humidity/setpoint lowerlimit 0
hsetprop ${scobj_hpath}/humidity/setpoint upperlimit 90 hsetprop ${scobj_hpath}/humidity/setpoint upperlimit 100
hsetprop ${scobj_hpath}/humidity/setpoint tolerance 1 hsetprop ${scobj_hpath}/humidity/setpoint tolerance 1
hsetprop ${scobj_hpath}/humidity/setpoint permlink data_set "G[format "%02d" ${id}]SP02" hsetprop ${scobj_hpath}/humidity/setpoint permlink data_set "G[format "%02d" ${id}]SP02"
hsetprop ${scobj_hpath}/humidity/setpoint @description "G[format "%02d" ${id}]SP02" hsetprop ${scobj_hpath}/humidity/setpoint @description "G[format "%02d" ${id}]SP02"
@ -1220,6 +1276,7 @@ proc ::scobj::hiden_xcs::mkDriver { sct_controller name device_class simulation_
hsetprop ${scobj_hpath}/humidity/setpoint nxalias "${name}_humidity_setpoint" hsetprop ${scobj_hpath}/humidity/setpoint nxalias "${name}_humidity_setpoint"
if {[string equal -nocase "${simulation_flag}" "false"]} { if {[string equal -nocase "${simulation_flag}" "false"]} {
${sct_controller} poll ${scobj_hpath}/humidity/setpoint 1
${sct_controller} write ${scobj_hpath}/humidity/setpoint ${sct_controller} write ${scobj_hpath}/humidity/setpoint
hsetprop ${scobj_hpath}/humidity/setpoint simulated false hsetprop ${scobj_hpath}/humidity/setpoint simulated false
} else { } else {

View File

@ -1,6 +1,6 @@
# #
# Template driver for the Knauer BlueShadow Pump 40P # Template driver for the Knauer BlueShadow Pump 40P
# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent # vim: ft=tcl ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent
# #
driver knauer_pump = { driver knauer_pump = {
debug_threshold = 0; debug_threshold = 0;
@ -10,7 +10,7 @@ driver knauer_pump = {
# #
group dummy = { group dummy = {
type = text; readable = 1; data = false; control = false; nxsave = false; type = text; readable = 1; data = false; control = false; nxsave = false;
var status = { read_command = 'STATUS?'; read_function = read_status; } var status = { read_command = 'STATUS?'; read_function = read_status; property real_data = ' '; }
var glp = { read_command = 'GLP?'; read_function = read_glp; property real_data = ' '; } var glp = { read_command = 'GLP?'; read_function = read_glp; property real_data = ' '; }
} }
@ -19,6 +19,7 @@ driver knauer_pump = {
type = int; type = int;
readable = 1; read_command = 'REMOTE?'; read_function = remote_read; readable = 1; read_command = 'REMOTE?'; read_function = remote_read;
writeable = 1; write_function = remote_write; writeable = 1; write_function = remote_write;
allowed = '0,1';
} }
var state = { var state = {
type = text; type = text;
@ -32,156 +33,71 @@ driver knauer_pump = {
read_command = ' '; read_command = ' ';
fetch_function = status_fetch; fetch_function = status_fetch;
} }
var volume_pv = { group volume = {
type = float; var pval = {
readable = 1; type = float;
read_command = ' '; readable = 1;
fetch_function = volume_fetch; read_command = ' ';
#checkrange_function = volume_reject; fetch_function = volume_fetch;
property 'units' = 'mL'; read_function = volume_read;
} property 'units' = 'mL';
var volume_sp = { }
type = float; var setp = {
writeable = 1; type = float;
write_command = ' '; writeable = 1;
write_function = volume_write; write_command = ' ';
driveable = pump/volume_pv write_function = volume_write;
check_function = volume_check;
driveable = pump/volume/pval;
checkstatus_function = volume_checkstatus; checkstatus_function = volume_checkstatus;
halt_function = volume_halt; halt_function = volume_halt;
lowerlimit = 0; upperlimit = 100; tolerance = 0.01; lowerlimit = 0; upperlimit = 100; tolerance = 0.01;
readable = 1; readable = 1;
read_command = ' '; read_command = ' ';
fetch_function = volume_checkpumping; fetch_function = volume_fsm;
property 'units' = 'mL'; read_function = volume_store;
property 'units' = 'mL';
property this_state = 0;
}
} }
var ratio_pv = { group ratio = {
type = text; var pval = {
readable = 1; read_command = ' '; fetch_function = ratios_fetch; type = text;
property 'units' = 'percent'; readable = 1; read_command = ' '; fetch_function = ratio_fetch;
property 'units' = 'percent';
}
var setp = {
type = text;
value = '25/25/25/25';
writeable = 1; write_command = ' '; write_function = ratio_write; checkrange_function = ratio_check;
property 'units' = 'percent';
}
} }
var ratio_sp = { group flow = {
type = text; var pval = {
writeable = 1; write_command = ' '; write_function = ratios_write; checkrange_function = ratios_check; type = float;
property 'units' = 'percent'; readable = 1; read_command = ' '; fetch_function = flow_fetch;
} property 'units' = 'mL/min';
var flow_pv = { }
type = float; var setp = {
readable = 1; read_command = ' '; fetch_function = flow_fetch; type = float;
property 'units' = 'mL/min'; value = 1.0;
} writeable = 1; write_command = ' '; write_function = flow_write;
var flow_sp = { lowerlimit = 0; upperlimit = 9.999;
type = float; property 'units' = 'mL/min';
writeable = 1; write_command = ' '; write_function = flow_write; }
lowerlimit = 0; upperlimit = 10;
property 'units' = 'mL/min';
} }
} }
group stuff = { #
readable = 60; # Ensure the pump starts up in REMOTE mode
type = text; #
data = false; control = false; nxsave = false; code mkDriver = {%%
var an_out = { read_command = 'AN_OUT?'; } #hset ${scobj_hpath}/pump/remote 1
var boardinfo = { read_command = 'BOARDINFO?'; }
var config = { read_command = 'CONFIG?'; }
var cprofinfo = { read_command = 'CPROFINFO?'; }
var dout = { read_command = 'DOUT?'; }
var error = { read_command = 'ERROR?'; }
var errors = { read_command = 'ERRORS?'; }
var flushpmp = { read_command = 'FLUSHPMP?'; }
var head = { read_command = 'HEAD?'; }
var head_par = { read_command = 'HEAD_PAR?'; }
var identify = { read_command = 'IDENTIFY?'; }
var lpg = { read_command = 'LPG?'; }
var oem = { read_command = 'OEM?'; }
var opt = { read_command = 'OPT?'; }
var plim = { read_command = 'PLIM?'; }
var pressure = { read_command = 'PRESSURE?'; }
var prfastacq = { read_command = 'PRFASTACQ?'; }
var purge = { read_command = 'PURGE?'; }
var remote = { read_command = 'REMOTE?'; }
var rfid = { read_command = 'RFID?'; }
var service = { read_command = 'SERVICE?'; }
var sysinfo = { read_command = 'SYSINFO?'; }
var 'units' = { read_command = 'UNITS?'; }
var valves = { read_command = 'VALVES?'; }
}
group prog = {
readable = 30;
type = text;
var line_01 = { read_command = "TT_GET:1,1"; }
var line_02 = { read_command = "TT_GET:1,2"; }
var line_03 = { read_command = "TT_GET:1,3"; }
var line_04 = { read_command = "TT_GET:1,4"; }
var line_05 = { read_command = "TT_GET:1,5"; }
}
group glp = {
type = text;
readable = 1;
fetch_function = fetch_from_glp;
var board_time = { read_command = '0'; }
var motor_time = { read_command = '1'; }
var head_count = { read_command = '3'; }
var head_time = { read_command = '4'; }
var head_volm = { read_command = '5'; }
var head_voln = { read_command = '6'; }
var head_pwrhi = { read_command = '7'; }
var head_pwrlo = { read_command = '8'; }
var pump_revs = { read_command = '9'; }
var pump_volm = { read_command = '10'; }
var pump_voln = { read_command = '11'; }
var pump_pwrhi = { read_command = '12'; }
var pump_pwrlo = { read_command = '13'; }
}
group status = {
type = text;
readable = 1;
fetch_function = fetch_from_status;
var state = { read_command = '1'; }
var cur_error = { read_command = '2'; }
var cur_run_time = { read_command = '3'; }
var flow_rate = { read_command = '4'; }
var lpg_0 = { read_command = '5'; }
var lpg_1 = { read_command = '6'; }
var lpg_2 = { read_command = '7'; }
var lpg_3 = { read_command = '8'; }
var evt_0 = { read_command = '9'; }
var evt_1 = { read_command = '10'; }
var evt_2 = { read_command = '11'; }
var evt_3 = { read_command = '12'; }
var evt_4 = { read_command = '13'; }
var evt_5 = { read_command = '14'; }
var evt_6 = { read_command = '15'; }
var evt_7 = { read_command = '16'; }
var cur_pres = { read_command = '17'; }
var start_in = { read_command = '18'; }
var error_in = { read_command = '19'; }
}
code fetch_from_glp = {%%
set index ${cmd_str}
set data [hgetpropval ${tc_root}/dummy/glp real_data]
set dlist [split ${data} ","]
if { [llength ${dlist}] > ${index} } {
sct result [lindex ${dlist} ${index}]
} else {
sct result ""
}
set cmd "@@NOSEND@@"
%%} %%}
#
code fetch_from_status = {%% # These functions handle the real_data returned by the pump for the GLP? command
set index ${cmd_str} #
set data [hgetpropval ${tc_root}/dummy/status real_data]
set dlist [split ${data} ","]
if { [llength ${dlist}] > ${index} } {
sct result [lindex ${dlist} ${index}]
} else {
sct result ""
}
set cmd "@@NOSEND@@"
%%}
code read_glp = {%% code read_glp = {%%
if { [string equal -nocase -length 6 ${data} "ERROR:"] } { if { [string equal -nocase -length 6 ${data} "ERROR:"] } {
} else { } else {
@ -190,11 +106,19 @@ driver knauer_pump = {
set data "Hidden in real_data property" set data "Hidden in real_data property"
} }
%%} %%}
#
# These functions handle the real_data returned by the pump for the STATUS? command
#
code read_status = {%% code read_status = {%%
set dlist [split [lindex [split ${data} ":"] 1] ","] set dlist [split [lindex [split ${data} ":"] 1] ","]
sct real_data "[join [lrange ${dlist} 0 end] ,]" sct real_data "[join [lrange ${dlist} 0 end] ,]"
set data "Hidden in real_data property" set data "Hidden in real_data property"
%%} %%}
#
# Decode the status from the real_data to PUMPING if it is pumping else IDLE
#
code status_fetch = {%% code status_fetch = {%%
set index 1 set index 1
set data [hgetpropval ${tc_root}/dummy/status real_data] set data [hgetpropval ${tc_root}/dummy/status real_data]
@ -207,11 +131,19 @@ driver knauer_pump = {
sct result "IDLE" sct result "IDLE"
} }
%%} %%}
#
# Decode the state from the real_data to one of the documented strings
#
code state_fetch = {%% code state_fetch = {%%
set index 1 set index 1
set data [hgetpropval ${tc_root}/dummy/status real_data] set data [hgetpropval ${tc_root}/dummy/status real_data]
set dlist [split ${data} ","] set dlist [split ${data} ","]
set state_code [lindex ${dlist} ${index}] if { [llength ${dlist}] > ${index} } {
set state_code [lindex ${dlist} ${index}]
} else {
set state_code "0"
}
set cmd "@@NOSEND@@" set cmd "@@NOSEND@@"
if { ${state_code} < 0 || ${state_code} > 9 } { if { ${state_code} < 0 || ${state_code} > 9 } {
sct geterror "Invalid device_state ${state_code}" sct geterror "Invalid device_state ${state_code}"
@ -224,22 +156,24 @@ driver knauer_pump = {
"SYS_ST_HOLD" \ "SYS_ST_HOLD" \
"SYS_ST_PURGE" \ "SYS_ST_PURGE" \
"SYS_ST_STANDBY" \ "SYS_ST_STANDBY" \
"SYS_ST_SEVEN" \
"SYS_ST_FAILED" \ "SYS_ST_FAILED" \
"SYS_ST_RUNATEND" \ "SYS_ST_RUNATEND" \
] ]
sct result [lindex ${slist} ${state_code}] sct result [lindex ${slist} ${state_code}]
%%} %%}
code halt = {%% #
set rlist [hval ${tc_root}/pump/ratio_sp] #
set ratio_tgt [join [split ${rlist} /] ,]
set cmd "RAMP:0,0,${ratio_tgt},0,0,0,0,0,0,0,0,2"
%%}
code flow_fetch = {%% code flow_fetch = {%%
set index 4
set data [hgetpropval ${tc_root}/dummy/status real_data] set data [hgetpropval ${tc_root}/dummy/status real_data]
set dlist [split ${data} ","] set dlist [split ${data} ","]
set flow_pv [lindex ${dlist} 4] if { [llength ${dlist}] > ${index} } {
set flow_pv [lindex ${dlist} 4]
} else {
set flow_pv 0.0
}
sct result [expr {0.001 * ${flow_pv}}] sct result [expr {0.001 * ${flow_pv}}]
set cmd "@@NOSEND@@" set cmd "@@NOSEND@@"
%%} %%}
@ -255,27 +189,41 @@ driver knauer_pump = {
} }
%%} %%}
code ratios_check = {%% #
#
code ratio_check = {%%
set rlist [split ${setpoint} /] set rlist [split ${setpoint} /]
if { [llength ${rlist}] != 4 } { if { [llength ${rlist}] != 4 } {
sct geterror "${setpoint} has [llength ${rlist}] components, needs 4" sct geterror "${setpoint} has [llength ${rlist}] components, needs 4"
error [sct geterror] error [sct geterror]
} }
set sum [expr [lindex ${rlist} 0] + [lindex ${rlist} 1] + [lindex ${rlist} 2] + [lindex ${rlist} 3]] 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 } { if { ${sum} != 100 } {
sct geterror "sum is ${sum}, must be 100" sct geterror "sum of components is ${sum}, must be 100"
error [sct geterror] error [sct geterror]
} }
%%} %%}
code ratios_fetch = {%% code ratio_fetch = {%%
set data [hgetpropval ${tc_root}/dummy/status real_data] set data [hgetpropval ${tc_root}/dummy/status real_data]
set dlist [split ${data} ","] set dlist [split ${data} ","]
set ratio_vals "[lindex ${dlist} 5]/[lindex ${dlist} 6]/[lindex ${dlist} 7]/[lindex ${dlist} 8]" set ratio_vals "[lindex ${dlist} 5]/[lindex ${dlist} 6]/[lindex ${dlist} 7]/[lindex ${dlist} 8]"
sct result ${ratio_vals} sct result ${ratio_vals}
set cmd "@@NOSEND@@" set cmd "@@NOSEND@@"
%%} %%}
code ratios_write = {%% code ratio_write = {%%
set data [sct target] set data [sct target]
set cmd "@@NOSEND@@" set cmd "@@NOSEND@@"
set nextState idle set nextState idle
@ -287,6 +235,8 @@ driver knauer_pump = {
} }
%%} %%}
#
#
code remote_read = {%% code remote_read = {%%
if { [string equal -length 7 ${data} "REMOTE:"] } { if { [string equal -length 7 ${data} "REMOTE:"] } {
set data [lindex [split ${data} :] 1] set data [lindex [split ${data} :] 1]
@ -303,6 +253,9 @@ driver knauer_pump = {
set cmd "REMOTE" set cmd "REMOTE"
} }
%%} %%}
#
#
code volume_fetch = {%% code volume_fetch = {%%
set data [hgetpropval ${tc_root}/dummy/glp real_data] set data [hgetpropval ${tc_root}/dummy/glp real_data]
set dlist [split ${data} ","] set dlist [split ${data} ","]
@ -322,12 +275,11 @@ driver knauer_pump = {
sct result [format "%.2f" ${pump_volume}] sct result [format "%.2f" ${pump_volume}]
set cmd "@@NOSEND@@" set cmd "@@NOSEND@@"
%%} %%}
code volume_write = {%% code volume_write = {%%
hsetprop ${tc_root}/[sct driveable] base_volume [hgetpropval ${tc_root}/[sct driveable] raw_volume]
hset ${tc_root}/[sct driveable] 0.0 hset ${tc_root}/[sct driveable] 0.0
set flow_tgt [expr {int(1000.0 * [hval ${tc_root}/pump/flow_sp])}] set cmd "REMOTE"
set ratio_tgt [join [split [hval ${tc_root}/pump/ratio_sp] /] ,] sct this_state 1
set cmd "RAMP:0,${flow_tgt},${ratio_tgt},0,0,0,0,0,0,0,0,3"
sct pumping 1 sct pumping 1
set data ${par} set data ${par}
if { ${data} != [sct oldval] } { if { ${data} != [sct oldval] } {
@ -338,35 +290,97 @@ driver knauer_pump = {
} }
%%} %%}
code volume_checkpumping = {%% code volume_fsm = {%%
set cmd "@@NOSEND@@" if { [sct this_state] > 0 } {
set nextState idle set flow_tgt [expr {int(1000.0 * [hval ${tc_root}/pump/flow/setp])}]
if { [hpropexists [sct] pumping] && [sct pumping] } { set ratio_tgt [join [split [hval ${tc_root}/pump/ratio/setp] /] ,]
if { [hpropexists [sct] driving] && [sct driving] } { set time_tgt [expr {int(60000.0 * 1000.0 * [sct target] / ${flow_tgt})}]
volume_checkstatus "${tc_root}" 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
} }
set sp "[sct target]" } else {
set pv "[hval ${tc_root}/[sct driveable]]" set cmd "@@NOSEND@@"
if { (${sp} - ${pv}) <= [sct tolerance] } { set nextState idle
set flow_tgt 0 if { [hpropexists [sct] pumping] && [sct pumping] } {
set ratio_tgt [join [split [hval ${tc_root}/pump/ratio_sp] /] ,] set new_value [hval ${tc_root}/pump/status]
set cmd "RAMP:0,${flow_tgt},${ratio_tgt},0,0,0,0,0,0,0,0,2" set old_value [sct oldval]
set nextState noResponse if {${new_value} != ${old_value}} {
sct driving 0 sct oldval ${new_value}
sct pumping 0 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
}
}
} }
} }
%%} %%}
code volume_store = {%%
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
}
%%}
code volume_halt = {%% code volume_halt = {%%
set flow_tgt 0 set cmd "STOP:0,0"
set ratio_tgt [join [split [hval ${tc_root}/pump/ratio_sp] /] ,] sct this_state 91
set cmd "RAMP:0,${flow_tgt},${ratio_tgt},0,0,0,0,0,0,0,0,2" debug_log ${tc_root} 1 "volume_halt sct send ${cmd}"
sct send ${cmd} sct send ${cmd}
%%} %%}
code volume_reject = {%%
sct geterror "cannot use hset on [sct]"
error "[sct geterror]"
%%}
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent
driver bruker = {
protocol = astvelsel
class = environment
simulation_group = environment_simulation
add_args = 'id datype {tol 0.1}'
make_args = 'id datype tol'
code mkWrapper = {%%
add_bruker_BEC1 $name $ip_address $tcp_port $tol
%%}
}

View File

@ -0,0 +1,167 @@
# Generated driver for bruker
# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent
#
namespace eval ::scobj::bruker {
set debug_threshold 5
}
proc ::scobj::bruker::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 fd [open "../log/bruker_[basename ${tc_root}].log" "a"]
set line "[clock format [clock seconds] -format "%T"] ${debug_string}"
puts ${fd} "${line}"
close ${fd}
}
} catch_message ]
}
proc ::scobj::bruker::sics_log {debug_level debug_string} {
set catch_status [ catch {
set debug_threshold ${::scobj::bruker::debug_threshold}
if {${debug_level} >= ${debug_threshold}} {
sicslog "::scobj::bruker::${debug_string}"
}
} catch_message ]
}
proc ::scobj::bruker::mkDriver { sct_controller name device_class simulation_flag ip_address tcp_port id datype tol } {
::scobj::bruker::sics_log 9 "::scobj::bruker::mkDriver ${sct_controller} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${datype} ${tol}"
set ns "[namespace current]"
set catch_status [ catch {
# mkWrapper hook code starts
add_bruker_BEC1 $name $ip_address $tcp_port $tol
# mkWrapper hook code ends
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
proc ::scobj::bruker::add_driver {name device_class simulation_flag ip_address tcp_port id datype {tol 0.1}} {
set catch_status [ catch {
::scobj::bruker::sics_log 9 "::scobj::bruker::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${datype} ${tol}"
if {[string equal -nocase "${simulation_flag}" "false"]} {
if {[string equal -nocase "aqadapter" "${ip_address}"]} {
::scobj::bruker::sics_log 9 "makesctcontroller sct_${name} aqadapter ${tcp_port}"
makesctcontroller sct_${name} aqadapter ${tcp_port}
} else {
::scobj::bruker::sics_log 9 "makesctcontroller sct_${name} astvelsel ${ip_address}:${tcp_port}"
makesctcontroller sct_${name} astvelsel ${ip_address}:${tcp_port}
}
} else {
::scobj::bruker::sics_log 9 "simulation_flag={simulation_flag} => No sctcontroller for bruker"
}
::scobj::bruker::sics_log 1 "::scobj::bruker::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${datype} ${tol}"
::scobj::bruker::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${datype} ${tol}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
namespace eval ::scobj::bruker {
namespace export debug_threshold
namespace export debug_log
namespace export sics_log
namespace export mkDriver
namespace export add_driver
}
proc add_bruker {name ip_address tcp_port id datype {tol 0.1}} {
set simulation_flag "[string tolower [SplitReply [environment_simulation]]]"
::scobj::bruker::add_driver ${name} "environment" "${simulation_flag}" ${ip_address} ${tcp_port} "${id}" "${datype}" "${{tol}" "${0.1}}"
}
clientput "file evaluation of sct_bruker.tcl"
::scobj::bruker::sics_log 9 "file evaluation of sct_bruker.tcl"
proc ::scobj::bruker::read_config {} {
set catch_status [ catch {
set ns "::scobj::bruker"
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"] "bruker"] } {
if { ![string equal -nocase "${simulation_flag}" "false"] } {
set asyncqueue "null"
${ns}::sics_log 9 "simulation_flag=${simulation_flag} => using null asyncqueue"
} 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]
}
} else {
if { [dict exists $v "asyncprotocol"] } {
set asyncprotocol [dict get $v "asyncprotocol"]
} else {
set asyncprotocol ${name}_protocol
MakeAsyncProtocol ${asyncprotocol}
if { [dict exists $v "terminator"] } {
${asyncprotocol} sendterminator "[dict get $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"]"
}
}
set arg_list [list]
set missing_list [list]
foreach arg {id datype tol} {
if {[dict exists $u $arg]} {
lappend arg_list "[dict get $u $arg]"
} elseif {[dict exists $v $arg]} {
lappend arg_list "[dict get $v $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"
}
if { [string equal -nocase ${asyncqueue} "sct"] } {
${ns}::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} {*}$arg_list
} else {
${ns}::add_driver ${name} ${device_class} ${simulation_flag} "aqadapter" ${asyncqueue} {*}$arg_list
}
}
}
}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
if { [info exists ::config_dict] } {
::scobj::bruker::read_config
} else {
::scobj::bruker::sics_log 5 "No config dict"
}

View File

@ -1366,88 +1366,5 @@ proc add_bruker_bec1 {name IP port {_tol 0.1} {CID 1} {CTYPE B} } {
handle_exception $catch_status $message "In subroutine add_bruker_bec1()." handle_exception $catch_status $message "In subroutine add_bruker_bec1()."
} }
namespace eval ::scobj::bruker_bec1 {
set debug_threshold 5
}
proc ::scobj::bruker_bec1::sics_log {debug_level debug_string} {
set catch_status [ catch {
set debug_threshold ${::scobj::bruker_bec1::debug_threshold}
if {${debug_level} >= ${debug_threshold}} {
sicslog "::scobj::bruker_bec1::${debug_string}"
}
} catch_message ]
}
clientput "file evaluation of sct_bruker_bec1.tcl" clientput "file evaluation of sct_bruker_bec1.tcl"
::scobj::bruker_bec1::sics_log 9 "file evaluation of sct_bruker_bec1.tcl"
proc ::scobj::bruker_bec1::read_config {} {
set catch_status [ catch {
set ns "::scobj::bruker_bec1"
dict for {k v} $::config_dict {
if { [dict exists $v "implementation"] } {
if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } {
continue
}
set name [dict get $v name]
set enabled [string tolower [dict get $v "enabled"]]
set implementation [dict get $v "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"] "bruker_bec1"] } {
if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } {
if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } {
set asyncqueue "null"
${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue"
} elseif { [dict exists $v "asyncqueue"] } {
set asyncqueue [dict get $v "asyncqueue"]
} else {
if { [dict exists $v "asyncprotocol"] } {
set asyncprotocol [dict get $v "asyncprotocol"]
} else {
set asyncprotocol ${name}_protocol
MakeAsyncProtocol ${asyncprotocol}
if { [dict exists $v "terminator"] } {
${asyncprotocol} sendterminator "[dict get $v "terminator"]"
${asyncprotocol} replyterminator "[dict get $v "terminator"]"
}
}
set asyncqueue ${name}_queue
set IP [dict get $v ip]
set PORT [dict get $v port]
MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT}
if { [dict exists $v "timeout"] } {
${asyncqueue} timeout "[dict get $v "timeout"]"
}
}
set arg_list [list]
foreach arg {tol id type} {
if {[dict exists $v $arg]} {
lappend arg_list "[dict get $v $arg]"
} else {
${ns}::sics_log 9 "Missing configuration value $arg"
error "Missing configuration value $arg"
}
}
add_bruker_bec1 ${name} "aqadapter" ${asyncqueue} {*}$arg_list
}
}
}
}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
if { [info exists ::config_dict] } {
::scobj::bruker_bec1::read_config
} else {
::scobj::bruker_bec1::sics_log 5 "No config dict"
}
namespace import ::scobj::bruker_BEC1::* namespace import ::scobj::bruker_BEC1::*

View File

@ -0,0 +1,12 @@
# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent
driver mvp_valve = {
protocol = hamilton
wrapper_property nosctcontroller = True
class = environment
simulation_group = environment_simulation
add_args = 'id datype'
make_args = 'id datype'
code mkWrapper = {%%
add_mvp $name $ip_address $tcp_port a
%%}
}

File diff suppressed because it is too large Load Diff

View File

@ -455,7 +455,7 @@ debug_log "Registering node $nodeName for write callback"
hsetprop $scobj_hpath device "$dev" hsetprop $scobj_hpath device "$dev"
set deviceCommand {\ set deviceCommand {\
Display Position 1 0 1 1 0 text internal {LQP} {rdValue} {} {} {}\ Display Position 1 0 1 1 0 int internal {LQP} {rdValue} {} {} {}\
Display Angle 1 0 1 1 0 text internal {LQA} {rdValue} {} {} {}\ Display Angle 1 0 1 1 0 text internal {LQA} {rdValue} {} {} {}\
Display Hertz 1 0 1 1 0 text internal {LQF} {rdValue} {} {} {}\ Display Hertz 1 0 1 1 0 text internal {LQF} {rdValue} {} {} {}\
Display Finished 1 0 1 1 0 text internal {F} {rdValue} {} {} {}\ Display Finished 1 0 1 1 0 text internal {F} {rdValue} {} {} {}\
@ -465,7 +465,7 @@ debug_log "Registering node $nodeName for write callback"
Display Device 1 0 1 1 0 text internal {E3} {rdValue} {} {} {}\ Display Device 1 0 1 1 0 text internal {E3} {rdValue} {} {} {}\
Display Encoder 1 0 1 1 0 text internal {E4} {rdValue} {} {} {}\ Display Encoder 1 0 1 1 0 text internal {E4} {rdValue} {} {} {}\
Control Direction 0 1 1 1 0 text user {} {} {} {setDirn} {}\ Control Direction 0 1 1 1 0 text user {} {} {} {setDirn} {}\
Control SetPoint 0 1 1 1 1 text user {} {} {} {setPoint} {}\ Control SetPoint 0 1 1 1 1 int user {} {} {} {setPoint} {}\
Control Command 0 1 1 1 0 text user {} {} {} {setCmnd.chkWrite} {}\ Control Command 0 1 1 1 0 text user {} {} {} {setCmnd.chkWrite} {}\
} }

View File

@ -0,0 +1,157 @@
# Generated driver for mvp_valve
# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent
#
namespace eval ::scobj::mvp_valve {
set debug_threshold 5
}
proc ::scobj::mvp_valve::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 fd [open "../log/mvp_valve_[basename ${tc_root}].log" "a"]
set line "[clock format [clock seconds] -format "%T"] ${debug_string}"
puts ${fd} "${line}"
close ${fd}
}
} catch_message ]
}
proc ::scobj::mvp_valve::sics_log {debug_level debug_string} {
set catch_status [ catch {
set debug_threshold ${::scobj::mvp_valve::debug_threshold}
if {${debug_level} >= ${debug_threshold}} {
sicslog "::scobj::mvp_valve::${debug_string}"
}
} catch_message ]
}
proc ::scobj::mvp_valve::mkDriver { sct_controller name device_class simulation_flag ip_address tcp_port id datype } {
::scobj::mvp_valve::sics_log 9 "::scobj::mvp_valve::mkDriver ${sct_controller} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${datype}"
set ns "[namespace current]"
set catch_status [ catch {
# mkWrapper hook code starts
add_mvp $name $ip_address $tcp_port a
# mkWrapper hook code ends
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
proc ::scobj::mvp_valve::add_driver {name device_class simulation_flag ip_address tcp_port id datype} {
set catch_status [ catch {
::scobj::mvp_valve::sics_log 9 "::scobj::mvp_valve::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${datype}"
::scobj::mvp_valve::sics_log 9 "No sctcontroller for mvp_valve"
::scobj::mvp_valve::sics_log 1 "::scobj::mvp_valve::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${datype}"
::scobj::mvp_valve::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${datype}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
namespace eval ::scobj::mvp_valve {
namespace export debug_threshold
namespace export debug_log
namespace export sics_log
namespace export mkDriver
namespace export add_driver
}
proc add_mvp_valve {name ip_address tcp_port id datype} {
set simulation_flag "[string tolower [SplitReply [environment_simulation]]]"
::scobj::mvp_valve::add_driver ${name} "environment" "${simulation_flag}" ${ip_address} ${tcp_port} "${id}" "${datype}"
}
clientput "file evaluation of sct_mvp_valve.tcl"
::scobj::mvp_valve::sics_log 9 "file evaluation of sct_mvp_valve.tcl"
proc ::scobj::mvp_valve::read_config {} {
set catch_status [ catch {
set ns "::scobj::mvp_valve"
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"] "mvp_valve"] } {
if { ![string equal -nocase "${simulation_flag}" "false"] } {
set asyncqueue "null"
${ns}::sics_log 9 "simulation_flag=${simulation_flag} => using null asyncqueue"
} 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]
}
} else {
if { [dict exists $v "asyncprotocol"] } {
set asyncprotocol [dict get $v "asyncprotocol"]
} else {
set asyncprotocol ${name}_protocol
MakeAsyncProtocol ${asyncprotocol}
if { [dict exists $v "terminator"] } {
${asyncprotocol} sendterminator "[dict get $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"]"
}
}
set arg_list [list]
set missing_list [list]
foreach arg {id datype} {
if {[dict exists $u $arg]} {
lappend arg_list "[dict get $u $arg]"
} elseif {[dict exists $v $arg]} {
lappend arg_list "[dict get $v $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"
}
if { [string equal -nocase ${asyncqueue} "sct"] } {
${ns}::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} {*}$arg_list
} else {
${ns}::add_driver ${name} ${device_class} ${simulation_flag} "aqadapter" ${asyncqueue} {*}$arg_list
}
}
}
}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
if { [info exists ::config_dict] } {
::scobj::mvp_valve::read_config
} else {
::scobj::mvp_valve::sics_log 5 "No config dict"
}

View File

@ -0,0 +1,167 @@
# Generated driver for syringe_pump
# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent
#
namespace eval ::scobj::syringe_pump {
set debug_threshold 5
}
proc ::scobj::syringe_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 fd [open "../log/syringe_pump_[basename ${tc_root}].log" "a"]
set line "[clock format [clock seconds] -format "%T"] ${debug_string}"
puts ${fd} "${line}"
close ${fd}
}
} catch_message ]
}
proc ::scobj::syringe_pump::sics_log {debug_level debug_string} {
set catch_status [ catch {
set debug_threshold ${::scobj::syringe_pump::debug_threshold}
if {${debug_level} >= ${debug_threshold}} {
sicslog "::scobj::syringe_pump::${debug_string}"
}
} catch_message ]
}
proc ::scobj::syringe_pump::mkDriver { sct_controller name device_class simulation_flag ip_address tcp_port id datype } {
::scobj::syringe_pump::sics_log 9 "::scobj::syringe_pump::mkDriver ${sct_controller} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${datype}"
set ns "[namespace current]"
set catch_status [ catch {
# mkWrapper hook code starts
::scobj::syr::mk_sct_syr $sct_controller environment $name
# mkWrapper hook code ends
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
proc ::scobj::syringe_pump::add_driver {name device_class simulation_flag ip_address tcp_port id datype} {
set catch_status [ catch {
::scobj::syringe_pump::sics_log 9 "::scobj::syringe_pump::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${datype}"
if {[string equal -nocase "${simulation_flag}" "false"]} {
if {[string equal -nocase "aqadapter" "${ip_address}"]} {
::scobj::syringe_pump::sics_log 9 "makesctcontroller sct_${name} aqadapter ${tcp_port}"
makesctcontroller sct_${name} aqadapter ${tcp_port}
} else {
::scobj::syringe_pump::sics_log 9 "makesctcontroller sct_${name} syringe ${ip_address}:${tcp_port}"
makesctcontroller sct_${name} syringe ${ip_address}:${tcp_port}
}
} else {
::scobj::syringe_pump::sics_log 9 "simulation_flag={simulation_flag} => No sctcontroller for syringe_pump"
}
::scobj::syringe_pump::sics_log 1 "::scobj::syringe_pump::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${datype}"
::scobj::syringe_pump::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${datype}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
namespace eval ::scobj::syringe_pump {
namespace export debug_threshold
namespace export debug_log
namespace export sics_log
namespace export mkDriver
namespace export add_driver
}
proc add_syringe_pump {name ip_address tcp_port id datype} {
set simulation_flag "[string tolower [SplitReply [environment_simulation]]]"
::scobj::syringe_pump::add_driver ${name} "environment" "${simulation_flag}" ${ip_address} ${tcp_port} "${id}" "${datype}"
}
clientput "file evaluation of sct_syringe_pump.tcl"
::scobj::syringe_pump::sics_log 9 "file evaluation of sct_syringe_pump.tcl"
proc ::scobj::syringe_pump::read_config {} {
set catch_status [ catch {
set ns "::scobj::syringe_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"] "syringe_pump"] } {
if { ![string equal -nocase "${simulation_flag}" "false"] } {
set asyncqueue "null"
${ns}::sics_log 9 "simulation_flag=${simulation_flag} => using null asyncqueue"
} 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]
}
} else {
if { [dict exists $v "asyncprotocol"] } {
set asyncprotocol [dict get $v "asyncprotocol"]
} else {
set asyncprotocol ${name}_protocol
MakeAsyncProtocol ${asyncprotocol}
if { [dict exists $v "terminator"] } {
${asyncprotocol} sendterminator "[dict get $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"]"
}
}
set arg_list [list]
set missing_list [list]
foreach arg {id datype} {
if {[dict exists $u $arg]} {
lappend arg_list "[dict get $u $arg]"
} elseif {[dict exists $v $arg]} {
lappend arg_list "[dict get $v $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"
}
if { [string equal -nocase ${asyncqueue} "sct"] } {
${ns}::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} {*}$arg_list
} else {
${ns}::add_driver ${name} ${device_class} ${simulation_flag} "aqadapter" ${asyncqueue} {*}$arg_list
}
}
}
}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
if { [info exists ::config_dict] } {
::scobj::syringe_pump::read_config
} else {
::scobj::syringe_pump::sics_log 5 "No config dict"
}

View File

@ -0,0 +1,11 @@
# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent
driver syringe_pump = {
protocol = syringe
class = environment
simulation_group = environment_simulation
add_args = 'id datype'
make_args = 'id datype'
code mkWrapper = {%%
::scobj::syr::mk_sct_syr $sct_controller environment $name
%%}
}

View File

@ -0,0 +1,57 @@
# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent
driver eurotherm_3200 = {
protocol = modbus_ap;
class = environment;
simulation_group = environment_simulation;
add_args = 'id datype dev_id tol';
make_args = 'id datype dev_id tol';
group util = {
data = false; control = false; nxsave = false; mutable = false;
var unit = { type = int; value = '${dev_id}'; }
var mode = { type = text; allowed = "int,float"; value = 'int'; }
}
group loop1 = {
readable = 1;
type = float;
var sensor = { read_command = '1'; permlink = 'T.S01'; };
writeable = 1;
var setpoint = { read_command = '2'; write_command = '2'; permlink = 'T.SP01';
driveable = loop1/sensor; lowerlimit = 0; upperlimit =40; tolerance = '${tol}';
};
}
group loop1_extra = {
readable = 1;
type = float;
data = false; control = false; nxsave = false; mutable = false;
var manual_output = { read_command = '3'; }
var working_output = { read_command = '4'; }
var working_setpoint = { read_command = '5'; }
var active_setpoint = { read_command = '15'; }
writeable = 1;
var alarm1_thresh = { read_command = '13'; write_command = '13'; }
var alarm2_thresh = { read_command = '14'; write_command = '14'; }
var power_limit_high = { read_command = '30'; write_command = '30'; }
var power_limit_low = { read_command = '31'; write_command = '31'; }
var setpoint_slew_rate = { read_command = '35'; write_command = '35'; }
var power_slew_rate = { read_command = '37'; write_command = '37'; }
}
code getValue = {
@TCL
if { [string equal -nocase [hval ${tc_root}/util/mode] "float"] } {
set cmd "[hval ${tc_root}/util/unit]:3:[expr {32768+2*${cmd_str}}]:1:F32"
} else {
set cmd "[hval ${tc_root}/util/unit]:3:${cmd_str}:1:U16"
}
@END
}
code setValue = {
@TCL
if { [string equal -nocase [hval ${tc_root}/util/mode] "float"] } {
set cmd "[hval ${tc_root}/util/unit]:16:[expr {32768+2*${cmd_str}}]:1:F32:${par}"
} else {
set cmd "[hval ${tc_root}/util/unit]:16:${cmd_str}:1:U16:${par}"
}
@END
}
}

View File

@ -7,6 +7,6 @@ driver eurotherm_m2000 = {
add_args = 'id datype dev_id tol' add_args = 'id datype dev_id tol'
make_args = 'id datype dev_id tol' make_args = 'id datype dev_id tol'
code mkDriver = {%% code mkDriver = {%%
mk_sct_eurotherm_et2000 sct_controller environment $name $dev_id $tol $id $datype add_eurotherm_2000 $name $ip_address $tcp_port $dev_id $tol $id $datype
%%} %%}
} }

View File

@ -42,7 +42,7 @@ proc ::scobj::eurotherm_m2000::mkDriver { sct_controller name device_class simul
hsetprop ${scobj_hpath} data true hsetprop ${scobj_hpath} data true
hsetprop ${scobj_hpath} debug_threshold 5 hsetprop ${scobj_hpath} debug_threshold 5
# mkDriver hook code starts # mkDriver hook code starts
mk_sct_eurotherm_et2000 sct_controller environment $name $dev_id $tol $id $datype add_eurotherm_2000 $name $ip_address $tcp_port $dev_id $tol $id $datype
# mkDriver hook code ends # mkDriver hook code ends
} catch_message ] } catch_message ]
handle_exception ${catch_status} ${catch_message} handle_exception ${catch_status} ${catch_message}

View File

@ -0,0 +1,620 @@
# Generated driver for eurotherm_3200
# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent
#
namespace eval ::scobj::eurotherm_3200 {
set debug_threshold 5
}
proc ::scobj::eurotherm_3200::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 fd [open "../log/eurotherm_3200_[basename ${tc_root}].log" "a"]
set line "[clock format [clock seconds] -format "%T"] ${debug_string}"
puts ${fd} "${line}"
close ${fd}
}
} catch_message ]
}
proc ::scobj::eurotherm_3200::sics_log {debug_level debug_string} {
set catch_status [ catch {
set debug_threshold ${::scobj::eurotherm_3200::debug_threshold}
if {${debug_level} >= ${debug_threshold}} {
sicslog "::scobj::eurotherm_3200::${debug_string}"
}
} catch_message ]
}
# checklimits function for driveable interface
proc ::scobj::eurotherm_3200::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::eurotherm_3200::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}
}
# checkstatus function for driveable interface
proc ::scobj::eurotherm_3200::checkstatus {tc_root} {
set catch_status [ catch {
# checkstatus hook code goes here
if {[sct driving]} {
set sp "[sct target]"
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::eurotherm_3200::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 starts
if { [string equal -nocase [hval ${tc_root}/util/mode] "float"] } {
set cmd "[hval ${tc_root}/util/unit]:3:[expr {32768+2*${cmd_str}}]:1:F32"
} else {
set cmd "[hval ${tc_root}/util/unit]:3:${cmd_str}:1:U16"
}
# getValue hook code ends
if { [hpropexists [sct] geterror] } {
debug_log ${tc_root} 9 "[sct] error: [sct geterror]"
error "[sct geterror]"
}
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}
}
# halt function for driveable interface
proc ::scobj::eurotherm_3200::halt {tc_root} {
set catch_status [ catch {
debug_log ${tc_root} 1 "halt tc_root=${tc_root} sct=[sct] driving=[sct driving]"
### TODO hset [sct] [hval [sct]]
# halt hook code goes here
sct driving 0
return "idle"
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to check the write parameter on a device
proc ::scobj::eurotherm_3200::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}
}
# function to parse the read of a parameter on a device
proc ::scobj::eurotherm_3200::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 write a parameter value on a device
proc ::scobj::eurotherm_3200::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 starts
if { [string equal -nocase [hval ${tc_root}/util/mode] "float"] } {
set cmd "[hval ${tc_root}/util/unit]:16:[expr {32768+2*${cmd_str}}]:1:F32:${par}"
} else {
set cmd "[hval ${tc_root}/util/unit]:16:${cmd_str}:1:U16:${par}"
}
# setValue 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 "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}
}
proc ::scobj::eurotherm_3200::mkDriver { sct_controller name device_class simulation_flag ip_address tcp_port id datype dev_id tol } {
::scobj::eurotherm_3200::sics_log 9 "::scobj::eurotherm_3200::mkDriver ${sct_controller} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${datype} ${dev_id} ${tol}"
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}/loop1 plain spy none
hsetprop ${scobj_hpath}/loop1 data "true"
hsetprop ${scobj_hpath}/loop1 klass "@none"
hsetprop ${scobj_hpath}/loop1 type "part"
hfactory ${scobj_hpath}/loop1/sensor plain user float
hsetprop ${scobj_hpath}/loop1/sensor read ${ns}::getValue ${scobj_hpath} rdValue {1}
hsetprop ${scobj_hpath}/loop1/sensor rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1/sensor control true
hsetprop ${scobj_hpath}/loop1/sensor data true
hsetprop ${scobj_hpath}/loop1/sensor mutable true
hsetprop ${scobj_hpath}/loop1/sensor nxsave true
hsetprop ${scobj_hpath}/loop1/sensor permlink data_set "T[format "%02d" ${id}]S01"
hsetprop ${scobj_hpath}/loop1/sensor @description "T[format "%02d" ${id}]S01"
hsetprop ${scobj_hpath}/loop1/sensor oldval 0.0
hsetprop ${scobj_hpath}/loop1/sensor klass "parameter"
hsetprop ${scobj_hpath}/loop1/sensor sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/loop1/sensor type "part"
hsetprop ${scobj_hpath}/loop1/sensor nxalias "${name}_loop1_sensor"
hfactory ${scobj_hpath}/loop1/setpoint plain user float
hsetprop ${scobj_hpath}/loop1/setpoint read ${ns}::getValue ${scobj_hpath} rdValue {2}
hsetprop ${scobj_hpath}/loop1/setpoint rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1/setpoint write ${ns}::setValue ${scobj_hpath} noResponse {2}
hsetprop ${scobj_hpath}/loop1/setpoint noResponse ${ns}::noResponse ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1/setpoint check ${ns}::checkrange ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1/setpoint driving 0
hsetprop ${scobj_hpath}/loop1/setpoint checklimits ${ns}::checklimits ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1/setpoint checkstatus ${ns}::checkstatus ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1/setpoint halt ${ns}::halt ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1/setpoint driveable loop1/sensor
hsetprop ${scobj_hpath}/loop1/setpoint control true
hsetprop ${scobj_hpath}/loop1/setpoint data true
hsetprop ${scobj_hpath}/loop1/setpoint mutable true
hsetprop ${scobj_hpath}/loop1/setpoint nxsave true
hsetprop ${scobj_hpath}/loop1/setpoint lowerlimit 0
hsetprop ${scobj_hpath}/loop1/setpoint upperlimit 40
hsetprop ${scobj_hpath}/loop1/setpoint tolerance ${tol}
hsetprop ${scobj_hpath}/loop1/setpoint permlink data_set "T[format "%02d" ${id}]SP01"
hsetprop ${scobj_hpath}/loop1/setpoint @description "T[format "%02d" ${id}]SP01"
hsetprop ${scobj_hpath}/loop1/setpoint oldval 0.0
hsetprop ${scobj_hpath}/loop1/setpoint klass "parameter"
hsetprop ${scobj_hpath}/loop1/setpoint sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/loop1/setpoint type "drivable"
hsetprop ${scobj_hpath}/loop1/setpoint nxalias "${name}_loop1_setpoint"
if {[string equal -nocase "${simulation_flag}" "false"]} {
${sct_controller} poll ${scobj_hpath}/loop1/sensor 1
${sct_controller} poll ${scobj_hpath}/loop1/setpoint 1
${sct_controller} write ${scobj_hpath}/loop1/setpoint
} else {
::scobj::eurotherm_3200::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for eurotherm_3200"
}
hfactory ${scobj_hpath}/loop1_extra plain spy none
hsetprop ${scobj_hpath}/loop1_extra data "false"
hsetprop ${scobj_hpath}/loop1_extra klass "@none"
hsetprop ${scobj_hpath}/loop1_extra type "part"
hfactory ${scobj_hpath}/loop1_extra/active_setpoint plain user float
hsetprop ${scobj_hpath}/loop1_extra/active_setpoint read ${ns}::getValue ${scobj_hpath} rdValue {15}
hsetprop ${scobj_hpath}/loop1_extra/active_setpoint rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/active_setpoint control false
hsetprop ${scobj_hpath}/loop1_extra/active_setpoint data false
hsetprop ${scobj_hpath}/loop1_extra/active_setpoint mutable false
hsetprop ${scobj_hpath}/loop1_extra/active_setpoint nxsave false
hsetprop ${scobj_hpath}/loop1_extra/active_setpoint oldval 0.0
hsetprop ${scobj_hpath}/loop1_extra/active_setpoint sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/loop1_extra/active_setpoint type "part"
hsetprop ${scobj_hpath}/loop1_extra/active_setpoint nxalias "${name}_loop1_extra_active_setpoint"
hfactory ${scobj_hpath}/loop1_extra/alarm1_thresh plain user float
hsetprop ${scobj_hpath}/loop1_extra/alarm1_thresh read ${ns}::getValue ${scobj_hpath} rdValue {13}
hsetprop ${scobj_hpath}/loop1_extra/alarm1_thresh rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/alarm1_thresh write ${ns}::setValue ${scobj_hpath} noResponse {13}
hsetprop ${scobj_hpath}/loop1_extra/alarm1_thresh noResponse ${ns}::noResponse ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/alarm1_thresh check ${ns}::checkrange ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/alarm1_thresh control false
hsetprop ${scobj_hpath}/loop1_extra/alarm1_thresh data false
hsetprop ${scobj_hpath}/loop1_extra/alarm1_thresh mutable false
hsetprop ${scobj_hpath}/loop1_extra/alarm1_thresh nxsave false
hsetprop ${scobj_hpath}/loop1_extra/alarm1_thresh oldval 0.0
hsetprop ${scobj_hpath}/loop1_extra/alarm1_thresh sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/loop1_extra/alarm1_thresh type "part"
hsetprop ${scobj_hpath}/loop1_extra/alarm1_thresh nxalias "${name}_loop1_extra_alarm1_thresh"
hfactory ${scobj_hpath}/loop1_extra/alarm2_thresh plain user float
hsetprop ${scobj_hpath}/loop1_extra/alarm2_thresh read ${ns}::getValue ${scobj_hpath} rdValue {14}
hsetprop ${scobj_hpath}/loop1_extra/alarm2_thresh rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/alarm2_thresh write ${ns}::setValue ${scobj_hpath} noResponse {14}
hsetprop ${scobj_hpath}/loop1_extra/alarm2_thresh noResponse ${ns}::noResponse ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/alarm2_thresh check ${ns}::checkrange ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/alarm2_thresh control false
hsetprop ${scobj_hpath}/loop1_extra/alarm2_thresh data false
hsetprop ${scobj_hpath}/loop1_extra/alarm2_thresh mutable false
hsetprop ${scobj_hpath}/loop1_extra/alarm2_thresh nxsave false
hsetprop ${scobj_hpath}/loop1_extra/alarm2_thresh oldval 0.0
hsetprop ${scobj_hpath}/loop1_extra/alarm2_thresh sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/loop1_extra/alarm2_thresh type "part"
hsetprop ${scobj_hpath}/loop1_extra/alarm2_thresh nxalias "${name}_loop1_extra_alarm2_thresh"
hfactory ${scobj_hpath}/loop1_extra/manual_output plain user float
hsetprop ${scobj_hpath}/loop1_extra/manual_output read ${ns}::getValue ${scobj_hpath} rdValue {3}
hsetprop ${scobj_hpath}/loop1_extra/manual_output rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/manual_output control false
hsetprop ${scobj_hpath}/loop1_extra/manual_output data false
hsetprop ${scobj_hpath}/loop1_extra/manual_output mutable false
hsetprop ${scobj_hpath}/loop1_extra/manual_output nxsave false
hsetprop ${scobj_hpath}/loop1_extra/manual_output oldval 0.0
hsetprop ${scobj_hpath}/loop1_extra/manual_output sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/loop1_extra/manual_output type "part"
hsetprop ${scobj_hpath}/loop1_extra/manual_output nxalias "${name}_loop1_extra_manual_output"
hfactory ${scobj_hpath}/loop1_extra/power_limit_high plain user float
hsetprop ${scobj_hpath}/loop1_extra/power_limit_high read ${ns}::getValue ${scobj_hpath} rdValue {30}
hsetprop ${scobj_hpath}/loop1_extra/power_limit_high rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/power_limit_high write ${ns}::setValue ${scobj_hpath} noResponse {30}
hsetprop ${scobj_hpath}/loop1_extra/power_limit_high noResponse ${ns}::noResponse ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/power_limit_high check ${ns}::checkrange ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/power_limit_high control false
hsetprop ${scobj_hpath}/loop1_extra/power_limit_high data false
hsetprop ${scobj_hpath}/loop1_extra/power_limit_high mutable false
hsetprop ${scobj_hpath}/loop1_extra/power_limit_high nxsave false
hsetprop ${scobj_hpath}/loop1_extra/power_limit_high oldval 0.0
hsetprop ${scobj_hpath}/loop1_extra/power_limit_high sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/loop1_extra/power_limit_high type "part"
hsetprop ${scobj_hpath}/loop1_extra/power_limit_high nxalias "${name}_loop1_extra_power_limit_high"
hfactory ${scobj_hpath}/loop1_extra/power_limit_low plain user float
hsetprop ${scobj_hpath}/loop1_extra/power_limit_low read ${ns}::getValue ${scobj_hpath} rdValue {31}
hsetprop ${scobj_hpath}/loop1_extra/power_limit_low rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/power_limit_low write ${ns}::setValue ${scobj_hpath} noResponse {31}
hsetprop ${scobj_hpath}/loop1_extra/power_limit_low noResponse ${ns}::noResponse ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/power_limit_low check ${ns}::checkrange ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/power_limit_low control false
hsetprop ${scobj_hpath}/loop1_extra/power_limit_low data false
hsetprop ${scobj_hpath}/loop1_extra/power_limit_low mutable false
hsetprop ${scobj_hpath}/loop1_extra/power_limit_low nxsave false
hsetprop ${scobj_hpath}/loop1_extra/power_limit_low oldval 0.0
hsetprop ${scobj_hpath}/loop1_extra/power_limit_low sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/loop1_extra/power_limit_low type "part"
hsetprop ${scobj_hpath}/loop1_extra/power_limit_low nxalias "${name}_loop1_extra_power_limit_low"
hfactory ${scobj_hpath}/loop1_extra/power_slew_rate plain user float
hsetprop ${scobj_hpath}/loop1_extra/power_slew_rate read ${ns}::getValue ${scobj_hpath} rdValue {37}
hsetprop ${scobj_hpath}/loop1_extra/power_slew_rate rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/power_slew_rate write ${ns}::setValue ${scobj_hpath} noResponse {37}
hsetprop ${scobj_hpath}/loop1_extra/power_slew_rate noResponse ${ns}::noResponse ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/power_slew_rate check ${ns}::checkrange ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/power_slew_rate control false
hsetprop ${scobj_hpath}/loop1_extra/power_slew_rate data false
hsetprop ${scobj_hpath}/loop1_extra/power_slew_rate mutable false
hsetprop ${scobj_hpath}/loop1_extra/power_slew_rate nxsave false
hsetprop ${scobj_hpath}/loop1_extra/power_slew_rate oldval 0.0
hsetprop ${scobj_hpath}/loop1_extra/power_slew_rate sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/loop1_extra/power_slew_rate type "part"
hsetprop ${scobj_hpath}/loop1_extra/power_slew_rate nxalias "${name}_loop1_extra_power_slew_rate"
hfactory ${scobj_hpath}/loop1_extra/setpoint_slew_rate plain user float
hsetprop ${scobj_hpath}/loop1_extra/setpoint_slew_rate read ${ns}::getValue ${scobj_hpath} rdValue {35}
hsetprop ${scobj_hpath}/loop1_extra/setpoint_slew_rate rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/setpoint_slew_rate write ${ns}::setValue ${scobj_hpath} noResponse {35}
hsetprop ${scobj_hpath}/loop1_extra/setpoint_slew_rate noResponse ${ns}::noResponse ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/setpoint_slew_rate check ${ns}::checkrange ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/setpoint_slew_rate control false
hsetprop ${scobj_hpath}/loop1_extra/setpoint_slew_rate data false
hsetprop ${scobj_hpath}/loop1_extra/setpoint_slew_rate mutable false
hsetprop ${scobj_hpath}/loop1_extra/setpoint_slew_rate nxsave false
hsetprop ${scobj_hpath}/loop1_extra/setpoint_slew_rate oldval 0.0
hsetprop ${scobj_hpath}/loop1_extra/setpoint_slew_rate sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/loop1_extra/setpoint_slew_rate type "part"
hsetprop ${scobj_hpath}/loop1_extra/setpoint_slew_rate nxalias "${name}_loop1_extra_setpoint_slew_rate"
hfactory ${scobj_hpath}/loop1_extra/working_output plain user float
hsetprop ${scobj_hpath}/loop1_extra/working_output read ${ns}::getValue ${scobj_hpath} rdValue {4}
hsetprop ${scobj_hpath}/loop1_extra/working_output rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/working_output control false
hsetprop ${scobj_hpath}/loop1_extra/working_output data false
hsetprop ${scobj_hpath}/loop1_extra/working_output mutable false
hsetprop ${scobj_hpath}/loop1_extra/working_output nxsave false
hsetprop ${scobj_hpath}/loop1_extra/working_output oldval 0.0
hsetprop ${scobj_hpath}/loop1_extra/working_output sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/loop1_extra/working_output type "part"
hsetprop ${scobj_hpath}/loop1_extra/working_output nxalias "${name}_loop1_extra_working_output"
hfactory ${scobj_hpath}/loop1_extra/working_setpoint plain user float
hsetprop ${scobj_hpath}/loop1_extra/working_setpoint read ${ns}::getValue ${scobj_hpath} rdValue {5}
hsetprop ${scobj_hpath}/loop1_extra/working_setpoint rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/loop1_extra/working_setpoint control false
hsetprop ${scobj_hpath}/loop1_extra/working_setpoint data false
hsetprop ${scobj_hpath}/loop1_extra/working_setpoint mutable false
hsetprop ${scobj_hpath}/loop1_extra/working_setpoint nxsave false
hsetprop ${scobj_hpath}/loop1_extra/working_setpoint oldval 0.0
hsetprop ${scobj_hpath}/loop1_extra/working_setpoint sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/loop1_extra/working_setpoint type "part"
hsetprop ${scobj_hpath}/loop1_extra/working_setpoint nxalias "${name}_loop1_extra_working_setpoint"
if {[string equal -nocase "${simulation_flag}" "false"]} {
${sct_controller} poll ${scobj_hpath}/loop1_extra/active_setpoint 1
${sct_controller} poll ${scobj_hpath}/loop1_extra/alarm1_thresh 1
${sct_controller} poll ${scobj_hpath}/loop1_extra/alarm2_thresh 1
${sct_controller} poll ${scobj_hpath}/loop1_extra/manual_output 1
${sct_controller} poll ${scobj_hpath}/loop1_extra/power_limit_high 1
${sct_controller} poll ${scobj_hpath}/loop1_extra/power_limit_low 1
${sct_controller} poll ${scobj_hpath}/loop1_extra/power_slew_rate 1
${sct_controller} poll ${scobj_hpath}/loop1_extra/setpoint_slew_rate 1
${sct_controller} poll ${scobj_hpath}/loop1_extra/working_output 1
${sct_controller} poll ${scobj_hpath}/loop1_extra/working_setpoint 1
${sct_controller} write ${scobj_hpath}/loop1_extra/alarm1_thresh
${sct_controller} write ${scobj_hpath}/loop1_extra/alarm2_thresh
${sct_controller} write ${scobj_hpath}/loop1_extra/power_limit_high
${sct_controller} write ${scobj_hpath}/loop1_extra/power_limit_low
${sct_controller} write ${scobj_hpath}/loop1_extra/power_slew_rate
${sct_controller} write ${scobj_hpath}/loop1_extra/setpoint_slew_rate
} else {
::scobj::eurotherm_3200::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for eurotherm_3200"
}
hfactory ${scobj_hpath}/util plain spy none
hsetprop ${scobj_hpath}/util data "false"
hsetprop ${scobj_hpath}/util klass "@none"
hsetprop ${scobj_hpath}/util type "part"
hfactory ${scobj_hpath}/util/mode plain user text
hsetprop ${scobj_hpath}/util/mode control false
hsetprop ${scobj_hpath}/util/mode data false
hsetprop ${scobj_hpath}/util/mode mutable false
hsetprop ${scobj_hpath}/util/mode nxsave false
hsetprop ${scobj_hpath}/util/mode values int,float
hsetprop ${scobj_hpath}/util/mode oldval int
hset ${scobj_hpath}/util/mode int
hsetprop ${scobj_hpath}/util/mode sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/util/mode type "part"
hsetprop ${scobj_hpath}/util/mode nxalias "${name}_util_mode"
hfactory ${scobj_hpath}/util/unit plain user int
hsetprop ${scobj_hpath}/util/unit control false
hsetprop ${scobj_hpath}/util/unit data false
hsetprop ${scobj_hpath}/util/unit mutable false
hsetprop ${scobj_hpath}/util/unit nxsave false
hsetprop ${scobj_hpath}/util/unit oldval ${dev_id}
hset ${scobj_hpath}/util/unit ${dev_id}
hsetprop ${scobj_hpath}/util/unit sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/util/unit type "part"
hsetprop ${scobj_hpath}/util/unit nxalias "${name}_util_unit"
hsetprop ${scobj_hpath} klass ${device_class}
hsetprop ${scobj_hpath} data true
hsetprop ${scobj_hpath} debug_threshold 5
if {[string equal -nocase "${simulation_flag}" "false"]} {
ansto_makesctdrive ${name}_loop1_setpoint ${scobj_hpath}/loop1/setpoint ${scobj_hpath}/loop1/sensor ${sct_controller}
}
# mkDriver hook code goes here
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
proc ::scobj::eurotherm_3200::add_driver {name device_class simulation_flag ip_address tcp_port id datype dev_id tol} {
set catch_status [ catch {
::scobj::eurotherm_3200::sics_log 9 "::scobj::eurotherm_3200::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${datype} ${dev_id} ${tol}"
if {[string equal -nocase "${simulation_flag}" "false"]} {
if {[string equal -nocase "aqadapter" "${ip_address}"]} {
::scobj::eurotherm_3200::sics_log 9 "makesctcontroller sct_${name} aqadapter ${tcp_port}"
makesctcontroller sct_${name} aqadapter ${tcp_port}
} else {
::scobj::eurotherm_3200::sics_log 9 "makesctcontroller sct_${name} modbus_ap ${ip_address}:${tcp_port}"
makesctcontroller sct_${name} modbus_ap ${ip_address}:${tcp_port}
}
} else {
::scobj::eurotherm_3200::sics_log 9 "simulation_flag={simulation_flag} => No sctcontroller for eurotherm_3200"
}
::scobj::eurotherm_3200::sics_log 1 "::scobj::eurotherm_3200::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${datype} ${dev_id} ${tol}"
::scobj::eurotherm_3200::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${datype} ${dev_id} ${tol}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
namespace eval ::scobj::eurotherm_3200 {
namespace export debug_threshold
namespace export debug_log
namespace export sics_log
namespace export mkDriver
namespace export add_driver
}
proc add_eurotherm_3200 {name ip_address tcp_port id datype dev_id tol} {
set simulation_flag "[string tolower [SplitReply [environment_simulation]]]"
::scobj::eurotherm_3200::add_driver ${name} "environment" "${simulation_flag}" ${ip_address} ${tcp_port} "${id}" "${datype}" "${dev_id}" "${tol}"
}
clientput "file evaluation of sct_eurotherm_3200.tcl"
::scobj::eurotherm_3200::sics_log 9 "file evaluation of sct_eurotherm_3200.tcl"
proc ::scobj::eurotherm_3200::read_config {} {
set catch_status [ catch {
set ns "::scobj::eurotherm_3200"
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"] "eurotherm_3200"] } {
if { ![string equal -nocase "${simulation_flag}" "false"] } {
set asyncqueue "null"
${ns}::sics_log 9 "simulation_flag=${simulation_flag} => using null asyncqueue"
} 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]
}
} else {
if { [dict exists $v "asyncprotocol"] } {
set asyncprotocol [dict get $v "asyncprotocol"]
} else {
set asyncprotocol ${name}_protocol
MakeAsyncProtocol ${asyncprotocol}
if { [dict exists $v "terminator"] } {
${asyncprotocol} sendterminator "[dict get $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"]"
}
}
set arg_list [list]
set missing_list [list]
foreach arg {id datype dev_id tol} {
if {[dict exists $u $arg]} {
lappend arg_list "[dict get $u $arg]"
} elseif {[dict exists $v $arg]} {
lappend arg_list "[dict get $v $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"
}
if { [string equal -nocase ${asyncqueue} "sct"] } {
${ns}::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} {*}$arg_list
} else {
${ns}::add_driver ${name} ${device_class} ${simulation_flag} "aqadapter" ${asyncqueue} {*}$arg_list
}
}
}
}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
if { [info exists ::config_dict] } {
::scobj::eurotherm_3200::read_config
} else {
::scobj::eurotherm_3200::sics_log 5 "No config dict"
}

View File

@ -1906,8 +1906,8 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable p
other selftest 1 0 0 0 0 1 1 int user {*TST?} {rdValue} {} {setValue} {} other selftest 1 0 0 0 0 1 1 int user {*TST?} {rdValue} {} {setValue} {}
other relayStatusHi 1 0 1 0 1 1 1 int spy {RELAYST? 1} {rdValue} {} {setValue} {} other relayStatusHi 1 0 1 0 1 1 1 int spy {RELAYST? 1} {rdValue} {} {setValue} {}
other relayStatusLo 1 0 1 0 2 1 1 int spy {RELAYST? 2} {rdValue} {} {setValue} {} other relayStatusLo 1 0 1 0 2 1 1 int spy {RELAYST? 2} {rdValue} {} {setValue} {}
other relayCtrlParmHi 1 1 1 0 0 1 1 int spy {RELAY? 1} {rdValue} {RELAY 1,} {setValue} {} other relayCtrlParmHi 1 1 1 0 0 1 1 int spy {RELAY? 1} {rdValue} {RELAY 1,2,} {setValue} {}
other relayCtrlParmLo 1 1 1 0 0 1 1 int spy {RELAY? 2} {rdValue} {RELAY 2,} {setValue} {} other relayCtrlParmLo 1 1 1 0 0 1 1 int spy {RELAY? 2} {rdValue} {RELAY 2,2,} {setValue} {}
other statusByte 1 0 1 0 0 1 1 int spy {*STB?} {rdValue} {} {setValue} {} other statusByte 1 0 1 0 0 1 1 int spy {*STB?} {rdValue} {} {setValue} {}
} }
# The following 2 commands take no parameter - this makes them difficult to implement in a hipadaba structure # The following 2 commands take no parameter - this makes them difficult to implement in a hipadaba structure

View File

@ -27,6 +27,33 @@ proc ::scobj::west_6100::sics_log {debug_level debug_string} {
} catch_message ] } catch_message ]
} }
# checklimits function for driveable interface
proc ::scobj::west_6100::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 # check function for hset change
proc ::scobj::west_6100::checkrange {tc_root} { proc ::scobj::west_6100::checkrange {tc_root} {
set catch_status [ catch { set catch_status [ catch {
@ -53,6 +80,40 @@ proc ::scobj::west_6100::checkrange {tc_root} {
handle_exception ${catch_status} ${catch_message} handle_exception ${catch_status} ${catch_message}
} }
# checkstatus function for driveable interface
proc ::scobj::west_6100::checkstatus {tc_root} {
set catch_status [ catch {
# checkstatus hook code goes here
if {[sct driving]} {
set sp "[sct target]"
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 # function to request the read of a parameter on a device
proc ::scobj::west_6100::getDecimal {tc_root nextState cmd_str} { proc ::scobj::west_6100::getDecimal {tc_root nextState cmd_str} {
set catch_status [ catch { set catch_status [ catch {
@ -101,6 +162,18 @@ proc ::scobj::west_6100::getInteger {tc_root nextState cmd_str} {
handle_exception ${catch_status} ${catch_message} handle_exception ${catch_status} ${catch_message}
} }
# halt function for driveable interface
proc ::scobj::west_6100::halt {tc_root} {
set catch_status [ catch {
debug_log ${tc_root} 1 "halt tc_root=${tc_root} sct=[sct] driving=[sct driving]"
### TODO hset [sct] [hval [sct]]
# halt hook code goes here
sct driving 0
return "idle"
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to check the write parameter on a device # function to check the write parameter on a device
proc ::scobj::west_6100::noResponse {tc_root} { proc ::scobj::west_6100::noResponse {tc_root} {
set catch_status [ catch { set catch_status [ catch {
@ -262,8 +335,8 @@ proc ::scobj::west_6100::wrInteger {tc_root nextState cmd_str} {
handle_exception ${catch_status} ${catch_message} handle_exception ${catch_status} ${catch_message}
} }
proc ::scobj::west_6100::mkDriver { sct_controller name device_class simulation_flag ip_address tcp_port dev_id } { proc ::scobj::west_6100::mkDriver { sct_controller name device_class simulation_flag ip_address tcp_port id } {
::scobj::west_6100::sics_log 9 "::scobj::west_6100::mkDriver ${sct_controller} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${dev_id}" ::scobj::west_6100::sics_log 9 "::scobj::west_6100::mkDriver ${sct_controller} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id}"
set ns "[namespace current]" set ns "[namespace current]"
set catch_status [ catch { set catch_status [ catch {
@ -358,6 +431,8 @@ proc ::scobj::west_6100::mkDriver { sct_controller name device_class simulation_
hsetprop ${scobj_hpath}/sensor data true hsetprop ${scobj_hpath}/sensor data true
hsetprop ${scobj_hpath}/sensor mutable true hsetprop ${scobj_hpath}/sensor mutable true
hsetprop ${scobj_hpath}/sensor nxsave true hsetprop ${scobj_hpath}/sensor nxsave true
hsetprop ${scobj_hpath}/sensor permlink data_set "T[format "%02d" ${id}]S01"
hsetprop ${scobj_hpath}/sensor @description "T[format "%02d" ${id}]S01"
hsetprop ${scobj_hpath}/sensor oldval 0.0 hsetprop ${scobj_hpath}/sensor oldval 0.0
hsetprop ${scobj_hpath}/sensor klass "parameter" hsetprop ${scobj_hpath}/sensor klass "parameter"
hsetprop ${scobj_hpath}/sensor sdsinfo "::nexus::scobj::sdsinfo" hsetprop ${scobj_hpath}/sensor sdsinfo "::nexus::scobj::sdsinfo"
@ -370,14 +445,25 @@ proc ::scobj::west_6100::mkDriver { sct_controller name device_class simulation_
hsetprop ${scobj_hpath}/setpoint write ${ns}::wrDecimal ${scobj_hpath} noResponse {2} hsetprop ${scobj_hpath}/setpoint write ${ns}::wrDecimal ${scobj_hpath} noResponse {2}
hsetprop ${scobj_hpath}/setpoint noResponse ${ns}::noResponse ${scobj_hpath} hsetprop ${scobj_hpath}/setpoint noResponse ${ns}::noResponse ${scobj_hpath}
hsetprop ${scobj_hpath}/setpoint check ${ns}::checkrange ${scobj_hpath} hsetprop ${scobj_hpath}/setpoint check ${ns}::checkrange ${scobj_hpath}
hsetprop ${scobj_hpath}/setpoint driving 0
hsetprop ${scobj_hpath}/setpoint checklimits ${ns}::checklimits ${scobj_hpath}
hsetprop ${scobj_hpath}/setpoint checkstatus ${ns}::checkstatus ${scobj_hpath}
hsetprop ${scobj_hpath}/setpoint halt ${ns}::halt ${scobj_hpath}
hsetprop ${scobj_hpath}/setpoint driveable sensor
hsetprop ${scobj_hpath}/setpoint control true hsetprop ${scobj_hpath}/setpoint control true
hsetprop ${scobj_hpath}/setpoint data true hsetprop ${scobj_hpath}/setpoint data true
hsetprop ${scobj_hpath}/setpoint mutable true hsetprop ${scobj_hpath}/setpoint mutable true
hsetprop ${scobj_hpath}/setpoint nxsave true hsetprop ${scobj_hpath}/setpoint nxsave true
hsetprop ${scobj_hpath}/setpoint lowerlimit 0
hsetprop ${scobj_hpath}/setpoint upperlimit 1600
hsetprop ${scobj_hpath}/setpoint tolerance 1
hsetprop ${scobj_hpath}/setpoint permlink data_set "T[format "%02d" ${id}]SP01"
hsetprop ${scobj_hpath}/setpoint @description "T[format "%02d" ${id}]SP01"
hsetprop ${scobj_hpath}/setpoint oldval 0.0 hsetprop ${scobj_hpath}/setpoint oldval 0.0
hsetprop ${scobj_hpath}/setpoint klass "parameter" hsetprop ${scobj_hpath}/setpoint klass "parameter"
hsetprop ${scobj_hpath}/setpoint sdsinfo "::nexus::scobj::sdsinfo" hsetprop ${scobj_hpath}/setpoint sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/setpoint type "part" hsetprop ${scobj_hpath}/setpoint settle_time "30"
hsetprop ${scobj_hpath}/setpoint type "drivable"
hsetprop ${scobj_hpath}/setpoint nxalias "${name}_setpoint" hsetprop ${scobj_hpath}/setpoint nxalias "${name}_setpoint"
hfactory ${scobj_hpath}/w_sp plain user float hfactory ${scobj_hpath}/w_sp plain user float
@ -471,14 +557,17 @@ proc ::scobj::west_6100::mkDriver { sct_controller name device_class simulation_
hsetprop ${scobj_hpath} klass ${device_class} hsetprop ${scobj_hpath} klass ${device_class}
hsetprop ${scobj_hpath} data true hsetprop ${scobj_hpath} data true
hsetprop ${scobj_hpath} debug_threshold 5 hsetprop ${scobj_hpath} debug_threshold 5
if {[string equal -nocase "${simulation_flag}" "false"]} {
ansto_makesctdrive ${name}_setpoint ${scobj_hpath}/setpoint ${scobj_hpath}/sensor ${sct_controller}
}
# mkDriver hook code goes here # mkDriver hook code goes here
} catch_message ] } catch_message ]
handle_exception ${catch_status} ${catch_message} handle_exception ${catch_status} ${catch_message}
} }
proc ::scobj::west_6100::add_driver {name device_class simulation_flag ip_address tcp_port dev_id} { proc ::scobj::west_6100::add_driver {name device_class simulation_flag ip_address tcp_port id} {
set catch_status [ catch { set catch_status [ catch {
::scobj::west_6100::sics_log 9 "::scobj::west_6100::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${dev_id}" ::scobj::west_6100::sics_log 9 "::scobj::west_6100::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id}"
if {[string equal -nocase "${simulation_flag}" "false"]} { if {[string equal -nocase "${simulation_flag}" "false"]} {
if {[string equal -nocase "aqadapter" "${ip_address}"]} { if {[string equal -nocase "aqadapter" "${ip_address}"]} {
::scobj::west_6100::sics_log 9 "makesctcontroller sct_${name} aqadapter ${tcp_port}" ::scobj::west_6100::sics_log 9 "makesctcontroller sct_${name} aqadapter ${tcp_port}"
@ -490,8 +579,8 @@ proc ::scobj::west_6100::add_driver {name device_class simulation_flag ip_addres
} else { } else {
::scobj::west_6100::sics_log 9 "simulation_flag={simulation_flag} => No sctcontroller for west_6100" ::scobj::west_6100::sics_log 9 "simulation_flag={simulation_flag} => No sctcontroller for west_6100"
} }
::scobj::west_6100::sics_log 1 "::scobj::west_6100::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${dev_id}" ::scobj::west_6100::sics_log 1 "::scobj::west_6100::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id}"
::scobj::west_6100::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${dev_id} ::scobj::west_6100::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id}
} catch_message ] } catch_message ]
handle_exception ${catch_status} ${catch_message} handle_exception ${catch_status} ${catch_message}
} }
@ -504,9 +593,9 @@ namespace eval ::scobj::west_6100 {
namespace export add_driver namespace export add_driver
} }
proc add_west_6100 {name ip_address tcp_port dev_id} { proc add_west_6100 {name ip_address tcp_port id} {
set simulation_flag "[string tolower [SplitReply [environment_simulation]]]" set simulation_flag "[string tolower [SplitReply [environment_simulation]]]"
::scobj::west_6100::add_driver ${name} "environment" "${simulation_flag}" ${ip_address} ${tcp_port} "${dev_id}" ::scobj::west_6100::add_driver ${name} "environment" "${simulation_flag}" ${ip_address} ${tcp_port} "${id}"
} }
clientput "file evaluation of sct_west_6100.tcl" clientput "file evaluation of sct_west_6100.tcl"
@ -572,7 +661,7 @@ proc ::scobj::west_6100::read_config {} {
} }
set arg_list [list] set arg_list [list]
set missing_list [list] set missing_list [list]
foreach arg {dev_id} { foreach arg {id} {
if {[dict exists $u $arg]} { if {[dict exists $u $arg]} {
lappend arg_list "[dict get $u $arg]" lappend arg_list "[dict get $u $arg]"
} elseif {[dict exists $v $arg]} { } elseif {[dict exists $v $arg]} {

View File

@ -20,10 +20,12 @@ MakeRS232Controller sertemp $IP 502
sertemp timeout 300 sertemp timeout 300
sertemp sendterminator 0x0 sertemp sendterminator 0x0
sertemp replyterminator 0x0 sertemp replyterminator 0x0
EvFactory new tc1 west4100 sertemp $ID 2 #ffr 2014-09-22: The modbus addr should be 1 for single port moxas (Not $ID which is a SICS ID)
# EvFactory new tc1 west4100 sertemp $ID 2
EvFactory new $temp_sobj west4100 sertemp 1 2
sicslist setatt tc1 units kelvin sicslist setatt $temp_sobj units kelvin
sicslist setatt tc1 klass @none sicslist setatt $temp_sobj klass @none
} }
# @brief Adds a west400 temperature controller object. # @brief Adds a west400 temperature controller object.

View File

@ -3,8 +3,8 @@ driver west_6100 = {
protocol = modbus_ap protocol = modbus_ap
class = environment class = environment
simulation_group = environment_simulation simulation_group = environment_simulation
add_args = 'dev_id' add_args = 'id'
make_args = 'dev_id' make_args = 'id'
Group = { Group = {
priv = user; data = true; control = true; mutable = true; priv = user; data = true; control = true; mutable = true;
type = float; type = float;
@ -12,8 +12,12 @@ driver west_6100 = {
fetch_function = getDecimal; fetch_function = getDecimal;
read_function = rdDecimal; read_function = rdDecimal;
write_function = wrDecimal; write_function = wrDecimal;
var sensor = { read_command = "1"; } var sensor = { read_command = "1"; permlink = "T.S01"; }
var setpoint = { read_command = "2"; write_command = "2"; writeable = 1; } var setpoint = {
read_command = "2"; permlink = "T.SP01";
write_command = "2"; writeable = 1;
driveable = sensor; lowerlimit = 0; upperlimit = 1600;
tolerance = 1; property settle_time = 30; }
var w_sp = { read_command = "21"; write_command = "21"; writeable = 1; } var w_sp = { read_command = "21"; write_command = "21"; writeable = 1; }
var ramprate = { read_command = "24"; write_command = "24"; writeable = 1; } var ramprate = { read_command = "24"; write_command = "24"; writeable = 1; }
var alarm1 = { read_command = "13"; write_command = "13"; writeable = 1; } var alarm1 = { read_command = "13"; write_command = "13"; writeable = 1; }

View File

@ -27,6 +27,33 @@ proc ::scobj::west_6100::sics_log {debug_level debug_string} {
} catch_message ] } catch_message ]
} }
# checklimits function for driveable interface
proc ::scobj::west_6100::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 # check function for hset change
proc ::scobj::west_6100::checkrange {tc_root} { proc ::scobj::west_6100::checkrange {tc_root} {
set catch_status [ catch { set catch_status [ catch {
@ -53,6 +80,45 @@ proc ::scobj::west_6100::checkrange {tc_root} {
handle_exception ${catch_status} ${catch_message} handle_exception ${catch_status} ${catch_message}
} }
# checkstatus function for driveable interface
proc ::scobj::west_6100::checkstatus {tc_root} {
set catch_status [ catch {
# checkstatus hook code goes here
if {[sct driving]} {
set sp "[sct target]"
if {[hpropexists [sct] simulated] && [sct simulated] == "true"} {
set pv "${sp}"
hset ${tc_root}/[sct driveable] ${sp}
}
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 # function to request the read of a parameter on a device
proc ::scobj::west_6100::getDecimal {tc_root nextState cmd_str} { proc ::scobj::west_6100::getDecimal {tc_root nextState cmd_str} {
set catch_status [ catch { set catch_status [ catch {
@ -101,6 +167,18 @@ proc ::scobj::west_6100::getInteger {tc_root nextState cmd_str} {
handle_exception ${catch_status} ${catch_message} handle_exception ${catch_status} ${catch_message}
} }
# halt function for driveable interface
proc ::scobj::west_6100::halt {tc_root} {
set catch_status [ catch {
debug_log ${tc_root} 1 "halt tc_root=${tc_root} sct=[sct] driving=[sct driving]"
### TODO hset [sct] [hval [sct]]
# halt hook code goes here
sct driving 0
return "idle"
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to check the write parameter on a device # function to check the write parameter on a device
proc ::scobj::west_6100::noResponse {tc_root} { proc ::scobj::west_6100::noResponse {tc_root} {
set catch_status [ catch { set catch_status [ catch {
@ -262,8 +340,8 @@ proc ::scobj::west_6100::wrInteger {tc_root nextState cmd_str} {
handle_exception ${catch_status} ${catch_message} handle_exception ${catch_status} ${catch_message}
} }
proc ::scobj::west_6100::mkDriver { sct_controller name device_class simulation_flag ip_address tcp_port dev_id } { proc ::scobj::west_6100::mkDriver { sct_controller name device_class simulation_flag ip_address tcp_port id } {
::scobj::west_6100::sics_log 9 "::scobj::west_6100::mkDriver ${sct_controller} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${dev_id}" ::scobj::west_6100::sics_log 9 "::scobj::west_6100::mkDriver ${sct_controller} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id}"
set ns "[namespace current]" set ns "[namespace current]"
set catch_status [ catch { set catch_status [ catch {
@ -409,6 +487,8 @@ proc ::scobj::west_6100::mkDriver { sct_controller name device_class simulation_
hsetprop ${scobj_hpath}/sensor data true hsetprop ${scobj_hpath}/sensor data true
hsetprop ${scobj_hpath}/sensor mutable true hsetprop ${scobj_hpath}/sensor mutable true
hsetprop ${scobj_hpath}/sensor nxsave true hsetprop ${scobj_hpath}/sensor nxsave true
hsetprop ${scobj_hpath}/sensor permlink data_set "T[format "%02d" ${id}]S01"
hsetprop ${scobj_hpath}/sensor @description "T[format "%02d" ${id}]S01"
hsetprop ${scobj_hpath}/sensor oldval 0.0 hsetprop ${scobj_hpath}/sensor oldval 0.0
hsetprop ${scobj_hpath}/sensor klass "parameter" hsetprop ${scobj_hpath}/sensor klass "parameter"
hsetprop ${scobj_hpath}/sensor sdsinfo "::nexus::scobj::sdsinfo" hsetprop ${scobj_hpath}/sensor sdsinfo "::nexus::scobj::sdsinfo"
@ -430,14 +510,25 @@ proc ::scobj::west_6100::mkDriver { sct_controller name device_class simulation_
hsetprop ${scobj_hpath}/setpoint write ${ns}::wrDecimal ${scobj_hpath} noResponse {2} hsetprop ${scobj_hpath}/setpoint write ${ns}::wrDecimal ${scobj_hpath} noResponse {2}
hsetprop ${scobj_hpath}/setpoint noResponse ${ns}::noResponse ${scobj_hpath} hsetprop ${scobj_hpath}/setpoint noResponse ${ns}::noResponse ${scobj_hpath}
hsetprop ${scobj_hpath}/setpoint check ${ns}::checkrange ${scobj_hpath} hsetprop ${scobj_hpath}/setpoint check ${ns}::checkrange ${scobj_hpath}
hsetprop ${scobj_hpath}/setpoint driving 0
hsetprop ${scobj_hpath}/setpoint checklimits ${ns}::checklimits ${scobj_hpath}
hsetprop ${scobj_hpath}/setpoint checkstatus ${ns}::checkstatus ${scobj_hpath}
hsetprop ${scobj_hpath}/setpoint halt ${ns}::halt ${scobj_hpath}
hsetprop ${scobj_hpath}/setpoint driveable sensor
hsetprop ${scobj_hpath}/setpoint control true hsetprop ${scobj_hpath}/setpoint control true
hsetprop ${scobj_hpath}/setpoint data true hsetprop ${scobj_hpath}/setpoint data true
hsetprop ${scobj_hpath}/setpoint mutable true hsetprop ${scobj_hpath}/setpoint mutable true
hsetprop ${scobj_hpath}/setpoint nxsave true hsetprop ${scobj_hpath}/setpoint nxsave true
hsetprop ${scobj_hpath}/setpoint lowerlimit 0
hsetprop ${scobj_hpath}/setpoint upperlimit 1600
hsetprop ${scobj_hpath}/setpoint tolerance 1
hsetprop ${scobj_hpath}/setpoint permlink data_set "T[format "%02d" ${id}]SP01"
hsetprop ${scobj_hpath}/setpoint @description "T[format "%02d" ${id}]SP01"
hsetprop ${scobj_hpath}/setpoint oldval 0.0 hsetprop ${scobj_hpath}/setpoint oldval 0.0
hsetprop ${scobj_hpath}/setpoint klass "parameter" hsetprop ${scobj_hpath}/setpoint klass "parameter"
hsetprop ${scobj_hpath}/setpoint sdsinfo "::nexus::scobj::sdsinfo" hsetprop ${scobj_hpath}/setpoint sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/setpoint type "part" hsetprop ${scobj_hpath}/setpoint settle_time "30"
hsetprop ${scobj_hpath}/setpoint type "drivable"
hsetprop ${scobj_hpath}/setpoint nxalias "${name}_setpoint" hsetprop ${scobj_hpath}/setpoint nxalias "${name}_setpoint"
if {[string equal -nocase "${simulation_flag}" "false"]} { if {[string equal -nocase "${simulation_flag}" "false"]} {
@ -479,6 +570,7 @@ proc ::scobj::west_6100::mkDriver { sct_controller name device_class simulation_
hsetprop ${scobj_hpath} klass "@none" hsetprop ${scobj_hpath} klass "@none"
hsetprop ${scobj_hpath} type "part" hsetprop ${scobj_hpath} type "part"
# End of unnamed group # End of unnamed group
ansto_makesctdrive ${name}_setpoint ${scobj_hpath}/setpoint ${scobj_hpath}/sensor ${sct_controller}
# Start of named group: aux # Start of named group: aux
hfactory ${scobj_hpath}/aux plain spy none hfactory ${scobj_hpath}/aux plain spy none
@ -558,9 +650,9 @@ proc ::scobj::west_6100::mkDriver { sct_controller name device_class simulation_
handle_exception ${catch_status} ${catch_message} handle_exception ${catch_status} ${catch_message}
} }
proc ::scobj::west_6100::add_driver {name device_class simulation_flag ip_address tcp_port dev_id} { proc ::scobj::west_6100::add_driver {name device_class simulation_flag ip_address tcp_port id} {
set catch_status [ catch { set catch_status [ catch {
::scobj::west_6100::sics_log 9 "::scobj::west_6100::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${dev_id}" ::scobj::west_6100::sics_log 9 "::scobj::west_6100::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id}"
if {[string equal -nocase "${simulation_flag}" "false"]} { if {[string equal -nocase "${simulation_flag}" "false"]} {
if {[string equal -nocase "aqadapter" "${ip_address}"]} { if {[string equal -nocase "aqadapter" "${ip_address}"]} {
::scobj::west_6100::sics_log 9 "makesctcontroller sct_${name} aqadapter ${tcp_port}" ::scobj::west_6100::sics_log 9 "makesctcontroller sct_${name} aqadapter ${tcp_port}"
@ -574,8 +666,8 @@ proc ::scobj::west_6100::add_driver {name device_class simulation_flag ip_addres
::scobj::west_6100::sics_log 9 "makesctcontroller sct_${name} aqadapter NULL" ::scobj::west_6100::sics_log 9 "makesctcontroller sct_${name} aqadapter NULL"
makesctcontroller sct_${name} aqadapter NULL makesctcontroller sct_${name} aqadapter NULL
} }
::scobj::west_6100::sics_log 1 "::scobj::west_6100::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${dev_id}" ::scobj::west_6100::sics_log 1 "::scobj::west_6100::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id}"
::scobj::west_6100::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${dev_id} ::scobj::west_6100::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id}
} catch_message ] } catch_message ]
handle_exception ${catch_status} ${catch_message} handle_exception ${catch_status} ${catch_message}
} }
@ -588,9 +680,9 @@ namespace eval ::scobj::west_6100 {
namespace export add_driver namespace export add_driver
} }
proc add_west_6100 {name ip_address tcp_port dev_id} { proc add_west_6100 {name ip_address tcp_port id} {
set simulation_flag "[string tolower [SplitReply [environment_simulation]]]" set simulation_flag "[string tolower [SplitReply [environment_simulation]]]"
::scobj::west_6100::add_driver ${name} "environment" ${simulation_flag} ${ip_address} ${tcp_port} ${dev_id} ::scobj::west_6100::add_driver ${name} "environment" ${simulation_flag} ${ip_address} ${tcp_port} ${id}
} }
clientput "file evaluation of sct_west_6100.tcl" clientput "file evaluation of sct_west_6100.tcl"
@ -668,7 +760,7 @@ proc ::scobj::west_6100::read_config {} {
} }
set arg_list [list] set arg_list [list]
set missing_list [list] set missing_list [list]
foreach arg {dev_id} { foreach arg {id} {
if {[dict exists $u $arg]} { if {[dict exists $u $arg]} {
lappend arg_list "[dict get $u $arg]" lappend arg_list "[dict get $u $arg]"
} elseif {[dict exists $v $arg]} { } elseif {[dict exists $v $arg]} {

View File

@ -390,7 +390,7 @@ namespace eval histogram_memory {
if [ catch { if [ catch {
set det_height_mm [SplitReply [detector_active_height_mm]] set det_height_mm [SplitReply [detector_active_height_mm]]
set max_chan [OAT_TABLE Y -getdata MAX_CHAN] set max_chan [OAT_TABLE Y -getdata MAX_CHAN]
set scale_factor [expr {$det_height_mm / $max_chan}] set scale_factor [expr {1.0 * $det_height_mm / $max_chan}]
set offset 0.0 set offset 0.0
::histogram_memory::calc_axis "y_pixel_offset" $scale_factor $offset [OAT_TABLE Y -getdata BOUNDARIES] ::histogram_memory::calc_axis "y_pixel_offset" $scale_factor $offset [OAT_TABLE Y -getdata BOUNDARIES]
if {$args == "-get_data_ref"} { if {$args == "-get_data_ref"} {
@ -426,7 +426,7 @@ namespace eval histogram_memory {
if [ catch { if [ catch {
set det_width_mm [SplitReply [detector_active_width_mm]] set det_width_mm [SplitReply [detector_active_width_mm]]
set max_chan [OAT_TABLE X -getdata MAX_CHAN] set max_chan [OAT_TABLE X -getdata MAX_CHAN]
set scale_factor [expr {$det_width_mm / $max_chan}] set scale_factor [expr {1.0 * $det_width_mm / $max_chan}]
set offset 0.0 set offset 0.0
::histogram_memory::calc_axis "x_pixel_offset" $scale_factor $offset [OAT_TABLE X -getdata BOUNDARIES] ::histogram_memory::calc_axis "x_pixel_offset" $scale_factor $offset [OAT_TABLE X -getdata BOUNDARIES]
if {$args == "-get_data_ref"} { if {$args == "-get_data_ref"} {

View File

@ -124,7 +124,7 @@ proc ::scobj::positmotor::mot2ID {mot precision table} {
if {abs($mot - $m) <= $precision} { if {abs($mot - $m) <= $precision} {
return $i return $i
} elseif {[expr {$sign * ($mot - $m)} ] < 0} { } elseif {[expr {$sign * ($mot - $m)} ] < 0} {
return [expr {($mot-$mprev)*($i - $iprev)/($m - $mprev)+$iprev}] return [expr {1.0 * ($mot-$mprev)*($i - $iprev)/($m - $mprev)+$iprev}]
} }
set iprev $i set iprev $i
set mprev $m set mprev $m

View File

@ -5,8 +5,6 @@ if {$sim_mode == "false"} {
MakeSafetyPLC plc plc_chan 0 MakeSafetyPLC plc plc_chan 0
} }
makesctcontroller sct_shutter std 137.157.204.213:30000
# Configuration Note: # Configuration Note:
# #
# A default setting has been set in safetyplc.c code. following configuration # A default setting has been set in safetyplc.c code. following configuration
@ -51,14 +49,38 @@ proc focuslight {args} {
sct_shutter transact $cmd sct_shutter transact $cmd
} }
proc tertiary_shutter {args} { proc tertiary {sw} {
set cmd "set tertiary shutter=$args\r\n" set sw [string tolower $sw]
sct_shutter transact $cmd switch $sw {
"open" {
wait 1
plc_chan send set output=0
wait 1
plc_chan send set output=3
wait 1
plc_chan send set output=1
wait 1
plc_chan send set output=3
}
"close" {
wait 1
plc_chan send set output=0
wait 1
plc_chan send set output=3
wait 1
plc_chan send set output=2
wait 1
plc_chan send set output=3
}
default {
clientput ERROR: [info level 0] command should be open or close not $sw
}
}
} }
publish shutter user publish shutter user
publish focuslight user publish focuslight user
publish tertiary_shutter user publish tertiary user
source $cfPath(plc)/plc_common_1.tcl source $cfPath(plc)/plc_common_1.tcl

View File

@ -24,11 +24,30 @@ fileeval $cfPath(motors)/motor_configuration.tcl
fileeval $cfPath(plc)/plc.tcl fileeval $cfPath(plc)/plc.tcl
#fileeval $cfPath(counter)/counter.tcl #fileeval $cfPath(counter)/counter.tcl
#fileeval $cfPath(hmm)/hmm_configuration.tcl #fileeval $cfPath(hmm)/hmm_configuration.tcl
fileeval $cfPath(environment)/sct_agilent_33220A.tcl
fileeval $cfPath(environment)/sct_isotech_ps.tcl
fileeval $cfPath(environment)/sct_keithley_2700.tcl
fileeval $cfPath(environment)/sct_keithley_m2700.tcl
fileeval $cfPath(environment)/temperature/sct_lakeshore_218.tcl
fileeval $cfPath(environment)/temperature/sct_lakeshore_336.tcl
fileeval $cfPath(environment)/temperature/sct_ls336.tcl
fileeval $cfPath(environment)/temperature/sct_lakeshore_340.tcl
fileeval $cfPath(environment)/temperature/sct_ls340.tcl
fileeval $cfPath(environment)/temperature/sct_mercury_base.tcl
fileeval $cfPath(environment)/temperature/sct_mercury_level.tcl
fileeval $cfPath(environment)/temperature/sct_mercury_pres.tcl
fileeval $cfPath(environment)/temperature/sct_mercury_scpi.tcl
fileeval $cfPath(environment)/temperature/sct_mercury_temp.tcl
fileeval $cfPath(environment)/temperature/sct_mercury_valve.tcl
fileeval $cfPath(environment)/sct_protek_common.tcl
fileeval $cfPath(environment)/sct_protekmm.tcl
fileeval $cfPath(environment)/temperature/west400.tcl
fileeval $cfPath(environment)/temperature/sct_west4100.tcl
fileeval $cfPath(nexus)/nxscripts.tcl fileeval $cfPath(nexus)/nxscripts.tcl
fileeval $cfPath(scan)/scan.tcl fileeval $cfPath(scan)/scan.tcl
fileeval $cfPath(commands)/commands.tcl fileeval $cfPath(commands)/commands.tcl
#fileeval $cfPath(commands)/pulser.tcl fileeval $cfPath(commands)/pulser.tcl
#fileeval $cfPath(commands)/hvcommands.tcl fileeval $cfPath(commands)/hvcommands.tcl
fileeval $cfPath(anticollider)/anticollider.tcl fileeval $cfPath(anticollider)/anticollider.tcl
source gumxml.tcl source gumxml.tcl

View File

@ -12,7 +12,7 @@ foreach {simflag icsval fakedev} {
motor_simulation false false motor_simulation false false
chopper_simulation false true chopper_simulation false true
velsel_simulation false true velsel_simulation false true
plc_simulation true true plc_simulation false true
rfgen_simulation false true rfgen_simulation false true
goniometer_simulation false true goniometer_simulation false true
magnetic_simulation false true magnetic_simulation false true

View File

@ -0,0 +1,189 @@
[CF5]
cascade = T1:CF5_ls340,sample_stage:normal_sample_stage
enabled = False
[Default]
cascade = sample_stage:normal_sample_stage
enabled = True
[Function_Generator]
datype = V
enabled = False
id = 1
implementation = none
name = pulser
optype = function_generator
[I1]
datype = I
enabled = False
id = 1
implementation = none
name = curr1
optype = multimeter
[I2]
datype = I
enabled = False
id = 2
implementation = none
name = curr2
optype = multimeter
[T1]
datype = T
enabled = False
id = 1
implementation = none
name = tc1
optype = temperature
[T2]
datype = T
enabled = False
id = 2
implementation = none
name = tc2
optype = temperature
[T3]
datype = T
enabled = False
id = 3
implementation = none
name = tc3
optype = temperature
[T4]
datype = T
enabled = False
id = 4
implementation = none
name = tc4
optype = temperature
[V1]
datype = V
enabled = False
id = 1
implementation = none
name = volts1
optype = multimeter
[V2]
datype = V
enabled = False
id = 2
implementation = none
name = volts2
optype = multimeter
[sample_stage]
enabled = Always
implementation = normal_sample_stage
name = sample_stage
optype = motion_axis
[CF5_ls340]
asyncqueue = sct
desc = "Lakeshore 340 temperature controller"
driver = "ls340"
imptype = temperature
ip = 10.157.205.34
port = 4001
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
[agilent_33220A]
asyncqueue = sct
desc = "Function Generator"
driver = agilent_33220A
imptype = function_generator
ip = 10.157.205.16
port = 5025
[ls336_01]
asyncqueue = sct
desc = "Lakeshore 336 temperature controller"
driver = "ls336"
imptype = temperature
ip = 10.157.205.28
port = 7777
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
[ls336_02]
asyncqueue = sct
desc = "Lakeshore 336 temperature controller"
driver = "ls336"
imptype = temperature
ip = 10.157.205.29
port = 7777
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
[ls336_04]
asyncqueue = sct
desc = "Lakeshore 336 temperature controller"
driver = "ls336"
imptype = temperature
ip = 10.157.205.30
port = 7777
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
[ls336_11]
desc = "Lakeshore 336 temperature controller"
driver = "ls336"
imptype = temperature
ip = 10.157.205.27
port = 7777
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
[ls336_12]
asyncqueue = sct
desc = "Lakeshore 336 temperature controller"
driver = "ls336"
imptype = temperature
ip = 10.157.205.31
port = 7777
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
[mercury_scpi_01]
desc = "Oxford Mercury temperature controller with three temperature loops."
driver = "mercury_base"
imptype = temperature
ip = 10.157.205.5
permlink = LT
port = 7020
terminator = \r\n
tol = 1.0
valve_tol = 2
[mercury_scpi_02]
desc = "Oxford Mercury temperature controller with four temperature loops and needle valve control"
driver = "mercury_scpi"
imptype = temperature
ip = 10.157.205.47
permlink = LT
port = 7020
terminator = \r\n
tol = 1.0
valve_tol = 2
[normal_sample_stage]
desc = "This is the default sample stage configuration"
imptype = motion_axis
[protek_01]
asyncqueue = sct
desc = "Protek Multimeter"
driver = "protekmm"
imptype = multimeter
ip = 10.157.205.36
port = 4001
[protek_02]
asyncqueue = sct
desc = "Protek Multimeter"
driver = "protekmm"
imptype = multimeter
ip = 10.157.205.37
port = 4001

View File

@ -6,7 +6,7 @@ namespace eval motor {
} }
namespace eval ajscmds { namespace eval ajscmds {
namespace export SetRadColl SimpleRun SimpleScan RadCollRun RadCollTimed RadCollScan namespace export SetRadColl SimpleRun SimpleScan RadCollRun RadCollTimed RadCollScan RadCollBiScan
# SetRadColl # SetRadColl
command SetRadColl { command SetRadColl {
@ -34,13 +34,13 @@ catch {
} msg } msg
clientput $msg clientput $msg
} }
# SimpleRun # SimpleRun
command SimpleRun { command SimpleRun {
float=0:inf steptime float=0:inf steptime
int=1:inf numsteps int=1:inf numsteps
} { } {
# RadCollOff
histmem mode time histmem mode time
histmem preset $steptime histmem preset $steptime
newfile HISTOGRAM_XY newfile HISTOGRAM_XY
@ -49,6 +49,7 @@ int=1:inf numsteps
save $i save $i
} }
} }
# SimpleScan # SimpleScan
command SimpleScan { command SimpleScan {
text=drivable motor text=drivable motor
@ -58,7 +59,6 @@ int=1:inf numsteps
float=0:inf steptime float=0:inf steptime
} { } {
# RadCollOff
histmem mode time histmem mode time
histmem preset $steptime histmem preset $steptime
newfile HISTOGRAM_XY newfile HISTOGRAM_XY
@ -68,13 +68,13 @@ float=0:inf steptime
save $i save $i
} }
} }
# RadCollRun # RadCollRun
command RadCollRun { command RadCollRun {
int=1:inf oscno int=1:inf oscno
int=1:inf reps int=1:inf reps
} { } {
# RadCollOn $oscno
histmem mode unlimited histmem mode unlimited
newfile HISTOGRAM_XY newfile HISTOGRAM_XY
for {set i 0} {$i < $reps} {incr i} { for {set i 0} {$i < $reps} {incr i} {
@ -83,8 +83,8 @@ int=1:inf reps
hmm countblock hmm countblock
save $i save $i
} }
# RadCollOff
} }
# RadCollTimed # RadCollTimed
command RadCollTimed { command RadCollTimed {
int=1:inf oscno int=1:inf oscno
@ -99,14 +99,16 @@ float=0:inf time
set i 0 set i 0
set timsecs [expr $time*60] set timsecs [expr $time*60]
while {$bool == 0} { while {$bool == 0} {
oct oscillate_count $oscno
oct oscillate start
histmem start block histmem start block
save $i save $i
incr i incr i
set tim2 [expr [clock seconds] - $tim1] set tim2 [expr [clock seconds] - $tim1]
if {$tim2 > $timsecs} {set bool 1} if {$tim2 > $timsecs} {set bool 1}
} }
RadCollOff
} }
# RadCollScan # RadCollScan
command RadCollScan { command RadCollScan {
text=drivable motor text=drivable motor
@ -115,8 +117,6 @@ float step
int=1:inf numsteps int=1:inf numsteps
int=1:inf oscno int=1:inf oscno
} { } {
# RadCollOn $oscno
histmem mode unlimited histmem mode unlimited
newfile HISTOGRAM_XY newfile HISTOGRAM_XY
for {set i 0} {$i < $numsteps} {incr i} { for {set i 0} {$i < $numsteps} {incr i} {
@ -126,8 +126,12 @@ int=1:inf oscno
hmm countblock hmm countblock
save $i save $i
} }
# RadCollOff
} }
} }
namespace import ::ajscmds::* namespace import ::ajscmds::*
publish SetRadColl user publish SetRadColl user
@ -140,3 +144,67 @@ publish RadCollScan user
proc ::commands::isc_initialize {} { proc ::commands::isc_initialize {} {
::commands::ic_initialize ::commands::ic_initialize
} }
# RadCollScanRange
proc RadCollScanRange {motor start step fin oscno} {
if {$step==0} {break}
if {($start > $fin) && ($step > 0)} {break}
if {($start < $fin) && ($step < 0)} {break}
set i_bool 0
histmem mode unlimited
set currentmot $start
set i 0
newfile HISTOGRAM_XY
while {$i_bool==0} {
drive $motor $currentmot
oct oscillate_count $oscno
oct oscillate start
hmm countblock
save $i
set currentmot [expr {$currentmot + $step}]
if {($step > 0) && ($currentmot > $fin)} {set i_bool 1}
if {($step < 0) && ($currentmot < $fin)} {set i_bool 1}
incr i
}
}
publish RadCollScanRange user
#RadCollScanBi
proc RadCollScanBi {motor start step fin oscno motdir} {
set i_bool 0
histmem mode unlimited
if {$motdir == 1} {
set currentmot $start
set i 0
} else {
set currentmot $fin
set i [expr {int(($fin-$start)/$step)}]
}
newfile HISTOGRAM_XY
while {$i_bool==0} {
# drive $motor $currentmot
oct oscillate_count $oscno
oct oscillate start
hmm countblock
if {($motdir > 0)} {
set currentmot [expr {$currentmot + $step}]
if {$currentmot > $fin} {set i_bool 1}
incr i
} else {
set currentmot [expr {$currentmot - $step}]
if {$currentmot < $start} {set i_bool 1}
incr i -1
}
run $motor $currentmot
save $i
}
}
publish RadCollScanBi user

View File

@ -148,7 +148,7 @@ proc SetHistoOneShot {frq framenum } {
bat_table -set NO_REPEAT_ENTRY 1 NO_REPEAT_TABLE 1 NO_EXECUTE_TABLE 1 PERIOD_INDICES { 0 1 } bat_table -set NO_REPEAT_ENTRY 1 NO_REPEAT_TABLE 1 NO_EXECUTE_TABLE 1 PERIOD_INDICES { 0 1 }
fat_table -set NOS_PERIODS $framenum fat_table -set NOS_PERIODS $framenum
oat_table -set T {0 2200000} NTC 1 oat_table -set T {0 2200000} NTC 1
oat_table -set Y {-0.5 15.5} NYC 16 oat_table -set Y {-0.5 31.5} NYC 16
histmem freq $frq histmem freq $frq
histmem loadconf histmem loadconf
@ -160,4 +160,22 @@ proc SetHistoOneShot {frq framenum } {
publish SetHistoOneShot user publish SetHistoOneShot user
proc SetHistoStd {} {
histmem stop
hmm astop
FAT_TABLE -set MULTI_HOST_HISTO_STITCH_OVERLAP 8 MULTI_HOST_HISTO_JOIN_STITCH_ORDER INVERTED
OAT_TABLE -set X { 991.5 987.5 } NXC 248 Y { -0.5 3.5 } NYC 128 T { 0 20000 } NTC 1
histmem loadconf
}
publish SetHistoStd user
proc SetHistoDX {} {
histmem stop
hmm astop
FAT_TABLE -set MULTI_HOST_HISTO_STITCH_OVERLAP 16 MULTI_HOST_HISTO_JOIN_STITCH_ORDER INVERTED
OAT_TABLE -set X { 991.5 989.5 } NXC 496 Y { -0.5 3.5 } NYC 128 T { 0 20000 } NTC 1
histmem loadconf
}
publish SetHistoDX user

View File

@ -56,20 +56,20 @@ Motor ephi $motor_driver_type [params \
asyncqueue mc2\ asyncqueue mc2\
axis C\ axis C\
units degrees\ units degrees\
hardlowerlim -185\ hardlowerlim -365\
hardupperlim 185\ hardupperlim 365\
maxSpeed 5\ maxSpeed 5\
maxAccel 5\ maxAccel 5\
maxDecel 1\ maxDecel 5\
stepsPerX -12500\ stepsPerX -12500\
absEnc 1\ absEnc 1\
absEncHome $ephi_Home\ absEncHome $ephi_Home\
cntsPerX -4096] cntsPerX -4096]
setHomeandRange -motor ephi -home 0 -lowrange 180 -uprange 180 setHomeandRange -motor ephi -home 0 -lowrange -360 -uprange 360
ephi softlowerlim -180 ephi softlowerlim -360
ephi softupperlim 180 ephi softupperlim 360
ephi home 0 ephi home 0
ephi speed 1 ephi speed 3
ephi movecount $move_count ephi movecount $move_count
ephi precision 0.01 ephi precision 0.01
ephi part sample ephi part sample

View File

@ -24,8 +24,9 @@ if {$sim_mode == "true"} {
#set mx_Home 23263535 #set mx_Home 23263535
set mx_Home 8390583 set mx_Home 8390583
#set mom_Home 9274794 #set mom_Home 9274794
#set mom_Home 8391038 ##set mom_Home 8391038
set mom_Home 8147038 #set mom_Home 8147038
set mom_Home 7736816
set mtth_Home 19927837 set mtth_Home 19927837
#set mphi_Home 7613516 #set mphi_Home 7613516
#set mphi_Home 27847793 #set mphi_Home 27847793
@ -291,7 +292,7 @@ Motor mom $motor_driver_type [params \
absEnc 1\ absEnc 1\
absEncHome $mom_Home\ absEncHome $mom_Home\
cntsPerX -2048] cntsPerX -2048]
setHomeandRange -motor mom -home 0 -lowrange 5 -uprange 165 setHomeandRange -motor mom -home 59.5066 -lowrange 5 -uprange 165
#setHomeandRange -motor mom -home 60.08 -lowrange 5 -uprange 165 #setHomeandRange -motor mom -home 60.08 -lowrange 5 -uprange 165
mom speed 1 mom speed 1
mom movecount $move_count mom movecount $move_count

View File

@ -1,7 +1,8 @@
# This must be loaded by motor_configuration.tcl # This must be loaded by motor_configuration.tcl
set sphi_Home 7938520 set sphi_Home 7938520
set schi_Home 7586052 #set schi_Home 7586052
set schi_Home 9932404
set sy_Home 7790194 set sy_Home 7790194
set sx_Home 7556649 set sx_Home 7556649

View File

@ -103,9 +103,11 @@ implementation = normal_sample_stage
name = sample_stage name = sample_stage
optype = motion_axis optype = motion_axis
[12tmagnet_oxford] [12tmagnet_oxford]
asyncqueue = sct
desc = "12 Tesla Oxford Magnet" desc = "12 Tesla Oxford Magnet"
driver = "oxford_labview" driver = "oxford12tlv"
imptype = magnetic_field imptype = magnetic_field
interval = 5
ip = 10.157.205.3 ip = 10.157.205.3
port = 55001 port = 55001
@ -291,17 +293,8 @@ desc = "Load the small omega configuration"
imptype = motion_axis imptype = motion_axis
[vf1_west4100] [vf1_west4100]
asyncqueue = sct
desc = "VF1 Blue furnace temperature controller"
dev_id = 1
driver = "west4100"
imptype = temperature
ip = 10.157.205.24
port = 502
[vf1_west6100]
asyncprotocol = modbus_ap asyncprotocol = modbus_ap
desc = "VF1 Blue furnace 6100 temperature controller" desc = "VF1 Blue furnace temperature controller"
dev_id = 1 dev_id = 1
driver = "west_6100" driver = "west_6100"
imptype = temperature imptype = temperature
@ -310,21 +303,11 @@ port = 502
timeout = 2000 timeout = 2000
[vf2_west4100] [vf2_west4100]
asyncqueue = sct
desc = "VF2 Blue furnace temperature controller"
dev_id = 1
driver = "west4100"
imptype = temperature
ip = 10.157.205.25
port = 502
[vf2_west6100]
asyncprotocol = modbus_ap asyncprotocol = modbus_ap
desc = "VF2 Blue furnace 6100 temperature controller" desc = "VF2 Blue furnace temperature controller"
dev_id = 1 dev_id = 1
driver = "west_6100" driver = "west_6100"
imptype = temperature imptype = temperature
ip = 10.157.205.25 ip = 10.157.205.25
port = 502 port = 502
timeout = 2000 timeout = 2000

View File

@ -52,6 +52,7 @@ fileeval $cfPath(environment)/temperature/julabo_lh45_gen_sct.tcl
fileeval $cfPath(environment)/temperature/sct_qlink.tcl fileeval $cfPath(environment)/temperature/sct_qlink.tcl
fileeval $cfPath(environment)/temperature/west400.tcl fileeval $cfPath(environment)/temperature/west400.tcl
fileeval $cfPath(environment)/temperature/west4100_sct.tcl fileeval $cfPath(environment)/temperature/west4100_sct.tcl
fileeval $cfPath(environment)/temperature/west_6100_sct.tcl
fileeval $cfPath(environment)/magneticField/sct_oxford_labview.tcl fileeval $cfPath(environment)/magneticField/sct_oxford_labview.tcl
fileeval $cfPath(environment)/magneticField/oxford12tlv_sct.tcl fileeval $cfPath(environment)/magneticField/oxford12tlv_sct.tcl
fileeval $cfPath(environment)/he3/sct_he3.tcl fileeval $cfPath(environment)/he3/sct_he3.tcl

View File

@ -5,7 +5,7 @@ enabled = False
cascade = T1:CF1_ls340,sample_stage:normal_sample_stage cascade = T1:CF1_ls340,sample_stage:normal_sample_stage
enabled = False enabled = False
[CF8] [CF8]
cascade = T1:ls336_01,T2:ls340_11,sample_stage:normal_sample_stage cascade = T1:ls336_08,T2:ls336_05,sample_stage:normal_sample_stage
enabled = False enabled = False
[Default] [Default]
cascade = sample_stage:normal_sample_stage cascade = sample_stage:normal_sample_stage
@ -95,8 +95,8 @@ implementation = none
name = volts2 name = volts2
optype = multimeter optype = multimeter
[robot] [robot]
enabled = True enabled = False
implementation = robbie implementation = none
name = robot name = robot
optype = pickandplace optype = pickandplace
[sample_stage] [sample_stage]
@ -176,7 +176,7 @@ asyncqueue = sct
desc = "Lakeshore 336 temperature controller" desc = "Lakeshore 336 temperature controller"
driver = "ls336" driver = "ls336"
imptype = temperature imptype = temperature
ip = 137.157.201.21 ip = 10.157.205.54
port = 7777 port = 7777
terminator = \r\n terminator = \r\n
tol1 = 1.0 tol1 = 1.0
@ -193,6 +193,17 @@ terminator = \r\n
tol1 = 1.0 tol1 = 1.0
tol2 = 1.0 tol2 = 1.0
[ls336_08]
asyncqueue = sct
desc = "Lakeshore 336 temperature controller"
driver = "ls336"
imptype = temperature
ip = 10.157.205.55
port = 7777
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
[ls336_11] [ls336_11]
desc = "Lakeshore 336 temperature controller" desc = "Lakeshore 336 temperature controller"
driver = "ls336" driver = "ls336"
@ -214,38 +225,6 @@ terminator = \r\n
tol1 = 1.0 tol1 = 1.0
tol2 = 1.0 tol2 = 1.0
[ls340_01]
asyncqueue = sct
desc = "Lakeshore 340 temperature controller"
driver = "ls340"
imptype = temperature
ip = 137.157.201.86
port = 4001
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
[ls340_02]
asyncqueue = sct
desc = "Lakeshore 340 temperature controller"
driver = "ls340"
imptype = temperature
ip = 137.157.201.86
port = 4002
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
[ls340_11]
desc = "Lakeshore 340 temperature controller"
driver = "ls340"
imptype = temperature
ip = 137.157.201.86
port = 4001
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
[ls370_1] [ls370_1]
desc = "Lakeshore 370 Resistance Bridge" desc = "Lakeshore 370 Resistance Bridge"
driver = "lakeshore_m370" driver = "lakeshore_m370"
@ -296,14 +275,14 @@ imptype = multimeter
ip = 10.157.205.37 ip = 10.157.205.37
port = 4001 port = 4001
[robbie] [robby]
asyncqueue = sct asyncqueue = sct
desc = "Robbie: Epson Pick and Place Robot" desc = "Robbie: Epson Pick and Place Robot"
driver = epson_pandp driver = epson_pandp
imptype = pickandplace imptype = pickandplace
ip = 137.157.201.26 ip = 137.157.201.26
port = 6000 port = 6000
robot_name = robbie robot_name = robby
[rosie] [rosie]
asyncqueue = sct asyncqueue = sct

View File

@ -10,7 +10,10 @@ foreach {var lname type priv units klass} {
wavelength wavelength float user Angstrom crystal wavelength wavelength float user Angstrom crystal
dOmega dOmega float user degrees crystal dOmega dOmega float user degrees crystal
gDQv gDQv float user none crystal gDQv gDQv float user none crystal
gDQh gDQh float user none crystal
scan_variable scan_variable text user none crystal
MainDeadTime MainDeadTime float user s detector MainDeadTime MainDeadTime float user s detector
TransBackground TransBackground int user none detector
TransDeadTime TransDeadTime float user s detector TransDeadTime TransDeadTime float user s detector
TransmissionTube TransmissionTube int user none detector TransmissionTube TransmissionTube int user none detector
bkgLevel bkgLevel float user 1 experiment bkgLevel bkgLevel float user 1 experiment

View File

@ -23,7 +23,28 @@ fileeval $cfPath(motors)/motor_configuration.tcl
#fileeval $cfPath(motors)/extraconfig.tcl #fileeval $cfPath(motors)/extraconfig.tcl
fileeval $cfPath(plc)/plc.tcl fileeval $cfPath(plc)/plc.tcl
fileeval $cfPath(counter)/counter.tcl fileeval $cfPath(counter)/counter.tcl
#fileeval $cfPath(environment)/temperature/lakeshore_218_sct.tcl fileeval $cfPath(environment)/agilent_33220A_sct.tcl
fileeval $cfPath(environment)/isotech_ps_sct.tcl
fileeval $cfPath(environment)/temperature/sct_eurotherm_2000.tcl
fileeval $cfPath(environment)/temperature/eurotherm_m2000_sct.tcl
fileeval $cfPath(environment)/sct_keithley_2700.tcl
fileeval $cfPath(environment)/keithley_m2700_sct.tcl
fileeval $cfPath(environment)/temperature/lakeshore_218_sct.tcl
fileeval $cfPath(environment)/temperature/sct_lakeshore_336.tcl
fileeval $cfPath(environment)/temperature/ls336_sct.tcl
fileeval $cfPath(environment)/temperature/sct_lakeshore_340.tcl
fileeval $cfPath(environment)/temperature/ls340_sct.tcl
fileeval $cfPath(environment)/temperature/sct_lakeshore_370.tcl
fileeval $cfPath(environment)/temperature/lakeshore_m370_sct.tcl
fileeval $cfPath(environment)/temperature/mercury_base_sct.tcl
fileeval $cfPath(environment)/temperature/mercury_level_sct.tcl
fileeval $cfPath(environment)/temperature/mercury_pres_sct.tcl
fileeval $cfPath(environment)/temperature/mercury_scpi_sct.tcl
fileeval $cfPath(environment)/temperature/mercury_temp_sct.tcl
fileeval $cfPath(environment)/temperature/mercury_valve_sct.tcl
fileeval $cfPath(environment)/sct_protek_common.tcl
fileeval $cfPath(environment)/protekmm_sct.tcl
fileeval $cfPath(environment)/temperature/julabo_lh45_gen_sct.tcl
fileeval $cfPath(counter)/sct_bm.tcl fileeval $cfPath(counter)/sct_bm.tcl
fileeval $cfPath(hmm)/hmm_configuration.tcl fileeval $cfPath(hmm)/hmm_configuration.tcl
fileeval $cfPath(nexus)/nxscripts.tcl fileeval $cfPath(nexus)/nxscripts.tcl

View File

@ -0,0 +1,217 @@
[Default]
cascade = sample_stage:normal_sample_stage
enabled = True
[B1]
datype = B
enabled = False
id = 1
implementation = none
name = magnet1
optype = magnetic_field
[Function_Generator]
datype = V
enabled = False
id = 1
implementation = none
name = pulser
optype = function_generator
[High_Voltage]
datype = V
enabled = False
id = 1
implementation = none
name = hv_val
optype = multimeter
[I1]
datype = I
enabled = False
id = 1
implementation = none
name = curr1
optype = multimeter
[I2]
datype = I
enabled = False
id = 2
implementation = none
name = curr2
optype = multimeter
[Power Supply]
datype = V
enabled = False
id = 1
implementation = none
name = power_supply
optype = power_supply
[T1]
datype = T
enabled = False
id = 1
implementation = none
name = tc1
optype = temperature
[T2]
datype = T
enabled = False
id = 2
implementation = none
name = tc2
optype = temperature
[T3]
datype = T
enabled = False
id = 3
implementation = none
name = tc3
optype = temperature
[T4]
datype = T
enabled = False
id = 4
implementation = none
name = tc4
optype = temperature
[T5]
datype = T
enabled = False
id = 5
implementation = none
name = tc5
optype = temperature
[T6]
datype = T
enabled = False
id = 6
implementation = none
name = tc6
optype = temperature
[V1]
datype = V
enabled = False
id = 1
implementation = none
name = volts1
optype = multimeter
[V2]
datype = V
enabled = False
id = 2
implementation = none
name = volts2
optype = multimeter
[sample_stage]
enabled = Always
implementation = normal_sample_stage
name = sample_stage
optype = motion_axis
[agilent_33220A]
asyncqueue = sct
desc = "Function Generator"
driver = agilent_33220A
imptype = function_generator
ip = 10.157.205.16
port = 5025
[isotech_ps]
desc = "Isotech Power Supply:Baud=2400,Data=8,Stop=1,Parity=None,Flow=None"
driver = "isotech_ps"
imptype = power_supply
ip = 137.157.202.79
port = 4001
[julabo_lh45]
ctrl_sensor = "bath"
desc = "Julabo temperature controller"
driver = "julabo_lh45"
imptype = temperature
ip = 10.157.205.39
port = 4001
tol = 5.0
type = T
[ls336_01]
asyncqueue = sct
desc = "Lakeshore 336 temperature controller"
driver = "ls336"
imptype = temperature
ip = 10.157.205.28
port = 7777
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
[ls336_02]
asyncqueue = sct
desc = "Lakeshore 336 temperature controller"
driver = "ls336"
imptype = temperature
ip = 10.157.205.29
port = 7777
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
[ls336_04]
asyncqueue = sct
desc = "Lakeshore 336 temperature controller"
driver = "ls336"
imptype = temperature
ip = 10.157.205.30
port = 7777
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
[ls336_12]
asyncqueue = sct
desc = "Lakeshore 336 temperature controller"
driver = "ls336"
imptype = temperature
ip = 10.157.205.31
port = 7777
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
[mercury_scpi_01]
desc = "Oxford Mercury temperature controller in Mercury mode"
driver = "mercury_scpi"
imptype = temperature
ip = 10.157.205.5
permlink = LT
port = 7020
terminator = \r\n
tol = 1.0
valve_tol = 2
[mercury_scpi_02]
desc = "Oxford Mercury temperature controller in Mercury mode"
driver = "mercury_scpi"
imptype = temperature
ip = 10.157.205.47
permlink = LT
port = 7020
terminator = \r\n
tol = 1.0
valve_tol = 2
[normal_sample_stage]
desc = "This is the default sample stage configuration xyz translation omega rotation but no tilt axes"
imptype = motion_axis
[protek_01]
asyncqueue = sct
desc = "Protek Multimeter"
driver = "protekmm"
imptype = multimeter
ip = 10.157.205.36
port = 4001
[protek_02]
asyncqueue = sct
desc = "Protek Multimeter"
driver = "protekmm"
imptype = multimeter
ip = 10.157.205.37
port = 4001

View File

@ -24,7 +24,6 @@ source $cfPath(hipadaba)/hipadaba_configuration.tcl
fileeval $cfPath(source)/source.tcl fileeval $cfPath(source)/source.tcl
fileeval $cfPath(motors)/motor_configuration.tcl fileeval $cfPath(motors)/motor_configuration.tcl
fileeval $cfPath(motors)/positmotor_configuration.tcl fileeval $cfPath(motors)/positmotor_configuration.tcl
#fileeval $cfPath(motors)/extraconfig.tcl
fileeval $cfPath(plc)/plc.tcl fileeval $cfPath(plc)/plc.tcl
fileeval $cfPath(counter)/counter.tcl fileeval $cfPath(counter)/counter.tcl
#fileeval $cfPath(beamline)/sct_power.tcl #fileeval $cfPath(beamline)/sct_power.tcl
@ -55,6 +54,7 @@ fileeval $cfPath(environment)/temperature/julabo_lh45_gen_sct.tcl
fileeval $cfPath(environment)/temperature/sct_qlink.tcl fileeval $cfPath(environment)/temperature/sct_qlink.tcl
fileeval $cfPath(environment)/temperature/west400.tcl fileeval $cfPath(environment)/temperature/west400.tcl
fileeval $cfPath(environment)/temperature/west4100_sct.tcl fileeval $cfPath(environment)/temperature/west4100_sct.tcl
fileeval $cfPath(environment)/temperature/west_6100_sct.tcl
fileeval $cfPath(environment)/magneticField/sct_oxford_labview.tcl fileeval $cfPath(environment)/magneticField/sct_oxford_labview.tcl
fileeval $cfPath(environment)/magneticField/oxford12tlv_sct.tcl fileeval $cfPath(environment)/magneticField/oxford12tlv_sct.tcl
fileeval $cfPath(environment)/he3/sct_he3.tcl fileeval $cfPath(environment)/he3/sct_he3.tcl

View File

@ -146,6 +146,9 @@ proc ::scobj::rfgen::set_frequency {basePath} {
## ##
# @brief Request a state report from the RF generator # @brief Request a state report from the RF generator
proc ::scobj::rfgen::rqStatFunc {} { proc ::scobj::rfgen::rqStatFunc {} {
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
sct send "L:[sct address]" sct send "L:[sct address]"
return rdState return rdState
} }
@ -167,7 +170,6 @@ proc ::scobj::rfgen::rdStatFunc {} {
set statStr [sct result] set statStr [sct result]
if {[string match "ASCERR:*" $statStr]} { if {[string match "ASCERR:*" $statStr]} {
sct geterror $statStr sct geterror $statStr
sct ramping $RAMPIDLE
return stateChange return stateChange
} }
set statList [split $statStr "|="] set statList [split $statStr "|="]
@ -402,6 +404,8 @@ proc ::scobj::rfgen::mkRFGen {argList} {
if {[SplitReply [rfgen_simulation]] == "false"} { if {[SplitReply [rfgen_simulation]] == "false"} {
set SCT_RFGEN sct_rfgen_$pa(NAME) set SCT_RFGEN sct_rfgen_$pa(NAME)
makesctcontroller $SCT_RFGEN rfamp $pa(IP):$pa(PORT) makesctcontroller $SCT_RFGEN rfamp $pa(IP):$pa(PORT)
# The RFGen has been observed to fail to respond within the default timeout of 2 sec
$SCT_RFGEN timeout 5
hsetprop /sics/$pa(NAME) contname $SCT_RFGEN hsetprop /sics/$pa(NAME) contname $SCT_RFGEN
# mkStatArr stateArr [split [$SCT_RFGEN transact "L:$pa(ADDRESS)"] "|="] # mkStatArr stateArr [split [$SCT_RFGEN transact "L:$pa(ADDRESS)"] "|="]

View File

@ -98,7 +98,7 @@ set ss4d_home_mm 0.0
set ss4l_home_mm 0.0 set ss4l_home_mm 0.0
set ss4r_home_mm 0.0 set ss4r_home_mm 0.0
Default upper and lower ranges for vertical slits #Default upper and lower ranges for vertical slits
set vSlitHome 0 set vSlitHome 0
set vSlitLoRange 5 set vSlitLoRange 5
set vSlitHiRange 25 set vSlitHiRange 25

View File

@ -26,13 +26,20 @@ fileeval $cfPath(parameters)/parameters.tcl
fileeval $cfPath(plc)/plc.tcl fileeval $cfPath(plc)/plc.tcl
fileeval $cfPath(counter)/counter.tcl fileeval $cfPath(counter)/counter.tcl
fileeval $cfPath(environment)/sct_syr.tcl fileeval $cfPath(environment)/sct_syr.tcl
fileeval $cfPath(environment)/sct_syringe_pump.tcl
fileeval $cfPath(environment)/sct_knauer_pump.tcl
fileeval $cfPath(environment)/sct_mvp.tcl fileeval $cfPath(environment)/sct_mvp.tcl
fileeval $cfPath(environment)/sct_mvp_valve.tcl
fileeval $cfPath(environment)/sct_protek_common.tcl fileeval $cfPath(environment)/sct_protek_common.tcl
fileeval $cfPath(environment)/protekmm_sct.tcl
fileeval $cfPath(environment)/omron_hldc_sct.tcl fileeval $cfPath(environment)/omron_hldc_sct.tcl
fileeval $cfPath(environment)/magneticField/sct_bruker_BEC1.tcl fileeval $cfPath(environment)/magneticField/sct_bruker_BEC1.tcl
fileeval $cfPath(environment)/magneticField/sct_bruker.tcl
fileeval $cfPath(environment)/temperature/sct_lakeshore_336.tcl fileeval $cfPath(environment)/temperature/sct_lakeshore_336.tcl
fileeval $cfPath(environment)/temperature/sct_ls336.tcl
fileeval $cfPath(environment)/temperature/sct_lakeshore_340.tcl fileeval $cfPath(environment)/temperature/sct_lakeshore_340.tcl
fileeval $cfPath(environment)/temperature/sct_julabo_lh45.tcl fileeval $cfPath(environment)/temperature/sct_ls340.tcl
fileeval $cfPath(environment)/temperature/sct_julabo_lh45_gen.tcl
fileeval $cfPath(hmm)/hmm_configuration.tcl fileeval $cfPath(hmm)/hmm_configuration.tcl
fileeval $cfPath(nexus)/nxscripts.tcl fileeval $cfPath(nexus)/nxscripts.tcl
fileeval $cfPath(hmm)/detector.tcl fileeval $cfPath(hmm)/detector.tcl

View File

@ -0,0 +1,304 @@
[Bruker_CF6]
cascade = T1:CF6_ls340,B1:bruker_bec1,sample_stage:normal_sample_stage
enabled = False
[Default]
cascade = sample_stage:normal_sample_stage
enabled = True
[Knauer and Syringe]
cascade = HPLC:knauer_01,Syringe:syringe,sample_stage:normal_sample_stage
enabled = False
[Knauer, Syringe and MVP]
cascade = HPLC:knauer_01,Syringe:syringe,MVP:mvp,sample_stage:normal_sample_stage
enabled = False
[B1]
datype = B
enabled = False
id = 1
implementation = none
name = ma1
optype = magnetic_field
[Function_Generator]
datype = V
enabled = False
id = 1
implementation = none
name = pulser
optype = function_generator
[HPLC]
datype = pump
enabled = False
id = 1
implementation = none
name = hplc
optype = hplc
[High_Voltage]
datype = V
enabled = False
id = 1
implementation = none
name = hv_val
optype = multimeter
[I1]
datype = I
enabled = False
id = 1
implementation = none
name = curr1
optype = multimeter
[I2]
datype = I
enabled = False
id = 2
implementation = none
name = curr2
optype = multimeter
[MVP]
datype = valve
enabled = False
id = 1
implementation = none
name = mvp
optype = valve
[Power Supply]
datype = V
enabled = False
id = 1
implementation = none
name = power_supply
optype = power_supply
[Syringe]
datype = pump
enabled = False
id = 1
implementation = none
name = syr
optype = syringe
[T1]
datype = T
enabled = False
id = 1
implementation = none
name = tc1
optype = temperature
[T2]
datype = T
enabled = False
id = 2
implementation = none
name = tc2
optype = temperature
[T3]
datype = T
enabled = False
id = 3
implementation = none
name = tc3
optype = temperature
[T4]
datype = T
enabled = False
id = 4
implementation = none
name = tc4
optype = temperature
[T5]
datype = T
enabled = False
id = 5
implementation = none
name = tc5
optype = temperature
[T6]
datype = T
enabled = False
id = 6
implementation = none
name = tc6
optype = temperature
[V1]
datype = V
enabled = False
id = 1
implementation = none
name = volts1
optype = multimeter
[V2]
datype = V
enabled = False
id = 2
implementation = none
name = volts2
optype = multimeter
[sample_stage]
enabled = Always
implementation = normal_sample_stage
name = sample_stage
optype = motion_axis
[5Tmagnet]
desc = "The New Zealand magnet"
driver = tsi_smc
imptype = magnetic_field
ip = 137.157.202.151
port = 4004
timeout = 2000
[CF6_ls340]
desc = "cf6: Bottom loading cryocooler"
driver = "ls340"
imptype = temperature
ip = 10.157.205.38
port = 4001
terminator = \r\n
tol1 = 0.2
tol2 = 0.2
[agilent_33220A]
asyncqueue = sct
desc = "Function Generator"
driver = agilent_33220A
imptype = function_generator
ip = 10.157.205.16
port = 5025
[bruker_bec1]
desc = "Bruker Magnet"
driver = "bruker"
imptype = magnetic_field
ip = 10.157.205.13
port = 4444
tol = 0.1
[hiden_xcs]
desc = "Hiden XCS Relative Humidity Flow Control"
driver = "hiden_xcs"
imptype = flowcontrol
ip = 137.157.202.151
port = 4001
[isotech_ps]
desc = "Isotech Power Supply:Baud=2400,Data=8,Stop=1,Parity=None,Flow=None"
driver = "isotech_ps"
imptype = power_supply
ip = 137.157.202.151
port = 4001
[knauer_01]
asyncprotocol = knauer_ap
desc = "Knauer BlueShadow Pump 40P (High Performance/Pressure Liquid Chromatography)"
driver = knauer_pump
imptype = hplc
ip = 10.157.205.51
port = 10001
timeout = 1000
[ls336_01]
asyncqueue = sct
desc = "Lakeshore 336 temperature controller"
driver = "ls336"
imptype = temperature
ip = 10.157.205.28
port = 7777
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
[ls336_02]
asyncqueue = sct
desc = "Lakeshore 336 temperature controller"
driver = "ls336"
imptype = temperature
ip = 10.157.205.29
port = 7777
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
[ls336_04]
asyncqueue = sct
desc = "Lakeshore 336 temperature controller"
driver = "ls336"
imptype = temperature
ip = 10.157.205.30
port = 7777
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
[ls336_12]
asyncqueue = sct
desc = "Lakeshore 336 temperature controller"
driver = "ls336"
imptype = temperature
ip = 10.157.205.31
port = 7777
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
[mercury_scpi_01]
desc = "Oxford Mercury temperature controller in Mercury mode"
driver = "mercury_scpi"
imptype = temperature
ip = 10.157.205.5
permlink = LT
port = 7020
terminator = \r\n
tol = 1.0
valve_tol = 2
[mercury_scpi_02]
desc = "Oxford Mercury temperature controller in Mercury mode"
driver = "mercury_scpi"
imptype = temperature
ip = 10.157.205.47
permlink = LT
port = 7020
terminator = \r\n
tol = 1.0
valve_tol = 2
[mvp]
desc = "Valve controller"
driver = mvp_valve
imptype = valve
ip = 137.157.202.151
port = 4004
[normal_sample_stage]
desc = "This is the default sample stage configuration xyz translation omega rotation but no tilt axes"
imptype = motion_axis
[platypus_julabo]
ctrl_sensor = "bath"
desc = "Julabo temperature controller"
driver = "julabo_lh45"
imptype = temperature
ip = 137.157.202.151
port = 4002
tol = 2.0
type = T
[protek_01]
asyncqueue = sct
desc = "Protek Multimeter"
driver = "protekmm"
imptype = multimeter
ip = 10.157.205.36
port = 4001
[protek_02]
asyncqueue = sct
desc = "Protek Multimeter"
driver = "protekmm"
imptype = multimeter
ip = 10.157.205.37
port = 4001
[syringe]
desc = "Syringe Pump"
driver = syringe_pump
imptype = syringe
ip = 137.157.202.151
port = 4003
timeout = 1000

View File

@ -23,12 +23,27 @@ source $cfPath(hipadaba)/hipadaba_configuration.tcl
fileeval $cfPath(motors)/positmotor_configuration.tcl fileeval $cfPath(motors)/positmotor_configuration.tcl
fileeval $cfPath(plc)/plc.tcl fileeval $cfPath(plc)/plc.tcl
fileeval $cfPath(counter)/counter.tcl fileeval $cfPath(counter)/counter.tcl
fileeval $cfPath(environment)/sct_keithley_2700.tcl fileeval $cfPath(environment)/sct_agilent_33220A.tcl
fileeval $cfPath(environment)/temperature/sct_oxford_mercury.tcl fileeval $cfPath(environment)/sct_isotech_ps.tcl
fileeval $cfPath(environment)/temperature/sct_lakeshore_336.tcl
fileeval $cfPath(environment)/temperature/sct_lakeshore_340.tcl
fileeval $cfPath(environment)/temperature/sct_eurotherm_2000.tcl fileeval $cfPath(environment)/temperature/sct_eurotherm_2000.tcl
fileeval $cfPath(environment)/temperature/sct_eurotherm_m2000.tcl
fileeval $cfPath(environment)/sct_keithley_2700.tcl
fileeval $cfPath(environment)/sct_keithley_m2700.tcl
fileeval $cfPath(environment)/temperature/sct_lakeshore_218.tcl
fileeval $cfPath(environment)/temperature/sct_lakeshore_336.tcl
fileeval $cfPath(environment)/temperature/sct_ls336.tcl
fileeval $cfPath(environment)/temperature/sct_lakeshore_340.tcl
fileeval $cfPath(environment)/temperature/sct_ls340.tcl
fileeval $cfPath(environment)/temperature/sct_lakeshore_370.tcl
fileeval $cfPath(environment)/temperature/sct_lakeshore_m370.tcl
fileeval $cfPath(environment)/temperature/sct_mercury_base.tcl
fileeval $cfPath(environment)/temperature/sct_mercury_level.tcl
fileeval $cfPath(environment)/temperature/sct_mercury_pres.tcl
fileeval $cfPath(environment)/temperature/sct_mercury_scpi.tcl
fileeval $cfPath(environment)/temperature/sct_mercury_temp.tcl
fileeval $cfPath(environment)/temperature/sct_mercury_valve.tcl
fileeval $cfPath(environment)/sct_protek_common.tcl fileeval $cfPath(environment)/sct_protek_common.tcl
fileeval $cfPath(environment)/sct_protekmm.tcl
fileeval $cfPath(environment)/magneticField/sct_oxford_labview.tcl fileeval $cfPath(environment)/magneticField/sct_oxford_labview.tcl
fileeval $cfPath(environment)/magneticField/oxford12tlv_sct.tcl fileeval $cfPath(environment)/magneticField/oxford12tlv_sct.tcl
fileeval $cfPath(hmm)/hmm_configuration.tcl fileeval $cfPath(hmm)/hmm_configuration.tcl

View File

@ -80,34 +80,6 @@ tol1 = 1.0
tol2 = 1.0 tol2 = 1.0
type = T type = T
[ls336_5]
desc = "tc5: Lakeshore 336 temperature controller"
driver = "ls336"
enabled = False
group = environment:temperature
id = 5
ip = 137.157.201.21
name = tc5
port = 7777
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
type = T
[ls336_6]
desc = "tc6: Lakeshore 336 temperature controller"
driver = "ls336"
enabled = False
group = environment:temperature
id = 6
ip = 137.157.201.21
name = tc6
port = 7777
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
type = T
[mercury_scpi] [mercury_scpi]
desc = "tc25: Oxford Mercury temperature controller in Mercury mode" desc = "tc25: Oxford Mercury temperature controller in Mercury mode"
driver = "mercury_scpi" driver = "mercury_scpi"

View File

@ -45,6 +45,13 @@ id = 1
implementation = none implementation = none
name = dsc_val name = dsc_val
optype = multimeter optype = multimeter
[Flow Control]
datype = FC
enabled = False
id = 1
implementation = none
name = fc1
optype = flowcontrol
[Function_Generator] [Function_Generator]
datype = V datype = V
enabled = False enabled = False
@ -200,8 +207,8 @@ imptype = temperature
ip = 10.157.205.43 ip = 10.157.205.43
port = 4001 port = 4001
terminator = \r\n terminator = \r\n
tol1 = 1.0 tol1 = 0.2
tol2 = 1.0 tol2 = 0.2
[Oxford_12tmagnet_sample_insert] [Oxford_12tmagnet_sample_insert]
desc = "som will be redefined as the magnet sample insert rotation. Sample stage will be renamed to somss" desc = "som will be redefined as the magnet sample insert rotation. Sample stage will be renamed to somss"
@ -235,6 +242,13 @@ ip = 10.157.205.13
port = 4444 port = 4444
type = B type = B
[hiden_xcs]
desc = "Hiden XCS Relative Humidity Flow Control"
driver = "hiden_xcs"
imptype = flowcontrol
ip = 137.157.202.79
port = 4001
[isotech_ps] [isotech_ps]
desc = "Isotech Power Supply:Baud=2400,Data=8,Stop=1,Parity=None,Flow=None" desc = "Isotech Power Supply:Baud=2400,Data=8,Stop=1,Parity=None,Flow=None"
driver = "isotech_ps" driver = "isotech_ps"

View File

@ -35,10 +35,16 @@ namespace eval anticollider { proc ::anticollider::init {} {} }
#fileeval $cfPath(anticollider)/anticollider.tcl #fileeval $cfPath(anticollider)/anticollider.tcl
#fileeval $cfPath(tasmad)/taspub_sics/tasp.tcl #fileeval $cfPath(tasmad)/taspub_sics/tasp.tcl
#fileeval $cfPath(tasmad)/taspub_sics/tasscript.tcl #fileeval $cfPath(tasmad)/taspub_sics/tasscript.tcl
fileeval $cfPath(environment)/sct_agilent_33220A.tcl
fileeval $cfPath(environment)/sct_protek_common.tcl
fileeval $cfPath(environment)/sct_protekmm.tcl
fileeval $cfPath(environment)/temperature/sct_eurotherm_2000.tcl fileeval $cfPath(environment)/temperature/sct_eurotherm_2000.tcl
fileeval $cfPath(environment)/temperature/sct_julabo_lh45.tcl fileeval $cfPath(environment)/temperature/sct_julabo_lh45.tcl
fileeval $cfPath(environment)/temperature/sct_lakeshore_336.tcl fileeval $cfPath(environment)/temperature/sct_lakeshore_336.tcl
fileeval $cfPath(environment)/temperature/sct_ls336.tcl
fileeval $cfPath(environment)/temperature/sct_lakeshore_340.tcl fileeval $cfPath(environment)/temperature/sct_lakeshore_340.tcl
fileeval $cfPath(environment)/temperature/sct_ls340.tcl
fileeval $cfPath(environment)/temperature/sct_lakeshore_370.tcl fileeval $cfPath(environment)/temperature/sct_lakeshore_370.tcl
fileeval $cfPath(environment)/temperature/sct_oxford_itc.tcl fileeval $cfPath(environment)/temperature/sct_oxford_itc.tcl
fileeval $cfPath(environment)/temperature/sct_oxford_mercury.tcl fileeval $cfPath(environment)/temperature/sct_oxford_mercury.tcl
@ -50,6 +56,7 @@ fileeval $cfPath(environment)/temperature/mercury_valve_sct.tcl
fileeval $cfPath(environment)/temperature/west400.tcl fileeval $cfPath(environment)/temperature/west400.tcl
fileeval $cfPath(environment)/he3/sct_he3.tcl fileeval $cfPath(environment)/he3/sct_he3.tcl
fileeval $cfPath(environment)/magneticField/oxford_labview.tcl fileeval $cfPath(environment)/magneticField/oxford_labview.tcl
fileeval $cfPath(environment)/magneticField/sct_oxford12tlv.tcl
fileeval config/load_setup.tcl fileeval config/load_setup.tcl
fileeval log.tcl fileeval log.tcl
publish logbook spy publish logbook spy
@ -64,6 +71,8 @@ puts "doing tasub"
MakeTasUB tasub m1 m2 mvfocus mhfocus s1 s2 sgu sgl a1 a2 avfocus ahfocus MakeTasUB tasub m1 m2 mvfocus mhfocus s1 s2 sgu sgl a1 a2 avfocus ahfocus
tasub mono dd 3.35416 tasub mono dd 3.35416
tasub ana dd 3.35416 tasub ana dd 3.35416
# NOTE Autofocussing parameters persist in status.tcl
# You must set them in extraconfig.tcl to override this behaviour
tasub mono vb1 102.2 tasub mono vb1 102.2
tasub mono vb2 1.78 tasub mono vb2 1.78
tasub mono hb1 184.42 tasub mono hb1 184.42

View File

@ -4,6 +4,9 @@ enabled = False
[CF1] [CF1]
cascade = T1:CF1_ls340,sample_stage:normal_sample_stage cascade = T1:CF1_ls340,sample_stage:normal_sample_stage
enabled = False enabled = False
[CF4]
cascade = T1:CF4_ls340,sample_stage:normal_sample_stage
enabled = False
[Default] [Default]
cascade = sample_stage:normal_sample_stage cascade = sample_stage:normal_sample_stage
enabled = True enabled = True
@ -105,6 +108,16 @@ terminator = \r\n
tol1 = 1.0 tol1 = 1.0
tol2 = 1.0 tol2 = 1.0
[CF4_ls340]
desc = "cf4: cryofurnace"
driver = "ls340"
imptype = temperature
ip = 137.157.203.137
port = 4001
terminator = \r\n
tol1 = 1.0
tol2 = 1.0
[agilent_33220A] [agilent_33220A]
asyncqueue = sct asyncqueue = sct
desc = "Function Generator" desc = "Function Generator"