# ips mercury level meters

namespace eval ipslev {} {
}

source drivers/ipsmag.tcl

proc stdConfig::ipslev {{slot DB3}} {
  controller std
  variable ctrl
  variable node

  prop write ipsmag::write
  prop read ipsmag::read
  prop update ipsmag::update
  prop startcmd *IDN?
  prop slot $slot

  obj ips_mercury_levels rd
  prop adr "DEV:${slot}.L1:LVL:SIG:HEL:LEV"
  prop slowperiod 300
  prop lastread 0
  prop slow 1
  prop maxtime 0
  prop maxval 0
  prop minval 100
  prop update ipslev::update_he

  set henode $node

  kids "level meter settings" {
    node mode par 1
    prop enum slow,fast

    node n2 rd
    prop adr "DEV:${slot}.L1:LVL:SIG:NIT:LEV"
    prop update ipslev::update_n2
  }

  helium_register $ctrl $henode
}

proc ipslev::update_n2 {} {
  set lev [ipsmag::cvt]
  # determine median of last 5 values
  set buffer "[silent {-999 -999 999 999} sct buffer] $lev"
  set lev [lindex [lsort $buffer] 2]
  sct update $lev
  sct buffer [lrange $buffer 1 4]
  return idle
}

proc ipslev::update_he {} {
  set lev [ipsmag::cvt]
  # determine median of last 5 values
  set buffer "[silent {-999 -999 999 999} sct buffer] $lev"
  set lev [lindex [lsort $buffer] 2]
  sct update $lev
  sct buffer [lrange $buffer 1 4]
  set now [DoubleTime]
  set action ""
  if {[hval [sct]/mode] == 0} {
    if {[sct slow]} {
      set p [sct slowperiod]
      if {int($now / $p) > int([sct lastread] / $p)} {
        sct slow 0
        set action OFF
        sct lastread $now
      }
    } else {
      if {![sct slow]} {
        sct slow 1
        sct minval $lev
        set action ON
      }
    }
    sct maxval $lev
    sct maxtime $now
    if {$lev < [sct minval]} {
      sct minval $lev
    } elseif {$lev > [sct minval] + 5} {
      hset [sct]/mode 1
      sct maxval $lev
clientput "[sct] switch to fast as an increase is detected $lev [sct minval]"
    }
  } else {
    if {[sct slow]} {
      set action OFF
      sct slow 0
      sct maxtime $now
    }
    if {$lev > [silent 0 sct maxval]} {
      sct maxval $lev
      sct maxtime $now
    } elseif {$now > [sct maxtime] + [sct slowperiod]} {
      hset [sct]/mode 0
      sct minval $lev
clientput "[sct] switch to slow as no increase detected"
    }
  }
  if {$action ne ""} {
    sct send "SET:DEV:[sct slot].L1:LVL:HEL:PULS:SLOW:$action"
    return ipslev::complete
  }
  return idle
}

proc ipslev::complete {} {
  return idle
}
