def OnRenameMachine(self, e):
		dialog = wx.TextEntryDialog(self, _("Enter the new name:"), _("Change machine name"), self.nb.GetPageText(self.nb.GetSelection()))
		if dialog.ShowModal() != wx.ID_OK:
			return
		self.nb.SetPageText(self.nb.GetSelection(), dialog.GetValue())
		profile.putMachineSetting('machine_name', dialog.GetValue(), self.nb.GetSelection())
		self.parent.updateMachineMenu()
    def __init__(self, parent):
        super(decideToUpdateSigma, self).__init__(parent,
                                                  _('Firmware Updater'))

        self._port = 'AUTO'
        self._baudrate = 250000

        if self._port == 'AUTO':
            print 'entramos en port auto despues de baudrate'
            programmer = stk500v2.Stk500v2()
            print 'antes', self._port
            if not programmer.isConnected():
                print 'not connected'
                for self._port in machineCom.serialList(False):
                    try:
                        print 'despues', self._port
                        programmer.connect(self._port)
                        print 'lo que devuelve', programmer.isConnected()
                        print self._baudrate
                        profile.putMachineSetting('serial_port_auto',
                                                  self._port)
                        print 'hemos llegado despues del port'
                        print self._port
                        #wx.MessageBox('esto es lo que tenemoss',self._port)
                        programmer.close()
                        self._serial = serial.Serial(str(self._port),
                                                     self._baudrate,
                                                     timeout=1)
                        print self._serial
                        profile.putMachineSetting('self_serial', self._serial)
                        self._state = 'Online'
                        print 'bueno', self._state
                        break
                    except ispBase.IspError as (e):
                        self._state = 'Offline'
                        pass
                    programmer.close()
                if self._port not in machineCom.serialList(False):
                    self._state = 'Offline'
                    print 'malo', self._state

        if self._state == 'Offline':
            self.AddText(
                _('Please connect your printer to the computer.\n\n'
                  'In case you already had it connected and it was not detected,\n'
                  'please disconnect and connect again.\n\n'
                  'Once you have done this, you may press Connect && Upgrade to\n'
                  'continue with the process.\n\n'
                  '(Note: this may take a minute)\n'))
            connectButton = self.AddButton('Connect && Upgrade')
            connectButton.Bind(wx.EVT_BUTTON, self.OnWantToConnect)
            self.AddSeperator()
        if self._state == 'Online':
            self.AddText(
                _('We have detected a printer, please press Upgrade to continue\n'
                  'with the process.\n\n'
                  '(Note: this may take a minute)\n'))
            upgradeButton = self.AddButton('Upgrade')
            upgradeButton.Bind(wx.EVT_BUTTON, self.OnWantToUpgrade)
            self.AddSeperator()
	def OnRenameMachine(self, e):
		dialog = wx.TextEntryDialog(self, _("Enter the new name:"), _("Change machine name"),
		                            self.nb.GetPageText(self.nb.GetSelection()))
		if dialog.ShowModal() != wx.ID_OK:
			return
		self.nb.SetPageText(self.nb.GetSelection(), dialog.GetValue())
		profile.putMachineSetting('machine_name', dialog.GetValue(), self.nb.GetSelection())
		self.parent.updateMachineMenu()
    def __init__(self, parent):
        super(decideToUpdateSigma, self).__init__(parent, _('Firmware Updater'))

        self._port = 'AUTO'
        self._baudrate = 250000

        if self._port == 'AUTO':
            print 'entramos en port auto despues de baudrate'
            programmer = stk500v2.Stk500v2()
            print 'antes',self._port
            if not programmer.isConnected():
                print 'not connected'
                for self._port in machineCom.serialList(False):
                    try:
                        print 'despues',self._port
                        programmer.connect(self._port)
                        print 'lo que devuelve', programmer.isConnected()
                        print self._baudrate
                        profile.putMachineSetting('serial_port_auto', self._port)
                        print 'hemos llegado despues del port'
                        print self._port
                        #wx.MessageBox('esto es lo que tenemoss',self._port)
                        programmer.close()
                        self._serial = serial.Serial(str(self._port), self._baudrate, timeout=1)
                        print self._serial
                        profile.putMachineSetting('self_serial', self._serial)
                        self._state = 'Online'
                        print 'bueno', self._state
                        break
                    except ispBase.IspError as (e):
                        self._state = 'Offline'
                        pass
                    programmer.close()
                if self._port not in machineCom.serialList(False):
                    self._state = 'Offline'
                    print 'malo',self._state


        if self._state == 'Offline':
            self.AddText(_('Please connect your printer to the computer.\n\n'
                           'In case you already had it connected and it was not detected,\n'
                           'please disconnect and connect again.\n\n'
                           'Once you have done this, you may press Connect && Upgrade to\n'
                           'continue with the process.\n\n'
                           '(Note: this may take a minute)\n'))
            connectButton = self.AddButton('Connect && Upgrade')
            connectButton.Bind(wx.EVT_BUTTON, self.OnWantToConnect)
            self.AddSeperator()
        if self._state == 'Online':
            self.AddText(_('We have detected a printer, please press Upgrade to continue\n'
                           'with the process.\n\n'
                           '(Note: this may take a minute)\n'))
            upgradeButton = self.AddButton('Upgrade')
            upgradeButton.Bind(wx.EVT_BUTTON, self.OnWantToUpgrade)
            self.AddSeperator()
Esempio n. 5
0
	def StoreData(self):
		profile.putMachineSetting('ultimaker_extruder_upgrade', str(self.springExtruder.GetValue()))
		profile.putMachineSetting('has_heated_bed', str(self.heatedBed.GetValue()))
		if self.dualExtrusion.GetValue():
			profile.putMachineSetting('extruder_amount', '2')
			profile.putMachineSetting('machine_depth', '195')
		else:
			profile.putMachineSetting('extruder_amount', '1')
		if profile.getMachineSetting('ultimaker_extruder_upgrade') == 'True':
			profile.putProfileSetting('retraction_enable', 'True')
		else:
			profile.putProfileSetting('retraction_enable', 'False')
    def OnWantToConnect(self, e):
        self._port = 'AUTO'
        self._baudrate = 250000

        if self._port == 'AUTO':
            print 'entramos en port auto despues de baudrate'
            programmer = stk500v2.Stk500v2()
            print 'antes', self._port
            if not programmer.isConnected():
                print 'not connected'
                for self._port in machineCom.serialList(False):
                    try:
                        print 'despues', self._port
                        programmer.connect(self._port)
                        print 'lo que devuelve', programmer.isConnected()
                        print self._baudrate
                        profile.putMachineSetting('serial_port_auto',
                                                  self._port)
                        print 'hemos llegado despues del port'
                        print self._port
                        programmer.close()
                        self._serial = serial.Serial(str(self._port),
                                                     self._baudrate,
                                                     timeout=1)
                        print self._serial
                        profile.putMachineSetting('self_serial', self._serial)
                        self._state = 'Online'
                        print 'bueno', self._state
                        break
                    except ispBase.IspError as (e):
                        self._state = 'Offline'
                        pass
                    programmer.close()
                if self._port not in machineCom.serialList(False):
                    self._state = 'Offline'
                    print 'malo', self._state

        if self._state == 'Online':
            self._serial.close()
            self.readFirstLine()
            self.getFirmwareHardware()
