namespace eval dilhtr {
}

proc stdConfig::dilhtr {} {
  variable name
  variable node

  controller std timeout=20
  prop startcmd id
  set node $node/tasks
  prop start dilhtr::start

  pollperiod 1 1

  obj DILHTR14 wr
  prop label {power set [mW]}
  prop write dilhtr::write
  prop read dilhtr::poll
  prop cmd p
  prop fact 0.001

  kids "dil heater ($name)" {
    node resistance out
    prop write dilhtr::write
    prop cmd r

    node power upd
    prop label "power read"
    prop cmd pr
    prop fact 0.001

    node sigma upd
    prop label "power error"
    prop cmd dp
    prop fact 0.001

    node current upd
    prop help {heater current [mA]}
    prop cmd i

    node voltage upd
    prop help {heater voltage [mV]}
    prop cmd v

    node state -int upd
    prop enum ok,short,open
    prop cmd h

    node range -int upd
    prop enum low=1,mid,high
    prop cmd k

    node lim out
    prop write dilhtr::write
    prop help "correction for resistor value and power\nhappens only above this value"
    prop cmd l
    prop fact 0.001

    node tol out
    prop write dilhtr::write
    prop help "correction for resistor value and power\nhappens only when difference is < tol * sigma"
    prop cmd t

    node timeout out
    prop write dilhtr::write
    prop help "after 'timeout' seconds with no connection, the heater is switched off"
    prop cmd tmo

    node pmin upd

    node pmax upd

    node cor upd
    prop cmd cor

    node resAdjust -int out
    prop cmd ra
  }
}

proc dilhtr::start {} {
  sct send id
  return stdSct::start
}

proc dilhtr::cmds {} {
  set base [sct objectPath]
  sct cmd_p $base
  foreach node [hlist $base] {
    catch {
      set cmd [hgetpropval $base/$node cmd]
      sct cmd_$cmd $base/$node
      lappend query $cmd
    }
  }
  return [join $query " "]
}

proc dilhtr::poll {{query {}}} {
  set base [sct objectPath]
  sct send "p [dilhtr::cmds]"
  return dilhtr::update
}

proc dilhtr::update {} {
  variable pathlist

  set kill ""
  foreach item [split [sct result]] {
    set itm [split $item =]
    set var [lindex $itm 0]
    set val [lindex $itm 1]
    catch {
      set path [sct cmd_$var]
      set fact [silent 1 hgetpropval $path fact]
      updateval $path [expr $fact * $val]
    }
  }
  set pr [hvali [sct objectPath]/power]
  set dp [hvali [sct objectPath]/sigma]
  hupdate [sct objectPath]/pmin [expr $pr - $dp]
  hupdate [sct objectPath]/pmax [expr $pr + $dp]
  if {$kill eq ""} {
    return idle
  }
  sct send [string trim $kill]
  return stdSct::complete
}

proc dilhtr::write {} {
  set p [expr [sct target]/double([silent 1 sct fact])]
  sct send "[sct cmd]=$p [dilhtr::cmds]"
  return dilhtr::update
}
