Files
sea/tcl/drivers/hepump.tcl
l_samenv 0e8dfa767b fix bug in hepump error log
the check that the pump is not running must run more frequently
than only every 30 seconds
2024-07-12 14:48:44 +02:00

427 lines
11 KiB
Tcl

namespace eval hepump {
}
proc stdConfig::hepump {{motname hemot}} {
variable name
controller syncedprot
prop write stdSct::complete
pollperiod 1 1
obj HePump -int wr
default 0
prop enum neodry=8,xds35_auto=0,xds35_manual=1,sv65=2,other=3,no=-1
prop help "xds35: scroll pump, sv65: leybold"
prop read hepump::read
prop write hepump::set_type
prop @motname $motname
prop health_cnt 0
kids "He pump ([silent xds35_auto result instconfig he_pump_type])" {
node running -int wr
prop enum 1
prop check hepump::chk_running
prop read hepump::get_running
node eco -int wr
prop enum 1
prop check hepump::set_eco
prop read hepump::get_eco
prop nonewline 1
node auto -int wr
default 1
prop enum 1
prop check hepump::set_auto
prop read hepump::get_auto
prop nonewline 1
node valve -int wr
prop enum closed,closing,opening,opened,undefined
prop check hepump::check_valve
prop write hepump::set_valve
prop read hepump::get_valve
prop buttontitle "operate valve"
prop buttons open/2/2,3:close/1/0,1
prop try 0
node eco_t_lim par 3
prop help "switch off eco mode when T_set < eco_t_lim and T < eco_t_lim * 2"
node calib par 1
node health upd
}
}
proc hepump::set_type {} {
sct update [sct target]
return hepump::set_calib
}
proc hepump::visible {pumpcode} {
if {$pumpcode == 0} {
set v true
if {[silent 0 result instconfig he_pump_type] eq "other_pump_with_valve"} {
set rv false
} else {
set rv true
}
set runv true
} elseif {$pumpcode == 8} {
set rv false
set runv true
set v true
} else {
set v false
set rv false
set runv false
}
foreach node "valve [sct @motname]" {
if {[silent true hgetpropval [sct]/$node visible] ne $v} {
hsetprop [sct]/$node visible $v
}
}
if {[silent true hgetpropval [sct]/running visible] ne $runv} {
hsetprop [sct]/running visible $runv
}
foreach node "eco auto eco_t_lim" {
if {[silent true hgetpropval [sct]/$node visible] ne $rv} {
hsetprop [sct]/$node visible $rv
}
}
if {$pumpcode == 3} {
set v true
} else {
set v false
}
if {[silent true hgetpropval [sct]/calib visible] ne $v} {
hsetprop [sct]/calib visible $v
}
}
proc hepump::set_calib {} {
set pumpcode [hvali [sct]]
sct update $pumpcode
if {$pumpcode < 0} { # no pump
_[sct @motname] disconnect
ignore_msg _[sct @motname] disconnected
hepump::visible $pumpcode
hsetprop [sct]/[sct @motname] group 0
return idle
} elseif {$pumpcode == 2} { # sv65
set f 0.9
hsetprop [sct]/[sct @motname] group 0
} elseif {$pumpcode == 1} { # xds35_manual
set f 0.6
hsetprop [sct]/[sct @motname] group 0
} elseif {$pumpcode == 0} { # xds35_auto
set status [string trim [_[sct @motname] status]]
if {$status eq "disconnected" || $status eq "offline"} {
# clientput [_[sct @motname] hostport]
_[sct @motname] reconnect
}
if {$status eq "no response"} {
set pumpcode 1 ;# treat as manual
hsetprop [sct]/[sct @motname] group "hepump valve motor (not connected)"
} else {
hsetprop [sct]/[sct @motname] group "hepump valve motor"
}
set eco [sctval [sct]/[sct @motname]/output1]
if {$eco == 1} {
set f 0.6 ;# this was 0.4
} else {
set f 0.6 ;# 0.95 at 30 mbar
}
} elseif {$pumpcode == 8} { # neodry
set status [string trim [_[sct @motname] status]]
if {$status eq "disconnected" || $status eq "offline"} {
# clientput [_[sct @motname] hostport]
_[sct @motname] reconnect
}
if {$status eq "no response"} {
set pumpcode 1 ;# treat as manual
hsetprop [sct]/[sct @motname] group "hepump valve motor (not connected)"
} else {
hsetprop [sct]/[sct @motname] group "hepump valve motor"
}
set f 0.55
} elseif {$pumpcode == 3} { # other
hsetprop [sct]/[sct @motname] group "hepump valve motor"
set f [hval [sct]/calib]
} else { # other: should not happen
error "illegal pump code"
}
hepump::visible $pumpcode
if {$f != [silent $f hval /nv/calib/ln_per_min_per_mbar]} {
nv calib/ln_per_min_per_mbar $f
hsetprop /nv off_until [expr [DoubleTime] + 20]
hsetprop /nv off_reason "pump mode changed"
sct print "pump mode change: suspend needle valve control for 20 sec."
}
return idle
}
proc hepump::read {} {
set p [silent 0 result nv flowp]
set f [silent 0 result nv flow]
set p_buf [silent 0 sct p_buf]
set f_buf [silent 0 sct f_buf]
lappend p_buf $p
lappend f_buf $f
sct p_buf [lrange $p_buf end-30 end]
sct f_buf [lrange $f_buf end-30 end]
set pmin [tcl::mathfunc::min {*}$p_buf]
set pmax [tcl::mathfunc::max {*}$p_buf]
set fmin [tcl::mathfunc::min {*}$f_buf]
set fmax [tcl::mathfunc::max {*}$f_buf]
if {[silent 0 hval [sct]/eco] == 0 && $pmin >= 1 && $fmin >= 0.5 && $fmin < 25} {
set hmax [expr round(100 * $fmax / ($pmin - 0.4))]
set hmin [expr round(100 * $fmin / ($pmax - 0.4))]
set health [silent 100 hval [sct]/health]
if {$hmax < $health} {
set health $hmax
} elseif {$hmin > $health} {
set health $hmin
}
hupdate [sct]/health $health
catch {prep0 / pump_health_update [result instrument] [expr min($health, 100)]} msg
}
return [hepump::set_calib]
}
proc hepump::set_valve_status {new} {
set old [silent "" sct valvestatus]
set path [sct objectPath]/status
set status [hvali $path]
if {$new ne "" || $old eq $status} {
hupdate $path $new
}
sct valvestatus $new
}
proc hepump::check_valve {} {
set_valve_status ""
sct try 5
sct slowspeed 50
}
proc hepump::set_valve {} {
if {[sctval [sct parent]] % 8 != 0} {return idle}
set val [hvali [sct]]
if {[sct target] < 2} {
if {[hvali [sct parent]/[sct @motname]/encoder] > 20} {
[sct @motname] maxspeed 200
sctsync {
run [sct @motname] 15
}
}
set val 1
catch {
# fix n.v.
hsetprop /nv off_until [expr [DoubleTime] + 10]
hsetprop /nv off_reason "pump valve closed"
}
sct update 1
return hepump::slow_close
} elseif {[sct target] < 4} {
[sct @motname] maxspeed 200
hset [sct parent]/[sct @motname] [hval [sct parent]/[sct @motname]/upperlimit]
set val 2
}
sct update $val
return idle
}
proc hepump::slow_close {} {
[sct @motname] maxspeed [sct slowspeed]
sct slowspeed [expr max(10,[sct slowspeed] - 10)]
run [sct @motname] [hval [sct parent]/[sct @motname]/lowerlimit]
return idle
}
proc hepump::get_valve {} {
if {[sctval [sct parent]] % 8 != 0} {return idle}
set p [sct parent]/[sct @motname]
set stat [hgetpropval $p status]
set pos [hvali $p/encoder]
if {$pos < [hval $p/lowerlimit] - 15 ||
$pos > [hval $p/upperlimit] + 15} {
hsetprop $p/encoder adjust_zero 1
return idle
}
set dir [string map {0 close 1 close 2 open 3 open 4 undefined} [silent 4 sct target]]
if {[sct try] == 0} {
set dir undefined
}
if {$stat eq "run"} {
if {[hgetpropval $p target] > $pos} {
sct update 2
} else {
sct update 1
}
} elseif {$pos < 2 && $dir ne "open"} {
sct update 0 ;# closed
sct try 0
set_valve_status ""
} elseif {$pos > 30 && $dir ne "close"} {
sct update 3 ;# opened
sct try 0
set_valve_status ""
} else {
if {[sct try] > 1 && $dir ne "undefined"} {
set try [sct try]
incr try -1
if {$try <= 3} {
clientput "[sct] try again to $dir ($try)"
}
hset [sct] [sct target]
sct try $try
} else {
sct try 0
if {$dir ne "undefined"} {
set txt "cannot $dir valve at He pump. Please do it manually"
clientput "ERROR: $txt"
set_valve_status $txt
sct target 4
}
sct update 4 ;# undefined
}
}
if {[hvali [sct]] != 3} {
# not open - fix n.v.
catch {
hsetprop /nv off_until [expr [DoubleTime] + 10]
hsetprop /nv off_reason "pump valve closed"
}
}
return idle
}
proc hepump::chk_running {} {
if {[sctval [sct parent]] % 8 != 0} return
if {[sct target]} {
hset [sct parent]/[sct @motname]/output0 1
} else { # off
if {[silent 0 result instconfig he_pump_type] ne "other_pump_with_valve"} {
# fix n.v.
catch {
hsetprop /nv off_until [expr [DoubleTime] + 10]
hsetprop /nv off_reason "He pump not running"
}
hset [sct parent]/[sct @motname]/output0 0
}
}
hsetprop [sct parent]/[sct @motname]/output0 trigger_path [sct parent]/[sct @motname]/input3
sct update [sct target]
}
proc hepump::get_running {} {
# only for xds35 and neodry
if {[sctval [sct parent]] % 8 != 0} {return idle}
set running [sctval [sct parent]/[sct @motname]/output0]
set pumpoff [silent 1 hval [sct parent]/[sct @motname]/input3]
set now [DoubleTime]
if {$running != [silent 0 sct last_running]} {
sct last_running $running
# leave early (status should be checked later, when input3 is read again)
return idle
}
sct update $running
if {!$running} {
catch {
hsetprop /nv off_until [expr $now + 10]
hsetprop /nv off_reason "He pump not running"
}
}
if {$now < [silent 0 sct last_ok] + 30} {
return idle
}
set old [hvali [sct parent]/status]
set new ""
if {$running} {
if {$pumpoff} {
if {[silent 0 result instconfig he_pump_type] ne "other_pump_with_valve"} {
set new "He pump remote cable is not connected"
catch {hsetprop /nv off_until [expr $now + 10]}
}
} else {
sct last_ok [DoubleTime]
}
} else {
if {!$pumpoff} {
set new "He pump is still running - manual power must be switched off"
} else {
sct last_ok [DoubleTime]
}
}
if {$new ne $old} {
if {$new ne ""} {
clientput "ERROR: $new"
}
hupdate [sct parent]/status $new
}
return idle
}
proc hepump::set_eco {} {
# xds35 only, not for neodry
if {[sctval [sct parent]] != 0} {return idle}
if {[sct target] != [hvali [sct]]} {
hset [sct parent]/auto 0
}
if {[sct target]} {
hset [sct parent]/[sct @motname]/output1 1
} else { # eco off
hset [sct parent]/[sct @motname]/output1 0
}
hepump::get_eco
}
proc hepump::get_eco {} {
# xds35 only, not for neodry
if {[sctval [sct parent]] != 0} {
sct update 0
return idle
}
set eco [sctval [sct parent]/[sct @motname]/output1]
sct update $eco
[sct controller] queue [sct parent] write hepump::set_calib
return idle
}
proc hepump::set_auto {} {
# xds35 only, not for neodry
if {[sctval [sct parent]] != 0} {return idle}
sct update [sct target]
}
proc hepump::get_auto {} {
# xds35 only, not for neodry
if {[sctval [sct parent]] != 0} {return idle}
set auto [hvali [sct]]
set oldeco [sctval [sct parent]/eco]
if {$auto && $oldeco != 2} {
set eco [sctval [sct parent]/eco]
set lim [sctval [sct parent]/eco_t_lim 7]
set target [silent [silent $lim hval /tt/target] hval /tt/set/reg]
if {[silent 0 result nv use_pressure]} {
set ecoset 0
} elseif {$target < $lim && [silent $lim hval /tt] < 2 * $lim} {
set ecoset 0
} elseif {$target > $lim || [silent $lim hval /tt] > 3 * $lim} {
set ecoset 1
} else {
set ecoset $eco
}
if {$oldeco != $ecoset} {
hset [sct parent]/eco $ecoset
}
}
sct update $auto
return idle
}