Esempio n. 7
0
    def OnPageFinished(self, e):
        print "Configuration wizard finished..."
        disco_addons_printers = self.configurationPage.optionsPanel.disco_addons_printers
        multinozzle_printers = self.configurationPage.optionsPanel.multinozzle_printers
        name = self.configurationPage.printersPanel.name
        extruder_amount = self.configurationPage.optionsPanel.extruder_amount
        machine_width = self.configurationPage.optionsPanel.machine_width
        nozzle_size = self.configurationPage.optionsPanel.nozzle_size

        if name in disco_addons_printers:
            machine_width = 205 if machine_width < 205 else machine_width
        profile.putMachineSetting('machine_width', machine_width)

        xml_file = name.lower() + '.xml'
        if name in multinozzle_printers and not nozzle_size == 0.4:
            xml_file = name.lower() + '_' + str(nozzle_size) + '.xml'
        if name in disco_addons_printers and int(extruder_amount) == 2:
            xml_file = name.lower() + '_dual.xml'
        profile.putPreference('xml_file', xml_file)

        if self.parent is not None:
            self.parent.ReloadSettingPanels()
    def OnWantToConnect(self,e):
        self._port = 'AUTO'
        self._baudrate = 250000

        if self._port == 'AUTO':
            print 'entramos en port auto despues de baudrate'
            programmer = stk500v2.Stk500v2()
            print 'antes', self._port
            if not programmer.isConnected():
                print 'not connected'
                for self._port in machineCom.serialList(False):
                    try:
                        print 'despues', self._port
                        programmer.connect(self._port)
                        print 'lo que devuelve', programmer.isConnected()
                        print self._baudrate
                        profile.putMachineSetting('serial_port_auto', self._port)
                        print 'hemos llegado despues del port'
                        print self._port
                        programmer.close()
                        self._serial = serial.Serial(str(self._port), self._baudrate, timeout=1)
                        print self._serial
                        profile.putMachineSetting('self_serial', self._serial)
                        self._state = 'Online'
                        print 'bueno', self._state
                        break
                    except ispBase.IspError as (e):
                        self._state = 'Offline'
                        pass
                    programmer.close()
                if self._port not in machineCom.serialList(False):
                    self._state = 'Offline'
                    print 'malo', self._state

        if self._state == 'Online':
            self._serial.close()
            self.readFirstLine()
            self.getFirmwareHardware()
Esempio n. 9
0
	def checkMachineConfigurations(self):
		from Cura.util import profile
		for index in xrange(0, profile.getMachineCount()):
			machine_type = profile.getMachineSetting('machine_type', index)
			# Fix the Ultimaker2 build volume, which was wrong in previous version of Cura.
			if machine_type.startswith('ultimaker2') and not machine_type.startswith('ultimaker2go'):
				if abs(float(profile.getMachineSetting('machine_width', index)) - 230) < 10:
					profile.putMachineSetting('machine_width', '223', index)
				if abs(float(profile.getMachineSetting('machine_depth', index)) - 230) < 10:
					profile.putMachineSetting('machine_depth', '223', index)
				if abs(float(profile.getMachineSetting('machine_depth', index)) - 315) < 1:
					profile.putMachineSetting('machine_depth', '305', index)
	def checkMachineConfigurations(self):
		from Cura.util import profile
		for index in xrange(0, profile.getMachineCount()):
			machine_type = profile.getMachineSetting('machine_type', index)
			# Fix the Ultimaker2 build volume, which was wrong in previous version of Cura.
			if machine_type.startswith('ultimaker2') and not machine_type.startswith('ultimaker2go'):
				if abs(float(profile.getMachineSetting('machine_width', index)) - 230) < 10:
					profile.putMachineSetting('machine_width', '223', index)
				if abs(float(profile.getMachineSetting('machine_depth', index)) - 230) < 10:
					profile.putMachineSetting('machine_depth', '223', index)
				if abs(float(profile.getMachineSetting('machine_depth', index)) - 315) < 1:
					profile.putMachineSetting('machine_depth', '305', index)
Esempio n. 11
0
 def OnRegisterMachine(self, e):
     if "Not" in profile.getMachineSetting('machine_name',
                                           self.nb.GetSelection()):
         data = {
             'name':
             str(profile.getMachineSetting('name', self.nb.GetSelection())),
             'address':
             str(
                 profile.getMachineSetting('address',
                                           self.nb.GetSelection())),
             'state':
             str(profile.getMachineSetting('state',
                                           self.nb.GetSelection())),
             'city':
             str(profile.getMachineSetting('city', self.nb.GetSelection())),
             'email':
             str(profile.getMachineSetting('email',
                                           self.nb.GetSelection())),
             'sn_number':
             str(
                 profile.getMachineSetting('sn_number',
                                           self.nb.GetSelection())),
         }
         if not data['name']:
             dlg = wx.MessageDialog(self, "Enter name", 'Please check...',
                                    wx.OK | wx.ICON_INFORMATION)
             dlg.ShowModal()
             return
         if not data['email']:
             dlg = wx.MessageDialog(self, "Enter email", 'Please check...',
                                    wx.OK | wx.ICON_INFORMATION)
             dlg.ShowModal()
             return
         if not data['sn_number']:
             dlg = wx.MessageDialog(self, "Enter serial number",
                                    'Please check...',
                                    wx.OK | wx.ICON_INFORMATION)
             dlg.ShowModal()
             return
         try:
             bi = wx.BusyInfo("Please Wait...", self)
             f = urllib2.urlopen("http://printers.fracktory.in/api/Client/",
                                 data=urllib.urlencode(data),
                                 timeout=3)
             msg_response = f.read()
             f.close()
             if f.getcode() == 201:
                 r = urllib2.urlopen(
                     "http://printers.fracktory.in/registered_mail",
                     data=urllib.urlencode(data),
                     timeout=3)
                 print r.read()
                 r.close()
             bi.Destroy()
             # profile.putMachineSetting('name',str(self.name.GetValue()))
             # profile.putMachineSetting('address',str(self.address.GetValue()))
             # profile.putMachineSetting('state',str(self.state.GetValue()))
             # profile.putMachineSetting('city',str(self.city.GetValue()))
             # profile.putMachineSetting('email',str(self.email.GetValue()))
             # profile.putMachineSetting('sn_number',str(self.sn_number.GetValue()))
             machine_name = profile.getMachineSetting(
                 'machine_name', self.nb.GetSelection())
             sn_numbername = profile.getMachineSetting(
                 'sn_number', self.nb.GetSelection())
             profile.putMachineSetting('machine_name',
                                       str("Julia" + ' - ' + sn_numbername),
                                       self.nb.GetSelection())
             dlg = wx.MessageDialog(
                 self,
                 "Succesfully Registered With Fracktal Database, Email is sent with further information.",
                 'Response from server...', wx.OK | wx.ICON_INFORMATION)
             dlg.ShowModal()
             self.Close()
         except:
             dlg = wx.MessageDialog(
                 self,
                 'Registration failed, Check your internet connection',
                 'Error', wx.OK | wx.ICON_WARNING)
             dlg.ShowModal()
     else:
         dlg = wx.MessageDialog(self, "Printer already registered with us",
                                'Printer already registered',
                                wx.OK | wx.ICON_INFORMATION)
         dlg.ShowModal()
