# rs485, 9600 baud / 8 bit / no parity / 2 stop

namespace eval salsa {} {
}

proc stdConfig::salsa {adr upperlimit} {
  # timeout 5, try again 2
  controller bin modbus-crc 1 2
  prop read salsa::read
  prop write salsa::write
  # prop startcmd "int1 4 3 int2 0 6 crc / skip code skip str12 crc"

  obj SALSA rd
  prop @adr $adr
  prop adr 24
  prop scale 10

  kids "salsa" {

    node set wr
    prop adr 25
    prop upperlimit $upperlimit
    prop scale 10

    node clamp rd
    prop adr 21
    prop scale 10

    node hwstatus rd
    prop adr 19
  }
}

proc salsa::read {} {
  set cmd [format {int1 %d 3 int2 %d 1 crc} [sct @adr] [sct adr]]
  # code 3: read multiple input registers, 1: size / reply: code, bytesize, value
  sct send "int1 [sct @adr] 3 int2 [sct adr] 1 crc / skip code skip int2 crc"
  # sct send "int1 [sct @adr] 3 int2 [sct adr] 1 crc / hex hex hex hex hex hex dump"
  # alternatively code 4: read multiple holding registers
  # sct send "int1 [sct @adr] 4 int2 [sct adr] 1 crc / skip code skip int2 crc"
  # return salsa::update
  return salsa::update
}

proc salsa::update {} {
  set crcerror ""
  lassign [sct result] result crcerror
  if {$crcerror ne ""} {
    clientlog "WARNING: sended [sct send] reply: $crcerror"
  }
  set scale [silent 1 sct scale]
  if {$scale != 1} {
    set result [expr $result / double($scale)]
  }
  sct update $result
  return idle
}

proc salsa::write {} {
  if {[sct target] > [silent [sct target] sct upperlimit]} {
    error "[sct] [sct target] is above upper limit [sct upperlimit]"
  }
  set tg [expr round([sct target] * [silent 1 sct scale])]
  # code 16: write multiple registers, 1: size (words), 2: size (bytes) / reply: code, int2 adr, int2 size
  sct send "int1 [sct @adr] 16 int2 [sct adr] 1 int1 2 int2 $tg crc / skip code skip4 crc"
  # alternatively: code 6: write single register: no size) / reply: code int2 adr int2 value
  # sct send "int1 [sct @adr] 6 int2 [sct adr] int2 $tg crc / skip code skip4 crc"
  return salsa::read
}

proc salsa::write_coil {} {
  # code 5: write single coil
  sct send "int1 [sct @adr] 5 int2 [sct adr] int2 [sct target] crc / skip code skip4 crc"
  return salsa::read
}
