############################## 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

  # Define relay switches: NAME = switch_number
  #
  NET    = 8
  RACK   = 7
  OPTODE = 6
  PUMP   = 5
  V5     = 4
  V12    = 3
  VIDEO  = 2
  MOTORS = 1
  #
  
  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
  
  def videoOn
    turn_on VIDEO
  end
  
  def videoOff
    turn_off VIDEO
  end
  
  def rackOn
    turn_on RACK
  end
  
  def rackOff
    turn_off RACK
  end
  
  def motorsOn
    turn_on MOTORS
  end
  
  def motorsOff
    turn_off MOTORS
  end
  
  def optodeOn
    turn_on OPTODE
  end
  
  def optodeOff
    turn_off OPTODE
  end
  
  def netOn
    turn_on NET
  end
  
  def netOff
    turn_off NET
  end
  
  def v5On
    turn_on V5
  end
  
  def v5Off
    turn_off V5
  end
  
  def v12On
    turn_on V12
  end
  
  def v12Off
    turn_off V12
  end
  
  def pumpOn
    turn_on PUMP
  end
  
  def pumpOff
    turn_off PUMP
  end
  
  def allOff
    turn_off VIDEO
    turn_off RACK
    turn_off MOTORS
    turn_off OPTODE
    #turn_off NET
    turn_off V5
    turn_off V12
    turn_off PUMP
  end
  
end
