# # Automatic N2 refill # # watching state (2): # if lower sensor falls below startvalue for more than startdelay seconds, # start fill, go to fillstart state (3) # fillstart state (3): # wait fillmini seconds, then go to filling state # filling state (4): # if upper sensor goes beyond fillvalue for more than filldelay seconds, # stip fill, go to quiet state (1) # quiet state (1): # wait stopmini seconds, then go to watching state (2) proc makeN2fill {} { makeobject n2fillPar array logged n2fillPar makeitem state 0 n2fillPar makeitem lower "tt tm" n2fillPar makeitem upper "tt ts" n2fillPar makeitem startvalue 100 n2fillPar makeitem stopvalue 100 n2fillPar makeitem lasttime 0 n2fillPar makeitem lastcron 0 n2fillPar makeitem startdelay 10 n2fillPar makeitem stopdelay 5 n2fillPar makeitem fillmini 10 n2fillPar makeitem stopmini 60 n2fillPar makeitem instance 0 n2fillPar makeitem errcnt 0 obj_list makeitem n2fillPar "LN2 refill parameters" Layout n2fill } proc n2fillLayout args { Group n2fill "LN2 refill" } proc n2fillGroup args { showStatus n2fill RadioGroup n2fill Label "LN2 refill" NoNewline CheckBox active "n2fill on" if {[result n2fill on]} { NoNewline CheckBox fill "n2fill fill" } NoNewline Label "state: [result n2fill]" Newline Tip "upper sensor parameter name" Input "upper sensor" "n2fillPar upper" Tip "lower sensor parameter name" Input "lower sensor" "n2fillPar lower" Newline Tip "switch-off value on upper sensor" Input "stop value" "n2fillPar stopvalue" Tip "switch-on value on lower sensor" Input "start value" "n2fillPar startvalue" Newline Input "start delay" "n2fillPar startdelay" Input "stop delay" "n2fillPar stopdelay" Newline Tip "minimum switch-on time" Input "minimum fill time" "n2fillPar fillmini" Tip "minimum switch-off time" Input "minimum stop time" "n2fillPar stopmini" Newline } proc n2state {state} { n2fillPar lasttime [clock seconds] if {$state > 2} { clientput "valve ON" tt send relay 2:2,1 } else { clientput "valve OFF" tt send relay 2:2,0 } n2fillPar state $state } proc n2fill {{action none} {value none}} { set now [clock seconds] set lasttime [result n2fillPar lasttime] set uval [result eval [result n2fillPar upper]] set lval [result eval [result n2fillPar lower]] set state [result n2fillPar state] set errcnt [result n2fillPar errcnt] switch -- $action { none { switch -- $state { 0 { return "n2fill = off (0)" } 1 { return "n2fill = quiet (1)" } 2 { return "n2fill = watching (2)" } 3 { return "n2fill = fillstart (3)" } 4 { return "n2fill = filling (4)" } } } cron { n2fillPar lastcron $now if {$value != [result n2fillPar instance]} { n2state 0 error "n2fill instance $value stopped" } if {$uval < 420 && $uval > 65 && $lval < 420 && $lval > 65} { n2fillPar errcnt 0 } else { incr errcnt if {$errcnt >= 5} { n2state 0 error "illegal upper ($uval) or lower ($lval) temperature" } n2fillPar errcnt $errcnt return } switch -- $state { 3 { if {$now > $lasttime + [result n2fillPar fillmini]} { n2state 4 } } 4 { if {$uval < [result n2fillPar stopvalue]} { if {$now > $lasttime + [result n2fillpar stopdelay]} { n2state 1 } } else { n2fillpar lasttime $now } } 1 { if {$now > $lasttime + [result n2fillPar stopmini]} { n2state 2 } } 2 { if {$lval > [result n2fillPar startvalue] && $lval < 250} { if {$now > $lasttime + [result n2fillpar startdelay]} { n2state 3 } } else { n2fillpar lasttime $now } } default { error "n2fill stopped with state $state" } } } on { switch -- $value { 1 { set instance [result n2fillPar instance] incr instance n2fillPar instance $instance sicscron 1 n2fill cron $instance n2state 2 return "n2fill.on = 1" } 0 { n2state 0 return "n2fill.on = 0" } none { if {$now > [result n2fillPar lastcron] + 10} { return "n2fill.on = 0" } if {$state > 0} { return "n2fill.on = 1" } else { return "n2fill.on = 0" } } } } fill { switch -- $value { 1 { n2state 4 return "n2fill.fill = 1" } 0 { n2state 2 return "n2fill.fill = 1" } none { if {$state > 2} { return "n2fill.fill = 1" } else { return "n2fill.fill = 0" } } } } } } publishLazy n2fill spy