/// <summary>
        /// Analyzes a response from the printer.
        /// Updates data and sends events according to the data.
        /// </summary>
        /// <param name="res"></param>
        public void analyzeResponse(string res)
        {
            res = res.Trim();
            int level = 0;
            if (logWriter != null)
            {
                DateTime time = DateTime.Now;
                lock (logWriter)
                {
                    logWriter.WriteLine("> " + time.Hour.ToString("00") + ":" + time.Minute.ToString("00") + ":" +
                    time.Second.ToString("00") + "." + time.Millisecond.ToString("000") + " : " + res);
                }
            }
            if (eventResponse != null)
            {
                eventResponse(res);
            }
            string h = extract(res, "FIRMWARE_NAME:");
            if (h != null)
            {
                level = 3;
                firmware = h;
                if (h.IndexOf("Repetier") >= 0)
                {
                    isRepetier = true;
                }
                if (h.IndexOf("Marlin") >= 0) isMarlin = true;
                if (isMarlin || isRepetier) // Activate special menus and function
                {
                    Main.main.Invoke(Main.main.UpdateEEPROM);
                    injectManualCommand("M220 S" + speedMultiply.ToString());
                    injectManualCommand("M221 S" + flowMultiply.ToString());
                }
                Main.main.Invoke(Main.main.FirmwareDetected);
            }
            h = extract(res, "FIRMWARE_URL:");
            if (h != null)
            {
                level = 3;
                firmware_url = h;
            }
            h = extract(res, "PROTOCOL_VERSION:");
            if (h != null)
            {
                level = 3;
                protocol = h;
            }
            h = extract(res, "MACHINE_TYPE:");
            if (h != null)
            {
                level = 3;
                machine = h;
            }
            h = extract(res, "EXTRUDER_COUNT:");
            if (h != null)
            {
                level = 3;
                if (!int.TryParse(h, out numberExtruder)) numberExtruder = 1;
            }
            h = extract(res, "X:");
            if (h != null)
            {
                level = 3;
                float.TryParse(h, NumberStyles.Float, GCode.format, out x);
                analyzer.x = x;
                analyzer.hasXHome = true;
            }
            h = extract(res, "Y:");
            if (h != null)
            {
                level = 3;
                float.TryParse(h, NumberStyles.Float, GCode.format, out y);
                analyzer.y = y;
                analyzer.hasYHome = true;
            }
            h = extract(res, "Z:");
            if (h != null)
            {
                level = 3;
                float.TryParse(h, NumberStyles.Float, GCode.format, out z);
                analyzer.z = z;
                analyzer.hasZHome = true;
            }
            h = extract(res, "E:");
            if (h != null)
            {
                level = 3;
                float.TryParse(h, NumberStyles.Float, GCode.format, out e);
                analyzer.e = e;
            }
            if ((h = extract(res, "SpeedMultiply:")) != null)
            {
                int.TryParse(h,out speedMultiply);
                if (speedMultiply < 25) speedMultiply = 25;
                if (speedMultiply > 300) speedMultiply = 300;
                analyzer.fireChanged();
            }
            if ((h = extract(res, "FlowMultiply:")) != null)
            {
                int.TryParse(h, out flowMultiply);
                if (flowMultiply < 50) flowMultiply = 50;
                if (flowMultiply > 150) flowMultiply = 150;
                analyzer.fireChanged();
            }
            if ((h = extract(res, "TargetExtr0:")) != null)
            {
                if (analyzer.activeExtruder == 0)
                    float.TryParse(h,NumberStyles.Float,GCode.format,out analyzer.extruderTemp);
                analyzer.fireChanged();
            }
            if ((h = extract(res, "TargetExtr1:")) != null)
            {
                if (analyzer.activeExtruder == 1)
                    float.TryParse(h, NumberStyles.Float, GCode.format, out analyzer.extruderTemp);
                analyzer.fireChanged();
            }
            if ((h = extract(res, "TargetBed:")) != null)
            {
                float.TryParse(h, NumberStyles.Float, GCode.format, out analyzer.bedTemp);
                analyzer.fireChanged();
            }
            if ((h = extract(res, "Fanspeed:")) != null)
            {
                int.TryParse(h, out analyzer.fanVoltage);
                analyzer.fireChanged();
            }

            bool tempChange = false;
            h = extract(res, "T:");
            if (h != null)
            {
                level = -1; // dont log, we see result in status
                //if (h.IndexOf('.') > 0) h = h.Substring(0, h.IndexOf('.'));
                float.TryParse(h, NumberStyles.Float, GCode.format, out extruderTemp);
                tempChange = true;
                extruderOutput = -1;
                h = extract(res, "@:");
                int.TryParse(h, out extruderOutput);
                if (isMarlin) extruderOutput *= 2;
            }
            h = extract(res, "B:");
            if (h != null)
            {
                level = -1; // don't log, we see result in status
                //if (h.IndexOf('.') > 0) h = h.Substring(0, h.IndexOf('.'));
                float.TryParse(h, NumberStyles.Float, GCode.format, out bedTemp);
                tempChange = true;
            }
            if (isRepetier)
            { // Repetier specific answers
                if (res.StartsWith("EPR:"))
                {
                    eeprom.Add(res);
                }
            }
            if (isMarlin)
            { // Marlin specifix answers
                if (res.StartsWith("echo:") && (res.IndexOf("M92") > 0) || (res.IndexOf("M203") > 0) || (res.IndexOf("M201") > 0) ||
                    (res.IndexOf("M204") > 0) || (res.IndexOf("M205") > 0) || (res.IndexOf("M301") > 0))
                {
                    eepromm.Add(res);
                }
            }
            if (res.StartsWith("MTEMP:")) // Temperature monitor
            {
                level = -1; // this happens to often to log. Temperture monitor i sthe log
                string[] sl = res.Substring(6).Split(' ');
                if (sl.Length == 4)
                {
                    UInt32 time;
                    int temp, target, output;
                    UInt32.TryParse(sl[0], out time);
                    int.TryParse(sl[1], out temp);
                    int.TryParse(sl[2], out target);
                    int.TryParse(sl[3], out output);
                    if (time > 0 && eventTempMonitor != null)
                    {
                        try
                        {
                            Main.main.Invoke(eventTempMonitor, time, temp, target, output);
                        }
                        catch { }
                    }
                    if (eventTempHistory != null)
                    {
                        TemperatureEntry te = new TemperatureEntry(analyzer.tempMonitor, temp, output, analyzer.bedTemp, analyzer.extruderTemp);
                        Main.main.Invoke(eventTempHistory, te);
                    }
                }
            }
            h = extract(res, "REPETIER_PROTOCOL:");
            if (h != null)
            {
                level = 3;
                int.TryParse(h, out binaryVersion);
                if (transferProtocol == 1) binaryVersion = 0; // force ascii transfer
            }
            if (res.Equals("start") || (garbageCleared == false && res.IndexOf("start") != -1))
            {
                lastline = 0;
                job.KillJob(); // continuing the old job makes no sense, better save the plastic
                resendNode = null;
                sdcardMounted = true;
                history.Clear();
                analyzer.start();
                readyForNextSend = true;
                nackLines.Clear();
                garbageCleared = true;
            }
            if (extract(res, "Error:") != null)
            {
                level = 2;
                RepetierHost.view.SoundConfig.PlayError(false);
            }
            if (tempChange && eventTempChange != null)
            {
                Main.main.Invoke(eventTempChange, extruderTemp, bedTemp);
            }
            if (tempChange && eventTempHistory != null)
            {
                TemperatureEntry te = new TemperatureEntry(extruderTemp, bedTemp, analyzer.bedTemp, analyzer.extruderTemp);
                if (extruderOutput >= 0)
                    te.output = extruderOutput;
                Main.main.Invoke(eventTempHistory, te);
            }
            if (res.StartsWith(" ")) level = 3;
            h = extract(res, "Resend:");
            if (h != null)
            {
                level = 1;
                log(res, true, level);
                int line;
                int.TryParse(h, out line);
                ignoreNextOk = true;
                ResendLine(line);
            }
            else if (res.StartsWith("ok"))
            {
                garbageCleared = true;
                if (Main.main.logView.switchACK.On)
                    log(res, true, level);
                if (!ignoreNextOk)  // ok in response of resend?
                {
                    if (pingpong) readyForNextSend = true;
                    else
                    {
                        lock (nackLines)
                        {
                            if (nackLines.Count > 0)
                                nackLines.RemoveFirst();
                        }
                    }
                    resendError = 0;
                    TrySendNextLine();
                }
                else
                    ignoreNextOk = false;
            }
            else if (res.Equals("wait") && DateTime.Now.Ticks - lastCommandSend > 5000)
            {
                if (Main.main.logView.switchACK.On)
                    log(res, true, level);
                if (pingpong) readyForNextSend = true;
                else
                {
                    lock (nackLines)
                    {
                        if (nackLines.Count > 0)
                            nackLines.Clear();
                    }
                }
                resendError = 0;
                TrySendNextLine();
            }
            else if (level >= 0 && garbageCleared) log(res, true, level);
        }
        public void addNotify(TemperatureEntry ent)
        {
            history.entries.AddLast(ent);
            // Remove old entries
            long time = DateTime.UtcNow.Ticks;
            long ltime = (long)time;
            long lhour = ltime / 36000000000;
            double mintime = time - 36000000000;
            while (history.entries.First.Value.time < mintime)
                history.entries.RemoveFirst();
            // Create average values
            int nExtruder = 0, nBed = 0, nOut = 0;
            float sumExtruder = 0, sumBed = 0, sumOutput = 0;
            mintime = DateTime.UtcNow.Ticks - avgPeriod * 10000000;
            foreach (TemperatureEntry e in history.entries)
            {
                if (e.time < mintime) continue;
                if (e.extruder > -1000)
                {
                    nExtruder++;
                    sumExtruder += e.extruder;
                }
                if (e.bed > -1000)
                {
                    nBed++;
                    sumBed += e.bed;
                }
                if (e.output > -1000)
                {
                    nOut++;
                    sumOutput += e.output;
                }
            }
            if (nExtruder > 0)
                ent.avgExtruder = sumExtruder / (float)nExtruder;
            if (nBed > 0)
                ent.avgBed = sumBed / (float)nBed;
            if (nOut > 0)
                ent.avgOutput = sumOutput / (float)nOut;
            history.maxTime = time;
            history.minTime = time - 36000000000;

            if (lhour != currentHour)
            {
                currentHour = lhour;
                DateTime now = DateTime.Now;
                string stime = now.ToString("MMMM dd, HH");
                ToolStripMenuItem item = new ToolStripMenuItem(stime,null, Main.main.selectTimePeriod);
                item.Tag = lists.Count;
                hourHistory = new TemperatureList();
                hourHistory.minTime = lhour * 36000000000;
                hourHistory.maxTime = hourHistory.minTime + 36000000000;
                lists.AddLast(hourHistory);
                Main.main.timeperiodMenuItem.DropDownItems.Add(item);
            }
            hourHistory.entries.AddLast(ent);
            if (Main.main.tabControlView.SelectedIndex == 1)
                Main.main.tabPageTemp.Refresh();
        }
        /// <summary>
        /// Analyzes a response from the printer.
        /// Updates data and sends events according to the data.
        /// </summary>
        /// <param name="res"></param>
        public void analyzeResponse(string res, ref int level)
        {
            while (res.Length > 0 && res[0] < 32)
            {
                res = res.Substring(1);
            }
            res = res.Trim();
            bool ignoreFB = shouldIgnoreFeedback();

            if (logWriter != null)
            {
                DateTime time = DateTime.Now;
                lock (logWriter)
                {
                    logWriter.WriteLine("> " + time.Hour.ToString("00") + ":" + time.Minute.ToString("00") + ":" +
                                        time.Second.ToString("00") + "." + time.Millisecond.ToString("000") + " : " + res);
                }
            }
            if (eventResponse != null)
            {
                eventResponse(res);
            }
            string h = extract(res, "FIRMWARE_NAME:");

            if (h != null)
            {
                level    = 3;
                firmware = h;
                h        = h.ToLower();
                if (h.IndexOf("repetier") >= 0)
                {
                    isRepetier = true;
                }
                if (h.IndexOf("marlin") >= 0)
                {
                    isMarlin = true;
                }
                if (h.IndexOf("sprinter") >= 0)
                {
                    isSprinter = true;
                }
                if (isMarlin || isRepetier || isSprinter) // Activate special menus and function
                {
                    Main.main.Invoke(Main.main.UpdateEEPROM);
                    injectManualCommand("M220 S" + speedMultiply.ToString());
                    injectManualCommand("M221 S" + flowMultiply.ToString());
                }
                Main.main.Invoke(Main.main.FirmwareDetected);
            }
            h = extract(res, "FIRMWARE_URL:");
            if (h != null)
            {
                level        = 3;
                firmware_url = h;
            }
            h = extract(res, "PROTOCOL_VERSION:");
            if (h != null)
            {
                level    = 3;
                protocol = h;
            }
            h = extract(res, "MACHINE_TYPE:");
            if (h != null)
            {
                level   = 3;
                machine = h;
            }
            h = extract(res, "EXTRUDER_COUNT:");
            if (h != null)
            {
                level = 3;
                if (!int.TryParse(h, out numberExtruder))
                {
                    numberExtruder = 1;
                }
            }
            h = extract(res, "X:");
            if (h != null)
            {
                level = 3;
                float.TryParse(h, NumberStyles.Float, GCode.format, out x);
                analyzer.x = x;
                //analyzer.hasXHome = true;
            }
            h = extract(res, "Y:");
            if (h != null)
            {
                level = 3;
                float.TryParse(h, NumberStyles.Float, GCode.format, out y);
                analyzer.y = y;
                //analyzer.hasYHome = true;
            }
            h = extract(res, "Z:");
            if (h != null)
            {
                level = 3;
                float.TryParse(h, NumberStyles.Float, GCode.format, out z);
                analyzer.z = z;
                // analyzer.hasZHome = true;
            }
            h = extract(res, "E:");
            if (h != null)
            {
                level = 3;
                float.TryParse(h, NumberStyles.Float, GCode.format, out e);
                analyzer.activeExtruder.e = e;
            }
            if (!ignoreFB)
            {
                if ((h = extract(res, "SpeedMultiply:")) != null)
                {
                    int.TryParse(h, out speedMultiply);
                    if (speedMultiply < 25)
                    {
                        speedMultiply = 25;
                    }
                    if (speedMultiply > 300)
                    {
                        speedMultiply = 300;
                    }
                    analyzer.fireChanged();
                }
                if ((h = extract(res, "FlowMultiply:")) != null)
                {
                    int.TryParse(h, out flowMultiply);
                    if (flowMultiply < 50)
                    {
                        flowMultiply = 50;
                    }
                    if (flowMultiply > 150)
                    {
                        flowMultiply = 150;
                    }
                    analyzer.fireChanged();
                }
            }
            if ((h = extract(res, "TargetExtr0:")) != null)
            {
                float et;
                float.TryParse(h, NumberStyles.Float, GCode.format, out et);
                analyzer.setTemperature(0, et);
                analyzer.fireChanged();
            }
            if ((h = extract(res, "TargetExtr1:")) != null)
            {
                float et;
                float.TryParse(h, NumberStyles.Float, GCode.format, out et);
                analyzer.setTemperature(1, et);
                analyzer.fireChanged();
            }
            if ((h = extract(res, "TargetBed:")) != null)
            {
                float.TryParse(h, NumberStyles.Float, GCode.format, out analyzer.bedTemp);
                analyzer.fireChanged();
            }
            if ((h = extract(res, "Fanspeed:")) != null)
            {
                int.TryParse(h, out analyzer.fanVoltage);
                analyzer.fanOn = analyzer.fanVoltage > 0;
                analyzer.fireChanged();
            }
            if (res.Contains("RequestPause:"))
            {
                Main.main.Invoke(firmwareRequestedPause);
            }
            bool tempChange = false;

            h = extract(res, "T0:");
            if (h != null)
            {
                multiTempRead = true;
                int n = 0;
                level = -1; // dont log, we see result in status
                //if (h.IndexOf('.') > 0) h = h.Substring(0, h.IndexOf('.'));
                do
                {
                    float et;
                    float.TryParse(h, NumberStyles.Float, GCode.format, out et);
                    tempChange = true;
                    setTemperature(n, et);
                    h = extract(res, "@" + n + ":");
                    int eo = -1;
                    int.TryParse(h, out eo);
                    if (isMarlin)
                    {
                        eo *= 2;
                    }
                    setOutput(n, eo);
                    n++;
                    h = extract(res, "T" + n + ":");
                } while (h != null);
            }
            else
            {
                h = extract(res, "T:");
                if (h != null)
                {
                    level = -1; // dont log, we see result in status
                    //if (h.IndexOf('.') > 0) h = h.Substring(0, h.IndexOf('.'));
                    float et;
                    float.TryParse(h, NumberStyles.Float, GCode.format, out et);
                    setTemperature(-1, et);
                    tempChange = true;
                    int eo = -1;
                    h = extract(res, "@:");
                    int.TryParse(h, out eo);
                    if (isMarlin)
                    {
                        eo *= 2;
                    }
                    setOutput(-1, eo);
                }
            }
            h = extract(res, "B:");
            if (h != null)
            {
                level = -1; // don't log, we see result in status
                //if (h.IndexOf('.') > 0) h = h.Substring(0, h.IndexOf('.'));
                float.TryParse(h, NumberStyles.Float, GCode.format, out bedTemp);
                tempChange = true;
            }
            h = extract(res, "RAW0:");
            if (h != null)
            {
                level = 3; // don't log, we see result in status
            }
            if (isRepetier)
            { // Repetier specific answers
                if (res.StartsWith("EPR:"))
                {
                    eeprom.Add(res);
                }
            }
            if (isMarlin)
            { // Marlin specifix answers
                if (res.StartsWith("echo:") && (res.IndexOf("M92") > 0) || (res.IndexOf("M203") > 0) || (res.IndexOf("M201") > 0) ||
                    (res.IndexOf("M204") > 0) || (res.IndexOf("M205") > 0) || (res.IndexOf("M206") > 0) || (res.IndexOf("M301") > 0))
                {
                    eepromm.Add(res);
                }
            }
            if (res.StartsWith("MTEMP:")) // Temperature monitor
            {
                level = -1;               // this happens to often to log. Temperture monitor i sthe log
                string[] sl = res.Substring(6).Split(' ');
                if (sl.Length == 4)
                {
                    UInt32 time;
                    int    temp, target, output;
                    UInt32.TryParse(sl[0], out time);
                    int.TryParse(sl[1], out temp);
                    int.TryParse(sl[2], out target);
                    int.TryParse(sl[3], out output);
                    if (time > 0 && eventTempMonitor != null)
                    {
                        try
                        {
                            Main.main.Invoke(eventTempMonitor, time, temp, target, output);
                        }
                        catch { }
                    }
                    if (eventTempHistory != null)
                    {
                        TemperatureEntry te = new TemperatureEntry(analyzer.tempMonitor, temp, output, analyzer.bedTemp, analyzer.getTemperature(-1));
                        Main.main.Invoke(eventTempHistory, te);
                    }
                }
            }

            if (extract(res, "Error:") != null)
            {
                level = 2;
                RepetierHost.view.SoundConfig.PlayError(false);
            }
            if (tempChange && eventTempChange != null)
            {
                Main.main.Invoke(eventTempChange, getTemperature(-1), bedTemp);
            }
            if (tempChange && eventTempHistory != null)
            {
                TemperatureEntry te = new TemperatureEntry(getTemperature(-1), bedTemp, analyzer.bedTemp, analyzer.getTemperature(-1));
                if (getOutput(-1) >= 0)
                {
                    te.output = getOutput(-1);
                }
                Main.main.Invoke(eventTempHistory, te);
            }
            if (res.StartsWith(" "))
            {
                level = 3;
            }
        }
        public void addNotify(TemperatureEntry ent)
        {
            history.entries.AddLast(ent);
            // Remove old entries
            long   time    = DateTime.UtcNow.Ticks;
            long   ltime   = (long)time;
            long   lhour   = ltime / 36000000000;
            double mintime = time - 36000000000;

            while (history.entries.First.Value.time < mintime)
            {
                history.entries.RemoveFirst();
            }
            // Create average values
            int   nExtruder = 0, nBed = 0, nOut = 0;
            float sumExtruder = 0, sumBed = 0, sumOutput = 0;

            mintime = DateTime.UtcNow.Ticks - avgPeriod * 10000000;
            foreach (TemperatureEntry e in history.entries)
            {
                if (e.time < mintime)
                {
                    continue;
                }
                if (e.extruder > -1000)
                {
                    nExtruder++;
                    sumExtruder += e.extruder;
                }
                if (e.bed > -1000)
                {
                    nBed++;
                    sumBed += e.bed;
                }
                if (e.output > -1000)
                {
                    nOut++;
                    sumOutput += e.output;
                }
            }
            if (nExtruder > 0)
            {
                ent.avgExtruder = sumExtruder / (float)nExtruder;
            }
            if (nBed > 0)
            {
                ent.avgBed = sumBed / (float)nBed;
            }
            if (nOut > 0)
            {
                ent.avgOutput = sumOutput / (float)nOut;
            }
            history.maxTime = time;
            history.minTime = time - 36000000000;

            if (lhour != currentHour)
            {
                currentHour = lhour;
                DateTime          now   = DateTime.Now;
                string            stime = now.ToString("MMMM dd, HH");
                ToolStripMenuItem item  = new ToolStripMenuItem(stime, null, Main.main.selectTimePeriod);
                item.Tag            = lists.Count;
                hourHistory         = new TemperatureList();
                hourHistory.minTime = lhour * 36000000000;
                hourHistory.maxTime = hourHistory.minTime + 36000000000;
                lists.AddLast(hourHistory);
                Main.main.timeperiodMenuItem.DropDownItems.Add(item);
            }
            hourHistory.entries.AddLast(ent);
            //if (Main.main.tabControlView.SelectedIndex == 1)
            //    Main.main.tabPageTemp.Refresh();
        }
        /// <summary>
        /// Analyzes a response from the printer.
        /// Updates data and sends events according to the data.
        /// </summary>
        /// <param name="res"></param>
        public void analyzeResponse(string res,ref int level)
        {
            while (res.Length > 0 && res[0] < 32) res = res.Substring(1);
            res = res.Trim();
            bool ignoreFB = shouldIgnoreFeedback();
            if (logWriter != null)
            {
                DateTime time = DateTime.Now;
                lock (logWriter)
                {
                    logWriter.WriteLine("> " + time.Hour.ToString("00") + ":" + time.Minute.ToString("00") + ":" +
                    time.Second.ToString("00") + "." + time.Millisecond.ToString("000") + " : " + res);
                }
            }
            if (eventResponse != null)
            {
                eventResponse(res);
            }
            string h = extract(res, "FIRMWARE_NAME:");
            if (h != null)
            {
                level = 3;
                firmware = h;
                h = h.ToLower();
                if (h.IndexOf("repetier") >= 0)
                {
                    isRepetier = true;
                }
                if (h.IndexOf("marlin") >= 0) isMarlin = true;
                if (h.IndexOf("sprinter") >= 0) isSprinter = true;
                if (isMarlin || isRepetier || isSprinter) // Activate special menus and function
                {
                    Main.main.Invoke(Main.main.UpdateEEPROM);
                    injectManualCommand("M220 S" + speedMultiply.ToString());
                    injectManualCommand("M221 S" + flowMultiply.ToString());
                }
                Main.main.Invoke(Main.main.FirmwareDetected);
            }
            h = extract(res, "FIRMWARE_URL:");
            if (h != null)
            {
                level = 3;
                firmware_url = h;
            }
            h = extract(res, "PROTOCOL_VERSION:");
            if (h != null)
            {
                level = 3;
                protocol = h;
            }
            h = extract(res, "MACHINE_TYPE:");
            if (h != null)
            {
                level = 3;
                machine = h;
            }
            h = extract(res, "EXTRUDER_COUNT:");
            if (h != null)
            {
                level = 3;
                if (!int.TryParse(h, out numberExtruder)) numberExtruder = 1;
            }
            h = extract(res, "X:");
            if (h != null)
            {
                level = 3;
                float.TryParse(h, NumberStyles.Float, GCode.format, out x);
                analyzer.x = x;
                //analyzer.hasXHome = true;
            }
            h = extract(res, "Y:");
            if (h != null)
            {
                level = 3;
                float.TryParse(h, NumberStyles.Float, GCode.format, out y);
                analyzer.y = y;
                //analyzer.hasYHome = true;
            }
            h = extract(res, "Z:");
            if (h != null)
            {
                level = 3;
                float.TryParse(h, NumberStyles.Float, GCode.format, out z);
                analyzer.z = z;
               // analyzer.hasZHome = true;
            }
            h = extract(res, "E:");
            if (h != null)
            {
                level = 3;
                float.TryParse(h, NumberStyles.Float, GCode.format, out e);
                analyzer.activeExtruder.e = e;
            }
            if (!ignoreFB)
            {
                if ((h = extract(res, "SpeedMultiply:")) != null)
                {
                    int.TryParse(h, out speedMultiply);
                    if (speedMultiply < 25) speedMultiply = 25;
                    if (speedMultiply > 300) speedMultiply = 300;
                    analyzer.fireChanged();
                }
                if ((h = extract(res, "FlowMultiply:")) != null)
                {
                    int.TryParse(h, out flowMultiply);
                    if (flowMultiply < 50) flowMultiply = 50;
                    if (flowMultiply > 150) flowMultiply = 150;
                    analyzer.fireChanged();
                }
            }
            if ((h = extract(res, "TargetExtr0:")) != null)
            {
                float et;
                float.TryParse(h, NumberStyles.Float, GCode.format, out et);
                analyzer.setTemperature(0, et);
                analyzer.fireChanged();
            }
            if ((h = extract(res, "TargetExtr1:")) != null)
            {
                float et;
                float.TryParse(h, NumberStyles.Float, GCode.format, out et);
                analyzer.setTemperature(1, et);
                analyzer.fireChanged();
            }
            if ((h = extract(res, "TargetBed:")) != null)
            {
                float.TryParse(h, NumberStyles.Float, GCode.format, out analyzer.bedTemp);
                analyzer.fireChanged();
            }
            if ((h = extract(res, "Fanspeed:")) != null)
            {
                int.TryParse(h, out analyzer.fanVoltage);
                analyzer.fanOn = analyzer.fanVoltage > 0;
                analyzer.fireChanged();
            }
            if (res.Contains("RequestPause:"))
            {
                Main.main.Invoke(firmwareRequestedPause);
            }
            bool tempChange = false;
            h = extract(res, "T0:");
            if (h != null)
            {
                multiTempRead = true;
                int n = 0;
                level = -1; // dont log, we see result in status
                //if (h.IndexOf('.') > 0) h = h.Substring(0, h.IndexOf('.'));
                do
                {
                    float et;
                    float.TryParse(h, NumberStyles.Float, GCode.format, out et);
                    tempChange = true;
                    setTemperature(n, et);
                    h = extract(res, "@" + n + ":");
                    int eo = -1;
                    int.TryParse(h, out eo);
                    if (isMarlin) eo *= 2;
                    setOutput(n, eo);
                    n++;
                    h = extract(res, "T" + n + ":");
                } while (h != null);
            }
            else
            {
                h = extract(res, "T:");
                if (h != null)
                {
                    level = -1; // dont log, we see result in status
                    //if (h.IndexOf('.') > 0) h = h.Substring(0, h.IndexOf('.'));
                    float et;
                    float.TryParse(h, NumberStyles.Float, GCode.format, out et);
                    setTemperature(-1, et);
                    tempChange = true;
                    int eo = -1;
                    h = extract(res, "@:");
                    int.TryParse(h, out eo);
                    if (isMarlin) eo *= 2;
                    setOutput(-1, eo);
                }
            }
            h = extract(res, "B:");
            if (h != null)
            {
                level = -1; // don't log, we see result in status
                //if (h.IndexOf('.') > 0) h = h.Substring(0, h.IndexOf('.'));
                float.TryParse(h, NumberStyles.Float, GCode.format, out bedTemp);
                tempChange = true;
            }
            h = extract(res, "RAW0:");
            if (h != null)
            {
                level = 3; // don't log, we see result in status
            }
            if (isRepetier)
            { // Repetier specific answers
                if (res.StartsWith("EPR:"))
                {
                    eeprom.Add(res);
                }
            }
            if (isMarlin)
            { // Marlin specifix answers
                if (res.StartsWith("echo:") && (res.IndexOf("M92") > 0) || (res.IndexOf("M203") > 0) || (res.IndexOf("M201") > 0) ||
                    (res.IndexOf("M204") > 0) || (res.IndexOf("M205") > 0) || (res.IndexOf("M206") > 0) || (res.IndexOf("M301") > 0))
                {
                    eepromm.Add(res);
                }
            }
            if (res.StartsWith("MTEMP:")) // Temperature monitor 
            {
                level = -1; // this happens to often to log. Temperture monitor i sthe log
                string[] sl = res.Substring(6).Split(' ');
                if (sl.Length == 4)
                {
                    UInt32 time;
                    int temp, target, output;
                    UInt32.TryParse(sl[0], out time);
                    int.TryParse(sl[1], out temp);
                    int.TryParse(sl[2], out target);
                    int.TryParse(sl[3], out output);
                    if (time > 0 && eventTempMonitor != null)
                    {
                        try
                        {
                            Main.main.Invoke(eventTempMonitor, time, temp, target, output);
                        }
                        catch { }
                    }
                    if (eventTempHistory != null)
                    {
                        TemperatureEntry te = new TemperatureEntry(analyzer.tempMonitor, temp, output, analyzer.bedTemp, analyzer.getTemperature(-1));
                        Main.main.Invoke(eventTempHistory, te);
                    }
                }
            }

            if (extract(res, "Error:") != null)
            {
                level = 2;
                RepetierHost.view.SoundConfig.PlayError(false);
            }
            if (tempChange && eventTempChange != null)
            {
                Main.main.Invoke(eventTempChange, getTemperature(-1), bedTemp);
            }
            if (tempChange && eventTempHistory != null)
            {
                TemperatureEntry te = new TemperatureEntry(getTemperature(-1), bedTemp, analyzer.bedTemp, analyzer.getTemperature(-1));
                if (getOutput(-1) >= 0)
                    te.output = getOutput(-1);
                Main.main.Invoke(eventTempHistory, te);
            }
            if (res.StartsWith(" ")) level = 3;
        }