diff --git a/cura/PrinterOutput/FirmwareUpdater.py b/cura/PrinterOutput/FirmwareUpdater.py index 2f200118a9..88169b1d75 100644 --- a/cura/PrinterOutput/FirmwareUpdater.py +++ b/cura/PrinterOutput/FirmwareUpdater.py @@ -16,6 +16,8 @@ class FirmwareUpdater(QObject): firmwareUpdateStateChanged = pyqtSignal() def __init__(self, output_device: PrinterOutputDevice) -> None: + super().__init__() + self._output_device = output_device self._update_firmware_thread = Thread(target=self._updateFirmware, daemon=True) @@ -31,29 +33,35 @@ class FirmwareUpdater(QObject): self._firmware_location = QUrl(file).toLocalFile() else: self._firmware_location = file - self.showFirmwareInterface() - self.setFirmwareUpdateState(FirmwareUpdateState.updating) + self._showFirmwareInterface() + self._setFirmwareUpdateState(FirmwareUpdateState.updating) + self._update_firmware_thread.start() def _updateFirmware(self) -> None: raise NotImplementedError("_updateFirmware needs to be implemented") - def cleanupAfterUpdate(self) -> None: + ## Show firmware interface. + # This will create the view if its not already created. + def _showFirmwareInterface(self) -> None: + if self._firmware_view is None: + path = Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "FirmwareUpdateWindow.qml") + self._firmware_view = CuraApplication.getInstance().createQmlComponent(path, {"manager": self}) + + if not self._firmware_view: + return + + self._onFirmwareProgress(0) + self._setFirmwareUpdateState(FirmwareUpdateState.idle) + self._firmware_view.show() + + ## Cleanup after a succesful update + def _cleanupAfterUpdate(self) -> None: # Clean up for next attempt. self._update_firmware_thread = Thread(target=self._updateFirmware, daemon=True) self._firmware_location = "" self._onFirmwareProgress(100) - self.setFirmwareUpdateState(FirmwareUpdateState.completed) - - ## Show firmware interface. - # This will create the view if its not already created. - def showFirmwareInterface(self) -> None: - if self._firmware_view is None: - path = Resources.getPath(self.ResourceTypes.QmlFiles, "FirmwareUpdateWindow.qml") - self._firmware_view = CuraApplication.getInstance().createQmlComponent(path, {"manager": self}) - - if self._firmware_view: - self._firmware_view.show() + self._setFirmwareUpdateState(FirmwareUpdateState.completed) @pyqtProperty(float, notify = firmwareProgressChanged) def firmwareProgress(self) -> float: @@ -63,7 +71,7 @@ class FirmwareUpdater(QObject): def firmwareUpdateState(self) -> "FirmwareUpdateState": return self._firmware_update_state - def setFirmwareUpdateState(self, state) -> None: + def _setFirmwareUpdateState(self, state) -> None: if self._firmware_update_state != state: self._firmware_update_state = state self.firmwareUpdateStateChanged.emit() diff --git a/plugins/USBPrinting/AvrFirmwareUpdater.py b/plugins/USBPrinting/AvrFirmwareUpdater.py index ab71f70e30..505e1ddb7e 100644 --- a/plugins/USBPrinting/AvrFirmwareUpdater.py +++ b/plugins/USBPrinting/AvrFirmwareUpdater.py @@ -22,39 +22,43 @@ class AvrFirmwareUpdater(FirmwareUpdater): assert len(hex_file) > 0 except (FileNotFoundError, AssertionError): Logger.log("e", "Unable to read provided hex file. Could not update firmware.") - self.setFirmwareUpdateState(FirmwareUpdateState.firmware_not_found_error) + self._setFirmwareUpdateState(FirmwareUpdateState.firmware_not_found_error) return programmer = stk500v2.Stk500v2() programmer.progress_callback = self._onFirmwareProgress + # Ensure that other connections are closed. + if self._output_device.isConnected(): + self._output_device.close() + try: - programmer.connect(self._serial_port) + programmer.connect(self._output_device._serial_port) except: programmer.close() Logger.logException("e", "Failed to update firmware") - self.setFirmwareUpdateState(FirmwareUpdateState.communication_error) + self._setFirmwareUpdateState(FirmwareUpdateState.communication_error) return # Give programmer some time to connect. Might need more in some cases, but this worked in all tested cases. sleep(1) if not programmer.isConnected(): Logger.log("e", "Unable to connect with serial. Could not update firmware") - self.setFirmwareUpdateState(FirmwareUpdateState.communication_error) + self._setFirmwareUpdateState(FirmwareUpdateState.communication_error) try: programmer.programChip(hex_file) except SerialException as e: Logger.log("e", "A serial port exception occured during firmware update: %s" % e) - self.setFirmwareUpdateState(FirmwareUpdateState.io_error) + self._setFirmwareUpdateState(FirmwareUpdateState.io_error) return except Exception as e: Logger.log("e", "An unknown exception occured during firmware update: %s" % e) - self.setFirmwareUpdateState(FirmwareUpdateState.unknown_error) + self._setFirmwareUpdateState(FirmwareUpdateState.unknown_error) return programmer.close() # Try to re-connect with the machine again, which must be done on the Qt thread, so we use call later. - CuraApplication.getInstance().callLater(self.connect) + CuraApplication.getInstance().callLater(self._output_device.connect) - self.cleanupAfterUpdate() + self._cleanupAfterUpdate()