Esempio n. 12
0
    def _monitor(self):
        #Open the serial port.
        if self._port == 'AUTO':
            self._changeState(self.STATE_DETECT_SERIAL)
            programmer = stk500v2.Stk500v2()
            for p in serialList(True):
                try:
                    self._log("Connecting to: %s (programmer)" % (p))
                    programmer.connect(p)
                    self._serial = programmer.leaveISP()
                    profile.putMachineSetting('serial_port_auto', p)
                    break
                except ispBase.IspError as (e):
                    self._log("Error while connecting to %s: %s" % (p, str(e)))
                    pass
                except:
                    self._log(
                        "Unexpected error while connecting to serial port: %s %s"
                        % (p, getExceptionString()))
                programmer.close()
            if self._serial is None:
                self._log("Serial port list: %s" % (str(serialList(True))))
                self._serialDetectList = serialList(True)
        elif self._port == 'VIRTUAL':
            self._changeState(self.STATE_OPEN_SERIAL)
            self._serial = VirtualPrinter()
        else:
            self._changeState(self.STATE_OPEN_SERIAL)
            try:
                if self._baudrate == 0:
                    self._log(
                        "Connecting to: %s with baudrate: 115200 (fallback)" %
                        (self._port))
                    self._serial = serial.Serial(str(self._port),
                                                 115200,
                                                 timeout=3,
                                                 writeTimeout=10000)
                else:
                    self._log(
                        "Connecting to: %s with baudrate: %s (configured)" %
                        (self._port, self._baudrate))
                    self._serial = serial.Serial(str(self._port),
                                                 self._baudrate,
                                                 timeout=5,
                                                 writeTimeout=10000)
            except:
                self._log(
                    "Unexpected error while connecting to serial port: %s %s" %
                    (self._port, getExceptionString()))
        if self._serial is None:
            baudrate = self._baudrate
            if baudrate == 0:
                baudrate = self._baudrateDetectList.pop(0)
            if len(self._serialDetectList) < 1:
                self._log("Found no ports to try for auto detection")
                self._errorValue = 'Failed to autodetect serial port.'
                self._changeState(self.STATE_ERROR)
                return
            port = self._serialDetectList.pop(0)
            self._log("Connecting to: %s with baudrate: %s (auto)" %
                      (port, baudrate))
            try:
                self._serial = serial.Serial(port,
                                             baudrate,
                                             timeout=3,
                                             writeTimeout=10000)
            except:
                pass
        else:
            self._log("Connected to: %s, starting monitor" % (self._serial))
            if self._baudrate == 0:
                self._changeState(self.STATE_DETECT_BAUDRATE)
            else:
                self._changeState(self.STATE_CONNECTING)

        #Start monitoring the serial port.
        if self._state == self.STATE_CONNECTING:
            timeout = time.time() + 15
        else:
            timeout = time.time() + 5
        tempRequestTimeout = timeout
        while True:
            line = self._readline()
            if line is None:
                break

            #No matter the state, if we see an fatal error, goto the error state and store the error for reference.
            # Only goto error on known fatal errors.
            if line.startswith('Error:'):
                #Oh YEAH, consistency.
                # Marlin reports an MIN/MAX temp error as "Error:x\n: Extruder switched off. MAXTEMP triggered !\n"
                #	But a bed temp error is reported as "Error: Temperature heated bed switched off. MAXTEMP triggered !!"
                #	So we can have an extra newline in the most common case. Awesome work people.
                if re.match('Error:[0-9]\n', line):
                    line = line.rstrip() + self._readline()
                #Skip the communication errors, as those get corrected.
                if 'Extruder switched off' in line or 'Temperature heated bed switched off' in line or 'Something is wrong, please turn off the printer.' in line:
                    if not self.isError():
                        self._errorValue = line[6:]
                        self._changeState(self.STATE_ERROR)
            if ' T:' in line or line.startswith('T:'):
                try:
                    self._temp[self._temperatureRequestExtruder] = float(
                        re.search("T: *([0-9\.]*)", line).group(1))
                except:
                    pass
                if 'B:' in line:
                    try:
                        self._bedTemp = float(
                            re.search("B: *([0-9\.]*)", line).group(1))
                    except:
                        pass
                self._callback.mcTempUpdate(self._temp, self._bedTemp,
                                            self._targetTemp,
                                            self._bedTargetTemp)
                #If we are waiting for an M109 or M190 then measure the time we lost during heatup, so we can remove that time from our printing time estimate.
                if not 'ok' in line and self._heatupWaitStartTime != 0:
                    t = time.time()
                    self._heatupWaitTimeLost = t - self._heatupWaitStartTime
                    self._heatupWaitStartTime = t
            elif line.strip() != '' and line.strip(
            ) != 'ok' and not line.startswith(
                    'Resend:'
            ) and not line.startswith(
                    'Error:checksum mismatch'
            ) and not line.startswith(
                    'Error:Line Number is not Last Line Number+1'
            ) and line != 'echo:Unknown command:""\n' and self.isOperational():
                self._callback.mcMessage(line)

            if self._state == self.STATE_DETECT_BAUDRATE or self._state == self.STATE_DETECT_SERIAL:
                if line == '' or time.time() > timeout:
                    if len(self._baudrateDetectList) < 1:
                        self.close()
                        self._errorValue = "No more baudrates to test, and no suitable baudrate found."
                        self._changeState(self.STATE_ERROR)
                    elif self._baudrateDetectRetry > 0:
                        self._baudrateDetectRetry -= 1
                        self._serial.write('\n')
                        self._log("Baudrate test retry: %d" %
                                  (self._baudrateDetectRetry))
                        self._sendCommand("M105")
                        self._testingBaudrate = True
                    else:
                        if self._state == self.STATE_DETECT_SERIAL:
                            if len(self._serialDetectList) == 0:
                                if len(self._baudrateDetectList) == 0:
                                    self._log(
                                        "Tried all serial ports and baudrates, but still not printer found that responds to M105."
                                    )
                                    self._errorValue = 'Failed to autodetect serial port.'
                                    self._changeState(self.STATE_ERROR)
                                    return
                                else:
                                    self._serialDetectList = serialList(True)
                                    baudrate = self._baudrateDetectList.pop(0)
                            self._serial.close()
                            self._serial = serial.Serial(
                                self._serialDetectList.pop(0),
                                baudrate,
                                timeout=2.5,
                                writeTimeout=10000)
                        else:
                            baudrate = self._baudrateDetectList.pop(0)
                        try:
                            self._setBaudrate(baudrate)
                            self._serial.timeout = 0.5
                            self._log("Trying baudrate: %d" % (baudrate))
                            self._baudrateDetectRetry = 5
                            self._baudrateDetectTestOk = 0
                            timeout = time.time() + 5
                            self._serial.write('\n')
                            self._sendCommand("M105")
                            self._testingBaudrate = True
                        except:
                            self._log(
                                "Unexpected error while setting baudrate: %d %s"
                                % (baudrate, getExceptionString()))
                elif 'T:' in line:
                    self._baudrateDetectTestOk += 1
                    if self._baudrateDetectTestOk < 10:
                        self._log("Baudrate test ok: %d" %
                                  (self._baudrateDetectTestOk))
                        self._sendCommand("M105")
                    else:
                        self._sendCommand("M999")
                        self._serial.timeout = 2
                        profile.putMachineSetting('serial_baud_auto',
                                                  self._serial.baudrate)
                        self._changeState(self.STATE_OPERATIONAL)
                else:
                    self._testingBaudrate = False
            elif self._state == self.STATE_CONNECTING:
                if line == '' or 'wait' in line:  # 'wait' needed for Repetier (kind of watchdog)
                    self._sendCommand("M105")
                elif 'ok' in line:
                    self._changeState(self.STATE_OPERATIONAL)
                if time.time() > timeout:
                    self.close()
            elif self._state == self.STATE_OPERATIONAL:
                #Request the temperature on comm timeout (every 2 seconds) when we are not printing.
                if line == '':
                    if self._extruderCount > 0:
                        self._temperatureRequestExtruder = (
                            self._temperatureRequestExtruder +
                            1) % self._extruderCount
                        self.sendCommand("M105 T%d" %
                                         (self._temperatureRequestExtruder))
                    else:
                        self.sendCommand("M105")
                    tempRequestTimeout = time.time() + 5
            elif self._state == self.STATE_PRINTING:
                #Even when printing request the temperature every 5 seconds.
                if time.time() > tempRequestTimeout:
                    if self._extruderCount > 0:
                        self._temperatureRequestExtruder = (
                            self._temperatureRequestExtruder +
                            1) % self._extruderCount
                        self.sendCommand("M105 T%d" %
                                         (self._temperatureRequestExtruder))
                    else:
                        self.sendCommand("M105")
                    tempRequestTimeout = time.time() + 5
                if line == '' and time.time() > timeout:
                    self._log(
                        "Communication timeout during printing, forcing a line"
                    )
                    line = 'ok'
                if 'ok' in line:
                    timeout = time.time() + 5
                    if not self._commandQueue.empty():
                        self._sendCommand(self._commandQueue.get())
                    else:
                        self._sendNext()
                elif "resend" in line.lower() or "rs" in line:
                    try:
                        self._gcodePosition = int(
                            line.replace("N:", " ").replace("N", " ").replace(
                                ":", " ").split()[-1])
                    except:
                        if "rs" in line:
                            self._gcodePosition = int(line.split()[1])
        self._log("Connection closed, closing down monitor")
