secop improvements

This commit is contained in:
l_samenv
2023-03-31 10:31:55 +02:00
parent 66b2bbab3d
commit 2223077cf0

View File

@ -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
}