Files
sea/tcl/drivers/dilprep.tcl
2022-08-22 14:59:00 +02:00

182 lines
4.4 KiB
Tcl

namespace eval dilprep {
array set score {dil2 0 dil3 0 dil4 0}
array set curves {dil2 cx198 dil3 cx262 dil4 cx078}
}
proc stdConfig::dilprep {} {
controller syncedprot
obj DILPREP wr
prop enum warm=0,warmup=1,undef=-1
default -1
prop read dilprep::poll
prop check dilprep::check
prop write stdSct::complete
prop buffer ""
# last time when sample was warm
prop warmtime 0
# last time when sample was cold
prop coldtime 0
# last time when sample warming up faster than slopelimit
prop steeptime 0
# last time when detection was undefined
prop undeftime [DoubleTime]
kids dilprep {
node coldlimit par 280
prop help "stick is detected cold when T < coldlimit"
node warmlimit par 290
prop help "stick is detected warm when T > warmlimit for more than window sec"
node slopelimit par 0.1
prop help "stick is detected warm when tslope < slopelimit for more than window sec"
node window par 600
prop help "time window (sec)"
node dil out -int
prop enum undef=0,dil2=2,dil3=3,dil4=4
prop check dilprep::checktype
prop write stdSct::complete
}
}
proc dilprep::check {} {
if {[sct target] == 1} {
# reset slope
tslope node /ts
}
sct update [sct target]
}
proc dilprep::checktype {} {
variable score
variable curves
enum_decode [sct] [sct target] num dilname
foreach {key value} [array get score] {
set score($key) 0
}
if {$dilname ne "undef"} {
set score($dilname) 12
}
set crv $curves($dilname)
ts curve $crv
sct update [sct target]
}
proc dilprep::poll {} {
variable score
variable curves
if {[result _tmon status] eq "no response"} {
sct connected 0
} elseif {[silent 1 sct connected] == 0} {
device name none
device makeitem action plugged
device makeitem newdevice dilprep
}
set now [DoubleTime]
set onek [silent 0 result tmon onek/raw]
set stillt [silent 0 result tmon stillt/raw]
set mix [silent 0 result tmon mix/raw]
if {$onek * $stillt * $mix == 0} {
sct update -1
return idle
}
# guess dilution type from typical resistivities
# determine possible candidate
set dilname undef
if {abs($mix - 2200) < 50 && abs($onek - 2260) < 100 && abs($stillt - 2260) < 100} {
if {$onek > 2260} {
if {$stillt > 2260} {
set dilname dil4
}
} elseif {$stillt < 2260} {
set dilname dil2
} else {
set dilname dil3
}
}
set maxscore 0
# increase score for matching candidate, decrease for others (clamped within 0..12)
foreach {key value} [array get score] {
if {$key eq $dilname} {
set value [expr min(12, $value + 1)]
} else {
set value [expr max(0, $value - 1)]
}
if {$value > $maxscore} {
set maxscore $value
}
set score($key) $value
}
if {$dilname eq "undef"} {
sct undeftime $now
return idle
}
if {$maxscore eq 0} {
# no max score
enum_update [sct]/dil undef
} elseif {$score($dilname) >= $maxscore} {
if {$dilname ne [enum_txt [sct]/dil]} {
clientput "detected $dilname"
# highest score for $dilname
enum_update [sct]/dil $dilname
set crv $curves($dilname)
ts curve $crv
}
}
set mode [sctval [sct]]
set lim [hval [sct]/warmlimit]
set ts [silent 0 result ts]
set window [hval [sct]/window]
if {$mode == 1} {
# warming up
if {$ts < $lim} {
sct coldtime $now
}
if {[silent 999 hval /tslope] > [hval [sct]/slopelimit]} {
sct steeptime $now
}
if {$now > min([sct steeptime], [sct coldtime]) + $window} {
# warm
if {[sct steeptime] < [sct coldtime]} {
clientput "stick is warm (slope < [hval [sct]/slopelimit] for more than $window sec)"
} else {
clientput "stick is warm (T > [hval [sct]/warmlimit] for more than $window sec)"
}
sct target 0
check
return idle
}
} elseif {$mode < 0} {
# undef
if {$ts != 0} {
if {$now > [sct undeftime] + 120} {
if {$ts > [hval [sct]/warmlimit]} {
set mode 0
clientput "stick is warm"
} else {
set mode 1
clientput "stick is warming up"
}
}
sct target $mode
check
return idle
}
} else {
# warm or undef
if {$ts > [hval [sct]/coldlimit]} {
sct warmtime $now
}
if {[hval [sct]/dil] != 0 && $now > [sct warmtime] + $window} {
# warmup
sct target 1
check
return idle
}
}
sct update $mode
return idle
}