221 lines
6.0 KiB
Tcl
221 lines
6.0 KiB
Tcl
# flow control module based on hipadaba
|
|
|
|
namespace eval flow {
|
|
}
|
|
|
|
proc flow::loop {difget flowget flowset path flowstd flowlim} {
|
|
$difget $path difmin difmax
|
|
$flowget $path flowmin flowmax
|
|
set setval [hvali $path/flowset]
|
|
set setmin [expr [hvali $path/prop] * $difmin + $flowmin - $setval]
|
|
set setmax [expr [hvali $path/prop] * $difmax + $flowmax - $setval]
|
|
hupdate $path/setmin $setmin
|
|
hupdate $path/setmax $setmax
|
|
set c [hvali $path/smooth]
|
|
if {$setmin > $setval} {
|
|
set setval [expr $setmin * $c + $setval * (1 - $c)]
|
|
} elseif {$setmax < $setval} {
|
|
set setval [expr $setmax * $c + $setval * (1 - $c)]
|
|
}
|
|
putIntoLimits setval $flowstd $flowlim
|
|
$flowset $path $setval
|
|
# the above calculation has the disantvantage, that $path/flowset might be higher
|
|
# than the flowstd, when the actual flow is very high. We calculate a
|
|
# more meaningful target just for make the user happy.
|
|
set flowtarget [expr [hvali $path/prop] * ($difmin + $difmax) * 0.5]
|
|
#clientput "$flowtarget := [hvali $path/prop] * ($difmin + $difmax) * 0.5"
|
|
if {$flowtarget < $flowstd && $setval < $flowmin} {
|
|
set flowtarget [expr $c * $flowstd + (1 - $c) * [hvali $path/flowtarget]]
|
|
} else {
|
|
set flowtarget $setval
|
|
}
|
|
putIntoLimits flowtarget $flowstd $flowlim
|
|
set suppress_auto [silent 0 sct suppress_auto]
|
|
if {$suppress_auto || $flowtarget > ($flowstd + $flowlim) * 0.5} {
|
|
sct suppress_auto 0
|
|
hupdate $path/flowtarget $flowtarget
|
|
} else {
|
|
if {$flowtarget < $flowstd + 0.1} {
|
|
sct suppress_auto 1
|
|
} else {
|
|
hupdate $path/flowtarget $flowtarget
|
|
}
|
|
}
|
|
}
|
|
|
|
proc flow::bufferPut {path name var value} {
|
|
upvar $var buf
|
|
set buf [hvali $path/${name}Buf]
|
|
lappend buf [format %.11g $value]
|
|
set buf [lrange $buf end-[expr [hvali $path/${name}Size] - 1] end]
|
|
hupdate $path/${name}Buf $buf
|
|
}
|
|
|
|
proc flow::difget {path minname maxname} {
|
|
upvar $minname min
|
|
upvar $maxname max
|
|
|
|
set t [eval [hvali $path/getTemp]]
|
|
if {$t eq "NaN"} {
|
|
set t 0
|
|
}
|
|
set s $t
|
|
if {[catch {
|
|
set s [eval [hvali $path/getTset]]
|
|
hsetprop $path/getTset t_set_undefined 0
|
|
}]} {
|
|
hsetprop $path/getTset t_set_undefined 1
|
|
}
|
|
if {$s eq "NaN"} {
|
|
set s $t
|
|
}
|
|
if {$s < [hvali $path/Tmin]} {
|
|
set s [hvali $path/Tmin]
|
|
}
|
|
#clientput [format {set %.11g ist %.11g} $s $t]
|
|
flow::bufferPut $path dif buf [expr $t - $s]
|
|
set last [lindex $buf end]
|
|
set first [lindex $buf 0]
|
|
set l [hvali $path/difSize]
|
|
set slope1 [expr ($last - $first) / $l]
|
|
set slope2 [expr ([lindex $buf [hvali $path/difRange]] - $first) / $l]
|
|
#clientput [format {dif %.11g %.11g slope %.11g %.11g} $t $s $slope1 $slope2]
|
|
if {$slope1 > $slope2} {
|
|
set max [expr $last + $slope1 * [hvali $path/convTime]]
|
|
# set min $last
|
|
set min [expr $last + $slope2 * [hvali $path/convTime]]
|
|
} else {
|
|
set min [expr $last + $slope1 * [hvali $path/convTime]]
|
|
set max [expr $last + $slope2 * [hvali $path/convTime]]
|
|
}
|
|
#clientput [format {last %.11g min %.11g max %.11g} $last $min $max]
|
|
hupdate $path/difmax $max
|
|
hupdate $path/difmin $min
|
|
}
|
|
|
|
proc flow::flowget {path flowmin flowmax} {
|
|
upvar $flowmin min
|
|
upvar $flowmax max
|
|
|
|
flow::bufferPut $path flow buf [eval [hvali $path/getFlow]]
|
|
set s [lsort -real $buf]
|
|
set max [lindex $s end]
|
|
set min [lindex $s 0]
|
|
hupdate $path/flowmin $min
|
|
hupdate $path/flowmax $max
|
|
}
|
|
|
|
proc flow::flowset {path setval} {
|
|
set val [format "%.1f" $setval]
|
|
# if {[hvali $path/flowset] != $val} {
|
|
# eval "[hvali $path/setFlow] $val"
|
|
# }
|
|
hupdate $path/flowset $setval
|
|
}
|
|
|
|
proc flow::task {path flowstd flowlim} {
|
|
flow::loop flow::difget flow::flowget flow::flowset $path $flowstd $flowlim
|
|
}
|
|
|
|
proc flow::pitask {path flowstd flowlim} {
|
|
set tt [silent 1 result tt tm]
|
|
set p [silent 0 result tt set/power]
|
|
set tt [expr $tt - $p]
|
|
set st $tt
|
|
if {[catch {
|
|
set st [eval [hvali $path/getTset]]
|
|
hsetprop $path/getTset t_set_undefined 0
|
|
}]} {
|
|
hsetprop $path/getTset t_set_undefined 1
|
|
}
|
|
if {$st < [hvali $path/Tmin]} {
|
|
set st [hvali $path/Tmin]
|
|
}
|
|
set y [hvali $path/flowmin]
|
|
set dif [expr $tt - $st]
|
|
set now [DoubleTime]
|
|
set lastim [silent $now hgetpropval $path lastim]
|
|
hsetprop $path lastim $now
|
|
set lasdif [silent 0 hgetpropval $path lasdif]
|
|
hsetprop $path lasdif $dif
|
|
set dt [expr $now - $lastim]
|
|
set prop [hvali $path/prop]
|
|
set convTime [hvali $path/convTime]
|
|
set y [expr $y + $prop * (($dif - $lasdif) + ($dif - 5 * $p) * $dt / double($convTime))]
|
|
putIntoLimits y [expr -$flowlim] $flowlim
|
|
hupdate $path/flowmin $y
|
|
putIntoLimits y $flowstd $flowlim
|
|
hupdate $path/flowset $y
|
|
hupdate $path/flowtarget $y
|
|
}
|
|
|
|
proc flow::make {{getT flow::tmts} {getS "result tt tr"} {getF "result nv flow"}} {
|
|
namespace eval ::stdConfig [subst {
|
|
node suspended par 0
|
|
prop enum 1
|
|
node prop par 5
|
|
node flowstd par 2
|
|
node flowlim par 20
|
|
node smooth par 0.05
|
|
node difSize par 10
|
|
node difRange par 7
|
|
node flowSize par 10
|
|
node convTime par 30
|
|
node Tmin par 1.5
|
|
node script -text par "flow::task"
|
|
prop width 24
|
|
node getTemp -text par "$getT"
|
|
prop width 24
|
|
node getTset -text par "$getS"
|
|
prop t_set_undefined 0
|
|
prop width 24
|
|
node getFlow -text par "$getF"
|
|
prop width 24
|
|
node difBuf -nolog -text upd
|
|
default ""
|
|
node flowBuf -nolog -text upd
|
|
default ""
|
|
node flowset upd
|
|
default 2
|
|
node flowmin upd
|
|
node flowmax upd
|
|
node difmin upd
|
|
node difmax upd
|
|
node setmin upd
|
|
node setmax upd
|
|
node flowtarget upd
|
|
}]
|
|
}
|
|
|
|
proc flow::tmts {} {
|
|
set tm [silent 1 result tt tm]
|
|
set ts [silent $tm result tt ts]
|
|
if {$ts < $tm} {
|
|
return $ts
|
|
} else {
|
|
return $tm
|
|
}
|
|
}
|
|
|
|
proc flow::tmts2 {} {
|
|
set tm [silent 1 result tt tm]
|
|
# set ts [silent $tm result tt ts]
|
|
set p [silent 0 result tt set/power]
|
|
set pr [silent 0 hvali /nv/autoflow/prop]
|
|
return [expr $tm - $p / $pr]
|
|
}
|
|
|
|
proc flow::ma15tmts {} {
|
|
set tm [result te]
|
|
set ts [result tt]
|
|
if {$ts < 0} {
|
|
return $tm
|
|
}
|
|
if {$ts < $tm} {
|
|
return $ts
|
|
} else {
|
|
return $tm
|
|
}
|
|
}
|
|
|