From d7262c6ac69356337bba6be49d6a4765d15769cb Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 10 Apr 2015 13:41:28 +0200 Subject: [PATCH] Added bed & extruder temp + error state logging to usb gui --- ControlWindow.qml | 19 ++++++++-- PrinterConnection.py | 42 +++++++++++++++++---- USBPrinterManager.py | 87 ++++++++++++++++++++++++++++++++------------ 3 files changed, 114 insertions(+), 34 deletions(-) diff --git a/ControlWindow.qml b/ControlWindow.qml index 944c48a14d..4ea83f7bb3 100644 --- a/ControlWindow.qml +++ b/ControlWindow.qml @@ -6,10 +6,21 @@ Rectangle width: 300; height: 100 ColumnLayout { - Text + RowLayout { - text: "Hello world!" - color: "blue" + Text + { + text: "extruder temperature " + manager.extruderTemperature + } + Text + { + text: "bed temperature " + manager.bedTemperature + } + Text + { + text: "" + manager.error + } + } RowLayout { @@ -17,11 +28,13 @@ Rectangle { text: "Print" onClicked: { manager.startPrint() } + enabled: manager.progress == 0 ? true : false } Button { text: "Cancel" onClicked: { manager.cancelPrint() } + enabled: manager.progress == 0 ? false: true } } ProgressBar diff --git a/PrinterConnection.py b/PrinterConnection.py index 0ec7435817..9d3cb1c767 100644 --- a/PrinterConnection.py +++ b/PrinterConnection.py @@ -119,9 +119,7 @@ class PrinterConnection(SignalEmitter): programmer = stk500v2.Stk500v2() try: programmer.connect(self._serial_port) #Connect with the serial, if this succeeds, it's an arduino based usb device. - self._serial = programmer.leaveISP() - # Create new printer connection - Logger.log('i', "Established connection on port %s" % self._serial_port) + self._serial = programmer.leaveISP() except ispBase.IspError as e: Logger.log('i', "Could not establish connection on %s: %s. Device is not arduino based." %(self._serial_port,str(e))) except: @@ -150,6 +148,7 @@ class PrinterConnection(SignalEmitter): if sucesfull_responses >= self._required_responses_auto_baud: self._serial.timeout = 2 #Reset serial timeout self.setIsConnected(True) + Logger.log('i', "Established connection on port %s" % self._serial_port) return self.setIsConnected(False) @@ -223,9 +222,11 @@ class PrinterConnection(SignalEmitter): self._serial.write((cmd + '\n').encode()) except Exception as e: Logger.log("e","Unexpected error while writing serial port %s " % e) + self._setErrorState("Unexpected error while writing serial port %s " % e) self.close() except Exception as e: Logger.log('e',"Unexpected error while writing serial port %s" % e) + self._setErrorState("Unexpected error while writing serial port %s " % e) self.close() ## Ensure that close gets called when object is destroyed @@ -240,6 +241,28 @@ class PrinterConnection(SignalEmitter): elif self.isConnected(): self._sendCommand(cmd) + def _setErrorState(self, error): + self._error_state = error + self.onError.emit(error) + + onError = Signal() + + def _setExtruderTemperature(self, index, temperature): + try: + self._extruder_temperatures[index] = temperature + self.onExtruderTemperatureChange.emit(self._serial_port,index,temperature) + except: + pass + + onExtruderTemperatureChange = Signal() + + def _setBedTemperature(self, temperature): + self._bed_temperature = temperature + self.onBedTemperatureChange.emit(self._serial_port,temperature) + + onBedTemperatureChange = Signal() + + ## Listen thread function. def _listen(self): temperature_request_timeout = time.time() @@ -258,16 +281,19 @@ class PrinterConnection(SignalEmitter): #Skip the communication errors, as those get corrected. if b'Extruder switched off' in line or b'Temperature heated bed switched off' in line or b'Something is wrong, please turn off the printer.' in line: if not self.hasError(): - self._error_state = line[6:] + self._setErrorState(line[6:]) + #self._error_state = line[6:] elif b' T:' in line or line.startswith(b'T:'): #Temperature message try: - self._extruder_temperatures[self._temperatureRequestExtruder] = float(re.search(b"T: *([0-9\.]*)", line).group(1)) + self._setExtruderTemperature(self._temperature_requested_extruder_index,float(re.search(b"T: *([0-9\.]*)", line).group(1))) + #self._extruder_temperatures[self._temperature_requested_extruder_index] = float(re.search(b"T: *([0-9\.]*)", line).group(1)) except: pass if b'B:' in line: #Check if it's a bed temperature try: + self._setBedTemperature(float(re.search(b"B: *([0-9\.]*)", line).group(1))) #print("BED TEMPERATURE" ,float(re.search(b"B: *([0-9\.]*)", line).group(1))) - pass + except: pass #TODO: temperature changed callback @@ -323,6 +349,7 @@ class PrinterConnection(SignalEmitter): self._current_z = z except Exception as e: Logger.log('e', "Unexpected error: %s" % e) + self._setErrorState("Unexpected error: %s" %e) checksum = functools.reduce(lambda x,y: x^y, map(ord, 'N%d%s' % (self._gcode_position, line))) self._sendCommand("N%d%s*%d" % (self._gcode_position, line, checksum)) @@ -354,7 +381,8 @@ class PrinterConnection(SignalEmitter): try: ret = self._serial.readline() except: - Logger.log('e',"Unexpected error while reading serial port.") + Logger.log('e',"Unexpected error while reading serial port.") + self._setErrorState("Printer has been disconnected") #self._errorValue = getExceptionString() self.close() return None diff --git a/USBPrinterManager.py b/USBPrinterManager.py index e3102d2e33..feabfd6541 100644 --- a/USBPrinterManager.py +++ b/USBPrinterManager.py @@ -22,15 +22,13 @@ class USBPrinterManager(QObject, SignalEmitter,PluginObject): self._check_ports_thread.daemon = True self._check_ports_thread.start() - self._progress = 50 - + self._progress = 0 - ## DEBUG CODE - self.view = QQuickView() - self.view.setSource(QUrl("plugins/USBPrinting/ControlWindow.qml")) - self.view.show() - self.view.engine().rootContext().setContextProperty('manager',self) + self.view = None + self._extruder_temp = 0 + self._bed_temp = 0 + self._error_message = "" #time.sleep(1) #self.connectAllConnections() #time.sleep(5) @@ -42,27 +40,37 @@ class USBPrinterManager(QObject, SignalEmitter,PluginObject): #print("sending heat " , self.sendCommandToAllActive("M104 S190")) - #def spawnInterface(self): - #view = QQuickView() - #view.setSource(QUrl("plugins/USBPrinting/ControlWindow.qml")) - #view.show() - - ## Check all serial ports and create a PrinterConnection object for them. - # Note that this does not validate if the serial ports are actually usable! - # This is only done when the connect function is called. - + def spawnInterface(self,serial_port): + if self.view is None: + self.view = QQuickView() + self.view.engine().rootContext().setContextProperty('manager',self) + self.view.setSource(QUrl("plugins/USBPrinting/ControlWindow.qml")) + self.view.show() + processingProgress = pyqtSignal(float, arguments = ['amount']) - #@pyqtProperty(float, notify = processingProgress) @pyqtProperty(float,notify = processingProgress) def progress(self): return self._progress - @pyqtSlot() - def test(self): - print("derp") + pyqtExtruderTemperature = pyqtSignal(float, arguments = ['amount']) + @pyqtProperty(float,notify = pyqtExtruderTemperature) + def extruderTemperature(self): + return self._extruder_temp + pyqtBedTemperature = pyqtSignal(float, arguments = ['amount']) + @pyqtProperty(float,notify = pyqtBedTemperature) + def bedTemperature(self): + return self._bed_temp + pyqtError = pyqtSignal(str, arguments = ['amount']) + @pyqtProperty(str,notify = pyqtError) + def error(self): + return self._error_message + + ## Check all serial ports and create a PrinterConnection object for them. + # Note that this does not validate if the serial ports are actually usable! + # This (the validation) is only done when the connect function is called. def _updateConnectionList(self): while True: temp_serial_port_list = self.getSerialPortList(only_list_usb = True) @@ -76,6 +84,9 @@ class USBPrinterManager(QObject, SignalEmitter,PluginObject): connection.connect() connection.connectionStateChanged.connect(self.serialConectionStateCallback) connection.progressChanged.connect(self.onProgress) + connection.onExtruderTemperatureChange.connect(self.onExtruderTemperature) + connection.onBedTemperatureChange.connect(self.onBedTemperature) + connection.onError.connect(self.onError) self._printer_connections.append(connection) for serial_port in disconnected_ports: # Close connections and remove them from list. @@ -85,6 +96,24 @@ class USBPrinterManager(QObject, SignalEmitter,PluginObject): connection.close() time.sleep(5) #Throttle, as we don't need this information to be updated every single second. + def onExtruderTemperature(self, serial_port, index,temperature): + #print("ExtruderTemperature " , serial_port, " " , index, " " , temperature) + self._extruder_temp = temperature + self.pyqtExtruderTemperature.emit(temperature) + + pass + + def onBedTemperature(self, serial_port,temperature): + self._bed_temperature = temperature + self.pyqtBedTemperature.emit(temperature) + #print("bedTemperature " , serial_port, " " , temperature) + pass + + def onError(self, error): + self._error_message = error + self.pyqtError.emit(error) + pass + def onProgress(self, progress, serial_port): self._progress = progress self.processingProgress.emit(progress) @@ -102,6 +131,7 @@ class USBPrinterManager(QObject, SignalEmitter,PluginObject): printer_connection.printGCode(gcode_list) return True return False + @pyqtSlot() def cancelPrint(self): for printer_connection in self.getActiveConnections(): @@ -145,21 +175,30 @@ class USBPrinterManager(QObject, SignalEmitter,PluginObject): if connection.isConnected(): Application.getInstance().addOutputDevice(serial_port, { 'id': serial_port, - 'function': self._writeToSerial, + 'function': self.spawnInterface, 'description': 'Write to USB {0}'.format(serial_port), 'icon': 'print_usb', 'priority': 1 }) else: Application.getInstance().removeOutputDevice(serial_port) - - def _writeToSerial(self, serial_port): + + '''def _writeToSerial(self, serial_port): gcode_list = getattr(Application.getInstance().getController().getScene(), 'gcode_list', None) if gcode_list: final_list = [] for gcode in gcode_list: final_list += gcode.split('\n') - self.sendGCodeByPort(serial_port, gcode_list) + self.sendGCodeByPort(serial_port, gcode_list)''' + @pyqtSlot() + def startPrint(self): + gcode_list = getattr(Application.getInstance().getController().getScene(), 'gcode_list', None) + if gcode_list: + final_list = [] + for gcode in gcode_list: + final_list += gcode.split('\n') + self.sendGCodeToAllActive(gcode_list) + ## Get a list of printer connection objects that are connected. def getActiveConnections(self):