1305 lines
50 KiB
Tcl
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}
|
|
} else {
|
|
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"
|
|
}
|