# magnet resistivity measured with IPS

namespace eval magres {} {
}

proc stdConfig::magres {} {
  variable hostport none
  variable name
  controller syncedprot
  pollperiod 1 1

  obj magres rd
  prop read magres::read
  prop last 0
  prop htr 0
  prop exc 0
  kids "magnet resistance" {
    node active out
    default 0
    prop enum 1
    prop write magres::setactive

    node coil upd

    node excitation par 0.1
  }
}

proc magres::setactive {} {
  if {[sct target]} {
    sct init 1
    mf persmode 3
  } else {
    sct init 11
  }
  sct update [sct target]
  return idle
}

proc magres::read {} {
  if {[result mf persmode] != 3} {
    # switch off immedately as a run mf has been done
    updateval [sct]/active 0
    return idle
  }
  set ramp [result mf ramp]
  set ampRamp [result mf ampRamp]
  if {$ramp == 0 || $ampRamp == 0} {
    mf ramp 0.5
    sct init 1
    return idle
  }
  set fact [expr $ramp / $ampRamp]
  set exc [hvali [sct]/excitation]
  if {abs($exc) > 0.1} {
    clientput "excitation is limited to 0.1 A"
    set exc 0.1
  }
  set init [sct init]
  if {[hvali [sct]/active] == 0} {
    sct geterror "off"
    if {$init > 0} {
      if {$init <= 10} {
        if {abs([result mf current] - [sct exc] * $fact) > 0.001} {
          clientput "bad state of power supply"
          return idle
        }
        set init 11
      }
      switch $init {
        11 { mf send C3 }
        12 { mf send H2 }
        30 { mf send I0 }
        31 { mf send A1 }
        32 { mf send H0 }
        33 {
          mf send C1
          mf persmode 1
        }
        34 { return idle }
        default {
        }
      }
      incr init
      sct init $init
    }
    return idle
  }
  if {$init > 10 || ($init == 10 && $exc != [sct exc])} {
    set init 1
  }
  if {$init < 10} {
    switch $init {
      1 {
        mf send C3
      }
      2 { mf send T0.5000 }
      3 {
        mf send [format I%.4f $exc]
        sct exc $exc
      }
      4 { mf send A1 }
      5 { mf send R0 }
      default {
        sct init 10
        return idle
      }
    }
    incr init
    sct init $init
    return idle
  }
  set mf [expr $fact * $exc]
  set curT [result mf current]
  set res [expr [result mf voltage] / $curT * $fact]
  set now [DoubleTime]
  if {[sct htr]} {
    if {$now > [sct last] + 10} {
      updateval [sct]/coil $res
      if {$now > [sct last] + 20} {
        sct last $now
        sct htr 0
        mf send H0
      }
    }
  } else {
    if {$now > [sct last] + 10} {
      sct update $res
      if {$res > 1} {
        hsetprop [sct]/coil geterror off
      } elseif {$now > [sct last] + 20} {
        sct last $now
        sct htr 1
        mf send H2
      }
    }
  }
  return idle
}