Esempio n. 13
0
	def _monitor(self):
		#Open the serial port.
		if self._port == 'AUTO':
			self._changeState(self.STATE_DETECT_SERIAL)
			programmer = stk500v2.Stk500v2()
			for p in serialList(True):
				try:
					self._log("Connecting to: %s (programmer)" % (p))
					programmer.connect(p)
					self._serial = programmer.leaveISP()
					profile.putMachineSetting('serial_port_auto', p)
					break
				except ispBase.IspError as (e):
					self._log("Error while connecting to %s: %s" % (p, str(e)))
					pass
				except:
					self._log("Unexpected error while connecting to serial port: %s %s" % (p, getExceptionString()))
				programmer.close()
			if self._serial is None:
				self._log("Serial port list: %s" % (str(serialList(True))))
				self._serialDetectList = serialList(True)
		elif self._port == 'VIRTUAL':
			self._changeState(self.STATE_OPEN_SERIAL)
			self._serial = VirtualPrinter()
		else:
			self._changeState(self.STATE_OPEN_SERIAL)
			try:
				if self._baudrate == 0:
					self._log("Connecting to: %s with baudrate: 115200 (fallback)" % (self._port))
					self._serial = serial.Serial(str(self._port), 115200, timeout=3, writeTimeout=10000)
				else:
					self._log("Connecting to: %s with baudrate: %s (configured)" % (self._port, self._baudrate))
					self._serial = serial.Serial(str(self._port), self._baudrate, timeout=5, writeTimeout=10000)
			except:
				self._log("Unexpected error while connecting to serial port: %s %s" % (self._port, getExceptionString()))
		if self._serial is None:
			baudrate = self._baudrate
			if baudrate == 0:
				baudrate = self._baudrateDetectList.pop(0)
			if len(self._serialDetectList) < 1:
				self._log("Found no ports to try for auto detection")
				self._errorValue = 'Failed to autodetect serial port.'
				self._changeState(self.STATE_ERROR)
				return
			port = self._serialDetectList.pop(0)
			self._log("Connecting to: %s with baudrate: %s (auto)" % (port, baudrate))
			try:
				self._serial = serial.Serial(port, baudrate, timeout=3, writeTimeout=10000)
			except:
				pass
		else:
			self._log("Connected to: %s, starting monitor" % (self._serial))
			if self._baudrate == 0:
				self._changeState(self.STATE_DETECT_BAUDRATE)
			else:
				self._changeState(self.STATE_CONNECTING)

		#Start monitoring the serial port.
		if self._state == self.STATE_CONNECTING:
			timeout = time.time() + 15
		else:
			timeout = time.time() + 5
		tempRequestTimeout = timeout
		while True:
			line = self._readline()
			if line is None:
				break

			#No matter the state, if we see an fatal error, goto the error state and store the error for reference.
			# Only goto error on known fatal errors.
			if line.startswith('Error:'):
				#Oh YEAH, consistency.
				# Marlin reports an MIN/MAX temp error as "Error:x\n: Extruder switched off. MAXTEMP triggered !\n"
				#	But a bed temp error is reported as "Error: Temperature heated bed switched off. MAXTEMP triggered !!"
				#	So we can have an extra newline in the most common case. Awesome work people.
				if re.match('Error:[0-9]\n', line):
					line = line.rstrip() + self._readline()
				#Skip the communication errors, as those get corrected.
				if 'Extruder switched off' in line or 'Temperature heated bed switched off' in line or 'Something is wrong, please turn off the printer.' in line:
					if not self.isError():
						self._errorValue = line[6:]
						self._changeState(self.STATE_ERROR)
			if ' T:' in line or line.startswith('T:'):
				try:
					self._temp[self._temperatureRequestExtruder] = float(re.search("T: *([0-9\.]*)", line).group(1))
				except:
					pass
				if 'B:' in line:
					try:
						self._bedTemp = float(re.search("B: *([0-9\.]*)", line).group(1))
					except:
						pass
				self._callback.mcTempUpdate(self._temp, self._bedTemp, self._targetTemp, self._bedTargetTemp)
				#If we are waiting for an M109 or M190 then measure the time we lost during heatup, so we can remove that time from our printing time estimate.
				if not 'ok' in line and self._heatupWaitStartTime != 0:
					t = time.time()
					self._heatupWaitTimeLost = t - self._heatupWaitStartTime
					self._heatupWaitStartTime = t
			elif line.strip() != '' and line.strip() != 'ok' and not line.startswith('Resend:') and not line.startswith('Error:checksum mismatch') and not line.startswith('Error:Line Number is not Last Line Number+1') and line != 'echo:Unknown command:""\n' and self.isOperational():
				self._callback.mcMessage(line)

			if self._state == self.STATE_DETECT_BAUDRATE or self._state == self.STATE_DETECT_SERIAL:
				if line == '' or time.time() > timeout:
					if len(self._baudrateDetectList) < 1:
						self.close()
						self._errorValue = "No more baudrates to test, and no suitable baudrate found."
						self._changeState(self.STATE_ERROR)
					elif self._baudrateDetectRetry > 0:
						self._baudrateDetectRetry -= 1
						self._serial.write('\n')
						self._log("Baudrate test retry: %d" % (self._baudrateDetectRetry))
						self._sendCommand("M105")
						self._testingBaudrate = True
					else:
						if self._state == self.STATE_DETECT_SERIAL:
							if len(self._serialDetectList) == 0:
								if len(self._baudrateDetectList) == 0:
									self._log("Tried all serial ports and baudrates, but still not printer found that responds to M105.")
									self._errorValue = 'Failed to autodetect serial port.'
									self._changeState(self.STATE_ERROR)
									return
								else:
									self._serialDetectList = serialList(True)
									baudrate = self._baudrateDetectList.pop(0)
							self._serial.close()
							self._serial = serial.Serial(self._serialDetectList.pop(0), baudrate, timeout=2.5, writeTimeout=10000)
						else:
							baudrate = self._baudrateDetectList.pop(0)
						try:
							self._setBaudrate(baudrate)
							self._serial.timeout = 0.5
							self._log("Trying baudrate: %d" % (baudrate))
							self._baudrateDetectRetry = 5
							self._baudrateDetectTestOk = 0
							timeout = time.time() + 5
							self._serial.write('\n')
							self._sendCommand("M105")
							self._testingBaudrate = True
						except:
							self._log("Unexpected error while setting baudrate: %d %s" % (baudrate, getExceptionString()))
				elif 'T:' in line:
					self._baudrateDetectTestOk += 1
					if self._baudrateDetectTestOk < 10:
						self._log("Baudrate test ok: %d" % (self._baudrateDetectTestOk))
						self._sendCommand("M105")
					else:
						self._sendCommand("M999")
						self._serial.timeout = 2
						profile.putMachineSetting('serial_baud_auto', self._serial.baudrate)
						self._changeState(self.STATE_OPERATIONAL)
				else:
					self._testingBaudrate = False
			elif self._state == self.STATE_CONNECTING:
				if line == '' or 'wait' in line:        # 'wait' needed for Repetier (kind of watchdog)
					self._sendCommand("M105")
				elif 'ok' in line:
					self._changeState(self.STATE_OPERATIONAL)
				if time.time() > timeout:
					self.close()
			elif self._state == self.STATE_OPERATIONAL:
				#Request the temperature on comm timeout (every 2 seconds) when we are not printing.
				if line == '':
					if self._extruderCount > 0:
						self._temperatureRequestExtruder = (self._temperatureRequestExtruder + 1) % self._extruderCount
						self.sendCommand("M105 T%d" % (self._temperatureRequestExtruder))
					else:
						self.sendCommand("M105")
					tempRequestTimeout = time.time() + 5
			elif self._state == self.STATE_PRINTING:
				#Even when printing request the temperature every 5 seconds.
				if time.time() > tempRequestTimeout:
					if self._extruderCount > 0:
						self._temperatureRequestExtruder = (self._temperatureRequestExtruder + 1) % self._extruderCount
						self.sendCommand("M105 T%d" % (self._temperatureRequestExtruder))
					else:
						self.sendCommand("M105")
					tempRequestTimeout = time.time() + 5
				if line == '' and time.time() > timeout:
					self._log("Communication timeout during printing, forcing a line")
					line = 'ok'
				if 'ok' in line:
					timeout = time.time() + 5
					if not self._commandQueue.empty():
						self._sendCommand(self._commandQueue.get())
					else:
						self._sendNext()
				elif "resend" in line.lower() or "rs" in line:
					try:
						self._gcodePosition = int(line.replace("N:"," ").replace("N"," ").replace(":"," ").split()[-1])
					except:
						if "rs" in line:
							self._gcodePosition = int(line.split()[1])
		self._log("Connection closed, closing down monitor")
