############################## relay_board.rb achase@mbari.org #################
#
# Control the (temporary) relay board for switching power on the rover
#
# The relay boards response protocol is slightly non-standard. When a on or off
# command is sent the relay board echoes the command characters but nothing else
# however, when the status command is sent the relay board echoes both the command
# characters and a newline/carriage return. That is why the reads on the turn_on
# and turn_off commands subtract 1 from their value and the read from the status
# adds 1 (1, not 2, because there is already a \r character, so we just have to
# subtract it, or add the \n character)
#
################################################################################

require 'rover_environment'
require 'posix/serialport'
require 'rover_utils'

class RelayBoard
  include LogHelper
  attr_reader :serial_port

  def initialize config, portname='/dev/relay'
    unless config
      config = SerialPort::Configuration.default
      config.baud = 9600
    end
    @serial_port = Posix::SerialPort.new portname, config
  end

  def valid_relay?(relay_num)
    if relay_num && relay_num > -1 && relay_num < 9
      true
    else
      false
    end
  end
  
  def flush_prompt
    @serial_port.read(3)
  end

  def turn_on(relay_num)
    if !valid_relay?(relay_num)
      puts "invalid relay number"
      return
    end
    num_bytes = @serial_port.write("N#{relay_num}\r")
    read = @serial_port.read(num_bytes - 1)
    flush_prompt
    nil
  end

  def turn_off(relay_num)
    if !valid_relay?(relay_num)
      puts "invalid relay number"
      return
    end
    num_bytes = @serial_port.write("F#{relay_num}\r")
    read = @serial_port.read(num_bytes - 1)
    flush_prompt
    nil
  end

  def get_status(relay_num)
    if !valid_relay?(relay_num)
      puts "invalid relay number"
      return
    end
    num_bytes = @serial_port.write("S#{relay_num}\r")
    line = @serial_port.read(num_bytes + 1)
    if(relay_num == 0)
      line = @serial_port.read(2)
    else
      line = @serial_port.read(1)
    end
    flush_prompt
    line 
  end
end
