# based on untested flowbusprot, not used M.Z. Feb 2017

namespace eval flowbus {} {
}

proc stdConfig::flowbus {label scale {adr 128} {readonly 0}} {

  controller flowbus "\r\n"

# driver for Bronkhorst Flow or Pressure regulator  (i.e.P-602CV-21KA-AAD) 
# serial interface is set to:
# Char Size/Stop Bits:         8/1    Input Speed:                38400
# Flow Ctrl:                  None    Output Speed:               38400
# Parity:                     None    Modem Control:               None

# syntax (chaining not mentioned):
# read command:  :06Ad04CopyPrTp
# write command: :LnAd01PrTpData
# where:
#   Ln: number of bytes (hex digits pairs) following
#   Ad: node address (starting from 3)
#   Copy: values just to be copied by the reply (first and third digit < 8)
#         recommended practice: Use PrTp for Copy
#   Pr: Process number (<80)
#   Tp: Type + parameter number. Type: 00 byte, 20 int, 40 long/float, 60 string
#       for strings either 00 (for nul terminated) or the max. number of chars
#       has to be appended to the type
#   Data: length depending on type.

# the interface returns readings on a scale where 32000 is 100%

  set adr [format %02x $adr]
  clientput "BRONK $label $scale $adr"

  obj bflow rd
  prop label $label
  prop readcmd "r$adr 1 i0"
  prop readfmt "%d"
  prop update flowbus::conv $scale
  prop @adr $adr

  kids "$label" {
    node setpoint wr
    prop label Setpoint
    prop write flowbus::setp $scale
    prop readcmd "r$adr 1 i1"
    prop readfmt "%d"
    prop update flowbus::conv $scale
   
  }
  
}


proc flowbus::conv {scale} {
  if {[scan [sct result] [sct readfmt] flow ] != 1} {
    error "bad result format: '[sct result]'"
  }
  sct update [format %.6g [expr $flow * $scale / 32000.]]
  return idle
}


proc flowbus::setp {scale} {
   set setval [expr int( [sct target] * 32000.0 / $scale) ]
   if {$setval > 32000 } {
      if {$setval < 32320} {
        set setval 32000
      } else {
        error "[sct]: setpoint [sct target] must be <= $scale"
      }
   } elseif {$setval < 0 } {
      error "[sct]: setpoint [sct target] must be >= 0"
   }
  sct send "w [sct @adr] 1 i1=$setval"
  return "flowbus::acknowledge"
}

proc flowbus::acknowledge {} {
   if {[string compare [sct result] "0" ] != 0} {
    error "bad result format: '[sct result]' [sct result]"
  }
  return read
}
