protected override void RunJob(Job job)
        {
            if (_client == null)
            {
                Log.WriteLine($"TCP: Configuration error, IP [{_ip}] or port [{_port}] is invalid.");
                job.OnFulFilled(new CommandResponse(string.Empty, false, $"Configuration error, IP [{_ip}] or port [{_port}] is invalid."));
                return;
            }

            int    attempt    = 1;
            var    respString = String.Empty;
            string command    = job.Command;

            while ((attempt < 4) && (_client != null))
            {
                Log.WriteLine("TCP: [{0}] Attempt {1} to send command.", command, attempt);
                if (!_client.Connected)
                {
                    try
                    {
                        _client = new TcpClient();
                        _client.Connect(_ip, _port);
                    }
                    catch (Exception e)
                    {
                        Log.WriteLine("TCP: [{0}] Failed To connect or create client for command: {1}", command, e.Message);
                        job.OnFulFilled(new CommandResponse("", false, $"Failed To Connect to Client: {e.Message}"));
                        return;
                    }
                }

                _client.ReceiveTimeout = 1000;
                _client.SendTimeout    = 1000;

                string error = String.Empty;

                var stream = _client.GetStream();
                var bytes  = Encoding.ASCII.GetBytes(command);
                try
                {
                    stream.Write(bytes, 0, bytes.Length);
                    Log.WriteLine("TCP: [{0}] Sent command!", command);
                }
                catch (Exception e)
                {
                    Log.WriteLine("TCP: [{0}] Unable to write command to stream: {1}", command, e.Message);
                    job.OnFulFilled(new CommandResponse("", false, $"Failed to send message: {e.Message}"));
                    return;
                }

                try
                {
                    switch (job.ResponseType)
                    {
                    case ResponseType.NoResponse:
                        attempt = 10;
                        Log.WriteLine("TCP: [{0}] No reply needed to command", command);
                        break;

                    case ResponseType.DoubleFullResponse:
                    case ResponseType.DigitResponse:
                    case ResponseType.FullResponse:
                    {
                        Log.WriteLine("TCP: [{0}] Expecting a {1} reply to command, waiting...", command, job.ResponseType.ToString());
                        var response  = new byte[256];
                        var respCount = stream.Read(response, 0, response.Length);
                        respString = Encoding.ASCII.GetString(response, 0, respCount);
                        Log.WriteLine("TCP: [{0}] Received reply to command -> [{1}], trimming", command, respString);
                        int hashPos = respString.IndexOf('#');
                        if (hashPos > 0)
                        {
                            respString = respString.Substring(0, hashPos);
                        }
                        Log.WriteLine("TCP: [{0}] Returning reply to command -> [{1}]", command, respString);
                        attempt = 10;
                    }
                    break;
                    }
                }
                catch (Exception e)
                {
                    Log.WriteLine("TCP: [{0}] Failed to read reply to command. {1} thrown", command, e.GetType().Name);
                    if (job.ResponseType != ResponseType.NoResponse)
                    {
                        respString = "0#";
                    }
                }

                stream.Close();
                attempt++;
            }

            job.OnFulFilled(new CommandResponse(respString));
        }
        protected override void RunJob(Job job)
        {
            CommandResponse response = null;

            if (_logJobs)
            {
                Log.WriteLine("ASCOM: {0:0000}: [{1}] Processing Job", job.Number, job.Command);
            }
            if (Connected)
            {
                if (_logJobs)
                {
                    Log.WriteLine("ASCOM: {0:0000}: [{1}] Connected! Discarding any bytes in input buffer", job.Number, job.Command);
                }
                string reply;
                try
                {
                    if (_logJobs)
                    {
                        Log.WriteLine("ASCOM: {0:0000}: [{1}] Sending command", job.Number, job.Command);
                    }
                    string command = job.Command;
                    switch (job.ResponseType)
                    {
                    case ResponseType.NoResponse:
                        if (_logJobs)
                        {
                            Log.WriteLine("ASCOM: {0:0000}: [{1}] Expecting no response for command", job.Number, job.Command);
                        }
                        break;

                    case ResponseType.DigitResponse:
                        if (_logJobs)
                        {
                            Log.WriteLine("ASCOM: {0:0000}: [{1}] Expecting single digit response for command", job.Number, job.Command);
                        }
                        command += ",n";
                        break;

                    case ResponseType.FullResponse:
                        if (_logJobs)
                        {
                            Log.WriteLine("ASCOM: {0:0000}: [{1}] Expecting #-delimited response for Command...", job.Number, job.Command);
                        }
                        command += ",#";
                        break;

                    case ResponseType.DoubleFullResponse:
                        command += ",##";
                        if (_logJobs)
                        {
                            Log.WriteLine("ASCOM: {0:0000}: [{1}] Expecting two #-delimited responses for Command...", job.Number, job.Command);
                        }
                        break;
                    }

                    reply = _oat.Action("Serial:PassThroughCommand", command);
                    if (_logJobs)
                    {
                        Log.WriteLine("ASCOM: {0:0000}: [{1}] Received reply: '{2}'", job.Number, job.Command, reply);
                    }
                    response = new CommandResponse(reply, true);
                }
                catch (Exception ex)
                {
                    Log.WriteLine("ASCOM: {0:0000}: [{1}] Failed to send command. {2}", job.Number, job.Command, ex.Message);
                    job.OnFulFilled(new CommandResponse(string.Empty, false, $"Unable to execute command. " + ex.Message));
                    return;
                }
            }
            else
            {
                Log.WriteLine("ASCOM: {0:0000}: Telescope is not connected!", job.Number);
                response = new CommandResponse(string.Empty, false, $"Unable to connect to telescope");
            }

            if (_logJobs)
            {
                Log.WriteLine("ASCOM: {0:0000}: Calling OnFulFilled lambda", job.Number);
            }
            job.OnFulFilled(response);
            job.Succeeded = response.Success;
            if (_logJobs)
            {
                Log.WriteLine("ASCOM: {0:0000}: Job completed", job.Number);
            }
        }