Esempio n. 14
0
	def _monitor(self):
		#Open the serial port.
		if self._port == 'AUTO':
			self._changeState(self.STATE_DETECT_SERIAL)
			programmer = stk500v2.Stk500v2()
			for p in serialList(True):
				try:
					self._log("Connecting to: %s (programmer)" % (p))
					programmer.connect(p)
					self._serial = programmer.leaveISP()
					profile.putMachineSetting('serial_port_auto', p)
					break
				except ispBase.IspError as (e):
					self._log("Error while connecting to %s: %s" % (p, str(e)))
					pass
				except:
					self._log("Unexpected error while connecting to serial port: %s %s" % (p, getExceptionString()))
				programmer.close()
			if self._serial is None:
				self._log("Serial port list: %s" % (str(serialList(True))))
				self._serialDetectList = serialList(True)
		elif self._port == 'VIRTUAL':
			self._changeState(self.STATE_OPEN_SERIAL)
			self._serial = VirtualPrinter()
		else:
			self._changeState(self.STATE_OPEN_SERIAL)
			try:
				if self._baudrate == 0:
					self._log("Connecting to: %s with baudrate: 115200 (fallback)" % (self._port))
					self._serial = serial.Serial(str(self._port), 115200, timeout=3)
					# Need to set writeTimeout separately in order to be compatible with pyserial 3.0
					self._serial.writeTimeout=10000
				else:
					self._log("Connecting to: %s with baudrate: %s (configured)" % (self._port, self._baudrate))
					self._serial = serial.Serial(str(self._port), self._baudrate, timeout=5)
					# Need to set writeTimeout separately in order to be compatible with pyserial 3.0
					self._serial.writeTimeout=10000
			except:
				self._log("Unexpected error while connecting to serial port: %s %s" % (self._port, getExceptionString()))
		if self._serial is None:
			baudrate = self._baudrate
			if baudrate == 0:
				baudrate = self._baudrateDetectList.pop(0)
			if len(self._serialDetectList) < 1:
				self._log("Found no ports to try for auto detection")
				self._errorValue = 'Failed to autodetect serial port.'
				self._changeState(self.STATE_ERROR)
				return
			port = self._serialDetectList.pop(0)
			self._log("Connecting to: %s with baudrate: %s (auto)" % (port, baudrate))
			try:
				self._serial = serial.Serial(port, baudrate, timeout=3)
				# Need to set writeTimeout separately in order to be compatible with pyserial 3.0
				self._serial.writeTimeout=10000
			except:
				pass
		else:
			self._log("Connected to: %s, starting monitor" % (self._serial))
			if self._baudrate == 0:
				self._changeState(self.STATE_DETECT_BAUDRATE)
			else:
				self._changeState(self.STATE_CONNECTING)

		#Start monitoring the serial port.
		if self._state == self.STATE_CONNECTING:
			timeout = time.time() + 15
		else:
			timeout = time.time() + 5
		tempRequestTimeout = timeout
		while True:
			line = self._readline()
			if line is None:
				break

			#No matter the state, if we see an fatal error, goto the error state and store the error for reference.
			# Only goto error on known fatal errors.
			if line.startswith('Error:'):
				#Oh YEAH, consistency.
				# Marlin reports an MIN/MAX temp error as "Error:x\n: Extruder switched off. MAXTEMP triggered !\n"
				#	But a bed temp error is reported as "Error: Temperature heated bed switched off. MAXTEMP triggered !!"
				#	So we can have an extra newline in the most common case. Awesome work people.
				if re.match('Error:[0-9]\n', line):
					line = line.rstrip() + self._readline()
				#Skip the communication errors, as those get corrected.
				if 'Extruder switched off' in line or 'Temperature heated bed switched off' in line or 'Something is wrong, please turn off the printer.' in line or 'PROBE FAIL' in line:
					if not self.isError():
						self._errorValue = line[6:]
						self._changeState(self.STATE_ERROR)
			if ' T:' in line or line.startswith('T:'):
				tempRequestTimeout = time.time() + 5
				try:
					self._temp[self._temperatureRequestExtruder] = float(re.search("T: *([0-9\.]*)", line).group(1))
				except:
					pass
				if 'B:' in line:
					try:
						self._bedTemp = float(re.search("B: *([0-9\.]*)", line).group(1))
					except:
						pass
				self._callback.mcTempUpdate(self._temp, self._bedTemp, self._targetTemp, self._bedTargetTemp)
				#If we are waiting for an M109 or M190 then measure the time we lost during heatup, so we can remove that time from our printing time estimate.
				if not 'ok' in line and self._heatupWaitStartTime != 0:
					t = time.time()
					self._heatupWaitTimeLost = t - self._heatupWaitStartTime
					self._heatupWaitStartTime = t
			elif line.strip() != '' and line.strip() != 'ok' and not line.startswith('Resend:') and \
				 not line.startswith('Error:checksum mismatch') and not line.startswith('Error:Line Number is not Last Line Number+1') and \
				 not line.startswith('Error:No Checksum with line number') and not line.startswith('Error:No Line Number with checksum') and \
				 line != 'echo:Unknown command:""\n' and self.isOperational():
				self._callback.mcMessage(line)

			if self._state == self.STATE_DETECT_BAUDRATE or self._state == self.STATE_DETECT_SERIAL:
				if line == '' or time.time() > timeout:
					if len(self._baudrateDetectList) < 1:
						self.close()
						self._errorValue = "No more baudrates to test, and no suitable baudrate found."
						self._changeState(self.STATE_ERROR)
					elif self._baudrateDetectRetry > 0:
						self._baudrateDetectRetry -= 1
						self._serial.write('\n')
						self._log("Baudrate test retry: %d" % (self._baudrateDetectRetry))
						self._sendCommand("M105")
						self._testingBaudrate = True
					else:
						if self._state == self.STATE_DETECT_SERIAL:
							if len(self._serialDetectList) == 0:
								if len(self._baudrateDetectList) == 0:
									self._log("Tried all serial ports and baudrates, but still not printer found that responds to M105.")
									self._errorValue = 'Failed to autodetect serial port.'
									self._changeState(self.STATE_ERROR)
									return
								else:
									self._serialDetectList = serialList(True)
									baudrate = self._baudrateDetectList.pop(0)
							self._serial.close()
							self._serial = serial.Serial(self._serialDetectList.pop(0), baudrate, timeout=2.5)
							# Need to set writeTimeout separately in order to be compatible with pyserial 3.0
							self._serial.writeTimeout=10000
						else:
							baudrate = self._baudrateDetectList.pop(0)
						try:
							self._setBaudrate(baudrate)
							self._serial.timeout = 0.5
							self._log("Trying baudrate: %d" % (baudrate))
							self._baudrateDetectRetry = 5
							self._baudrateDetectTestOk = 0
							timeout = time.time() + 5
							self._serial.write('\n')
							self._sendCommand("M105")
							self._testingBaudrate = True
						except:
							self._log("Unexpected error while setting baudrate: %d %s" % (baudrate, getExceptionString()))
				elif 'T:' in line:
					self._baudrateDetectTestOk += 1
					if self._baudrateDetectTestOk < 10:
						self._log("Baudrate test ok: %d" % (self._baudrateDetectTestOk))
						self._sendCommand("M105")
					else:
						self._sendCommand("M999")
						self._serial.timeout = 2
						profile.putMachineSetting('serial_baud_auto', self._serial.baudrate)
						self._changeState(self.STATE_OPERATIONAL)
				else:
					self._testingBaudrate = False
			elif self._state == self.STATE_CONNECTING:
				if line == '' or 'wait' in line or 'start' in line:        # 'wait' needed for Repetier (kind of watchdog)
					self._sendCommand("M105")
				elif 'ok' in line:
					self._changeState(self.STATE_OPERATIONAL)
				if time.time() > timeout:
					self.close()
			elif self._state == self.STATE_OPERATIONAL:
				# Request the temperature on comm timeout (every 2 seconds) when we are not printing.
				# unless we had a temperature feedback (from M109 or M190 for example)
				if line == '' and time.time() > tempRequestTimeout:
					if self._heatupWaiting and len(self._currentCommands) == 1:
						self._log("Canceling heatup due to missing T: line in the past 5 seconds. cmdbuffer desync?")
						self._heatupWaiting = False
						# Force a timeout now if necessary
						timeout = time.time() - 1
					if self._extruderCount > 0:
						self._temperatureRequestExtruder = (self._temperatureRequestExtruder + 1) % self._extruderCount
						self.sendCommand("M105 T%d" % (self._temperatureRequestExtruder))
					else:
						self.sendCommand("M105")
					# set timeout to less than 2 seconds to make sure it always triggers when comm times out
					tempRequestTimeout = time.time() + 1.5
				if line == '' and time.time() > timeout:
					line = 'ok'
				if 'ok' in line:
					self.receivedOK()
					timeout = time.time() + 30
					if not self._heatupWaiting and not self._commandQueue.empty():
						self._sendCommand(self._commandQueue.get())
					if len(self._currentCommands) > 0 and \
					   ("G28" in self._currentCommands[0] or "G29" in self._currentCommands[0] or \
						"M109" in self._currentCommands[0] or "M190" in self._currentCommands[0]):
						# Long command detected. Timeout is now set to 10 minutes to avoid forcing 'ok'
						# every 30 seconds while it's not needed
						timeout = time.time() + 600
				elif 'start' in line:
					self._currentCommands = []
					timeout = time.time() + 30
			elif self._state == self.STATE_PRINTING:
				#Even when printing request the temperature every 5 seconds.
				if time.time() > tempRequestTimeout:
					if self._heatupWaiting and len(self._currentCommands) == 1:
						self._log("Canceling heatup due to missing T: line in the past 5 seconds. cmdbuffer desync?")
						self._heatupWaiting = False
						# Force a timeout now if necessary
						timeout = time.time() - 1
					if self._extruderCount > 0:
						self._temperatureRequestExtruder = (self._temperatureRequestExtruder + 1) % self._extruderCount
						self.sendCommand("M105 T%d" % (self._temperatureRequestExtruder))
					else:
						self.sendCommand("M105")
					tempRequestTimeout = time.time() + 5
				if line == '' and time.time() > timeout:
					self._log("Communication timeout during printing, forcing a line")
					line = 'ok'
				if 'ok' in line:
					self.receivedOK()
					timeout = time.time() + 30
					# If we are heating up with M109 or M190, then we can't send any new
					# commands until the command buffer queue in firmware is empty (M109/M190 done)
					# otherwise, we will fill up the buffer queue (2 more commands will be accepted after M109/M190)
					# and anything else we send will just end up in the serial ringbuffer and will not be read until
					# the M109/M190 is done.
					# So if we want to cancel the heatup, we need to send M108 which needs to be able to be read from
					# the ringbuffer, which means the command queue needs to be empty.
					# So we stop sending any commands after M109/M190 unless it's M108 (or until heating done) if we want
					# M108 to get handled.
					# the small delay that is caused by the firmware buffer getting empty is not important because
					# this happens during a heat&wait, not during a move command.
					# If M108 is received, it gets sent directly from the receiving thread, not from here
					# because the _commandQueue is not iterable
					if not self._heatupWaiting:
						# We iterate in case we just came out of a heat&wait
						for i in xrange(len(self._currentCommands), CMDBUFFER_SIZE):
							# One of the next 4 could enable the heatupWaiting mode
							if not self._heatupWaiting:
								if not self._commandQueue.empty():
									self._sendCommand(self._commandQueue.get())
								else:
									self._sendNext()
					if len(self._currentCommands) > 0 and \
					   ("G28" in self._currentCommands[0] or "G29" in self._currentCommands[0] or \
						"M109" in self._currentCommands[0] or "M190" in self._currentCommands[0]):
						# Long command detected. Timeout is now set to 10 minutes to avoid forcing 'ok'
						# every 30 seconds while it's not needed
						timeout = time.time() + 600

				elif 'start' in line:
					self._currentCommands = []
					timeout = time.time() + 30
				elif "resend" in line.lower() or "rs" in line:
					newPos = self._gcodePos
					try:
						newPos = int(line.replace("N:"," ").replace("N"," ").replace(":"," ").split()[-1])
					except:
						if "rs" in line:
							newPos = int(line.split()[1])
					# If we need to resend more than 10 lines, we can assume that the machine
					# was shut down and turned back on or something else that's weird just happened.
					# In that case, it can be dangerous to restart the print, so we'd better kill it
					if newPos == 1 or self._gcodePos > newPos + 100:
						self._callback.mcMessage("Print canceled due to loss of communication to printer (USB unplugged or power lost)")
						self.cancelPrint()
					else:
						self._gcodePos = newPos
			elif self._state == self.STATE_PAUSED:
				#Even when printing request the temperature every 5 seconds.
				if time.time() > tempRequestTimeout:
					if self._heatupWaiting and len(self._currentCommands) == 1:
						self._log("Canceling heatup due to missing T: line in the past 5 seconds. cmdbuffer desync?")
						self._heatupWaiting = False
						# Force a timeout now if necessary
						timeout = time.time() - 1
					if self._extruderCount > 0:
						self._temperatureRequestExtruder = (self._temperatureRequestExtruder + 1) % self._extruderCount
						self.sendCommand("M105 T%d" % (self._temperatureRequestExtruder))
					else:
						self.sendCommand("M105")
					tempRequestTimeout = time.time() + 5
				if line == '' and time.time() > timeout:
					line = 'ok'
				if 'ok' in line:
					self.receivedOK()
					timeout = time.time() + 30
					if not self._heatupWaiting and not self._commandQueue.empty():
						self._sendCommand(self._commandQueue.get())
					if len(self._currentCommands) > 0 and \
					   ("G28" in self._currentCommands[0] or "G29" in self._currentCommands[0] or \
						"M109" in self._currentCommands[0] or "M190" in self._currentCommands[0]):
						# Long command detected. Timeout is now set to 10 minutes to avoid forcing 'ok'
						# every 30 seconds while it's not needed
						timeout = time.time() + 600
				elif 'start' in line:
					self._currentCommands = []
					timeout = time.time() + 30

		self._log("Connection closed, closing down monitor")
