Files
sea/tcl/drivers/svumot.tcl
2022-08-18 15:04:28 +02:00

172 lines
3.5 KiB
Tcl

# 7-8 solenoid valves + one motorized valve (DC-motor with endswitch)
namespace eval svumot {} {
}
proc stdConfig::svumot {valvelist} {
controller std "\n" 5
prop mot 0
prop startcmd "tv1"
foreach {name nr} $valvelist {
if {$nr == 8} {
# disable button 8 for motor
prop startcmd "tv0"
} elseif {$nr eq "mot"} {
prop mot $name
} elseif {$nr < 1 || $nr > 9} {
error "bad valve number / mot: /$nr/"
}
}
obj svumot rd -none
prop read svumot::read
prop @closetime 0
kids "valves" {
foreach {name nr} $valvelist {
node $name out
if {$nr eq "mot"} {
prop label $name
prop enum close,open
prop write svumot::swrite
} else {
prop nr $nr
prop enum 1
prop write svumot::write
prop nonewline 1
}
}
node motpos upd
kids "set" {
node set out
default 0
prop write svumot::wset
}
node n2top upd
# prop visible false
prop label N2top
prop newline 1
node n2bot
prop label N2bot
}
}
proc svumot::write {} {
if {[sct target]} {
sct send o[sct nr]
} else {
sct send c[sct nr]
}
[sct controller] queue [sct parent] read read
return stdSct::completeUpdate
}
proc svumot::swrite {} {
if {[sct target] == 1 || [sct target] == 3} {
sct send o9
sct @closetime -1
} else {
sct send c9
sct @closetime -1
}
[sct controller] queue [sct parent] read read
return stdSct::completeUpdate
}
proc svumot::read {} {
sct send enmp
return svumot::update
}
proc svumot::update {} {
set pos -1
set state -1
set error ""
set valves none
scan [sct result] "e%d n%f m%f p%f %d %s" state n2a n2b pos valves error
if {$valves eq "none"} {
return idle
}
updateval [sct]/motpos $pos
switch $state {
0 {set enum closed,open}
1 {set enum close,opened}
2 {set enum close,open,closing}
3 {set enum close,open,opening=3}
7 {set enum unplugged=7}
default {set enum close,open,$error=$state}
}
hsetprop [sct]/[sct mot] enum $enum
foreach nr {1 2 3 4 5 6 7 8} {
set vs($nr) 0
}
foreach nr [split $valves {}] {
set vs($nr) 1
}
foreach node [hlist [sct]] {
set nr [silent 0 hgetpropval [sct]/$node nr]
if {$nr != 0} {
updateval [sct]/$node $vs($nr)
}
}
updateval [sct]/[sct mot] $state
if {"$error" ne "" && "$error" ne "stopped"} {
hsetprop [sct]/motpos geterror $error
} else {
hdelprop [sct]/motpos geterror
}
updateval [sct]/n2top $n2a
updateval [sct]/n2bot $n2b
return idle
}
proc svumot::holdopen {} {
if {[sct @closetime] < 0} {
return unpoll
}
if {[doubletime] >= [sct @closetime]} {
sct send s
return svumot::unpoll
}
return idle
}
proc svumot::unpoll {} {
sct @closetime 0
[sct controller] queue [sct parent] read read
return unpoll
}
proc svumot::wset {} {
if {[sct @closetime] <= 0} {
set t2o 60
scan [sct idn] "t%f v" t2o
set pos [hvali [sct]]
set posr [hvali [sct parent]]
if {$pos > $posr + 0.002} {
set pos [expr $posr + 0.002]
} elseif {$pos < $posr - 0.002} {
set pos [expr $posr - 0.002]
}
set dif [expr [sct target] - $pos]
set delta [expr abs($dif) * $t2o]
if {abs($dif) > 0.0001} {
sct update [sct target]
sct @closetime [expr [doubletime] + $delta]
if {$dif > 0} {
sct send o9
} else {
sct send c9
}
[sct controller] poll [sct parent] 0.001 write svumot::holdopen
return stdSct::complete
} else {
sct update $pos
}
}
return idle
}