Files
sics/site_ansto/instrument/config/environment/sct_knauer_pump.tcl
2014-11-07 09:14:09 +11:00

1305 lines
50 KiB
Tcl

# Generated driver for knauer_pump
# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent
#
namespace eval ::scobj::knauer_pump {
set debug_threshold 0
}
proc ::scobj::knauer_pump::debug_log {tc_root debug_level debug_string} {
set catch_status [ catch {
set debug_threshold [hgetpropval ${tc_root} debug_threshold]
if {${debug_level} >= ${debug_threshold}} {
set fd [open "../log/knauer_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::knauer_pump::sics_log {debug_level debug_string} {
set catch_status [ catch {
set debug_threshold ${::scobj::knauer_pump::debug_threshold}
if {${debug_level} >= ${debug_threshold}} {
sicslog "::scobj::knauer_pump::${debug_string}"
}
} catch_message ]
}
# checklimits function for driveable interface
proc ::scobj::knauer_pump::checklimits {tc_root} {
set catch_status [ catch {
debug_log ${tc_root} 1 "checklimits tc_root=${tc_root} sct=[sct] target=[sct target]"
set setpoint [sct target]
if { [hpropexists [sct] lowerlimit] } {
set lolimit [sct lowerlimit]
} else {
# lowerlimit not set, use target
set lolimit [sct target]
}
if { [hpropexists [sct] upperlimit] } {
set hilimit [sct upperlimit]
} else {
# upperlimit not set, use target
set hilimit [sct target]
}
# checklimits hook code goes here
if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } {
sct driving 0
error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]"
}
return OK
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# check function for hset change
proc ::scobj::knauer_pump::checkrange {tc_root} {
set catch_status [ catch {
debug_log ${tc_root} 1 "checkrange tc_root=${tc_root} sct=[sct] target=[sct target]"
set setpoint [sct target]
if { [hpropexists [sct] lowerlimit] } {
set lolimit [sct lowerlimit]
} else {
# lowerlimit not set, use target
set lolimit [sct target]
}
if { [hpropexists [sct] upperlimit] } {
set hilimit [sct upperlimit]
} else {
# upperlimit not set, use target
set hilimit [sct target]
}
# checkrange hook code goes here
if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } {
error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]"
}
return OK
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to request the read of a parameter on a device
proc ::scobj::knauer_pump::flow_fetch {tc_root nextState cmd_str} {
set catch_status [ catch {
debug_log ${tc_root} 1 "flow_fetch tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set cmd "${cmd_str}"
# flow_fetch hook code starts
set index 4
set data [hgetpropval ${tc_root}/dummy/status real_data]
set dlist [split ${data} ","]
if { [llength ${dlist}] > ${index} } {
set flow_pv [lindex ${dlist} 4]
} else {
set flow_pv 0.0
}
sct result [expr {0.001 * ${flow_pv}}]
set cmd "@@NOSEND@@"
# flow_fetch hook code ends
if { [hpropexists [sct] geterror] } {
debug_log ${tc_root} 9 "[sct] error: [sct geterror]"
error "[sct geterror]"
}
debug_log ${tc_root} 1 "flow_fetch sct send ${cmd}"
if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {
sct send "${cmd}"
}
return ${nextState}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to write a parameter value on a device
proc ::scobj::knauer_pump::flow_write {tc_root nextState cmd_str} {
set catch_status [ catch {
debug_log ${tc_root} 1 "flow_write tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set par [sct target]
set cmd "${cmd_str}${par}"
# flow_write hook code starts
set data [sct target]
set cmd "@@NOSEND@@"
set nextState idle
if { ${data} != [sct oldval] } {
debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]"
sct oldval ${data}
sct update ${data}
sct utime readtime
}
# flow_write hook code ends
if { [hpropexists [sct] geterror] } {
debug_log ${tc_root} 9 "[sct] error: [sct geterror]"
error "[sct geterror]"
}
if { [hpropexists [sct] driving] } {
if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } {
sct driving 1
}
}
debug_log ${tc_root} 1 "flow_write sct send ${cmd}"
if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {
sct send "${cmd}"
}
return ${nextState}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to request the read of a parameter on a device
proc ::scobj::knauer_pump::getValue {tc_root nextState cmd_str} {
set catch_status [ catch {
debug_log ${tc_root} 1 "getValue tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set cmd "${cmd_str}"
# getValue hook code goes here
debug_log ${tc_root} 1 "getValue sct send ${cmd}"
if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {
sct send "${cmd}"
}
return ${nextState}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to check the write parameter on a device
proc ::scobj::knauer_pump::noResponse {tc_root} {
set catch_status [ catch {
debug_log ${tc_root} 1 "noResponse tc_root=${tc_root} sct=[sct] resp=[sct result]"
# noResponse hook code goes here
return "idle"
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# check function for hset change
proc ::scobj::knauer_pump::ratio_check {tc_root} {
set catch_status [ catch {
debug_log ${tc_root} 1 "ratio_check tc_root=${tc_root} sct=[sct] target=[sct target]"
set setpoint [sct target]
if { [hpropexists [sct] lowerlimit] } {
set lolimit [sct lowerlimit]
} else {
# lowerlimit not set, use target
set lolimit [sct target]
}
if { [hpropexists [sct] upperlimit] } {
set hilimit [sct upperlimit]
} else {
# upperlimit not set, use target
set hilimit [sct target]
}
# ratio_check hook code starts
set rlist [split ${setpoint} /]
if { [llength ${rlist}] != 4 } {
sct geterror "${setpoint} has [llength ${rlist}] components, needs 4"
error [sct geterror]
}
set sum 0
for {set i 0} {$i < 4} {incr i} {
set cmp [lindex ${rlist} ${i}]
if { ![string is integer -strict ${cmp}] } {
sct geterror "component [expr {${i} + 1}] is not integer: \"${cmp}\""
error [sct geterror]
}
if { !(${cmp} >= 0 && ${cmp} <= 100) } {
sct geterror "component [expr {${i} + 1}] is not between 0 and 100: \"${cmp}\""
error [sct geterror]
}
set sum [expr {${sum} + ${cmp}}]
}
if { ${sum} != 100 } {
sct geterror "sum of components is ${sum}, must be 100"
error [sct geterror]
}
# ratio_check hook code ends
if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } {
error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]"
}
return OK
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to request the read of a parameter on a device
proc ::scobj::knauer_pump::ratio_fetch {tc_root nextState cmd_str} {
set catch_status [ catch {
debug_log ${tc_root} 1 "ratio_fetch tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set cmd "${cmd_str}"
# ratio_fetch hook code starts
set data [hgetpropval ${tc_root}/dummy/status real_data]
set dlist [split ${data} ","]
set ratio_vals "[lindex ${dlist} 5]/[lindex ${dlist} 6]/[lindex ${dlist} 7]/[lindex ${dlist} 8]"
sct result ${ratio_vals}
set cmd "@@NOSEND@@"
# ratio_fetch hook code ends
if { [hpropexists [sct] geterror] } {
debug_log ${tc_root} 9 "[sct] error: [sct geterror]"
error "[sct geterror]"
}
debug_log ${tc_root} 1 "ratio_fetch sct send ${cmd}"
if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {
sct send "${cmd}"
}
return ${nextState}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to write a parameter value on a device
proc ::scobj::knauer_pump::ratio_write {tc_root nextState cmd_str} {
set catch_status [ catch {
debug_log ${tc_root} 1 "ratio_write tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set par [sct target]
set cmd "${cmd_str}${par}"
# ratio_write hook code starts
set data [sct target]
set cmd "@@NOSEND@@"
set nextState idle
if { ${data} != [sct oldval] } {
debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]"
sct oldval ${data}
sct update ${data}
sct utime readtime
}
# ratio_write hook code ends
if { [hpropexists [sct] geterror] } {
debug_log ${tc_root} 9 "[sct] error: [sct geterror]"
error "[sct geterror]"
}
if { [hpropexists [sct] driving] } {
if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } {
sct driving 1
}
}
debug_log ${tc_root} 1 "ratio_write sct send ${cmd}"
if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {
sct send "${cmd}"
}
return ${nextState}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to parse the read of a parameter on a device
proc ::scobj::knauer_pump::rdValue {tc_root} {
set catch_status [ catch {
debug_log ${tc_root} 1 "rdValue tc_root=${tc_root} sct=[sct] result=[sct result]"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set data [sct result]
set nextState "idle"
if {[string equal -nocase -length 7 ${data} "ASCERR:"]} {
# the protocol driver has reported an error
sct geterror "${data}"
error "[sct geterror]"
}
# rdValue hook code goes here
if { ${data} != [sct oldval] } {
debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]"
sct oldval ${data}
sct update ${data}
sct utime readtime
}
return ${nextState}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to parse the read of a parameter on a device
proc ::scobj::knauer_pump::read_glp {tc_root} {
set catch_status [ catch {
debug_log ${tc_root} 1 "read_glp tc_root=${tc_root} sct=[sct] result=[sct result]"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set data [sct result]
set nextState "idle"
if {[string equal -nocase -length 7 ${data} "ASCERR:"]} {
# the protocol driver has reported an error
sct geterror "${data}"
error "[sct geterror]"
}
# read_glp hook code starts
if { [string equal -nocase -length 6 ${data} "ERROR:"] } {
} else {
set dlist [split [lindex [split ${data} ":"] 1] ","]
sct real_data "[join [lrange ${dlist} 0 end] ,]"
set data "Hidden in real_data property"
}
# read_glp hook code ends
if { [hpropexists [sct] geterror] } {
debug_log ${tc_root} 9 "[sct] error: [sct geterror]"
error "[sct geterror]"
}
if { ${data} != [sct oldval] } {
debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]"
sct oldval ${data}
sct update ${data}
sct utime readtime
}
return ${nextState}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to parse the read of a parameter on a device
proc ::scobj::knauer_pump::read_status {tc_root} {
set catch_status [ catch {
debug_log ${tc_root} 1 "read_status tc_root=${tc_root} sct=[sct] result=[sct result]"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set data [sct result]
set nextState "idle"
if {[string equal -nocase -length 7 ${data} "ASCERR:"]} {
# the protocol driver has reported an error
sct geterror "${data}"
error "[sct geterror]"
}
# read_status hook code starts
set dlist [split [lindex [split ${data} ":"] 1] ","]
sct real_data "[join [lrange ${dlist} 0 end] ,]"
set data "Hidden in real_data property"
# read_status hook code ends
if { [hpropexists [sct] geterror] } {
debug_log ${tc_root} 9 "[sct] error: [sct geterror]"
error "[sct geterror]"
}
if { ${data} != [sct oldval] } {
debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]"
sct oldval ${data}
sct update ${data}
sct utime readtime
}
return ${nextState}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to parse the read of a parameter on a device
proc ::scobj::knauer_pump::remote_read {tc_root} {
set catch_status [ catch {
debug_log ${tc_root} 1 "remote_read tc_root=${tc_root} sct=[sct] result=[sct result]"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set data [sct result]
set nextState "idle"
if {[string equal -nocase -length 7 ${data} "ASCERR:"]} {
# the protocol driver has reported an error
sct geterror "${data}"
error "[sct geterror]"
}
# remote_read hook code starts
if { [string equal -length 7 ${data} "REMOTE:"] } {
set data [lindex [split ${data} :] 1]
} else {
sct geterror "bad response"
error "[sct geterror]"
}
# remote_read hook code ends
if { [hpropexists [sct] geterror] } {
debug_log ${tc_root} 9 "[sct] error: [sct geterror]"
error "[sct geterror]"
}
if { ${data} != [sct oldval] } {
debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]"
sct oldval ${data}
sct update ${data}
sct utime readtime
}
return ${nextState}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to write a parameter value on a device
proc ::scobj::knauer_pump::remote_write {tc_root nextState cmd_str} {
set catch_status [ catch {
debug_log ${tc_root} 1 "remote_write tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set par [sct target]
set cmd "${cmd_str}${par}"
# remote_write hook code starts
if { ${par} == 0 } {
set cmd "LOCAL"
} else {
set cmd "REMOTE"
}
# remote_write hook code ends
if { [hpropexists [sct] geterror] } {
debug_log ${tc_root} 9 "[sct] error: [sct geterror]"
error "[sct geterror]"
}
if { [hpropexists [sct] driving] } {
if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } {
sct driving 1
}
}
debug_log ${tc_root} 1 "remote_write sct send ${cmd}"
if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {
sct send "${cmd}"
}
return ${nextState}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to write a parameter value on a device
proc ::scobj::knauer_pump::setValue {tc_root nextState cmd_str} {
set catch_status [ catch {
debug_log ${tc_root} 1 "setValue tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set par [sct target]
set cmd "${cmd_str}${par}"
# setValue hook code goes here
if { [hpropexists [sct] driving] } {
if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } {
sct driving 1
}
}
debug_log ${tc_root} 1 "setValue sct send ${cmd}"
if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {
sct send "${cmd}"
}
return ${nextState}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to request the read of a parameter on a device
proc ::scobj::knauer_pump::state_fetch {tc_root nextState cmd_str} {
set catch_status [ catch {
debug_log ${tc_root} 1 "state_fetch tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set cmd "${cmd_str}"
# state_fetch hook code starts
set index 1
set data [hgetpropval ${tc_root}/dummy/status real_data]
set dlist [split ${data} ","]
if { [llength ${dlist}] > ${index} } {
set state_code [lindex ${dlist} ${index}]
} else {
set state_code "0"
}
set cmd "@@NOSEND@@"
if { ${state_code} < 0 || ${state_code} > 9 } {
sct geterror "Invalid device_state ${state_code}"
error "[sct geterror]"
}
set slist [list "SYS_ST_INITIALIZING" \
"SYS_ST_OFF" \
"SYS_ST_IDLE" \
"SYS_ST_RUN" \
"SYS_ST_HOLD" \
"SYS_ST_PURGE" \
"SYS_ST_STANDBY" \
"SYS_ST_SEVEN" \
"SYS_ST_FAILED" \
"SYS_ST_RUNATEND" \
]
sct result [lindex ${slist} ${state_code}]
# state_fetch hook code ends
if { [hpropexists [sct] geterror] } {
debug_log ${tc_root} 9 "[sct] error: [sct geterror]"
error "[sct geterror]"
}
debug_log ${tc_root} 1 "state_fetch sct send ${cmd}"
if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {
sct send "${cmd}"
}
return ${nextState}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to request the read of a parameter on a device
proc ::scobj::knauer_pump::status_fetch {tc_root nextState cmd_str} {
set catch_status [ catch {
debug_log ${tc_root} 1 "status_fetch tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set cmd "${cmd_str}"
# status_fetch hook code starts
set index 1
set data [hgetpropval ${tc_root}/dummy/status real_data]
set dlist [split ${data} ","]
set status_code [lindex ${dlist} ${index}]
set cmd "@@NOSEND@@"
if { ${status_code} == 3 } {
sct result "PUMPING"
} else {
sct result "IDLE"
}
# status_fetch hook code ends
if { [hpropexists [sct] geterror] } {
debug_log ${tc_root} 9 "[sct] error: [sct geterror]"
error "[sct geterror]"
}
debug_log ${tc_root} 1 "status_fetch sct send ${cmd}"
if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {
sct send "${cmd}"
}
return ${nextState}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to check the write parameter on a device
proc ::scobj::knauer_pump::volume_check {tc_root} {
set catch_status [ catch {
debug_log ${tc_root} 1 "volume_check tc_root=${tc_root} sct=[sct] resp=[sct result]"
# volume_check hook code goes here
return "idle"
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# checkstatus function for driveable interface
proc ::scobj::knauer_pump::volume_checkstatus {tc_root} {
set catch_status [ catch {
# volume_checkstatus hook code goes here
if {[sct driving]} {
set sp "[sct target]"
if {[hpropexists [sct] simulated] && [sct simulated] == "true"} {
set pv "${sp}"
hupdateif ${tc_root}/[sct driveable] ${sp}
}
set pv "[hval ${tc_root}/[sct driveable]]"
}
if { abs(${pv} - ${sp}) <= [sct tolerance] } {
if { [hpropexists [sct] settle_time] } {
if { [hpropexists [sct] settle_time_start] } {
if { [sct utime] - [sct settle_time_start] >= [sct settle_time]} {
sct driving 0
return "idle"
}
return "busy"
} else {
sct utime settle_time_start
return "busy"
}
}
sct driving 0
return "idle"
}
if { [hpropexists [sct] settle_time_start] } {
hdelprop [sct] settle_time_start
}
return "busy"
} else {
return "idle"
}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to request the read of a parameter on a device
proc ::scobj::knauer_pump::volume_fetch {tc_root nextState cmd_str} {
set catch_status [ catch {
debug_log ${tc_root} 1 "volume_fetch tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set cmd "${cmd_str}"
# volume_fetch hook code starts
set data [hgetpropval ${tc_root}/dummy/glp real_data]
set dlist [split ${data} ","]
if { [llength ${dlist}] > 11 } {
set pump_volm [lindex ${dlist} 10]
set pump_voln [lindex ${dlist} 11]
set pump_volume [expr {${pump_volm} + 0.000001 * ${pump_voln}}]
} else {
set pump_volume 0.0
}
sct raw_volume ${pump_volume}
if { [hpropexists [sct] base_volume] } {
set pump_volume [expr {${pump_volume} - [sct base_volume]}]
} elseif { [hpropexists [sct] raw_volume] } {
sct base_volume [sct raw_volume]
}
sct result [format "%.2f" ${pump_volume}]
set cmd "@@NOSEND@@"
# volume_fetch hook code ends
if { [hpropexists [sct] geterror] } {
debug_log ${tc_root} 9 "[sct] error: [sct geterror]"
error "[sct geterror]"
}
debug_log ${tc_root} 1 "volume_fetch sct send ${cmd}"
if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {
sct send "${cmd}"
}
return ${nextState}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to request the read of a parameter on a device
proc ::scobj::knauer_pump::volume_fsm {tc_root nextState cmd_str} {
set catch_status [ catch {
debug_log ${tc_root} 1 "volume_fsm tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set cmd "${cmd_str}"
# volume_fsm hook code starts
if { [sct this_state] > 0 } {
set flow_tgt [expr {int(1000.0 * [hval ${tc_root}/pump/flow/setp])}]
set ratio_tgt [join [split [hval ${tc_root}/pump/ratio/setp] /] ,]
set time_tgt [expr {int(60000.0 * 1000.0 * [sct target] / ${flow_tgt})}]
set time_1 [expr {${time_tgt} - 500}]
set time_2 [expr {${time_tgt} + 500}]
set saveState ${nextState}
set nextState "noResponse"
if { [sct this_state] == 1 } {
set cmd "GLP?"
set nextState ${saveState}
sct this_state [expr {[sct this_state] + 1}]
} elseif { [sct this_state] == 2 } {
set cmd "TT_LOAD:1"
sct this_state [expr {[sct this_state] + 1}]
} elseif { [sct this_state] == 3 } {
set cmd "TT_SET:0,0,${flow_tgt},${ratio_tgt},0,0,0,0,0,0,0,0"
sct this_state [expr {[sct this_state] + 1}]
} elseif { [sct this_state] == 4 } {
set cmd "TT_SET:1,${time_1},${flow_tgt},${ratio_tgt},0,0,0,0,0,0,0,0"
sct this_state [expr {[sct this_state] + 1}]
} elseif { [sct this_state] == 5 } {
set cmd "TT_SET:2,${time_2},0,${ratio_tgt},0,0,0,0,0,0,0,0"
sct this_state [expr {[sct this_state] + 1}]
} elseif { [sct this_state] == 6 } {
set cmd "START:1,0"
sct this_state 0
} elseif { [sct this_state] == 91 } {
set cmd "STOP:1,0"
sct this_state 92
} elseif { [sct this_state] == 92 } {
set cmd "STOP:0,0"
sct this_state 93
} elseif { [sct this_state] == 93 } {
if { !([hpropexists ${tc_root}/pump/remote target] && [hgetpropval ${tc_root}/pump/remote target] == 1) } {
set cmd "LOCAL"
} else {
set cmd "@@NOSEND@@"
}
sct this_state 0
} else {
sct this_state 0
set cmd "@@NOSEND@@"
set nextState idle
}
} else {
set cmd "@@NOSEND@@"
set nextState idle
if { [hpropexists [sct] pumping] && [sct pumping] } {
set new_value [hval ${tc_root}/pump/status]
set old_value [sct oldval]
if {${new_value} != ${old_value}} {
sct oldval ${new_value}
if {${old_value} == "PUMPING" && ${new_value} == "IDLE"} {
set cmd "STOP:0,0"
sct this_state 91
set nextState noResponse
sct result ""
sct driving 0
sct pumping 0
}
}
}
}
# volume_fsm hook code ends
if { [hpropexists [sct] geterror] } {
debug_log ${tc_root} 9 "[sct] error: [sct geterror]"
error "[sct geterror]"
}
debug_log ${tc_root} 1 "volume_fsm sct send ${cmd}"
if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {
sct send "${cmd}"
}
return ${nextState}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# halt function for driveable interface
proc ::scobj::knauer_pump::volume_halt {tc_root} {
set catch_status [ catch {
debug_log ${tc_root} 1 "volume_halt tc_root=${tc_root} sct=[sct] driving=[sct driving]"
### TODO hset [sct] [hval [sct]]
# volume_halt hook code starts
set cmd "STOP:0,0"
sct this_state 91
debug_log ${tc_root} 1 "volume_halt sct send ${cmd}"
sct send ${cmd}
# volume_halt hook code ends
sct driving 0
return "idle"
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to parse the read of a parameter on a device
proc ::scobj::knauer_pump::volume_read {tc_root} {
set catch_status [ catch {
debug_log ${tc_root} 1 "volume_read tc_root=${tc_root} sct=[sct] result=[sct result]"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set data [sct result]
set nextState "idle"
if {[string equal -nocase -length 7 ${data} "ASCERR:"]} {
# the protocol driver has reported an error
sct geterror "${data}"
error "[sct geterror]"
}
# volume_read hook code goes here
if { ${data} != [sct oldval] } {
debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]"
sct oldval ${data}
sct update ${data}
sct utime readtime
}
return ${nextState}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to parse the read of a parameter on a device
proc ::scobj::knauer_pump::volume_store {tc_root} {
set catch_status [ catch {
debug_log ${tc_root} 1 "volume_store tc_root=${tc_root} sct=[sct] result=[sct result]"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set data [sct result]
set nextState "idle"
if {[string equal -nocase -length 7 ${data} "ASCERR:"]} {
# the protocol driver has reported an error
sct geterror "${data}"
error "[sct geterror]"
}
# volume_store hook code starts
if { [sct this_state] == 2 } {
set ns [namespace current]
# store the GLP result
hsetprop ${tc_root}/dummy/glp result "${data}"
sct with ${tc_root}/dummy/glp "${ns}::read_glp ${tc_root}"
# extract the volume
sct with ${tc_root}/[sct driveable] "${ns}::volume_fetch ${tc_root} ${nextState} @@NOSEND@@"
sct with ${tc_root}/[sct driveable] "${ns}::volume_read ${tc_root}"
# copy it to base_volume
hsetprop ${tc_root}/[sct driveable] base_volume [hgetpropval ${tc_root}/[sct driveable] raw_volume]
}
if { [hpropexists [sct] target] } {
set data [sct target]
} else {
set data 0.0
}
# volume_store hook code ends
if { [hpropexists [sct] geterror] } {
debug_log ${tc_root} 9 "[sct] error: [sct geterror]"
error "[sct geterror]"
}
if { ${data} != [sct oldval] } {
debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]"
sct oldval ${data}
sct update ${data}
sct utime readtime
}
return ${nextState}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to write a parameter value on a device
proc ::scobj::knauer_pump::volume_write {tc_root nextState cmd_str} {
set catch_status [ catch {
debug_log ${tc_root} 1 "volume_write tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set par [sct target]
set cmd "${cmd_str}${par}"
# volume_write hook code starts
hset ${tc_root}/[sct driveable] 0.0
set cmd "REMOTE"
sct this_state 1
sct pumping 1
set data ${par}
if { ${data} != [sct oldval] } {
debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]"
sct oldval ${data}
sct update ${data}
sct utime readtime
}
# volume_write hook code ends
if { [hpropexists [sct] geterror] } {
debug_log ${tc_root} 9 "[sct] error: [sct geterror]"
error "[sct geterror]"
}
if { [hpropexists [sct] driving] } {
if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } {
sct driving 1
}
}
debug_log ${tc_root} 1 "volume_write sct send ${cmd}"
if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {
sct send "${cmd}"
}
return ${nextState}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
proc ::scobj::knauer_pump::mkDriver { sct_controller name device_class simulation_flag ip_address tcp_port } {
::scobj::knauer_pump::sics_log 9 "::scobj::knauer_pump::mkDriver ${sct_controller} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port}"
set ns "[namespace current]"
set catch_status [ catch {
MakeSICSObj ${name} SCT_OBJECT
sicslist setatt ${name} klass ${device_class}
sicslist setatt ${name} long_name ${name}
set scobj_hpath /sics/${name}
hfactory ${scobj_hpath}/dummy plain spy none
hfactory ${scobj_hpath}/dummy/glp plain user text
hsetprop ${scobj_hpath}/dummy/glp read ${ns}::getValue ${scobj_hpath} read_glp {GLP?}
hsetprop ${scobj_hpath}/dummy/glp read_glp ${ns}::read_glp ${scobj_hpath}
hsetprop ${scobj_hpath}/dummy/glp control false
hsetprop ${scobj_hpath}/dummy/glp data false
hsetprop ${scobj_hpath}/dummy/glp mutable true
hsetprop ${scobj_hpath}/dummy/glp nxsave false
hsetprop ${scobj_hpath}/dummy/glp oldval UNKNOWN
hsetprop ${scobj_hpath}/dummy/glp real_data " "
hsetprop ${scobj_hpath}/dummy/glp sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/dummy/glp type "part"
hsetprop ${scobj_hpath}/dummy/glp nxalias "${name}_dummy_glp"
if {[string equal -nocase "${simulation_flag}" "false"]} {
${sct_controller} poll ${scobj_hpath}/dummy/glp 1
hsetprop ${scobj_hpath}/dummy/glp simulated false
} else {
::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump"
hsetprop ${scobj_hpath}/dummy/glp simulated true
}
hfactory ${scobj_hpath}/dummy/status plain user text
hsetprop ${scobj_hpath}/dummy/status read ${ns}::getValue ${scobj_hpath} read_status {STATUS?}
hsetprop ${scobj_hpath}/dummy/status read_status ${ns}::read_status ${scobj_hpath}
hsetprop ${scobj_hpath}/dummy/status control false
hsetprop ${scobj_hpath}/dummy/status data false
hsetprop ${scobj_hpath}/dummy/status mutable true
hsetprop ${scobj_hpath}/dummy/status nxsave false
hsetprop ${scobj_hpath}/dummy/status oldval UNKNOWN
hsetprop ${scobj_hpath}/dummy/status real_data " "
hsetprop ${scobj_hpath}/dummy/status sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/dummy/status type "part"
hsetprop ${scobj_hpath}/dummy/status nxalias "${name}_dummy_status"
if {[string equal -nocase "${simulation_flag}" "false"]} {
${sct_controller} poll ${scobj_hpath}/dummy/status 1
hsetprop ${scobj_hpath}/dummy/status simulated false
} else {
::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump"
hsetprop ${scobj_hpath}/dummy/status simulated true
}
hsetprop ${scobj_hpath}/dummy data "false"
hsetprop ${scobj_hpath}/dummy klass "@none"
hsetprop ${scobj_hpath}/dummy type "part"
hfactory ${scobj_hpath}/pump plain spy none
hfactory ${scobj_hpath}/pump/remote plain user int
hsetprop ${scobj_hpath}/pump/remote read ${ns}::getValue ${scobj_hpath} remote_read {REMOTE?}
hsetprop ${scobj_hpath}/pump/remote remote_read ${ns}::remote_read ${scobj_hpath}
hsetprop ${scobj_hpath}/pump/remote write ${ns}::remote_write ${scobj_hpath} noResponse {}
hsetprop ${scobj_hpath}/pump/remote noResponse ${ns}::noResponse ${scobj_hpath}
hsetprop ${scobj_hpath}/pump/remote check ${ns}::checkrange ${scobj_hpath}
hsetprop ${scobj_hpath}/pump/remote control true
hsetprop ${scobj_hpath}/pump/remote data true
hsetprop ${scobj_hpath}/pump/remote mutable true
hsetprop ${scobj_hpath}/pump/remote nxsave true
hsetprop ${scobj_hpath}/pump/remote values 0,1
hsetprop ${scobj_hpath}/pump/remote oldval 0
hsetprop ${scobj_hpath}/pump/remote klass "parameter"
hsetprop ${scobj_hpath}/pump/remote sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/pump/remote type "part"
hsetprop ${scobj_hpath}/pump/remote nxalias "${name}_pump_remote"
if {[string equal -nocase "${simulation_flag}" "false"]} {
${sct_controller} poll ${scobj_hpath}/pump/remote 1
${sct_controller} write ${scobj_hpath}/pump/remote
hsetprop ${scobj_hpath}/pump/remote simulated false
} else {
::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump"
hsetprop ${scobj_hpath}/pump/remote simulated true
}
hfactory ${scobj_hpath}/pump/state plain user text
hsetprop ${scobj_hpath}/pump/state read ${ns}::state_fetch ${scobj_hpath} rdValue { }
hsetprop ${scobj_hpath}/pump/state rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/pump/state control true
hsetprop ${scobj_hpath}/pump/state data true
hsetprop ${scobj_hpath}/pump/state mutable true
hsetprop ${scobj_hpath}/pump/state nxsave true
hsetprop ${scobj_hpath}/pump/state oldval UNKNOWN
hsetprop ${scobj_hpath}/pump/state klass "parameter"
hsetprop ${scobj_hpath}/pump/state sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/pump/state type "part"
hsetprop ${scobj_hpath}/pump/state nxalias "${name}_pump_state"
if {[string equal -nocase "${simulation_flag}" "false"]} {
${sct_controller} poll ${scobj_hpath}/pump/state 1
hsetprop ${scobj_hpath}/pump/state simulated false
} else {
::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump"
hsetprop ${scobj_hpath}/pump/state simulated true
}
hfactory ${scobj_hpath}/pump/status plain user text
hsetprop ${scobj_hpath}/pump/status read ${ns}::status_fetch ${scobj_hpath} rdValue { }
hsetprop ${scobj_hpath}/pump/status rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/pump/status control true
hsetprop ${scobj_hpath}/pump/status data true
hsetprop ${scobj_hpath}/pump/status mutable true
hsetprop ${scobj_hpath}/pump/status nxsave true
hsetprop ${scobj_hpath}/pump/status oldval UNKNOWN
hsetprop ${scobj_hpath}/pump/status klass "parameter"
hsetprop ${scobj_hpath}/pump/status sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/pump/status type "part"
hsetprop ${scobj_hpath}/pump/status nxalias "${name}_pump_status"
if {[string equal -nocase "${simulation_flag}" "false"]} {
${sct_controller} poll ${scobj_hpath}/pump/status 1
hsetprop ${scobj_hpath}/pump/status simulated false
} else {
::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump"
hsetprop ${scobj_hpath}/pump/status simulated true
}
hsetprop ${scobj_hpath}/pump data "true"
hsetprop ${scobj_hpath}/pump klass "@none"
hsetprop ${scobj_hpath}/pump type "part"
hfactory ${scobj_hpath}/pump/flow plain spy none
hfactory ${scobj_hpath}/pump/flow/pval plain user float
hsetprop ${scobj_hpath}/pump/flow/pval read ${ns}::flow_fetch ${scobj_hpath} rdValue { }
hsetprop ${scobj_hpath}/pump/flow/pval rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/pump/flow/pval control true
hsetprop ${scobj_hpath}/pump/flow/pval data true
hsetprop ${scobj_hpath}/pump/flow/pval mutable true
hsetprop ${scobj_hpath}/pump/flow/pval nxsave true
hsetprop ${scobj_hpath}/pump/flow/pval oldval 0.0
hsetprop ${scobj_hpath}/pump/flow/pval klass "parameter"
hsetprop ${scobj_hpath}/pump/flow/pval sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/pump/flow/pval type "part"
hsetprop ${scobj_hpath}/pump/flow/pval units "mL/min"
hsetprop ${scobj_hpath}/pump/flow/pval nxalias "${name}_pump_flow_pval"
if {[string equal -nocase "${simulation_flag}" "false"]} {
${sct_controller} poll ${scobj_hpath}/pump/flow/pval 1
hsetprop ${scobj_hpath}/pump/flow/pval simulated false
} else {
::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump"
hsetprop ${scobj_hpath}/pump/flow/pval simulated true
}
hfactory ${scobj_hpath}/pump/flow/setp plain user float
hsetprop ${scobj_hpath}/pump/flow/setp write ${ns}::flow_write ${scobj_hpath} noResponse { }
hsetprop ${scobj_hpath}/pump/flow/setp noResponse ${ns}::noResponse ${scobj_hpath}
hsetprop ${scobj_hpath}/pump/flow/setp check ${ns}::checkrange ${scobj_hpath}
hsetprop ${scobj_hpath}/pump/flow/setp control true
hsetprop ${scobj_hpath}/pump/flow/setp data true
hsetprop ${scobj_hpath}/pump/flow/setp mutable true
hsetprop ${scobj_hpath}/pump/flow/setp nxsave true
hsetprop ${scobj_hpath}/pump/flow/setp lowerlimit 0
hsetprop ${scobj_hpath}/pump/flow/setp upperlimit 9.999
hsetprop ${scobj_hpath}/pump/flow/setp oldval 1.0
hset ${scobj_hpath}/pump/flow/setp 1.0
hsetprop ${scobj_hpath}/pump/flow/setp klass "parameter"
hsetprop ${scobj_hpath}/pump/flow/setp sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/pump/flow/setp type "part"
hsetprop ${scobj_hpath}/pump/flow/setp units "mL/min"
hsetprop ${scobj_hpath}/pump/flow/setp nxalias "${name}_pump_flow_setp"
if {[string equal -nocase "${simulation_flag}" "false"]} {
${sct_controller} write ${scobj_hpath}/pump/flow/setp
hsetprop ${scobj_hpath}/pump/flow/setp simulated false
} else {
::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump"
hsetprop ${scobj_hpath}/pump/flow/setp simulated true
}
hsetprop ${scobj_hpath}/pump/flow data "true"
hsetprop ${scobj_hpath}/pump/flow klass "@none"
hsetprop ${scobj_hpath}/pump/flow type "part"
hfactory ${scobj_hpath}/pump/ratio plain spy none
hfactory ${scobj_hpath}/pump/ratio/pval plain user text
hsetprop ${scobj_hpath}/pump/ratio/pval read ${ns}::ratio_fetch ${scobj_hpath} rdValue { }
hsetprop ${scobj_hpath}/pump/ratio/pval rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/pump/ratio/pval control true
hsetprop ${scobj_hpath}/pump/ratio/pval data true
hsetprop ${scobj_hpath}/pump/ratio/pval mutable true
hsetprop ${scobj_hpath}/pump/ratio/pval nxsave true
hsetprop ${scobj_hpath}/pump/ratio/pval oldval UNKNOWN
hsetprop ${scobj_hpath}/pump/ratio/pval klass "parameter"
hsetprop ${scobj_hpath}/pump/ratio/pval sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/pump/ratio/pval type "part"
hsetprop ${scobj_hpath}/pump/ratio/pval units "percent"
hsetprop ${scobj_hpath}/pump/ratio/pval nxalias "${name}_pump_ratio_pval"
if {[string equal -nocase "${simulation_flag}" "false"]} {
${sct_controller} poll ${scobj_hpath}/pump/ratio/pval 1
hsetprop ${scobj_hpath}/pump/ratio/pval simulated false
} else {
::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump"
hsetprop ${scobj_hpath}/pump/ratio/pval simulated true
}
hfactory ${scobj_hpath}/pump/ratio/setp plain user text
hsetprop ${scobj_hpath}/pump/ratio/setp write ${ns}::ratio_write ${scobj_hpath} noResponse { }
hsetprop ${scobj_hpath}/pump/ratio/setp noResponse ${ns}::noResponse ${scobj_hpath}
hsetprop ${scobj_hpath}/pump/ratio/setp check ${ns}::ratio_check ${scobj_hpath}
hsetprop ${scobj_hpath}/pump/ratio/setp control true
hsetprop ${scobj_hpath}/pump/ratio/setp data true
hsetprop ${scobj_hpath}/pump/ratio/setp mutable true
hsetprop ${scobj_hpath}/pump/ratio/setp nxsave true
hsetprop ${scobj_hpath}/pump/ratio/setp oldval 25/25/25/25
hset ${scobj_hpath}/pump/ratio/setp 25/25/25/25
hsetprop ${scobj_hpath}/pump/ratio/setp klass "parameter"
hsetprop ${scobj_hpath}/pump/ratio/setp sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/pump/ratio/setp type "part"
hsetprop ${scobj_hpath}/pump/ratio/setp units "percent"
hsetprop ${scobj_hpath}/pump/ratio/setp nxalias "${name}_pump_ratio_setp"
if {[string equal -nocase "${simulation_flag}" "false"]} {
${sct_controller} write ${scobj_hpath}/pump/ratio/setp
hsetprop ${scobj_hpath}/pump/ratio/setp simulated false
} else {
::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump"
hsetprop ${scobj_hpath}/pump/ratio/setp simulated true
}
hsetprop ${scobj_hpath}/pump/ratio data "true"
hsetprop ${scobj_hpath}/pump/ratio klass "@none"
hsetprop ${scobj_hpath}/pump/ratio type "part"
hfactory ${scobj_hpath}/pump/volume plain spy none
hfactory ${scobj_hpath}/pump/volume/pval plain user float
hsetprop ${scobj_hpath}/pump/volume/pval read ${ns}::volume_fetch ${scobj_hpath} volume_read { }
hsetprop ${scobj_hpath}/pump/volume/pval volume_read ${ns}::volume_read ${scobj_hpath}
hsetprop ${scobj_hpath}/pump/volume/pval control true
hsetprop ${scobj_hpath}/pump/volume/pval data true
hsetprop ${scobj_hpath}/pump/volume/pval mutable true
hsetprop ${scobj_hpath}/pump/volume/pval nxsave true
hsetprop ${scobj_hpath}/pump/volume/pval oldval 0.0
hsetprop ${scobj_hpath}/pump/volume/pval klass "parameter"
hsetprop ${scobj_hpath}/pump/volume/pval sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/pump/volume/pval type "part"
hsetprop ${scobj_hpath}/pump/volume/pval units "mL"
hsetprop ${scobj_hpath}/pump/volume/pval nxalias "${name}_pump_volume_pval"
if {[string equal -nocase "${simulation_flag}" "false"]} {
${sct_controller} poll ${scobj_hpath}/pump/volume/pval 1
hsetprop ${scobj_hpath}/pump/volume/pval simulated false
} else {
::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump"
hsetprop ${scobj_hpath}/pump/volume/pval simulated true
}
hfactory ${scobj_hpath}/pump/volume/setp plain user float
hsetprop ${scobj_hpath}/pump/volume/setp read ${ns}::volume_fsm ${scobj_hpath} volume_store { }
hsetprop ${scobj_hpath}/pump/volume/setp volume_store ${ns}::volume_store ${scobj_hpath}
hsetprop ${scobj_hpath}/pump/volume/setp write ${ns}::volume_write ${scobj_hpath} volume_check { }
hsetprop ${scobj_hpath}/pump/volume/setp volume_check ${ns}::volume_check ${scobj_hpath}
hsetprop ${scobj_hpath}/pump/volume/setp check ${ns}::checkrange ${scobj_hpath}
hsetprop ${scobj_hpath}/pump/volume/setp driving 0
hsetprop ${scobj_hpath}/pump/volume/setp checklimits ${ns}::checklimits ${scobj_hpath}
hsetprop ${scobj_hpath}/pump/volume/setp checkstatus ${ns}::volume_checkstatus ${scobj_hpath}
hsetprop ${scobj_hpath}/pump/volume/setp halt ${ns}::volume_halt ${scobj_hpath}
hsetprop ${scobj_hpath}/pump/volume/setp driveable pump/volume/pval
hsetprop ${scobj_hpath}/pump/volume/setp control true
hsetprop ${scobj_hpath}/pump/volume/setp data true
hsetprop ${scobj_hpath}/pump/volume/setp mutable true
hsetprop ${scobj_hpath}/pump/volume/setp nxsave true
hsetprop ${scobj_hpath}/pump/volume/setp lowerlimit 0
hsetprop ${scobj_hpath}/pump/volume/setp upperlimit 100
hsetprop ${scobj_hpath}/pump/volume/setp tolerance 0.01
hsetprop ${scobj_hpath}/pump/volume/setp oldval 0.0
hsetprop ${scobj_hpath}/pump/volume/setp klass "parameter"
hsetprop ${scobj_hpath}/pump/volume/setp sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/pump/volume/setp this_state "0"
hsetprop ${scobj_hpath}/pump/volume/setp type "drivable"
hsetprop ${scobj_hpath}/pump/volume/setp units "mL"
hsetprop ${scobj_hpath}/pump/volume/setp nxalias "${name}_pump_volume_setp"
if {[string equal -nocase "${simulation_flag}" "false"]} {
${sct_controller} poll ${scobj_hpath}/pump/volume/setp 1
${sct_controller} write ${scobj_hpath}/pump/volume/setp
hsetprop ${scobj_hpath}/pump/volume/setp simulated false
} else {
::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for knauer_pump"
hsetprop ${scobj_hpath}/pump/volume/setp simulated true
}
hsetprop ${scobj_hpath}/pump/volume data "true"
hsetprop ${scobj_hpath}/pump/volume klass "@none"
hsetprop ${scobj_hpath}/pump/volume type "part"
ansto_makesctdrive ${name}_pump_volume_setp ${scobj_hpath}/pump/volume/setp ${scobj_hpath}/pump/volume/pval ${sct_controller}
hsetprop ${scobj_hpath} klass ${device_class}
hsetprop ${scobj_hpath} data true
hsetprop ${scobj_hpath} debug_threshold 0
# mkDriver hook code starts
#hset ${scobj_hpath}/pump/remote 1
# mkDriver hook code ends
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
proc ::scobj::knauer_pump::add_driver {name device_class simulation_flag ip_address tcp_port} {
set catch_status [ catch {
::scobj::knauer_pump::sics_log 9 "::scobj::knauer_pump::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port}"
if {[string equal -nocase "${simulation_flag}" "false"]} {
if {[string equal -nocase "aqadapter" "${ip_address}"]} {
::scobj::knauer_pump::sics_log 9 "makesctcontroller sct_${name} aqadapter ${tcp_port}"
makesctcontroller sct_${name} aqadapter ${tcp_port}
} else {
::scobj::knauer_pump::sics_log 9 "makesctcontroller sct_${name} knauer_ap ${ip_address}:${tcp_port}"
makesctcontroller sct_${name} knauer_ap ${ip_address}:${tcp_port}
}
} else {
::scobj::knauer_pump::sics_log 9 "simulation_flag=${simulation_flag} => Null sctcontroller for knauer_pump"
::scobj::knauer_pump::sics_log 9 "makesctcontroller sct_${name} aqadapter NULL"
makesctcontroller sct_${name} aqadapter NULL
}
::scobj::knauer_pump::sics_log 1 "::scobj::knauer_pump::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port}"
::scobj::knauer_pump::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
namespace eval ::scobj::knauer_pump {
namespace export debug_threshold
namespace export debug_log
namespace export sics_log
namespace export mkDriver
namespace export add_driver
}
proc add_knauer_pump {name ip_address tcp_port} {
set simulation_flag "[string tolower [SplitReply [environment_simulation]]]"
::scobj::knauer_pump::add_driver ${name} "environment" ${simulation_flag} ${ip_address} ${tcp_port}
}
clientput "file evaluation of sct_knauer_pump.tcl"
::scobj::knauer_pump::sics_log 9 "file evaluation of sct_knauer_pump.tcl"
proc ::scobj::knauer_pump::read_config {} {
set catch_status [ catch {
set ns "::scobj::knauer_pump"
dict for {k u} $::config_dict {
if { [dict exists $u "implementation"] } {
set simulation_flag "[string tolower [SplitReply [environment_simulation]]]"
set device_class "environment"
if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } {
continue
}
set enabled [string tolower [dict get $u "enabled"]]
if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } {
continue
}
if { [dict exists $u "simulation_group"] } {
set simulation_flag [SplitReply [[string tolower [dict get $u "simulation_group"]]]]
}
if { [dict exists $u "device_class"] } {
set device_class "[dict get $u "device_class"]"
}
set name [dict get $u name]
set implementation [dict get $u "implementation"]
if { !([dict exists $::config_dict $implementation]) } {
continue
}
set v [dict get $::config_dict $implementation]
if { !([dict exists $v "driver"]) } {
continue
}
if { [string equal -nocase [dict get $v "driver"] "knauer_pump"] } {
if { ![string equal -nocase "${simulation_flag}" "false"] } {
set asyncqueue "null"
${ns}::sics_log 9 "simulation_flag=${simulation_flag} => using null asyncqueue"
${ns}::sics_log 9 "makesctcontroller sct_${name} aqadapter NULL"
makesctcontroller sct_${name} aqadapter NULL
} elseif { [dict exists $v "asyncqueue"] } {
set asyncqueue [dict get $v "asyncqueue"]
if { [string equal -nocase ${asyncqueue} "sct"] } {
set ip_address [dict get $v ip]
set tcp_port [dict get $v port]
makesctcontroller sct_${name} knauer_ap ${ip_address}:${tcp_port}
} else {
makesctcontroller sct_${name} aqadapter ${asyncqueue}
}
} else {
if { [dict exists $v "asyncprotocol"] } {
set asyncprotocol [dict get $v "asyncprotocol"]
} else {
set asyncprotocol ${name}_protocol
MakeAsyncProtocol ${asyncprotocol}
if { [dict exists $v "sendterminator"] } {
${asyncprotocol} sendterminator "[dict get $v "sendterminator"]"
} elseif { [dict exists $v "terminator"] } {
${asyncprotocol} sendterminator "[dict get $v "terminator"]"
}
if { [dict exists $v "replyterminator"] } {
${asyncprotocol} replyterminator "[dict get $v "replyterminator"]"
} elseif { [dict exists $v "terminator"] } {
${asyncprotocol} replyterminator "[dict get $v "terminator"]"
}
}
set asyncqueue ${name}_queue
set ip_address [dict get $v ip]
set tcp_port [dict get $v port]
MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${ip_address} ${tcp_port}
if { [dict exists $v "timeout"] } {
${asyncqueue} timeout "[dict get $v "timeout"]"
}
makesctcontroller sct_${name} aqadapter ${asyncqueue}
}
${ns}::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port}
}
}
}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
if { [info exists ::config_dict] } {
::scobj::knauer_pump::read_config
} else {
::scobj::knauer_pump::sics_log 5 "No config dict"
}