Esempio n. 15
0
	def StoreData(self):
		if self.Ultimaker2Radio.GetValue():
			profile.putMachineSetting('machine_width', '230')
			profile.putMachineSetting('machine_depth', '225')
			profile.putMachineSetting('machine_height', '205')
			profile.putMachineSetting('machine_type', 'ultimaker2')
			profile.putMachineSetting('machine_center_is_zero', 'False')
			profile.putMachineSetting('has_heated_bed', 'True')
			profile.putMachineSetting('gcode_flavor', 'UltiGCode')
			profile.putProfileSetting('nozzle_size', '0.4')
			profile.putMachineSetting('extruder_head_size_min_x', '40.0')
			profile.putMachineSetting('extruder_head_size_min_y', '10.0')
			profile.putMachineSetting('extruder_head_size_max_x', '60.0')
			profile.putMachineSetting('extruder_head_size_max_y', '30.0')
			profile.putMachineSetting('extruder_head_size_height', '60.0')
		elif self.UltimakerRadio.GetValue():
			profile.putMachineSetting('machine_width', '205')
			profile.putMachineSetting('machine_depth', '205')
			profile.putMachineSetting('machine_height', '200')
			profile.putMachineSetting('machine_type', 'ultimaker')
			profile.putMachineSetting('machine_center_is_zero', 'False')
			profile.putMachineSetting('gcode_flavor', 'RepRap (Marlin/Sprinter)')
			profile.putProfileSetting('nozzle_size', '0.4')
			profile.putMachineSetting('extruder_head_size_min_x', '75.0')
			profile.putMachineSetting('extruder_head_size_min_y', '18.0')
			profile.putMachineSetting('extruder_head_size_max_x', '18.0')
			profile.putMachineSetting('extruder_head_size_max_y', '35.0')
			profile.putMachineSetting('extruder_head_size_height', '60.0')
		else:
			profile.putMachineSetting('machine_width', '80')
			profile.putMachineSetting('machine_depth', '80')
			profile.putMachineSetting('machine_height', '60')
			profile.putMachineSetting('machine_type', 'reprap')
			profile.putMachineSetting('gcode_flavor', 'RepRap (Marlin/Sprinter)')
			profile.putPreference('startMode', 'Normal')
			profile.putProfileSetting('nozzle_size', '0.5')
		profile.checkAndUpdateMachineName()
		profile.putProfileSetting('wall_thickness', float(profile.getProfileSetting('nozzle_size')) * 2)
		if self.SubmitUserStats.GetValue():
			profile.putPreference('submit_slice_information', 'True')
		else:
			profile.putPreference('submit_slice_information', 'False')
