require 'rover_environment'
require 'rover_utils'
require 'posix/serialport'

################################################################
# MBARI Rover
#
# Driver for Aanderaa Optode
#
# Change history:
#    Date       Who    What
#    ---------  ---    -------------------------------------
#    19-Dec-06  RGH    V1.0 - basic functions incl logging
#
################################################################
class Aanderaa 
  include LogHelper

  attr_accessor :rawdata

  # Default configuration
  # /dev/acm 9600,8,N,1
  #
  def initialize config, portname = '/dev/ref_optode'
    unless config
      config = SerialPort::Configuration.default
      config.baud = 9600
    end
    @dev = Posix::SerialPort.new portname, config
    @name = portname[(portname.rindex("/")+1)..(portname.length-1)]
    @RAWDATA_ELEMENTS = 9
    
    # Distinguish between the multiple Aanderaa optodes on the vehicle
    # Model and S/N should come from configuration object
    # 
    @logfilename = @name + ".csv"
    datawrite("Rover Timestamp (UTC) , Oxygen (uM) , Oxygen Saturation (%) , " <<
              " Water Temp (Celcius), " <<
              ",Aanderra Oxygen Optode 3830  S/N 850\n,\n", @logfilename)
    
    @oxy  = -1
    @sat  = 0
    @temp = 0
    @thread = nil
    
  end

  def stop
    if self.is_running?
      @thread.kill
      @thread = nil
      syslog("_ Stopping #{@name} optode thread")
    end
  end
  
  def close
    self.stop
    syslog("_ Closing serial device for #{@name}")
    @dev.close
  end
  
  
  def acquire_data
    syslog("_ Obtaining optode data for #{@name}")
    # Aanderaa simply returns data string
    #
    #@dev.purge
    self.rawdata = @dev.gets
    
    # Process data
    #
    @data = self.rawdata.split
    
    # There should be 9 components in the data string
    #
    
    if @data.length == @RAWDATA_ELEMENTS
      @oxy  = @data[4].to_f
      @sat  = @data[6].to_f
      @temp = @data[8].to_f
    elsif @data.length == 6
      @oxy  = @data[3].to_f
      @sat  = @data[4].to_f
      @temp = @data[5].to_f
    else
      syslog("! Error parsing rawdata on #{@name}, @data array length is: " +
             "#{@data.length} and should be #{@RAWDATA_ELEMENTS}")
      elements_string = "["
      @data.each {|el| elements_string += el + ", "}
      elements_string += "]"
      syslog("_ elements in @data array: #{elements_string}")
      return false
    end
        
    return true
  end

  # Write data to log file
  #
  def log_data
    datalog("#{@oxy},#{@sat},#{@temp}", @logfilename)
  end

  # Run in thread
  #
  def run
    syslog("_ Running optode thread for #{@name}")
    @thread = RoverThread.new do
      while true
        log_data if acquire_data
      end
    end
  end
  
  def is_running?
    if @thread
      return @thread.alive?
    else
      return false
    end
  end
  
end