From 591c602da2d46d1a58406a9a0f7198453a6c692e Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Fri, 3 Oct 2014 10:17:46 +1000 Subject: [PATCH] Regen SCT drivers --- .../config/environment/sct_knauer_pump.tcl | 123 +++++++++++++++++- .../temperature/sct_lakeshore_m370.tcl | 111 +++++++++------- .../temperature/sct_pfeiffer_hg.tcl | 4 +- 3 files changed, 180 insertions(+), 58 deletions(-) diff --git a/site_ansto/instrument/config/environment/sct_knauer_pump.tcl b/site_ansto/instrument/config/environment/sct_knauer_pump.tcl index d58d4bf4..c92eebee 100644 --- a/site_ansto/instrument/config/environment/sct_knauer_pump.tcl +++ b/site_ansto/instrument/config/environment/sct_knauer_pump.tcl @@ -92,7 +92,11 @@ proc ::scobj::knauer_pump::fetch_from_glp {tc_root nextState cmd_str} { set index ${cmd_str} set data [hgetpropval ${tc_root}/dummy/glp real_data] set dlist [split ${data} ","] - sct result [lindex ${dlist} ${index}] + if { [llength ${dlist}] > ${index} } { + sct result [lindex ${dlist} ${index}] + } else { + sct result "" + } set cmd "@@NOSEND@@" # fetch_from_glp hook code ends if { [hpropexists [sct] geterror] } { @@ -120,7 +124,11 @@ proc ::scobj::knauer_pump::fetch_from_status {tc_root nextState cmd_str} { set index ${cmd_str} set data [hgetpropval ${tc_root}/dummy/status real_data] set dlist [split ${data} ","] - sct result [lindex ${dlist} ${index}] + if { [llength ${dlist}] > ${index} } { + sct result [lindex ${dlist} ${index}] + } else { + sct result "" + } set cmd "@@NOSEND@@" # fetch_from_status hook code ends if { [hpropexists [sct] geterror] } { @@ -374,9 +382,12 @@ proc ::scobj::knauer_pump::read_glp {tc_root} { error "[sct geterror]" } # read_glp hook code starts - set dlist [split [lindex [split ${data} ":"] 1] ","] - sct real_data "[join [lrange ${dlist} 0 end] ,]" - set data "Hidden in real_data property" + if { [string equal -nocase -length 6 ${data} "ERROR:"] } { + } else { + set dlist [split [lindex [split ${data} ":"] 1] ","] + sct real_data "[join [lrange ${dlist} 0 end] ,]" + set data "Hidden in real_data property" + } # read_glp hook code ends if { [hpropexists [sct] geterror] } { debug_log ${tc_root} 9 "[sct] error: [sct geterror]" @@ -427,6 +438,77 @@ proc ::scobj::knauer_pump::read_status {tc_root} { handle_exception ${catch_status} ${catch_message} } +# function to parse the read of a parameter on a device +proc ::scobj::knauer_pump::remote_read {tc_root} { + set catch_status [ catch { + debug_log ${tc_root} 1 "remote_read tc_root=${tc_root} sct=[sct] result=[sct result]" + if { [hpropexists [sct] geterror] } { + hdelprop [sct] geterror + } + set data [sct result] + set nextState "idle" + if {[string equal -nocase -length 7 ${data} "ASCERR:"]} { + # the protocol driver has reported an error + sct geterror "${data}" + error "[sct geterror]" + } +# remote_read hook code starts + if { [string equal -length 7 ${data} "REMOTE:"] } { + set data [lindex [split ${data} :] 1] + } else { + sct geterror "bad response" + error "[sct geterror]" + } +# remote_read hook code ends + if { [hpropexists [sct] geterror] } { + debug_log ${tc_root} 9 "[sct] error: [sct geterror]" + error "[sct geterror]" + } + if { ${data} != [sct oldval] } { + debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]" + sct oldval ${data} + sct update ${data} + sct utime readtime + } + return ${nextState} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +# function to write a parameter value on a device +proc ::scobj::knauer_pump::remote_write {tc_root nextState cmd_str} { + set catch_status [ catch { + debug_log ${tc_root} 1 "remote_write tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" + if { [hpropexists [sct] geterror] } { + hdelprop [sct] geterror + } + set par [sct target] + set cmd "${cmd_str}${par}" +# remote_write hook code starts + if { ${par} == 0 } { + set cmd "LOCAL" + } else { + set cmd "REMOTE" + } +# remote_write hook code ends + if { [hpropexists [sct] geterror] } { + debug_log ${tc_root} 9 "[sct] error: [sct geterror]" + error "[sct geterror]" + } + if { [hpropexists [sct] driving] } { + if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } { + sct driving 1 + } + } + debug_log ${tc_root} 1 "remote_write sct send ${cmd}" + if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { + sct send "${cmd}" + } + return ${nextState} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + # function to write a parameter value on a device proc ::scobj::knauer_pump::setValue {tc_root nextState cmd_str} { set catch_status [ catch { @@ -549,6 +631,7 @@ proc ::scobj::knauer_pump::volume_checkpumping {tc_root nextState cmd_str} { set ratio_tgt [join [split [hval ${tc_root}/pump/ratio_sp] /] ,] set cmd "RAMP:0,${flow_tgt},${ratio_tgt},0,0,0,0,0,0,0,0,2" set nextState noResponse + sct driving 0 sct pumping 0 } } @@ -621,10 +704,10 @@ proc ::scobj::knauer_pump::volume_fetch {tc_root nextState cmd_str} { sct raw_volume ${pump_volume} if { [hpropexists [sct] base_volume] } { set pump_volume [expr {${pump_volume} - [sct base_volume]}] - } else { + } elseif { [hpropexists [sct] raw_volume] } { sct base_volume [sct raw_volume] } - sct result ${pump_volume} + sct result [format "%.2f" ${pump_volume}] set cmd "@@NOSEND@@" # volume_fetch hook code ends if { [hpropexists [sct] geterror] } { @@ -673,6 +756,13 @@ proc ::scobj::knauer_pump::volume_write {tc_root nextState cmd_str} { set ratio_tgt [join [split [hval ${tc_root}/pump/ratio_sp] /] ,] set cmd "RAMP:0,${flow_tgt},${ratio_tgt},0,0,0,0,0,0,0,0,3" sct pumping 1 + set data ${par} + if { ${data} != [sct oldval] } { + debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]" + sct oldval ${data} + sct update ${data} + sct utime readtime + } # volume_write hook code ends if { [hpropexists [sct] geterror] } { debug_log ${tc_root} 9 "[sct] error: [sct geterror]" @@ -717,6 +807,7 @@ proc ::scobj::knauer_pump::mkDriver { sct_controller name device_class simulatio hsetprop ${scobj_hpath}/dummy/glp mutable true hsetprop ${scobj_hpath}/dummy/glp nxsave false hsetprop ${scobj_hpath}/dummy/glp oldval UNKNOWN + hsetprop ${scobj_hpath}/dummy/glp real_data " " hsetprop ${scobj_hpath}/dummy/glp sdsinfo "::nexus::scobj::sdsinfo" hsetprop ${scobj_hpath}/dummy/glp type "part" hsetprop ${scobj_hpath}/dummy/glp nxalias "${name}_dummy_glp" @@ -1077,6 +1168,22 @@ proc ::scobj::knauer_pump::mkDriver { sct_controller name device_class simulatio hsetprop ${scobj_hpath}/pump/ratio_sp units "percent" hsetprop ${scobj_hpath}/pump/ratio_sp nxalias "${name}_pump_ratio_sp" + hfactory ${scobj_hpath}/pump/remote plain user int + hsetprop ${scobj_hpath}/pump/remote read ${ns}::getValue ${scobj_hpath} remote_read {REMOTE?} + hsetprop ${scobj_hpath}/pump/remote remote_read ${ns}::remote_read ${scobj_hpath} + hsetprop ${scobj_hpath}/pump/remote write ${ns}::remote_write ${scobj_hpath} noResponse {} + hsetprop ${scobj_hpath}/pump/remote noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/pump/remote check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/pump/remote control true + hsetprop ${scobj_hpath}/pump/remote data true + hsetprop ${scobj_hpath}/pump/remote mutable true + hsetprop ${scobj_hpath}/pump/remote nxsave true + hsetprop ${scobj_hpath}/pump/remote oldval 0 + hsetprop ${scobj_hpath}/pump/remote klass "parameter" + hsetprop ${scobj_hpath}/pump/remote sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/pump/remote type "part" + hsetprop ${scobj_hpath}/pump/remote nxalias "${name}_pump_remote" + hfactory ${scobj_hpath}/pump/state plain user text hsetprop ${scobj_hpath}/pump/state read ${ns}::state_fetch ${scobj_hpath} rdValue { } hsetprop ${scobj_hpath}/pump/state rdValue ${ns}::rdValue ${scobj_hpath} @@ -1145,12 +1252,14 @@ proc ::scobj::knauer_pump::mkDriver { sct_controller name device_class simulatio if {[string equal -nocase "${simulation_flag}" "false"]} { ${sct_controller} poll ${scobj_hpath}/pump/flow_pv 1 ${sct_controller} poll ${scobj_hpath}/pump/ratio_pv 1 + ${sct_controller} poll ${scobj_hpath}/pump/remote 1 ${sct_controller} poll ${scobj_hpath}/pump/state 1 ${sct_controller} poll ${scobj_hpath}/pump/status 1 ${sct_controller} poll ${scobj_hpath}/pump/volume_pv 1 ${sct_controller} poll ${scobj_hpath}/pump/volume_sp 1 ${sct_controller} write ${scobj_hpath}/pump/flow_sp ${sct_controller} write ${scobj_hpath}/pump/ratio_sp + ${sct_controller} write ${scobj_hpath}/pump/remote ${sct_controller} write ${scobj_hpath}/pump/volume_sp } else { ::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump" diff --git a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_m370.tcl b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_m370.tcl index c959e923..8e6e7de7 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_m370.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_m370.tcl @@ -27,18 +27,19 @@ proc ::scobj::lakeshore_m370::sics_log {debug_level debug_string} { } catch_message ] } -proc ::scobj::lakeshore_m370::mkDriver { sct_controller name id tol} { - ::scobj::lakeshore_m370::sics_log 9 "::scobj::lakeshore_m370::mkDriver ${sct_controller} ${name} ${id} ${tol}" +proc ::scobj::lakeshore_m370::mkDriver { sct_controller name device_class simulation_flag ip_address tcp_port id tol } { + ::scobj::lakeshore_m370::sics_log 9 "::scobj::lakeshore_m370::mkDriver ${sct_controller} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${tol}" set ns "[namespace current]" set catch_status [ catch { MakeSICSObj ${name} SCT_OBJECT user none - sicslist setatt ${name} klass environment + sicslist setatt ${name} klass ${device_class} sicslist setatt ${name} long_name ${name} set scobj_hpath /sics/${name} - hsetprop ${scobj_hpath} klass environment + hsetprop ${scobj_hpath} klass ${device_class} + hsetprop ${scobj_hpath} data true hsetprop ${scobj_hpath} debug_threshold 5 # mkDriver hook code starts ::scobj::lakeshore_370::mk_sct_driver $sct_controller environment $name $tol @@ -51,31 +52,37 @@ proc ::scobj::lakeshore_m370::mkDriver { sct_controller name id tol} { handle_exception ${catch_status} ${catch_message} } +proc ::scobj::lakeshore_m370::add_driver {name device_class simulation_flag ip_address tcp_port id tol} { + set catch_status [ catch { + ::scobj::lakeshore_m370::sics_log 9 "::scobj::lakeshore_m370::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${tol}" + if {[string equal -nocase "${simulation_flag}" "false"]} { + if {[string equal -nocase "aqadapter" "${ip_address}"]} { + ::scobj::lakeshore_m370::sics_log 9 "makesctcontroller sct_${name} aqadapter ${tcp_port}" + makesctcontroller sct_${name} aqadapter ${tcp_port} + } else { + ::scobj::lakeshore_m370::sics_log 9 "makesctcontroller sct_${name} std ${ip_address}:${tcp_port}" + makesctcontroller sct_${name} std ${ip_address}:${tcp_port} + } + } else { + ::scobj::lakeshore_m370::sics_log 9 "simulation_flag={simulation_flag} => No sctcontroller for lakeshore_m370" + } + ::scobj::lakeshore_m370::sics_log 1 "::scobj::lakeshore_m370::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${tol}" + ::scobj::lakeshore_m370::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} ${id} ${tol} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + namespace eval ::scobj::lakeshore_m370 { namespace export debug_threshold namespace export debug_log namespace export sics_log namespace export mkDriver + namespace export add_driver } -proc add_lakeshore_m370 {name IP port id tol} { - set catch_status [ catch { - ::scobj::lakeshore_m370::sics_log 9 "add_lakeshore_m370 ${name} ${IP} ${port} ${tol}" - if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { - if {[string equal -nocase "aqadapter" "${IP}"]} { - ::scobj::lakeshore_m370::sics_log 9 "makesctcontroller sct_${name} aqadapter ${port}" - makesctcontroller sct_${name} aqadapter ${port} - } else { - ::scobj::lakeshore_m370::sics_log 9 "makesctcontroller sct_${name} std ${IP}:${port}" - makesctcontroller sct_${name} std ${IP}:${port} - } - } else { - ::scobj::lakeshore_m370::sics_log 9 "[environment_simulation] => No sctcontroller for lakeshore_m370" - } - ::scobj::lakeshore_m370::sics_log 1 "::scobj::lakeshore_m370::mkDriver sct_${name} ${name} ${id} ${tol}" - ::scobj::lakeshore_m370::mkDriver sct_${name} ${name} ${id} ${tol} - } catch_message ] - handle_exception ${catch_status} ${catch_message} +proc add_lakeshore_m370 {name ip_address tcp_port id tol} { + set simulation_flag "[string tolower [SplitReply [environment_simulation]]]" + ::scobj::lakeshore_m370::add_driver ${name} "environment" "${simulation_flag}" ${ip_address} ${tcp_port} "${id}" "${tol}" } clientput "file evaluation of sct_lakeshore_m370.tcl" @@ -84,42 +91,41 @@ clientput "file evaluation of sct_lakeshore_m370.tcl" proc ::scobj::lakeshore_m370::read_config {} { set catch_status [ catch { set ns "::scobj::lakeshore_m370" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + 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 $v "enabled"]] + set enabled [string tolower [dict get $u "enabled"]] if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { continue } - set name [dict get $v name] - set implementation [dict get $v "implementation"] + 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 arg_list [list] - foreach arg {id} { - 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" - } - } set v [dict get $::config_dict $implementation] if { !([dict exists $v "driver"]) } { continue } if { [string equal -nocase [dict get $v "driver"] "lakeshore_m370"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + if { ![string equal -nocase "${simulation_flag}" "false"] } { set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + ${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 [dict get $v ip] - set PORT [dict get $v port] + set ip_address [dict get $v ip] + set tcp_port [dict get $v port] } } else { if { [dict exists $v "asyncprotocol"] } { @@ -133,25 +139,32 @@ proc ::scobj::lakeshore_m370::read_config {} { } } set asyncqueue ${name}_queue - set IP [dict get $v ip] - set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + 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"]" } } - foreach arg {tol} { - if {[dict exists $v $arg]} { + set arg_list [list] + set missing_list [list] + foreach arg {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" - error "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"] } { - add_lakeshore_m370 ${name} ${IP} ${PORT} {*}$arg_list + ${ns}::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} {*}$arg_list } else { - add_lakeshore_m370 ${name} "aqadapter" ${asyncqueue} {*}$arg_list + ${ns}::add_driver ${name} ${device_class} ${simulation_flag} "aqadapter" ${asyncqueue} {*}$arg_list } } } diff --git a/site_ansto/instrument/config/environment/temperature/sct_pfeiffer_hg.tcl b/site_ansto/instrument/config/environment/temperature/sct_pfeiffer_hg.tcl index a9e1ebc6..1176f967 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_pfeiffer_hg.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_pfeiffer_hg.tcl @@ -201,14 +201,14 @@ proc ::scobj::pfeiffer_hg::pid_pressure {tc_root sp pv} { set p_value [expr {[sct pid_pvalue] * [sct pid_error]}] set d_value [expr {[sct pid_dvalue] * (${pv} - [sct oldval])}] sct pid_deriv [sct pid_error] - sct pid_integ [expr {[sct pid_integ] + [sct pid_error]}] + sct pid_integ [expr {[sct pid_integ] + [sct pid_error] * [sct pid_ivalue]}] if { [sct pid_integ] > [sct pid_imax] } { sct pid_integ [sct pid_imax] } if { [sct pid_integ] < -[sct pid_imax] } { sct pid_integ -[sct pid_imax] } - set i_value [expr {[sct pid_ivalue] * [sct pid_integ]}] + set i_value [sct pid_integ] set pid [expr {${p_value} + ${i_value} + ${d_value}}] # pid_pressure hook code starts if { [hpropexists [sct] pid_control] } {