public void SendString(string p, FocuserManualResetEvent responseEvent)
        {
            pendingCommands.Enqueue(p);

            if (responseEvent != null)
            {
                if (responseEvent.Command == CmdResponseOptions.M)
                    pendingMoveAcks.Enqueue(responseEvent);
                else if (responseEvent.Command == CmdResponseOptions.SET)
                    pendingSetAcks.Enqueue(responseEvent);
                else if (responseEvent.Command == CmdResponseOptions.H)
                    pendingHomeAcks.Enqueue(responseEvent);
                else if (responseEvent.Command == CmdResponseOptions.HALTED)
                    pendingHaltAcks.Enqueue(responseEvent);
            }
        }
        /*
        public void ParseIncomingStatus(object sender, EventArgs e)
        {
            List<string> data = ((FocuserDataReceivedEventArgs)e).ReceivedLines;
            parseStatusData(data);
            statusReceivedEvent.Set();
        }

        public void ParseIncomingConfig(object sender, EventArgs e)
        {
            List<string> data = ((FocuserDataReceivedEventArgs)e).ReceivedLines;
            parseConfigData(data);
            configReceivedEvent.Set();
        }

        public svoid ParseIncomingHubInfo(object sender, EventArgs e)
        {
            List<string> data = ((FocuserDataReceivedEventArgs)e).ReceivedLines;
            parseHubInfo(data);
            hubInfoReceivedEvent.Set();
        }
        */
        public void MoveAbsolute(int newPos)
        {
            // 1. Verify the position is valid
            if (newPos > MaxPosition) throw new ApplicationException("Invalid Position Request. This focuser cannot move beyond " + maxPosition + " steps");
            // 2. Format the command string to the form <F1MA12345>
            string cmd = (this.focuserNumber == FOCUSER_NUMBER.ONE) ? "<F1MA" : "<F2MA";
            cmd += (newPos.ToString().PadLeft(6, '0') + ">");
            // 3. Send the command and get responses
            try
            {
                EventLogger.LogMessage("Sending Move Absolute Command " + cmd, TraceLevel.Info);
                FocuserManualResetEvent responseEvent = new FocuserManualResetEvent(CmdResponseOptions.M);
                focuserCommunicator.SendString(cmd, responseEvent);
                if (responseEvent.WaitOne(CMD_RESPONSE_TIMEOUT))
                    ClearTimeoutCount();
                else
                {
                    responseEvent.SetTimeoutOccurred();
                    HandleTimeoutEvent();
                }
            }
            catch
            {
                throw;
            }
        }
 // This should send the halt command to the focuser regardless of whether the focuser is actually moving or not.
 public void Halt()
 {
     // Prepare the command to send
     string cmd = (focuserNumber == FOCUSER_NUMBER.ONE) ? "<F1HALT>" : "<F2HALT>";
     // Send the command
     try
     {
         FocuserManualResetEvent responseEvent = new FocuserManualResetEvent(CmdResponseOptions.HALTED);
         focuserCommunicator.SendString(cmd, responseEvent);
         if (responseEvent.WaitOne(CMD_RESPONSE_TIMEOUT))
             ClearTimeoutCount();
         else
         {
             responseEvent.SetTimeoutOccurred();
             HandleTimeoutEvent();
         }
     }
     catch
     {
         throw;
     }
 }
        public void Home()
        {
            // 1. create the command string
            string cmd = (this.focuserNumber == FOCUSER_NUMBER.ONE) ? "<F1HOME>" : "<F2HOME>";
            // 2. send the command and get responses
            try
            {
                FocuserManualResetEvent responseEvent = new FocuserManualResetEvent(CmdResponseOptions.H);
                focuserCommunicator.SendString(cmd, responseEvent);
                if (responseEvent.WaitOne(CMD_RESPONSE_TIMEOUT))
                {
                    ClearTimeoutCount();
                }
                else
                {
                    responseEvent.SetTimeoutOccurred();
                    HandleTimeoutEvent();
                }

            }
            catch
            {
                throw;
            }
        }
 /// <summary>
 /// Sends a command to the focuser hub, via the focuserCommunicator, and waits for a specific response depending on the command.
 /// </summary>
 /// <param name="cmd">The command to send to the device</param>
 /// <param name="resp">The expected response to the command</param>
 /// <param name="purpose">A description of the command (used when logging data and throwing exceptions).</param>
 private static void sendCommand(string cmd, CmdResponseOptions resp, string purpose)
 {
     try
     {
         FocuserManualResetEvent responseEvent = new FocuserManualResetEvent(resp);
         focuserCommunicator.SendString(cmd, responseEvent);
         if (responseEvent.WaitOne(CMD_RESPONSE_TIMEOUT))
             ClearTimeoutCount();
         else
         {
             responseEvent.SetTimeoutOccurred();
             HandleTimeoutEvent();
         }
     }
     catch
     {
         throw;
     }
 }