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

270 lines
6.2 KiB
Tcl

namespace eval jtccr {
}
proc stdConfig::jtccr {} {
variable node
controller syncedprot
pollperiod 1 1
obj JTCCR -int wr
default 0
prop check jtccr::set_mode
prop write stdSct::complete
prop read jtccr::read
prop dir 0
prop p1path /p1
prop p2path /p2
prop p3path /p3
prop pressregpath /pressreg/setpoint
prop compressorpath /epc/port1
prop tpath /tt/main
prop enum manual,high_pressure,circulating,warmup
kids "jtccr" {
#node p1min par 1.8
#prop help "go to high_pressure mode when p1 below this value"
node p1max par 2.2
prop help "go to circulating mode when p1 above this value"
node p2min par 0.12
prop help "stop compressor when p2 is below this value"
#node p2lim par 0.15
#prop help "do not start compressor when p2 is below this value"
node p2max par 0.8
prop help "start compressor when p2 is above this value"
node pdifmax par 5.0
prop help "maximum pressure difference for compressor"
node pdifmargin par 1
prop help "safety margin for pressure difference"
node p3margin par 0.01
prop help "start compressor when p3 is below pressreg setpoint plus this value"
node plow par 4
prop help "pressure below 5 K"
foreach i {1 2 3 4 5 6 7 8 9 10} {
node v$i wr
prop enum 1
prop check jtccr::setvalve $i
prop write stdSct::complete $i
prop read jtccr::getvalve $i
}
node vm wr
prop label vm
prop enum closed,opened
prop write jtccr::setmotvalve
prop read jtccr::getmotvalve
prop initstate init
node verbose -int par 0
prop enum 1
}
}
proc jtccr::setvalve {i} {
v vc$i [sct target]
sct update [sct target]
sct settime [DoubleTime]
}
proc jtccr::valve_state_text {i} {
return [lindex [list off on no_valve timeout timeout1 boost] $i]
}
proc jtccr::getvalve {i} {
if {[DoubleTime] < [silent 0 sct settime] + 2} {
# do not update while write operation might be pending
return idle
}
set vs [hvali /v/v$i]
if {$vs > 1 && $vs < 5} {
error "v$i error: [valve_state_text $vs]"
}
sct update $vs
return idle
}
proc jtccr::setmotvalve {} {
switch -- [sct target] {
0 {
v mp -[hval /v/mot]
sct enum start_closing,open
}
1 {
v mp [hval /v/mot]
sct enum close,start_opening
}
}
sct update [sct target]
return idle
}
proc jtccr::getmotvalve {} {
set fm [silent -1 hval /v/fm]
switch -- $fm {
1 {
sct update 3
sct enum close,open,opening=3
}
2 {
sct update 2
sct enum close,open,closing=2
}
3 {
sct update 1
sct enum close,opened
}
4 {
sct update 0
sct enum closed,open
}
5 {
sct update 4
sct enum close,open,no_motor=4
}
default {
if {[sct initstate] eq "init"} {
# try to close - if not done within short time, try to open
sct initstate done
}
sct update 5
sct enum close,open,undefined=5
}
}
return idle
}
proc jtccr::set_mode {} {
switch -- [sct target] {
0 { # manual }
1 { # high_pressure
foreach i {3 4 5 6 7 8 10} {
hset [sct]/v$i 0
}
foreach i {1 2 9 m} {
hset [sct]/v$i 1
}
hset [sct pressregpath] 12
}
2 { # circulate
foreach i {3 4 5 6 7 9 10} {
hset [sct]/v$i 0
}
foreach i {1 2 8 m} {
hset [sct]/v$i 1
}
hset [sct pressregpath] [hvali [sct]/plow]
}
3 { # warmup
foreach i {6 7 8 9 10} {
hset [sct]/v$i 0
}
foreach i {1 2 3 4 5 m} {
hset [sct]/v$i 1
}
}
default {
error "illegal mode"
}
}
sct update [sct target]
}
proc jtccr::read {} {
if {[hvali [sct]] == 0} {
return idle
}
#if {![silent 0 sct lowt] && [hvali [sct tpath]] < 5} {
# hset [sct pressregpath] [hvali [sct]/plow]
# sct lowt 1
#}
set p1 [hvali [sct p1path]]
set p2 [hvali [sct p2path]]
set p3 [hvali [sct p3path]]
set p3reg [expr [hvali [sct pressregpath]] + [hvali [sct]/p3margin]]
set pdifmax [hvali [sct]/pdifmax]
set p2min [hvali [sct]/p2min]
set p2max [hvali [sct]/p2max]
# security features:
if {$p3 >= $p2 + $pdifmax + [hvali [sct]/pdifmargin]} {
hset [sct compressorpath] 0
hset [sct]/v9 0
hset [sct]/v1 0
hset [sct] 0 ;# manual
hset [sct]/status "overpressure: He recovery output closed?"
return idle
}
if {$p2 < $p2min && $p3 < $p3reg && [sctval [sct]] != 1} {
hset [sct compressorpath] 0
hset [sct]/v9 0
hset [sct]/v1 0
hset [sct] 0 ;# manual
hset [sct]/status "underpressure: not enough He"
return idle
}
hset [sct]/status ""
set verbose [silent 0 hvali [sct]/verbose]
if {[sctval [sct]/v8]} { # circulating
if {$p3 < $p3reg && ![hvali [sct compressorpath]]} {
if {$verbose} {
clientput "switch compressor on (p3 < p3reg=$p3reg)"
}
hset [sct compressorpath] 1
} elseif {$p3 - $p2 > $pdifmax && [hvali [sct compressorpath]]} {
if {$verbose} {
clientput "switch compressor off (p3 - p2 > pdifmax=$pdifmax)"
}
hset [sct compressorpath] 0
# skip overpressure protection for one time
# return idle
}
}
if {[hvali [sct]] == 1 && $p1 > [hvali [sct]/p1max]} {
# switch from high pressure mode to circulating when p1 > p1max
hset [sct] 2
return idle
}
if {$p2 > $p2max && ![hvali [sct compressorpath]]} {
if {$verbose} {
clientput "switch compressor on (p2 > p2max=$p2max)"
}
hset [sct compressorpath] 1
} elseif {$p2 < $p2min && [hvali [sct compressorpath]]} {
if {$verbose} {
clientput "switch compressor off (p2 < p2min=$p2min)"
}
hset [sct compressorpath] 0
}
# overpressure protection
if {$p3 - $p2 >= $pdifmax + 0.1} {
# release to recovery
if {![sctval [sct]/v10]} {
hset [sct]/v10 1
if {$verbose} {
clientput "release to recovery (p3 - p2 > pdifmax=$pdifmax) p3-p2=[expr $p3 - $p2]"
}
}
} elseif {[sctval [sct]/v10]} {
# finish release to recovery
hset [sct]/v10 0
if {$verbose} {
clientput "release finished (p3 - p2 < pdifmax=$pdifmax)"
}
}
# clear error message
sct update [hvali [sct]]
return idle
}