Esempio n. 16
0
	def StoreData(self):
		profile.putMachineSetting('machine_name', self.machineName.GetValue())
		profile.putMachineSetting('machine_width', self.machineWidth.GetValue())
		profile.putMachineSetting('machine_depth', self.machineDepth.GetValue())
		profile.putMachineSetting('machine_height', self.machineHeight.GetValue())
		profile.putProfileSetting('nozzle_size', self.nozzleSize.GetValue())
		profile.putProfileSetting('wall_thickness', float(profile.getProfileSettingFloat('nozzle_size')) * 2)
		profile.putMachineSetting('has_heated_bed', str(self.heatedBed.GetValue()))
		profile.putMachineSetting('machine_center_is_zero', str(self.HomeAtCenter.GetValue()))
		profile.putMachineSetting('extruder_head_size_min_x', '0')
		profile.putMachineSetting('extruder_head_size_min_y', '0')
		profile.putMachineSetting('extruder_head_size_max_x', '0')
		profile.putMachineSetting('extruder_head_size_max_y', '0')
		profile.putMachineSetting('extruder_head_size_height', '0')
		profile.checkAndUpdateMachineName()
Esempio n. 17
0
    def _monitor(self):
        #Open the serial port.
        if self._port == 'AUTO':
            self._changeState(self.STATE_DETECT_SERIAL)
            programmer = stk500v2.Stk500v2()
            for p in serialList(True):
                try:
                    self._log("Connecting to: %s (programmer)" % (p))
                    programmer.connect(p)
                    self._serial = programmer.leaveISP()
                    profile.putMachineSetting('serial_port_auto', p)
                    break
                except ispBase.IspError as (e):
                    self._log("Error while connecting to %s: %s" % (p, str(e)))
                    pass
                except:
                    self._log(
                        "Unexpected error while connecting to serial port: %s %s"
                        % (p, getExceptionString()))
                programmer.close()
            if self._serial is None:
                self._log("Serial port list: %s" % (str(serialList(True))))
                self._serialDetectList = serialList(True)
        elif self._port == 'VIRTUAL':
            self._changeState(self.STATE_OPEN_SERIAL)
            self._serial = VirtualPrinter()
        else:
            self._changeState(self.STATE_OPEN_SERIAL)
            try:
                if self._baudrate == 0:
                    self._log(
                        "Connecting to: %s with baudrate: 115200 (fallback)" %
                        (self._port))
                    self._serial = serial.Serial(str(self._port),
                                                 115200,
                                                 timeout=3)
                    # Need to set writeTimeout separately in order to be compatible with pyserial 3.0
                    self._serial.writeTimeout = 10000
                else:
                    self._log(
                        "Connecting to: %s with baudrate: %s (configured)" %
                        (self._port, self._baudrate))
                    self._serial = serial.Serial(str(self._port),
                                                 self._baudrate,
                                                 timeout=5)
                    # Need to set writeTimeout separately in order to be compatible with pyserial 3.0
                    self._serial.writeTimeout = 10000
            except:
                self._log(
                    "Unexpected error while connecting to serial port: %s %s" %
                    (self._port, getExceptionString()))
        if self._serial is None:
            baudrate = self._baudrate
            if baudrate == 0:
                baudrate = self._baudrateDetectList.pop(0)
            if len(self._serialDetectList) < 1:
                self._log("Found no ports to try for auto detection")
                self._errorValue = 'Failed to autodetect serial port.'
                self._changeState(self.STATE_ERROR)
                return
            port = self._serialDetectList.pop(0)
            self._log("Connecting to: %s with baudrate: %s (auto)" %
                      (port, baudrate))
            try:
                self._serial = serial.Serial(port, baudrate, timeout=3)
                # Need to set writeTimeout separately in order to be compatible with pyserial 3.0
                self._serial.writeTimeout = 10000
            except:
                pass
        else:
            self._log("Connected to: %s, starting monitor" % (self._serial))
            if self._baudrate == 0:
                self._changeState(self.STATE_DETECT_BAUDRATE)
            else:
                self._changeState(self.STATE_CONNECTING)

        #Start monitoring the serial port.
        if self._state == self.STATE_CONNECTING:
            timeout = time.time() + 15
        else:
            timeout = time.time() + 5
        tempRequestTimeout = timeout
        while True:
            line = self._readline()
            if line is None:
                break

            #No matter the state, if we see an fatal error, goto the error state and store the error for reference.
            # Only goto error on known fatal errors.
            if line.startswith('Error:'):
                #Oh YEAH, consistency.
                # Marlin reports an MIN/MAX temp error as "Error:x\n: Extruder switched off. MAXTEMP triggered !\n"
                #	But a bed temp error is reported as "Error: Temperature heated bed switched off. MAXTEMP triggered !!"
                #	So we can have an extra newline in the most common case. Awesome work people.
                if re.match('Error:[0-9]\n', line):
                    line = line.rstrip() + self._readline()
                #Skip the communication errors, as those get corrected.
                if 'Extruder switched off' in line or 'Temperature heated bed switched off' in line or 'Something is wrong, please turn off the printer.' in line or 'PROBE FAIL' in line:
                    if not self.isError():
                        self._errorValue = line[6:]
                        self._changeState(self.STATE_ERROR)
            if ' T:' in line or line.startswith('T:'):
                tempRequestTimeout = time.time() + 5
                try:
                    self._temp[self._temperatureRequestExtruder] = float(
                        re.search("T: *([0-9\.]*)", line).group(1))
                except:
                    pass
                if 'B:' in line:
                    try:
                        self._bedTemp = float(
                            re.search("B: *([0-9\.]*)", line).group(1))
                    except:
                        pass
                self._callback.mcTempUpdate(self._temp, self._bedTemp,
                                            self._targetTemp,
                                            self._bedTargetTemp)
                #If we are waiting for an M109 or M190 then measure the time we lost during heatup, so we can remove that time from our printing time estimate.
                if not 'ok' in line and self._heatupWaitStartTime != 0:
                    t = time.time()
                    self._heatupWaitTimeLost = t - self._heatupWaitStartTime
                    self._heatupWaitStartTime = t
            elif line.strip() != '' and line.strip() != 'ok' and not line.startswith('Resend:') and \
              not line.startswith('Error:checksum mismatch') and not line.startswith('Error:Line Number is not Last Line Number+1') and \
              not line.startswith('Error:No Checksum with line number') and not line.startswith('Error:No Line Number with checksum') and \
              line != 'echo:Unknown command:""\n' and self.isOperational():
                self._callback.mcMessage(line)

            if self._state == self.STATE_DETECT_BAUDRATE or self._state == self.STATE_DETECT_SERIAL:
                if line == '' or time.time() > timeout:
                    if len(self._baudrateDetectList) < 1:
                        self.close()
                        self._errorValue = "No more baudrates to test, and no suitable baudrate found."
                        self._changeState(self.STATE_ERROR)
                    elif self._baudrateDetectRetry > 0:
                        self._baudrateDetectRetry -= 1
                        self._serial.write('\n')
                        self._log("Baudrate test retry: %d" %
                                  (self._baudrateDetectRetry))
                        self._sendCommand("M105")
                        self._testingBaudrate = True
                    else:
                        if self._state == self.STATE_DETECT_SERIAL:
                            if len(self._serialDetectList) == 0:
                                if len(self._baudrateDetectList) == 0:
                                    self._log(
                                        "Tried all serial ports and baudrates, but still not printer found that responds to M105."
                                    )
                                    self._errorValue = 'Failed to autodetect serial port.'
                                    self._changeState(self.STATE_ERROR)
                                    return
                                else:
                                    self._serialDetectList = serialList(True)
                                    baudrate = self._baudrateDetectList.pop(0)
                            self._serial.close()
                            self._serial = serial.Serial(
                                self._serialDetectList.pop(0),
                                baudrate,
                                timeout=2.5)
                            # Need to set writeTimeout separately in order to be compatible with pyserial 3.0
                            self._serial.writeTimeout = 10000
                        else:
                            baudrate = self._baudrateDetectList.pop(0)
                        try:
                            self._setBaudrate(baudrate)
                            self._serial.timeout = 0.5
                            self._log("Trying baudrate: %d" % (baudrate))
                            self._baudrateDetectRetry = 5
                            self._baudrateDetectTestOk = 0
                            timeout = time.time() + 5
                            self._serial.write('\n')
                            self._sendCommand("M105")
                            self._testingBaudrate = True
                        except:
                            self._log(
                                "Unexpected error while setting baudrate: %d %s"
                                % (baudrate, getExceptionString()))
                elif 'T:' in line:
                    self._baudrateDetectTestOk += 1
                    if self._baudrateDetectTestOk < 10:
                        self._log("Baudrate test ok: %d" %
                                  (self._baudrateDetectTestOk))
                        self._sendCommand("M105")
                    else:
                        self._sendCommand("M999")
                        self._serial.timeout = 2
                        profile.putMachineSetting('serial_baud_auto',
                                                  self._serial.baudrate)
                        self._changeState(self.STATE_OPERATIONAL)
                else:
                    self._testingBaudrate = False
            elif self._state == self.STATE_CONNECTING:
                if line == '' or 'wait' in line or 'start' in line:  # 'wait' needed for Repetier (kind of watchdog)
                    self._sendCommand("M105")
                elif 'ok' in line:
                    self._changeState(self.STATE_OPERATIONAL)
                if time.time() > timeout:
                    self.close()
            elif self._state == self.STATE_OPERATIONAL:
                # Request the temperature on comm timeout (every 2 seconds) when we are not printing.
                # unless we had a temperature feedback (from M109 or M190 for example)
                if line == '' and time.time() > tempRequestTimeout:
                    if self._heatupWaiting and len(self._currentCommands) == 1:
                        self._log(
                            "Canceling heatup due to missing T: line in the past 5 seconds. cmdbuffer desync?"
                        )
                        self._heatupWaiting = False
                        # Force a timeout now if necessary
                        timeout = time.time() - 1
                    if self._extruderCount > 0:
                        self._temperatureRequestExtruder = (
                            self._temperatureRequestExtruder +
                            1) % self._extruderCount
                        self.sendCommand("M105 T%d" %
                                         (self._temperatureRequestExtruder))
                    else:
                        self.sendCommand("M105")
                    # set timeout to less than 2 seconds to make sure it always triggers when comm times out
                    tempRequestTimeout = time.time() + 1.5
                if line == '' and time.time() > timeout:
                    line = 'ok'
                if 'ok' in line:
                    self.receivedOK()
                    timeout = time.time() + 30
                    if not self._heatupWaiting and not self._commandQueue.empty(
                    ):
                        self._sendCommand(self._commandQueue.get())
                    if len(self._currentCommands) > 0 and \
                       ("G28" in self._currentCommands[0] or "G29" in self._currentCommands[0] or \
                     "M109" in self._currentCommands[0] or "M190" in self._currentCommands[0]):
                        # Long command detected. Timeout is now set to 10 minutes to avoid forcing 'ok'
                        # every 30 seconds while it's not needed
                        timeout = time.time() + 600
                elif 'start' in line:
                    self._currentCommands = []
                    timeout = time.time() + 30
            elif self._state == self.STATE_PRINTING:
                #Even when printing request the temperature every 5 seconds.
                if time.time() > tempRequestTimeout:
                    if self._heatupWaiting and len(self._currentCommands) == 1:
                        self._log(
                            "Canceling heatup due to missing T: line in the past 5 seconds. cmdbuffer desync?"
                        )
                        self._heatupWaiting = False
                        # Force a timeout now if necessary
                        timeout = time.time() - 1
                    if self._extruderCount > 0:
                        self._temperatureRequestExtruder = (
                            self._temperatureRequestExtruder +
                            1) % self._extruderCount
                        self.sendCommand("M105 T%d" %
                                         (self._temperatureRequestExtruder))
                    else:
                        self.sendCommand("M105")
                    tempRequestTimeout = time.time() + 5
                if line == '' and time.time() > timeout:
                    self._log(
                        "Communication timeout during printing, forcing a line"
                    )
                    line = 'ok'
                if 'ok' in line:
                    self.receivedOK()
                    timeout = time.time() + 30
                    # If we are heating up with M109 or M190, then we can't send any new
                    # commands until the command buffer queue in firmware is empty (M109/M190 done)
                    # otherwise, we will fill up the buffer queue (2 more commands will be accepted after M109/M190)
                    # and anything else we send will just end up in the serial ringbuffer and will not be read until
                    # the M109/M190 is done.
                    # So if we want to cancel the heatup, we need to send M108 which needs to be able to be read from
                    # the ringbuffer, which means the command queue needs to be empty.
                    # So we stop sending any commands after M109/M190 unless it's M108 (or until heating done) if we want
                    # M108 to get handled.
                    # the small delay that is caused by the firmware buffer getting empty is not important because
                    # this happens during a heat&wait, not during a move command.
                    # If M108 is received, it gets sent directly from the receiving thread, not from here
                    # because the _commandQueue is not iterable
                    if not self._heatupWaiting:
                        # We iterate in case we just came out of a heat&wait
                        for i in xrange(len(self._currentCommands),
                                        CMDBUFFER_SIZE):
                            # One of the next 4 could enable the heatupWaiting mode
                            if not self._heatupWaiting:
                                if not self._commandQueue.empty():
                                    self._sendCommand(self._commandQueue.get())
                                else:
                                    self._sendNext()
                    if len(self._currentCommands) > 0 and \
                       ("G28" in self._currentCommands[0] or "G29" in self._currentCommands[0] or \
                     "M109" in self._currentCommands[0] or "M190" in self._currentCommands[0]):
                        # Long command detected. Timeout is now set to 10 minutes to avoid forcing 'ok'
                        # every 30 seconds while it's not needed
                        timeout = time.time() + 600

                elif 'start' in line:
                    self._currentCommands = []
                    timeout = time.time() + 30
                elif "resend" in line.lower() or "rs" in line:
                    newPos = self._gcodePos
                    try:
                        newPos = int(
                            line.replace("N:", " ").replace("N", " ").replace(
                                ":", " ").split()[-1])
                    except:
                        if "rs" in line:
                            newPos = int(line.split()[1])
                    # If we need to resend more than 10 lines, we can assume that the machine
                    # was shut down and turned back on or something else that's weird just happened.
                    # In that case, it can be dangerous to restart the print, so we'd better kill it
                    if newPos == 1 or self._gcodePos > newPos + 100:
                        self._callback.mcMessage(
                            "Print canceled due to loss of communication to printer (USB unplugged or power lost)"
                        )
                        self.cancelPrint()
                    else:
                        self._gcodePos = newPos
            elif self._state == self.STATE_PAUSED:
                #Even when printing request the temperature every 5 seconds.
                if time.time() > tempRequestTimeout:
                    if self._heatupWaiting and len(self._currentCommands) == 1:
                        self._log(
                            "Canceling heatup due to missing T: line in the past 5 seconds. cmdbuffer desync?"
                        )
                        self._heatupWaiting = False
                        # Force a timeout now if necessary
                        timeout = time.time() - 1
                    if self._extruderCount > 0:
                        self._temperatureRequestExtruder = (
                            self._temperatureRequestExtruder +
                            1) % self._extruderCount
                        self.sendCommand("M105 T%d" %
                                         (self._temperatureRequestExtruder))
                    else:
                        self.sendCommand("M105")
                    tempRequestTimeout = time.time() + 5
                if line == '' and time.time() > timeout:
                    line = 'ok'
                if 'ok' in line:
                    self.receivedOK()
                    timeout = time.time() + 30
                    if not self._heatupWaiting and not self._commandQueue.empty(
                    ):
                        self._sendCommand(self._commandQueue.get())
                    if len(self._currentCommands) > 0 and \
                       ("G28" in self._currentCommands[0] or "G29" in self._currentCommands[0] or \
                     "M109" in self._currentCommands[0] or "M190" in self._currentCommands[0]):
                        # Long command detected. Timeout is now set to 10 minutes to avoid forcing 'ok'
                        # every 30 seconds while it's not needed
                        timeout = time.time() + 600
                elif 'start' in line:
                    self._currentCommands = []
                    timeout = time.time() + 30

        self._log("Connection closed, closing down monitor")