add drivers from l_samenv@samenv
This commit is contained in:
754
tcl/drivers/secop_3.tcl
Normal file
754
tcl/drivers/secop_3.tcl
Normal file
@ -0,0 +1,754 @@
|
||||
# secop driver 3 (v1.0 RC2): modules/accesibles are JSON objects, datatype is 1-element JSON object
|
||||
|
||||
namespace eval secop {} {
|
||||
}
|
||||
|
||||
proc stdConfig::secop {{shownUnits ALL}} {
|
||||
variable node
|
||||
variable name
|
||||
|
||||
controller secop3 timeout=60
|
||||
prop commerror secop::errorscript_
|
||||
prop connection_lost 0
|
||||
prop check secop::check
|
||||
prop write secop::write
|
||||
prop startcmd *IDN?
|
||||
prop end_fast 0
|
||||
prop secopPath /$name
|
||||
prop active 0
|
||||
prop shownUnits $shownUnits
|
||||
|
||||
set node $node/tasks
|
||||
prop start secop::start
|
||||
|
||||
pollperiod 0.001 0.001
|
||||
obj SECoP -text wr
|
||||
|
||||
prop read secop::readmsg_
|
||||
prop test secop::test
|
||||
prop check secop::checkmsg
|
||||
prop write secop::writemsg
|
||||
prop cmd ""
|
||||
|
||||
variable ctrl
|
||||
variable path
|
||||
hsetprop /sics/$ctrl ignore_no_response 1
|
||||
|
||||
}
|
||||
|
||||
proc secop::errorscript_ {} {
|
||||
if {[string match {ASCERR: no response*} [sct result]]} {
|
||||
sct send ping
|
||||
return secop::update_
|
||||
}
|
||||
sct connection_lost 1
|
||||
[sct controller] poll [sct] 1
|
||||
error [sct result]
|
||||
}
|
||||
|
||||
proc secop::checkmsg {} {
|
||||
# variable MQ[sct]
|
||||
# upvar 0 MQ[sct] mq
|
||||
# if {![info exists mq]} {
|
||||
# # create message queue
|
||||
# set mq [list]
|
||||
# }
|
||||
# if {[llength $mq] > 0} {
|
||||
# set next [lindex $mq 0]
|
||||
# set mq [lrange $mq 1 end]
|
||||
# lappend mq [sct target]
|
||||
# sct target $next
|
||||
# }
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
proc secop::writemsg {} {
|
||||
sct send [sct target]
|
||||
return secop::update_
|
||||
}
|
||||
|
||||
proc secop::readmsg_ {} { # ending with _: invisible on debug
|
||||
if {[sct connection_lost]} {
|
||||
sct connection_lost 0
|
||||
return [secop::start]
|
||||
}
|
||||
sct send ""
|
||||
return secop::update_
|
||||
}
|
||||
|
||||
proc secop::test {} {
|
||||
clientput test
|
||||
return idle
|
||||
}
|
||||
|
||||
proc secop::check {} {
|
||||
if {[silent "" sct secopar] eq ""} return
|
||||
set validator [silent {} sct validator]
|
||||
eval $validator
|
||||
lassign [split [hinfo [sct]] ","] type
|
||||
if {$type eq "text"} {
|
||||
set msg "change [sct secopar] \"[sct target]\""
|
||||
} else {
|
||||
set msg "change [sct secopar] [sct target]"
|
||||
}
|
||||
[sct controller] que [sct secopPath] write [list secop::queuedwrite $msg]
|
||||
}
|
||||
|
||||
proc secop::queuedwrite {msg} {
|
||||
sct changed [DoubleTime]
|
||||
# send message on /secop node
|
||||
sct sent_message $msg
|
||||
sct send $msg
|
||||
return secop::update_
|
||||
}
|
||||
|
||||
proc secop::write {} {
|
||||
# dummy write
|
||||
# clientput "secop::write [sct] [hvali [sct]]"
|
||||
return idle
|
||||
}
|
||||
|
||||
proc secop::get {} {
|
||||
error "secop::get is obsolete"
|
||||
sct send ""
|
||||
return secop::update_
|
||||
}
|
||||
|
||||
proc secop::check_range {min max {absolute_resolution 0} {relative_resolution 0}} {
|
||||
set prec [expr max($absolute_resolution, $relative_resolution * abs([sct target]))]
|
||||
clientput "*** $prec [sct target] $max"
|
||||
if {[sct target] < $min} {
|
||||
if {[sct target] >= $min - $prec} {
|
||||
sct target $min
|
||||
return
|
||||
}
|
||||
} elseif {[sct target] > $max} {
|
||||
if {[sct target] <= $max + $prec} {
|
||||
sct target $max
|
||||
return
|
||||
}
|
||||
} else {
|
||||
return
|
||||
}
|
||||
error "[sct] value must be within \[$min, $max\]"
|
||||
}
|
||||
|
||||
proc secop::check_length {min max} {
|
||||
set len [string length [sct target]]
|
||||
if {$len < $min || $len > $max} {
|
||||
error "[sct] string length must be within \[$min, $max\]"
|
||||
}
|
||||
}
|
||||
|
||||
proc secop::check_bool {} {
|
||||
switch -- [string tolower [sct target]] {
|
||||
off - false - no - 0 - on - true - yes - 1 {
|
||||
return
|
||||
}
|
||||
}
|
||||
error "illegal value for boolean: [sct target]"
|
||||
}
|
||||
|
||||
proc secop::check_length {{low None} {high None}} {
|
||||
if {$low ne "None" && [string length [sct target]] < $low} {
|
||||
error "value [sct target] must not be shorter than $low"
|
||||
}
|
||||
if {$high ne "None" && [string length [sct target]] > $high} {
|
||||
error "value [sct target] must not be longer than $high"
|
||||
}
|
||||
}
|
||||
|
||||
proc secop::make_par {secopar desc {kind ""}} {
|
||||
set path [topath $secopar [silent "" dict get $desc group]]
|
||||
array set props $desc
|
||||
lassign [silent "" set props(datatype)] secoptype0 datadesc
|
||||
if {$secoptype0 eq "tuple" && [string match *:status $secopar]} {
|
||||
set members [dict get $datadesc members]
|
||||
# lassign $validator_args members
|
||||
set text_path [regsub {status_code$} $path status_text]
|
||||
make_par0 text $text_path $secopar $desc
|
||||
hsetprop $text_path width 24
|
||||
lassign [lindex $members 0] secoptype datadesc
|
||||
set status_node 1
|
||||
} else {
|
||||
set secoptype $secoptype0
|
||||
set status_node 0
|
||||
}
|
||||
switch -- $secoptype {
|
||||
double {set type float}
|
||||
int - enum {set type int}
|
||||
string {
|
||||
set type text
|
||||
# can not use SICS drivable for string
|
||||
set kind ""
|
||||
}
|
||||
bool {set type text}
|
||||
none {set type none}
|
||||
default {
|
||||
clientput "unknown type for $secopar (use text): $secoptype ($props(datatype))"
|
||||
set type text
|
||||
}
|
||||
}
|
||||
make_par0 $type $path $secopar $desc $kind
|
||||
hsetprop $path secoptype $secoptype0
|
||||
if {$status_node} {
|
||||
hsetprop $path nonewline 1
|
||||
}
|
||||
lassign [split $path /] nul obj par
|
||||
set fmtunit ""
|
||||
if {[lsearch [list enum int double] $secoptype0] >= 0} {
|
||||
set fmtunit ""
|
||||
if {[catch {set unit [dict get $datadesc unit]}]} {
|
||||
set unit 1
|
||||
} else {
|
||||
set fmtunit [format { [%s]} $unit]
|
||||
}
|
||||
if {$par eq "" || $par eq "target"} {
|
||||
if {[sct shownUnits] eq "ALL" || [lsearch [sct shownUnits] $unit] >= 0} {
|
||||
GraphAdd $path $unit
|
||||
}
|
||||
}
|
||||
}
|
||||
if {[info exists props(description)]} {
|
||||
hsetprop $path help "$props(description)$fmtunit"
|
||||
unset props(description)
|
||||
}
|
||||
switch -- $secoptype {
|
||||
enum {
|
||||
set enumprop [list]
|
||||
set wid 8
|
||||
set sorted [list]
|
||||
set members [dict get $datadesc members]
|
||||
|
||||
foreach {name value} $members {
|
||||
lappend sorted [list $value $name]
|
||||
}
|
||||
foreach value_name [lsort -integer -index 0 $sorted] {
|
||||
lassign $value_name value name
|
||||
lappend enumprop "$name=$value"
|
||||
set wid [expr max($wid,[string length $name])]
|
||||
}
|
||||
hsetprop $path enum [join $enumprop ,]
|
||||
if {[silent "" hgetpropval $path type] eq "drivable"} {
|
||||
hsetprop $path visible false
|
||||
}
|
||||
if {$wid > 8} {
|
||||
hsetprop $path width $wid
|
||||
}
|
||||
}
|
||||
bool {
|
||||
hsetprop $path enum 1
|
||||
hsetprop $path validator secop::check_bool
|
||||
}
|
||||
double {
|
||||
set min [silent -inf dict get $datadesc min]
|
||||
set max [silent inf dict get $datadesc max]
|
||||
set absolute_resolution [silent 0 dict get $datadesc absolute_resolution]
|
||||
set relative_resolution [silent 1.2e-7 dict get $datadesc relative_resolution]
|
||||
hsetprop $path validator [concat secop::check_range $min $max $absolute_resolution $relative_resolution]
|
||||
}
|
||||
int {
|
||||
set min [silent -inf dict get $datadesc min]
|
||||
set max [silent inf dict get $datadesc max]
|
||||
hsetprop $path validator [concat secop::check_range $min $max]
|
||||
}
|
||||
string {
|
||||
set min [silent -inf dict get $datadesc min]
|
||||
set max [silent inf dict get $datadesc max]
|
||||
hsetprop $path width 16
|
||||
hsetprop $path validator [concat secop::check_length $min $max]
|
||||
}
|
||||
}
|
||||
return $path
|
||||
}
|
||||
|
||||
proc secop::make_par0 {type path secopar desc {kind std}} {
|
||||
array set props $desc
|
||||
# clientput "$path $desc"
|
||||
set readonly [silent 0 set props(readonly)]
|
||||
if {$readonly} {
|
||||
set priv internal
|
||||
} else {
|
||||
set priv user
|
||||
}
|
||||
if {[silent "" hinfo $path] ne ""} {
|
||||
error "$path exists already!"
|
||||
}
|
||||
lassign [split $path /] nul obj par
|
||||
if {$par eq ""} {
|
||||
if {$kind eq "driv"} {
|
||||
dynsctdriveobj $obj float user SECoP [sct controller]
|
||||
hfactory $path link $obj
|
||||
hsetprop $obj checklimits secop::checklimits
|
||||
# hsetprop $obj checkstatus secop::checkstatus
|
||||
hsetprop $obj halt secop::halt
|
||||
# allow start without run:
|
||||
hsetprop $obj check secop::checklimits
|
||||
hsetprop $obj write secop::complete_run
|
||||
set readonly 0
|
||||
hsetprop $obj sicscommand "run $obj"
|
||||
} else {
|
||||
# clientput "OBJ $obj $type"
|
||||
dynsicsobj $obj SECoP $priv $type
|
||||
hfactory $path link $obj
|
||||
}
|
||||
hsetprop $path group $obj
|
||||
hsetprop $path s_group $obj
|
||||
hsetprop $path objectPath $path
|
||||
hsetprop /sics/[sct controller] p_$secopar:value $path
|
||||
} else {
|
||||
if {$par eq "status"} {
|
||||
set path /$obj/status_code
|
||||
}
|
||||
# clientput "PAR $path $type [array get props]"
|
||||
hfactory $path plain $priv $type
|
||||
if {[info exists props(visibility)]} {
|
||||
if {$props(visibility) >= 3} {
|
||||
hsetprop $path visible false
|
||||
}
|
||||
}
|
||||
}
|
||||
hsetprop $path secopar $secopar
|
||||
hsetprop /sics/[sct controller] p_$secopar $path
|
||||
if {!$readonly} {
|
||||
[sct controller] write $path
|
||||
} else {
|
||||
[sct controller] connect $path
|
||||
}
|
||||
logsetup $path 1
|
||||
if {[info exists props(value)]} {
|
||||
clientput "VALUE in descr $path"
|
||||
if {[catch {hupdate /$path $props(value)} msg]} {
|
||||
clientput $msg
|
||||
}
|
||||
unset props(value)
|
||||
}
|
||||
foreach {prop item} [array get props] {
|
||||
hsetprop $path s_$prop $item
|
||||
}
|
||||
}
|
||||
|
||||
proc secop::make_cmd {secopar desc {first 0}} {
|
||||
array set props $desc
|
||||
set path [topath $secopar [silent "" dict get $desc group]]
|
||||
set cmd [join [lassign [split $path /] _ obj] /]
|
||||
set datadesc [lindex $props(datatype) 1]
|
||||
set argument None
|
||||
catch {
|
||||
set argument [dict get $datadesc argument]
|
||||
}
|
||||
if {$argument eq "None"} {
|
||||
$obj makescriptfunc $cmd "secop::check_cmd [sct secopPath] $secopar" user
|
||||
hsetprop $path newline $first
|
||||
hsetprop $path secopar $secopar
|
||||
hsetprop $path sicscommand "$obj $cmd"
|
||||
if {[info exists props(visibility)]} {
|
||||
if {$props(visibility) >= 3} {
|
||||
hsetprop $path visible false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dict set desc datatype $argument
|
||||
make_par $secopar $desc
|
||||
lassign $argument maintype datadesc
|
||||
if {$maintype eq "double" || $maintype eq "int" || $maintype eq "bool"} {
|
||||
hsetprop $path check "secop::check_cmd_num [sct secopPath] $secopar"
|
||||
} else {
|
||||
hsetprop $path check "secop::check_cmd_text [sct secopPath] $secopar"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc secop::check_cmd {secopPath secopar} {
|
||||
hset $secopPath "do $secopar"
|
||||
}
|
||||
|
||||
proc secop::check_cmd_num {secopPath secopar} {
|
||||
hset $secopPath [format {do %s %.15g} $secopar [sct target]]
|
||||
sct update [sct target]
|
||||
}
|
||||
|
||||
proc secop::check_cmd_text {secopPath secopar} {
|
||||
hset $secopPath [format {do %s "%s"} $secopar [sct target]]
|
||||
sct update [sct target]
|
||||
}
|
||||
|
||||
proc secop::make_module {obj desc} {
|
||||
clientput "MAKE_MODULE $obj"
|
||||
if {[obj_list exists $obj]} {
|
||||
clientput "$obj exists already"
|
||||
return
|
||||
}
|
||||
obj_list makeitem $obj /$obj
|
||||
|
||||
array unset modprop
|
||||
set parlist [list]
|
||||
set pardict [dict create]
|
||||
foreach {key item} $desc {
|
||||
switch $key {
|
||||
accessibles {
|
||||
# foreach acsitm $item {
|
||||
# lassign $acsitm parname pardesc
|
||||
# dict set pardict $parname $pardesc
|
||||
# }
|
||||
foreach {parname pardesc} $item {
|
||||
dict set pardict $parname $pardesc
|
||||
}
|
||||
}
|
||||
default {
|
||||
set modprop($key) $item
|
||||
}
|
||||
}
|
||||
}
|
||||
if {[dict exists $pardict value]} {
|
||||
set value [dict get $pardict value]
|
||||
dict unset pardict value
|
||||
} else {
|
||||
set value [dict create datatype none]
|
||||
}
|
||||
set classes [silent "" set modprop(interface_class)]
|
||||
if {[string match "* Drivable *" " $classes "]} {
|
||||
set path [make_par $obj $value driv]
|
||||
} else {
|
||||
set path [make_par $obj $value]
|
||||
}
|
||||
if {[info exists modprop(visibility)] && $modprop(visibility) >= 3} {
|
||||
hdelprop $path group
|
||||
}
|
||||
foreach {prop val} [array get modprop] {
|
||||
hsetprop $obj sm_$prop $val
|
||||
}
|
||||
device_layout makeitem /$obj [silent 0 set modprop(layoutpos)]
|
||||
|
||||
set groups [dict create]
|
||||
foreach {parname pardesc} $pardict {
|
||||
if {[dict exists $pardesc group]} {
|
||||
dict set groups [dict get $pardesc group] 1
|
||||
}
|
||||
}
|
||||
foreach g [dict keys $groups] {
|
||||
clientput "GROUP $g"
|
||||
hfactory $obj/$g plain user none
|
||||
hsetprop $obj/$g group "group $g"
|
||||
}
|
||||
set shortcmds [list]
|
||||
foreach {parname pardesc} $pardict {
|
||||
set datatype [dict get $pardesc datatype]
|
||||
lassign $datatype secoptype datadesc
|
||||
if {$secoptype eq "command"} {
|
||||
if {[catch {set argument [dict get $datadesc argument]}]} {
|
||||
set argument None
|
||||
}
|
||||
if {$argument ne "None"} {
|
||||
# only commands with arguments
|
||||
make_cmd $obj:$parname $pardesc 1
|
||||
} else {
|
||||
lappend shortcmds $parname $pardesc
|
||||
}
|
||||
} else {
|
||||
make_par $obj:$parname $pardesc
|
||||
}
|
||||
}
|
||||
# then commands without arguments, on one line
|
||||
set first 1
|
||||
foreach {parname pardesc} $shortcmds {
|
||||
make_cmd $obj:$parname $pardesc $first
|
||||
set first 0
|
||||
}
|
||||
}
|
||||
|
||||
proc secop::make_node {desc} {
|
||||
array unset nodeprop
|
||||
set modlist [list]
|
||||
foreach {key item} $desc {
|
||||
switch $key {
|
||||
modules {
|
||||
set modlist $item
|
||||
}
|
||||
default {
|
||||
set nodeprop($key) $item
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach {modname moddesc} $modlist {
|
||||
make_module $modname $moddesc
|
||||
}
|
||||
foreach {prop val} [array get nodeprop] {
|
||||
sct sn_$prop $val
|
||||
}
|
||||
sort_layout
|
||||
}
|
||||
|
||||
proc secop::topath {secopar {pargroup ""}} {
|
||||
lassign [split [string tolower $secopar] :] module parameter
|
||||
if {$parameter eq "value" || $parameter eq ""} {
|
||||
return "/$module"
|
||||
}
|
||||
if {$parameter eq "status"} {
|
||||
set parameter status_code
|
||||
}
|
||||
if {[string match {_*} $parameter]} {
|
||||
set parameter [string range $parameter 1 end]
|
||||
}
|
||||
if {$pargroup ne ""} {
|
||||
return "/$module/$pargroup/$parameter"
|
||||
}
|
||||
return "/$module/$parameter"
|
||||
}
|
||||
|
||||
proc secop::update_ {{wait_for {}}} {
|
||||
if {$wait_for eq ""} {
|
||||
set return_script idle
|
||||
} else {
|
||||
set return_script "secop::update_ $wait_for"
|
||||
}
|
||||
if {[silent "" sct result] eq ""} {
|
||||
return idle
|
||||
}
|
||||
set sent_message [silent "" sct sent_message]
|
||||
set message_to_client ""
|
||||
|
||||
lassign "[sct result]" messagetype par val
|
||||
set path [silent "" hgetpropval /sics/[sct controller] p_$par]
|
||||
lassign [split $par :] obj
|
||||
switch $messagetype {
|
||||
update - changed {
|
||||
# clientput "*** [DoubleTime]: [sct result]"
|
||||
#if {[sct] ne "/secop"} {
|
||||
# clientput "[sct] is not /secop, why?"
|
||||
#}
|
||||
#if {![sct active]} {
|
||||
# clientput [sct result]
|
||||
#}
|
||||
if {$messagetype eq "changed"} {
|
||||
if {[string match *:target $par]} {
|
||||
hsetprop /$obj writestatus done
|
||||
}
|
||||
hsetprop $path changed 0
|
||||
if {[lrange $sent_message 0 1] eq [list change $par]} {
|
||||
set message_to_client [sct result]
|
||||
}
|
||||
# clientput "CH $path [sct result]"
|
||||
} else {
|
||||
if {[DoubleTime] < [silent 0 hgetpropval $path changed] + 10} {
|
||||
# ignore updates of variables during change
|
||||
clientput "ignore [sct result]"
|
||||
return idle
|
||||
}
|
||||
if {[lrange $sent_message 0 1] eq [list read $par]} {
|
||||
set message_to_client [sct result]
|
||||
}
|
||||
}
|
||||
lassign $val value qual
|
||||
if {[silent 0 hgetpropval $path secoptype] eq "tuple" &&
|
||||
[string match *:status $par]} {
|
||||
if {[llength $value] > 2} {
|
||||
set text_value [lrange $value 1 end]
|
||||
} else {
|
||||
set text_value [lindex $value 1]
|
||||
}
|
||||
set objpath [sct parent $path]
|
||||
lassign $value value
|
||||
if {$value != 0} {
|
||||
hsetprop $objpath group [hgetpropval $objpath s_group]
|
||||
set shown 1
|
||||
} else {
|
||||
catch {hdelprop $objpath group}
|
||||
set shown 0
|
||||
}
|
||||
if {$value < 100 || $value >= 400} { # error
|
||||
updateerror $objpath $text_value
|
||||
catch {
|
||||
logsetup $objpath/target clear
|
||||
}
|
||||
if {[silent 0 hgetpropval $objpath status] eq "run"} {
|
||||
hsetprop $objpath status posfault
|
||||
}
|
||||
} else {
|
||||
if {$value >= 300} { # busy
|
||||
hsetprop $objpath status run
|
||||
} else {
|
||||
hsetprop $objpath status idle
|
||||
}
|
||||
logsetup $objpath 1
|
||||
}
|
||||
GraphItem shown $objpath $shown
|
||||
if {[silent "" hgetpropval $objpath/target logger_name] ne ""} {
|
||||
GraphItem shown $objpath/target $shown
|
||||
}
|
||||
set text_path [regsub {status_code$} $path status_text]
|
||||
if {[catch {updateval $text_path $text_value}]} {
|
||||
clientput "cannot update $text_path to $text_value"
|
||||
clientput "MSG([sct result])"
|
||||
}
|
||||
}
|
||||
if {[catch {updateval $path $value} msg]} {
|
||||
if {$value eq "None"} {
|
||||
hsetprop $path geterror None
|
||||
} else {
|
||||
clientput "cannot update $path to $value"
|
||||
clientput $msg
|
||||
}
|
||||
} elseif {[string match *:target $par]} {
|
||||
if {[string match 1* [silent 0 hval /$obj/status_code]]} {
|
||||
hsetprop /$obj target $value
|
||||
}
|
||||
}
|
||||
catch {
|
||||
hsetprop $path timestamp [dict get $qual t]
|
||||
}
|
||||
}
|
||||
pong {
|
||||
if {[lindex $sent_message 0] eq "ping"} {
|
||||
set message_to_client [sct result]
|
||||
}
|
||||
}
|
||||
done {
|
||||
if {[lrange $sent_message 0 2] eq [list do $par]} {
|
||||
set message_to_client [sct result]
|
||||
} else {
|
||||
clientput "done $par $val"
|
||||
}
|
||||
}
|
||||
active {
|
||||
if {[lindex $sent_message 0] eq "activate"} {
|
||||
set message_to_client [sct result]
|
||||
} else {
|
||||
clientput ACTIVE
|
||||
}
|
||||
sct active 1
|
||||
sct end_fast 0
|
||||
}
|
||||
error {
|
||||
lassign $val origin errortext
|
||||
lassign $origin requesttype requestpar requestval
|
||||
set path [silent "" hgetpropval /sics/[sct controller] p_$requestpar]
|
||||
if {$requesttype eq "change" && $path ne ""} {
|
||||
hsetprop $path changed 0
|
||||
}
|
||||
if {$origin eq $sent_message} {
|
||||
set message_to_client [sct result]
|
||||
} else {
|
||||
clientput "ERROR: $path $errortext"
|
||||
}
|
||||
}
|
||||
describing {
|
||||
do_as_manager {
|
||||
make_node $val
|
||||
}
|
||||
sct send activate
|
||||
[sct controller] poll [sct] 0.001
|
||||
return secop::update_
|
||||
}
|
||||
default {
|
||||
if {[string match "*,*" $messagetype]} {
|
||||
clientput IDN=[sct result]
|
||||
sct send describe
|
||||
sct active 0
|
||||
return secop::update_
|
||||
}
|
||||
if {$sent_message ne ""} {
|
||||
set message_to_client [sct result]
|
||||
} else {
|
||||
# show untreated message
|
||||
clientput [sct result]
|
||||
}
|
||||
}
|
||||
}
|
||||
if {$message_to_client ne ""} {
|
||||
clientput "[sct]:\n> $sent_message\n< $message_to_client"
|
||||
sct sent_message ""
|
||||
sct sent_time 1e20
|
||||
} elseif {[DoubleTime] > [silent 1e20 sct sent_time] + 10} {
|
||||
clientput "timeout waiting for response to $sent_message"
|
||||
sct sent_message ""
|
||||
sct sent_time 1e20
|
||||
}
|
||||
#if {[DoubleTime] < [sct end_fast]} {
|
||||
# return secop::get
|
||||
#}
|
||||
# [sct controller] queue [sct] read secop::get
|
||||
return idle
|
||||
}
|
||||
|
||||
proc secop::checklimits {} {
|
||||
# for whatever strange reason checklimits is called twice
|
||||
# in addition again as write script of the obj node
|
||||
# do this only once
|
||||
set ws [silent 0 sct writestatus]
|
||||
if {$ws ne "checked" && $ws ne "start" ||
|
||||
[sct target] != [silent "x" hgetpropval [sct]/target target]} {
|
||||
hset [sct]/target [sct target]
|
||||
sct writestatus checked
|
||||
sct status run
|
||||
}
|
||||
}
|
||||
|
||||
proc secop::checkstatus {} {
|
||||
# obsolete
|
||||
set ws [silent 0 sct writestatus]
|
||||
set status [hvali [sct]/status_code]
|
||||
if {[string match 3* $status]} {
|
||||
set result run
|
||||
} elseif {[string match 4* $status]} {
|
||||
set result posfault
|
||||
} else {
|
||||
if {$ws ne "done"} {
|
||||
set result run
|
||||
} else {
|
||||
set result idle
|
||||
}
|
||||
}
|
||||
sct status $result
|
||||
return $result
|
||||
}
|
||||
|
||||
proc secop::complete_run {} {
|
||||
sct print "run [sct objectName] to [sct target]"
|
||||
return idle
|
||||
}
|
||||
|
||||
proc secop::halt {} {
|
||||
[sct objectName] stop
|
||||
sct writestatus done
|
||||
sct status idle
|
||||
# clientput HALT:[sct]
|
||||
return idle
|
||||
}
|
||||
|
||||
proc secop::start {} {
|
||||
sct send *IDN?
|
||||
return secop::update_
|
||||
}
|
||||
|
||||
proc secop::describe {} {
|
||||
sct send describe
|
||||
return secop::describing
|
||||
}
|
||||
|
||||
proc secop::describing {} {
|
||||
#obsolete?
|
||||
lassign [sct result] messagetype par val
|
||||
switch $messagetype {
|
||||
describing {
|
||||
do_as_manager {
|
||||
make_node $val
|
||||
}
|
||||
}
|
||||
default {
|
||||
clientput "ignore $messagetype $par ..."
|
||||
}
|
||||
}
|
||||
sct send activate
|
||||
sct end_fast [expr [DoubleTime] + 5]
|
||||
return secop::update_
|
||||
}
|
||||
|
||||
proc secop_send {args} {
|
||||
hset /secop $args
|
||||
hsetprop /secop sent_message $args
|
||||
hsetprop /secop sent_time [DoubleTime]
|
||||
}
|
||||
|
||||
publishLazy secop_send
|
Reference in New Issue
Block a user