     {:noreply, state}
   end
   
+  def handle_cast({type, _}, state={_, :not_ready}) when 
+    is_atom(type) and type in [:send, :send_read] do
+    
+    msg = "serial port has not been setup, call open_port"
+    
+    Logger.error msg
+    {:noreply, state}
+  end
+  
+  def handle_call({:open, _, _}, _from, state={_, :ready}) do
+    msg = "port is already open" 
+    
+    Logger.error msg
+    {:reply, {:error, msg}, state}
+  end
+  
+  def handle_call({:open, port_name, baud_rate}, _from, {port, :not_ready}) do
+    Logger.debug "opening serial port"
+    
+    Port.command(port, :erlang.term_to_binary({:open, port_name, baud_rate}))
+    
+    {:reply, :ok, {port, :ready}}
+  end
+  
   def handle_info({port, {:data, data}} , state={port, _}) do
     msg = :erlang.binary_to_term(data)
     Logger.debug "received - #{msg}"

    {:ok, {port, :not_ready}}
  end 

  # think I need this to say complete
  def handle_cast({:do_commands, []}, state) do
    {:noreply, state}
  end

  def handle_cast({:do_commands, [{:sleep, value}|rest]}, state) do
    Logger.debug "sleep - #{value}"

    :timer.sleep value
    
    # async - recursively call do_commands untill no more are in the list
    GenServer.cast(:roomba_server, {:do_commands, rest})

    {:noreply, state}
  end

  def handle_cast({:do_commands, [h|rest]}, state) do
    {:ok, parsed_command} = create_command h 

    GenServer.cast(:roomba_server, parsed_command)
    GenServer.cast(:roomba_server, {:do_commands, rest})

    {:noreply, state}
  end
  
  def handle_cast({type, _}, state={_, :not_ready}) when 
    is_atom(type) and type in [:send, :send_read] do
    
    msg = "serial port has not been setup, call open_port"
    
    Logger.error msg
    {:noreply, state}
  end
  
  def handle_call({:open, _, _}, _from, state={_, :ready}) do
    msg = "port is already open" 
    
    Logger.error msg
    {:reply, {:error, msg}, state}
  end
  
  def handle_call({:open, port_name, baud_rate}, _from, {port, :not_ready}) do
    Logger.debug "opening serial port"
    
    Port.command(port, :erlang.term_to_binary({:open, port_name, baud_rate}))
    
    {:reply, :ok, {port, :ready}}
  end
  
  def handle_cast({:send, command}, state={port, :ready}) do
    hexified = Hexate.encode command
    Logger.debug "sending command - #{hexified}"


  # private 
  #----------------------------------------------------------------------------

  defp get_command([]) do
    :ok
  end

  defp get_command([cmd={:sleep, _}|rest]) do
    {:ok, cmd, rest}
  end

  defp get_command([h|rest]) do
    {:ok, cmd} = create_command(h)
    {:ok, cmd, rest}
  end

  defp create_command(:start) do
    Logger.debug "start"
