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 enum_ closed,opened,closing,opening,no_motor,undefined 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 }