secop improvements
This commit is contained in:
@ -3,7 +3,10 @@
|
||||
namespace eval secop {} {
|
||||
}
|
||||
|
||||
proc stdConfig::secop {{shownUnits ALL} {restart no}} {
|
||||
proc stdConfig::secop {{shownUnits ALL} {restart no} {sepUnits ""}} {
|
||||
# shown units: restrict units shown
|
||||
# restart: whether to restart on reconnect
|
||||
# sepUnits: append sepUnits to unis for different graphic window
|
||||
variable node
|
||||
variable name
|
||||
|
||||
@ -23,6 +26,7 @@ proc stdConfig::secop {{shownUnits ALL} {restart no}} {
|
||||
prop secopPath /$name
|
||||
prop active 0
|
||||
prop shownUnits $shownUnits
|
||||
prop sepUnits $sepUnits
|
||||
|
||||
set node $node/tasks
|
||||
prop start secop::start
|
||||
@ -48,7 +52,7 @@ proc secop::errorscript_ {} {
|
||||
return secop::update_
|
||||
}
|
||||
sct connection_lost 1
|
||||
[sct controller] poll [sct secopPath] 1
|
||||
[sct controller] poll [sct secopPath] 5
|
||||
error [sct result]
|
||||
}
|
||||
|
||||
@ -76,6 +80,7 @@ proc secop::writemsg {} {
|
||||
|
||||
proc secop::readmsg_ {} { # ending with _: invisible on debug
|
||||
if {[sct connection_lost]} {
|
||||
[sct controller] poll [sct] 0.001
|
||||
sct connection_lost 0
|
||||
return [secop::start]
|
||||
}
|
||||
@ -90,14 +95,15 @@ proc secop::test {} {
|
||||
|
||||
proc secop::check {} {
|
||||
if {[silent "" sct secopar] eq ""} return
|
||||
set validator [silent {} sct validator]
|
||||
eval $validator
|
||||
lassign [split [hinfo [sct]] ","] type
|
||||
set msg "change [sct secopar] [sct target]"
|
||||
hsetprop [sct] secoprequested [sct target]
|
||||
if {[string match "f:*" [sct secopar]]} {
|
||||
clientput "REQ: $msg"
|
||||
set value [sct target]
|
||||
set validator [silent "" sct validator]
|
||||
if {$validator ne ""} {
|
||||
lappend validator $value
|
||||
set value [eval $validator]
|
||||
}
|
||||
lassign [split [hinfo [sct]] ","] type
|
||||
set msg "change [sct secopar] $value"
|
||||
hsetprop [sct] secoprequested [sct target]
|
||||
[sct controller] que [sct secopPath] write [list secop::queuedwrite $msg]
|
||||
}
|
||||
|
||||
@ -133,44 +139,80 @@ proc secop::get {} {
|
||||
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]))]
|
||||
if {[sct target] < $min} {
|
||||
if {[sct target] >= $min - $prec} {
|
||||
sct target $min
|
||||
return
|
||||
proc secop::check_double {datainfo value} {
|
||||
set min [silent -inf dict get $datainfo min]
|
||||
set max [silent inf dict get $datainfo max]
|
||||
set absolute_resolution [silent 0 dict get $datainfo absolute_resolution]
|
||||
set relative_resolution [silent 1.2e-7 dict get $datainfo relative_resolution]
|
||||
set prec [expr max($absolute_resolution, $relative_resolution * abs($value))]
|
||||
if {$value < $min} {
|
||||
if {$value >= $min - $prec} {
|
||||
return $min
|
||||
}
|
||||
} elseif {[sct target] > $max} {
|
||||
if {[sct target] <= $max + $prec} {
|
||||
sct target $max
|
||||
return
|
||||
} elseif {$value > $max} {
|
||||
if {$value <= $max + $prec} {
|
||||
return $max
|
||||
}
|
||||
} else {
|
||||
return
|
||||
return $value
|
||||
}
|
||||
error "[sct] value must be within \[$min, $max\]"
|
||||
error "[sct]: value must be within \[$min, $max\]"
|
||||
}
|
||||
|
||||
proc secop::check_string {min max} {
|
||||
set len [string length [sct target]]
|
||||
proc secop::check_int {datainfo value} {
|
||||
return [check_double $datainfo $value]
|
||||
}
|
||||
|
||||
proc secop::check_string {datainfo value} {
|
||||
set len [string length $value]
|
||||
set min [silent -inf dict get $datainfo minlen]
|
||||
set max [silent inf dict get $datainfo maxlen]
|
||||
if {$len < $min || $len > $max} {
|
||||
error "[sct] string length must be within \[$min, $max\]"
|
||||
error "[sct]: string length must be within \[$min, $max\]"
|
||||
}
|
||||
sct target [format {"%s"} [sct target]]
|
||||
return [format {"%s"} $value]
|
||||
}
|
||||
|
||||
proc secop::check_bool {} {
|
||||
switch -- [string tolower [sct target]] {
|
||||
off - false - no - 0 - on - true - yes - 1 {
|
||||
return
|
||||
|
||||
proc secop::check_bool {datainfo value} {
|
||||
switch -- [string tolower $value] {
|
||||
off - false - no - 0 {
|
||||
return 0
|
||||
}
|
||||
on - true - yes - 1 {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
error "illegal value for boolean: [sct target]"
|
||||
error "[sct]: illegal value for boolean: $value"
|
||||
}
|
||||
|
||||
proc secop::check_tuple args {
|
||||
sct target [format {[%s]} [join [sct target] ,]]
|
||||
clientput [sct target]
|
||||
proc secop::check_tuple {datainfo value} {
|
||||
set items [list]
|
||||
foreach v $value dt [dict get $datainfo members] {
|
||||
set type [dict get $dt type]
|
||||
lappend items [check_$type $dt $v]
|
||||
}
|
||||
return [format {[%s]} [join $items ,]]
|
||||
}
|
||||
|
||||
proc secop::check_array {datainfo value} {
|
||||
set items [list]
|
||||
set dt [dict get $datainfo members]
|
||||
set type [dict get $dt type]
|
||||
foreach v $value {
|
||||
lappend items [check_$type $dt $v]
|
||||
}
|
||||
return [format {[%s]} [join $items ,]]
|
||||
}
|
||||
|
||||
proc secop::check_struct {datainfo value} {
|
||||
set items [list]
|
||||
foreach {k dt} [dict get $datainfo members] {
|
||||
set type [dict get $dt type]
|
||||
set v [check_$type $dt [dict get $value $k]]
|
||||
lappend items [format {"%s": %s} $k $v]
|
||||
}
|
||||
return [format {{%s}} [join $items ", "]]
|
||||
}
|
||||
|
||||
proc secop::make_par {secopar desc {kind ""}} {
|
||||
@ -201,9 +243,8 @@ proc secop::make_par {secopar desc {kind ""}} {
|
||||
# can not use SICS drivable for string
|
||||
set kind ""
|
||||
}
|
||||
bool {set type text}
|
||||
bool - tuple - array - struct {set type text}
|
||||
none {set type none}
|
||||
tuple {set type text}
|
||||
default {
|
||||
clientput "unknown type for $secopar (use text): $secoptype ($datadesc)"
|
||||
set type text
|
||||
@ -224,8 +265,17 @@ proc secop::make_par {secopar desc {kind ""}} {
|
||||
set fmtunit [format { [%s]} $unit]
|
||||
}
|
||||
if {$par eq "" || $par eq "target"} {
|
||||
set label [join [split $secopar :] .]
|
||||
set prevlabel [silent "" result graph_label [string tolower $label]]
|
||||
if {$prevlabel ne ""} {
|
||||
set label $prevlabel
|
||||
}
|
||||
if {[sct shownUnits] eq "ALL" || [lsearch [sct shownUnits] $unit] >= 0} {
|
||||
GraphAdd $path $unit [join [split $secopar :] .]
|
||||
set sepUnits [silent "" sct sepUnits]
|
||||
if {$sepUnits ne ""} {
|
||||
set unit "${unit}_$sepUnits"
|
||||
}
|
||||
GraphAdd $path $unit $label
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -251,7 +301,7 @@ proc secop::make_par {secopar desc {kind ""}} {
|
||||
}
|
||||
hsetprop $path enum [join $enumprop ,]
|
||||
if {[silent "" hgetpropval $path type] eq "drivable"} {
|
||||
hsetprop $path visible false
|
||||
hsetprop $path visible readonly
|
||||
}
|
||||
if {$wid > 8} {
|
||||
hsetprop $path width $wid
|
||||
@ -260,29 +310,18 @@ proc secop::make_par {secopar desc {kind ""}} {
|
||||
}
|
||||
bool {
|
||||
hsetprop $path enum 1
|
||||
hsetprop $path validator secop::check_bool
|
||||
hsetprop $path validator [list secop::check_bool $datadesc]
|
||||
}
|
||||
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]
|
||||
hsetprop $path validator [list secop::check_double $datadesc]
|
||||
}
|
||||
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]
|
||||
hsetprop $path validator [list secop::check_int $datadesc]
|
||||
}
|
||||
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_string $min $max]
|
||||
}
|
||||
tuple { # TODO: make it work for more complex than number tuples
|
||||
set args [dict get $datadesc members]
|
||||
hsetprop $path validator [linsert $args 0 secop::check_tuple]
|
||||
string - tuple - struct - array {
|
||||
set type [dict get $datadesc type]
|
||||
hsetprop $path width 36
|
||||
hsetprop $path validator [list secop::check_$type $datadesc]
|
||||
}
|
||||
}
|
||||
return $path
|
||||
@ -349,12 +388,14 @@ proc secop::make_par0 {type path secopar desc {kind std}} {
|
||||
# logsetup $path 1
|
||||
logsetup $path 5
|
||||
if {[info exists props(value)]} {
|
||||
clientput "VALUE in descr $path"
|
||||
if {[catch {hupdate /$path $props(value)} msg]} {
|
||||
clientput $msg
|
||||
}
|
||||
unset props(value)
|
||||
}
|
||||
if {![catch {set fmtstr [dict get $props(datainfo) fmtstr]}]} {
|
||||
hsetprop $path fmtstr $fmtstr
|
||||
}
|
||||
foreach {prop item} [array get props] {
|
||||
hsetprop $path s_$prop $item
|
||||
}
|
||||
@ -571,6 +612,7 @@ proc secop::update_ {} {
|
||||
if {$messagetype eq "changed"} {
|
||||
if {[string match *:target $par]} {
|
||||
hsetprop /$obj writestatus done
|
||||
hsetprop /$obj changetime 0
|
||||
}
|
||||
hsetprop $path changed 0
|
||||
catch {hdelprop $path secoprequested}
|
||||
@ -609,6 +651,7 @@ proc secop::update_ {} {
|
||||
set shown 0
|
||||
}
|
||||
set writestatus [silent done hgetpropval $objpath writestatus]
|
||||
set changetime [silent 0 hgetpropval $objpath changetime]
|
||||
if {$value < 100 || $value >= 400} { # error
|
||||
# updateerror $objpath $text_value
|
||||
catch {
|
||||
@ -638,7 +681,12 @@ proc secop::update_ {} {
|
||||
}
|
||||
GraphItem shown $objpath $shown
|
||||
if {[silent "" hgetpropval $objpath/target logger_name] ne ""} {
|
||||
GraphItem shown $objpath/target $shown
|
||||
if {[string match *Drivable* [silent "" hgetpropval $objpath sm_interface_classes]]
|
||||
&& [silent "enum" hgetpropval $objpath/target secoptype] ne "enum"} {
|
||||
GraphItem shown $objpath/target $shown
|
||||
} else {
|
||||
GraphItem shown $objpath/target 0
|
||||
}
|
||||
}
|
||||
set text_path [regsub {status_code$} $path status_text]
|
||||
if {[catch {updateval $text_path $text_value}]} {
|
||||
@ -715,6 +763,7 @@ proc secop::update_ {} {
|
||||
hsetprop $path geterror "${etype}: $etext"
|
||||
}
|
||||
error_* {
|
||||
clientlog $val
|
||||
lassign $val etype etext
|
||||
set requesttype [string range $messagetype 6 end]
|
||||
if {$requesttype eq "change" && $path ne ""} {
|
||||
@ -768,6 +817,7 @@ proc secop::checklimits {} {
|
||||
[sct target] != [silent "x" hgetpropval [sct]/target target]} {
|
||||
hset [sct]/target [sct target]
|
||||
sct writestatus checked
|
||||
sct changetime [DoubleTime]
|
||||
sct status run
|
||||
}
|
||||
}
|
||||
@ -804,6 +854,7 @@ proc secop::halt {} {
|
||||
sct stop_issued [DoubleTime]
|
||||
} else {
|
||||
sct writestatus done
|
||||
sct changetime 0
|
||||
sct status idle
|
||||
}
|
||||
return idle
|
||||
@ -816,6 +867,7 @@ proc secop::finish_halt {} {
|
||||
return idle
|
||||
}
|
||||
sct writestatus done
|
||||
sct changetime 0
|
||||
sct status idle
|
||||
return unpoll
|
||||
}
|
||||
|
Reference in New Issue
Block a user