From 6770db9c51bc98020698701e218f0479aafb532e Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 5 Sep 2016 13:45:57 +0200 Subject: [PATCH 01/11] Update wording when unable to start a new printjob UM3IC-193 --- NetworkPrinterOutputDevice.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NetworkPrinterOutputDevice.py b/NetworkPrinterOutputDevice.py index a1708f395e..a5e86483d5 100644 --- a/NetworkPrinterOutputDevice.py +++ b/NetworkPrinterOutputDevice.py @@ -363,12 +363,12 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): def requestWrite(self, node, file_name = None, filter_by_machine = False): if self._progress != 0: - self._error_message = Message(i18n_catalog.i18nc("@info:status", "Printer is still printing. Unable to start a new job.")) + self._error_message = Message(i18n_catalog.i18nc("@info:status", "Unable to start a new print job because the printer is busy. Please check the printer.")) self._error_message.show() return if self._json_printer_state["status"] != "idle": self._error_message = Message( - i18n_catalog.i18nc("@info:status", "Unable to start a new print job, printer is not idle. Current printer status is %s.") % self._json_printer_state["status"]) + i18n_catalog.i18nc("@info:status", "Unable to start a new print job, printer is busy. Current printer status is %s.") % self._json_printer_state["status"]) self._error_message.show() return elif self._authentication_state != AuthState.Authenticated: From ef667c7ec7bc094fa850612ed25ec68fe000df97 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 6 Sep 2016 14:44:53 +0200 Subject: [PATCH 02/11] If there is no material or correct cartridges inserted into printer, the job is refused CURA-2285 --- NetworkPrinterOutputDevice.py | 38 ++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/NetworkPrinterOutputDevice.py b/NetworkPrinterOutputDevice.py index a5e86483d5..9af4c69ec2 100644 --- a/NetworkPrinterOutputDevice.py +++ b/NetworkPrinterOutputDevice.py @@ -381,12 +381,40 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): self._print_finished = True self._gcode = getattr(Application.getInstance().getController().getScene(), "gcode_list") - # TODO: Implement all checks. - # Check if cartridges are loaded at all (Error) - #self._json_printer_state["heads"][0]["extruders"][0]["hotend"]["id"] != "" + print_information = Application.getInstance().getPrintInformation() - # Check if there is material loaded at all (Error) - #self._json_printer_state["heads"][0]["extruders"][0]["active_material"]["GUID"] != "" + # TODO: Implement all checks. + # Check if PrintCores / materials are loaded at all (Error) + if print_information.materialLengths[0] != 0: # We need to print with extruder slot 1 + if self._json_printer_state["heads"][0]["extruders"][0]["hotend"]["id"] == "": + Logger.log("e", "No cartridge loaded in slot 1, unable to start print") + self._error_message = Message( + i18n_catalog.i18nc("@info:status", "Unable to start a new print job, no PowerCore loaded in slot 1")) + self._error_message.show() + return + if self._json_printer_state["heads"][0]["extruders"][0]["active_material"]["GUID"] == "": + Logger.log("e", "No material loaded in slot 1, unable to start print") + self._error_message = Message( + i18n_catalog.i18nc("@info:status", + "Unable to start a new print job, no material loaded in slot 1")) + self._error_message.show() + return + + if print_information.materialLengths[1] != 0: # We need to print with extruder slot 2 + if self._json_printer_state["heads"][0]["extruders"][1]["hotend"]["id"] == "": + Logger.log("e", "No cartridge loaded in slot 2, unable to start print") + self._error_message = Message( + i18n_catalog.i18nc("@info:status", + "Unable to start a new print job, no PowerCore loaded in slot 2")) + self._error_message.show() + return + if self._json_printer_state["heads"][0]["extruders"][1]["active_material"]["GUID"] == "": + Logger.log("e", "No material loaded in slot 2, unable to start print") + self._error_message = Message( + i18n_catalog.i18nc("@info:status", + "Unable to start a new print job, no material loaded in slot 2")) + self._error_message.show() + return # Check if there is enough material (Warning) #self._json_printer_state["heads"][0]["extruders"][0]["active_material"]["length_remaining"] From d76927ef5d441c78feba5899ecc7884f6f9239ed Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 7 Sep 2016 09:18:52 +0200 Subject: [PATCH 03/11] Added warning messages for mismatch / not enough material CURA-2285 --- NetworkPrinterOutputDevice.py | 77 ++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 6 deletions(-) diff --git a/NetworkPrinterOutputDevice.py b/NetworkPrinterOutputDevice.py index 9af4c69ec2..76f1ca097e 100644 --- a/NetworkPrinterOutputDevice.py +++ b/NetworkPrinterOutputDevice.py @@ -8,6 +8,7 @@ from UM.Message import Message import UM.Settings from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState +import cura.Settings.ExtruderManager from PyQt5.QtNetwork import QHttpMultiPart, QHttpPart, QNetworkRequest, QNetworkAccessManager, QNetworkReply from PyQt5.QtCore import QUrl, QTimer, pyqtSignal, pyqtProperty, pyqtSlot @@ -383,8 +384,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): print_information = Application.getInstance().getPrintInformation() - # TODO: Implement all checks. - # Check if PrintCores / materials are loaded at all (Error) + # Check if PrintCores / materials are loaded at all. Any failure in these results in an Error. if print_information.materialLengths[0] != 0: # We need to print with extruder slot 1 if self._json_printer_state["heads"][0]["extruders"][0]["hotend"]["id"] == "": Logger.log("e", "No cartridge loaded in slot 1, unable to start print") @@ -416,10 +416,71 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): self._error_message.show() return - # Check if there is enough material (Warning) - #self._json_printer_state["heads"][0]["extruders"][0]["active_material"]["length_remaining"] + warnings = [] # There might be multiple things wrong. Keep a list of all the stuff we need to warn about. - #TODO: Check if the cartridge is the right ID (give warning otherwise) + # Check if there is enough material. Any failure in these results in a warning. + material_length_1 = self._json_printer_state["heads"][0]["extruders"][0]["active_material"]["length_remaining"] + if material_length_1 != -1 and print_information.materialLengths[0] > material_length_1: + warnings.append("not_enough_material_1") + + material_length_2 = self._json_printer_state["heads"][0]["extruders"][1]["active_material"]["length_remaining"] + if material_length_2 != -1 and print_information.materialLengths[1] > material_length_2: + warnings.append("not_enough_material_2") + + # Check if the right cartridges are loaded. Any failure in these results in a warning. + extruder_manager = cura.Settings.ExtruderManager.getInstance() + if print_information.materialLengths[0] != 0: + variant = extruder_manager.getExtruderStack(0).findContainer({"type": "variant"}) + if variant: + if variant.getId() != self._json_printer_state["heads"][0]["extruders"][0]["hotend"]["id"]: + warnings.append("hotend_1") + + material = extruder_manager.getExtruderStack(0).findContainer({"type": "material"}) + if material: + if material.getMetaDataEntry("GUID") != self._json_printer_state["heads"][0]["extruders"][0]["active_material"]["GUID"]: + warnings.append("wrong_material_1") + + if print_information.materialLengths[1] != 0: + variant = extruder_manager.getExtruderStack(1).findContainer({"type": "variant"}) + if variant: + if variant.getId() != self._json_printer_state["heads"][0]["extruders"][1]["hotend"]["id"]: + warnings.append("hotend_2") + + material = extruder_manager.getExtruderStack(1).findContainer({"type": "material"}) + if material: + if material.getMetaDataEntry("GUID") != self._json_printer_state["heads"][0]["extruders"][1]["active_material"]["GUID"]: + warnings.append("wrong_material_2") + + if warnings: + text = i18n_catalog.i18nc("@label", "A number of configurations are mismatched. Are you sure you wish to print with the selected configuration?") + detailed_text = "
    " + if "not_enough_material_1" in warnings: + detailed_text += "
  • " + i18n_catalog.i18nc("@label", "Not enough material for spool 1.") + "
  • " + if "not_enough_material_2" in warnings: + detailed_text += "
  • " + i18n_catalog.i18nc("@label", "Not enough material for spool 2.") + "
  • " + if "hotend_1" in warnings: + detailed_text += "
  • " + i18n_catalog.i18nc("@label", + "Different PrintCore selected for extruder 1") + "
  • " + if "hotend_2" in warnings: + detailed_text += "
  • " + i18n_catalog.i18nc("@label", + "Different PrintCore selected for extruder 2") + "
  • " + if "wrong_material_1" in warnings: + detailed_text += "
  • " + i18n_catalog.i18nc("@label", + "Different material selected for extruder 1") + "
  • " + if "wrong_material_2" in warnings: + detailed_text += "
  • " + i18n_catalog.i18nc("@label", + "Different material selected for extruder 1") + "
  • " + + detailed_text += "
" + Application.getInstance().messageBox(i18n_catalog.i18nc("@window:title", "Mismatched configuration"), + text, + detailed_text, + buttons=QMessageBox.Yes + QMessageBox.No, + icon=QMessageBox.Question, + callback=self._configurationCallback + ) + + return self.startPrint() @@ -743,4 +804,8 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): buttons=QMessageBox.Yes + QMessageBox.No, icon=QMessageBox.Question, callback=callback - ) \ No newline at end of file + ) + + def _configurationCallback(self, button): + if button == QMessageBox.Yes: + self.startPrint() From b5d0b32bce66f6ab84e96cfb2e31fb034445801a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 7 Sep 2016 09:48:18 +0200 Subject: [PATCH 04/11] Variant is now matched by name instead of ID CURA-2285 --- NetworkPrinterOutputDevice.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NetworkPrinterOutputDevice.py b/NetworkPrinterOutputDevice.py index 76f1ca097e..f0b6d447a5 100644 --- a/NetworkPrinterOutputDevice.py +++ b/NetworkPrinterOutputDevice.py @@ -432,7 +432,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): if print_information.materialLengths[0] != 0: variant = extruder_manager.getExtruderStack(0).findContainer({"type": "variant"}) if variant: - if variant.getId() != self._json_printer_state["heads"][0]["extruders"][0]["hotend"]["id"]: + if variant.getName() != self._json_printer_state["heads"][0]["extruders"][0]["hotend"]["id"]: warnings.append("hotend_1") material = extruder_manager.getExtruderStack(0).findContainer({"type": "material"}) @@ -443,7 +443,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): if print_information.materialLengths[1] != 0: variant = extruder_manager.getExtruderStack(1).findContainer({"type": "variant"}) if variant: - if variant.getId() != self._json_printer_state["heads"][0]["extruders"][1]["hotend"]["id"]: + if variant.getName() != self._json_printer_state["heads"][0]["extruders"][1]["hotend"]["id"]: warnings.append("hotend_2") material = extruder_manager.getExtruderStack(1).findContainer({"type": "material"}) From f2e93bfd978df91fbcccce293130b5bb378e5e11 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 7 Sep 2016 11:46:55 +0200 Subject: [PATCH 05/11] Added time spent in timeout to re-check connection log CURA-2295 --- NetworkPrinterOutputDevice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NetworkPrinterOutputDevice.py b/NetworkPrinterOutputDevice.py index f0b6d447a5..8ec071cb82 100644 --- a/NetworkPrinterOutputDevice.py +++ b/NetworkPrinterOutputDevice.py @@ -237,7 +237,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): if self._last_response_time and self._connection_state_before_timeout: if time() - self._last_response_time > self._recreate_network_manager_time * self._recreate_network_manager_count: self._recreate_network_manager_count += 1 - Logger.log("d", "Timeout lasted over 30 seconds, re-checking connection.") + Logger.log("d", "Timeout lasted over 30 seconds (%.1fs), re-checking connection.", (time() - self._last_response_time)) self._createNetworkManager() return From 93cc25b4081e4a92feff6dc6bbeab2519e2f3560 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 7 Sep 2016 11:56:19 +0200 Subject: [PATCH 06/11] Added exception handling for when wrapped reply object is already deleted CURA-2295 --- NetworkPrinterOutputDevice.py | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/NetworkPrinterOutputDevice.py b/NetworkPrinterOutputDevice.py index 8ec071cb82..6ab697ed5e 100644 --- a/NetworkPrinterOutputDevice.py +++ b/NetworkPrinterOutputDevice.py @@ -252,13 +252,16 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): self._connection_message.show() # Check if we were uploading something. Abort if this is the case. # Some operating systems handle this themselves, others give weird issues. - if self._post_reply: - self._post_reply.abort() - try: - self._post_reply.uploadProgress.disconnect(self._onUploadProgress) - except TypeError: - pass # The disconnection can fail on mac in some cases. Ignore that. - self._progress_message.hide() + try: + if self._post_reply: + self._post_reply.abort() + try: + self._post_reply.uploadProgress.disconnect(self._onUploadProgress) + except TypeError: + pass # The disconnection can fail on mac in some cases. Ignore that. + self._progress_message.hide() + except RuntimeError: + self._post_reply = None # It can happen that the wrapped c++ object is already deleted. return else: self._recreate_network_manager_count = 1 @@ -273,13 +276,16 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): self._connection_message.show() # Check if we were uploading something. Abort if this is the case. # Some operating systems handle this themselves, others give weird issues. - if self._post_reply: - self._post_reply.abort() - try: - self._post_reply.uploadProgress.disconnect(self._onUploadProgress) - except TypeError: - pass # The disconnection can fail on mac in some cases. Ignore that. - self._progress_message.hide() + try: + if self._post_reply: + self._post_reply.abort() + try: + self._post_reply.uploadProgress.disconnect(self._onUploadProgress) + except TypeError: + pass # The disconnection can fail on mac in some cases. Ignore that. + self._progress_message.hide() + except RuntimeError: + self._post_reply = None # It can happen that the wrapped c++ object is already deleted. self.setConnectionState(ConnectionState.error) return From d0823fda118dc8e7ff18bb4349ddf905db1fba0f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 7 Sep 2016 12:58:48 +0200 Subject: [PATCH 07/11] If a timeout lasted to long without update, we only re-create network interface once CURA-2295 --- NetworkPrinterOutputDevice.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/NetworkPrinterOutputDevice.py b/NetworkPrinterOutputDevice.py index 6ab697ed5e..6f41f42e15 100644 --- a/NetworkPrinterOutputDevice.py +++ b/NetworkPrinterOutputDevice.py @@ -231,13 +231,21 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): ## Request data from the connected device. def _update(self): + if self._last_response_time: + time_since_last_response = time() - self._last_response_time + else: + time_since_last_response = 0 + # Connection is in timeout, check if we need to re-start the connection. # Sometimes the qNetwork manager incorrectly reports the network status on Mac & Windows. # Re-creating the QNetworkManager seems to fix this issue. if self._last_response_time and self._connection_state_before_timeout: - if time() - self._last_response_time > self._recreate_network_manager_time * self._recreate_network_manager_count: - self._recreate_network_manager_count += 1 - Logger.log("d", "Timeout lasted over 30 seconds (%.1fs), re-checking connection.", (time() - self._last_response_time)) + if time_since_last_response > self._recreate_network_manager_time * self._recreate_network_manager_count: + # It can happen that we had a very long timeout (multiple times the recreate time). + # In that case we should jump through the point that the next update won't be right away. + while time_since_last_response - self._recreate_network_manager_time * self._recreate_network_manager_count > self._recreate_network_manager_time: + self._recreate_network_manager_count += 1 + Logger.log("d", "Timeout lasted over 30 seconds (%.1fs), re-checking connection.", time_since_last_response) self._createNetworkManager() return @@ -268,9 +276,9 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): # Check that we aren't in a timeout state if self._last_response_time and not self._connection_state_before_timeout: - if time() - self._last_response_time > self._response_timeout_time: + if time_since_last_response > self._response_timeout_time: # Go into timeout state. - Logger.log("d", "We did not receive a response for %0.1f seconds, so it seems the printer is no longer accessible.", time() - self._last_response_time) + Logger.log("d", "We did not receive a response for %0.1f seconds, so it seems the printer is no longer accessible.", time_since_last_response) self._connection_state_before_timeout = self._connection_state self._connection_message = Message(i18n_catalog.i18nc("@info:status", "The connection with the printer was lost. Check your printer to see if it is connected.")) self._connection_message.show() From 357f1186da295535e54902bd68e286c1b271d346 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 7 Sep 2016 13:05:11 +0200 Subject: [PATCH 08/11] Added logging to start of uploading CURA-2295 --- NetworkPrinterOutputDevice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NetworkPrinterOutputDevice.py b/NetworkPrinterOutputDevice.py index 6f41f42e15..07c22268c0 100644 --- a/NetworkPrinterOutputDevice.py +++ b/NetworkPrinterOutputDevice.py @@ -563,7 +563,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): self._send_gcode_start = time() self._progress_message = Message(i18n_catalog.i18nc("@info:status", "Sending data to printer"), 0, False, -1) self._progress_message.show() - + Logger.log("d", "Started sending g-code to remote printer.") ## Mash the data into single string single_string_file_data = "" for line in self._gcode: From 97892273fc65e59fb4246d68fc3010f594192648 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 7 Sep 2016 14:04:23 +0200 Subject: [PATCH 09/11] Updated logging --- NetworkPrinterOutputDevice.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/NetworkPrinterOutputDevice.py b/NetworkPrinterOutputDevice.py index 07c22268c0..eade037315 100644 --- a/NetworkPrinterOutputDevice.py +++ b/NetworkPrinterOutputDevice.py @@ -155,6 +155,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): def _onAuthenticationRequired(self, reply, authenticator): if self._authentication_id is not None and self._authentication_key is not None: + Logger.log("d", "Authentication was required. Setting up authenticator.") authenticator.setUser(self._authentication_id) authenticator.setPassword(self._authentication_key) @@ -194,11 +195,13 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): # \param auth_state \type{AuthState} Enum value representing the new auth state def setAuthenticationState(self, auth_state): if auth_state == AuthState.AuthenticationRequested: + Logger.log("d", "Authentication state changed to authentication requested.") self.setAcceptsCommands(False) self.setConnectionText(i18n_catalog.i18nc("@info:status", "Connected over the network to {0} without access to control the printer.").format(self.name)) self._authentication_requested_message.show() self._authentication_timer.start() # Start timer so auth will fail after a while. elif auth_state == AuthState.Authenticated: + Logger.log("d", "Authentication state changed to authenticated") self.setAcceptsCommands(True) self.setConnectionText(i18n_catalog.i18nc("@info:status", "Connected over the network to {0}.").format(self.name)) self._authentication_requested_message.hide() @@ -211,6 +214,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): # Once we are authenticated we need to send all material profiles. self.sendMaterialProfiles() elif auth_state == AuthState.AuthenticationDenied: + Logger.log("d", "Authentication state changed to authentication denied") self.setAcceptsCommands(False) self._authentication_requested_message.hide() self._authentication_failed_message.show() @@ -606,6 +610,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): ## Check if the authentication request was allowed by the printer. def _checkAuthentication(self): + Logger.log("d", "Checking if authentication is correct.") self._manager.get(QNetworkRequest(QUrl("http://" + self._address + self._api_prefix + "auth/check/" + str(self._authentication_id)))) ## Request a authentication key from the printer so we can be authenticated @@ -801,6 +806,9 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): def _onUploadProgress(self, bytes_sent, bytes_total): if bytes_total > 0: new_progress = bytes_sent / bytes_total * 100 + # Treat upload progress as response. Uploading can take more than 10 seconds, so if we don't, we can get + # timeout responses if this happens. + self._last_response_time = time() if new_progress > self._progress_message.getProgress(): self._progress_message.show() # Ensure that the message is visible. self._progress_message.setProgress(bytes_sent / bytes_total * 100) From 1f3c8e093948aeb763ed82b636c650f8433894f2 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 7 Sep 2016 14:25:24 +0200 Subject: [PATCH 10/11] If saved authentication is wrong, it's now correctly reset CURA-2295 --- NetworkPrinterOutputDevice.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/NetworkPrinterOutputDevice.py b/NetworkPrinterOutputDevice.py index eade037315..c77ac95a3f 100644 --- a/NetworkPrinterOutputDevice.py +++ b/NetworkPrinterOutputDevice.py @@ -232,6 +232,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): self._authentication_requested_message.setProgress(0) self._authentication_id = None self._authentication_key = None + self._createNetworkManager() # Re-create network manager to force re-authentication. ## Request data from the connected device. def _update(self): @@ -394,6 +395,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): self._not_authenticated_message = Message(i18n_catalog.i18nc("@info:status", "Not authenticated to print with this machine. Unable to start a new job.")) self._not_authenticated_message.show() + Logger.log("d", "Attempting to perform an action without authentication. Auth state is %s", self._authentication_state) return Application.getInstance().showPrintMonitor.emit(True) @@ -747,7 +749,9 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): Logger.log("i", "Not authenticated. Attempting to request authentication") self._requestAuthentication() elif status_code == 403: - pass + # If we already had an auth (eg; didn't request one), we only need a single 403 to see it as denied. + if self._authentication_state != AuthState.AuthenticationRequested: + self.setAuthenticationState(AuthState.AuthenticationDenied) elif status_code == 200: self.setAuthenticationState(AuthState.Authenticated) global_container_stack = Application.getInstance().getGlobalContainerStack() From 65a2cedf9c8202524b733ad3f2f0493e51bd626e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 7 Sep 2016 15:05:07 +0200 Subject: [PATCH 11/11] Cleaned up code duplication in warning system CURA-2285 --- NetworkPrinterOutputDevice.py | 105 ++++++++++------------------------ 1 file changed, 31 insertions(+), 74 deletions(-) diff --git a/NetworkPrinterOutputDevice.py b/NetworkPrinterOutputDevice.py index c77ac95a3f..de78a03467 100644 --- a/NetworkPrinterOutputDevice.py +++ b/NetworkPrinterOutputDevice.py @@ -405,91 +405,48 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice): print_information = Application.getInstance().getPrintInformation() # Check if PrintCores / materials are loaded at all. Any failure in these results in an Error. - if print_information.materialLengths[0] != 0: # We need to print with extruder slot 1 - if self._json_printer_state["heads"][0]["extruders"][0]["hotend"]["id"] == "": - Logger.log("e", "No cartridge loaded in slot 1, unable to start print") - self._error_message = Message( - i18n_catalog.i18nc("@info:status", "Unable to start a new print job, no PowerCore loaded in slot 1")) - self._error_message.show() - return - if self._json_printer_state["heads"][0]["extruders"][0]["active_material"]["GUID"] == "": - Logger.log("e", "No material loaded in slot 1, unable to start print") - self._error_message = Message( - i18n_catalog.i18nc("@info:status", - "Unable to start a new print job, no material loaded in slot 1")) - self._error_message.show() - return - - if print_information.materialLengths[1] != 0: # We need to print with extruder slot 2 - if self._json_printer_state["heads"][0]["extruders"][1]["hotend"]["id"] == "": - Logger.log("e", "No cartridge loaded in slot 2, unable to start print") - self._error_message = Message( - i18n_catalog.i18nc("@info:status", - "Unable to start a new print job, no PowerCore loaded in slot 2")) - self._error_message.show() - return - if self._json_printer_state["heads"][0]["extruders"][1]["active_material"]["GUID"] == "": - Logger.log("e", "No material loaded in slot 2, unable to start print") - self._error_message = Message( - i18n_catalog.i18nc("@info:status", - "Unable to start a new print job, no material loaded in slot 2")) - self._error_message.show() - return + for index in range(0, self._num_extruders): + if print_information.materialLengths[index] != 0: + if self._json_printer_state["heads"][0]["extruders"][index]["hotend"]["id"] == "": + Logger.log("e", "No cartridge loaded in slot %s, unable to start print", index + 1) + self._error_message = Message( + i18n_catalog.i18nc("@info:status", "Unable to start a new print job; no PrinterCore loaded in slot {0}".format(index + 1))) + self._error_message.show() + return + if self._json_printer_state["heads"][0]["extruders"][index]["active_material"]["GUID"] == "": + Logger.log("e", "No material loaded in slot %s, unable to start print", index + 1) + self._error_message = Message( + i18n_catalog.i18nc("@info:status", + "Unable to start a new print job; no material loaded in slot {0}".format(index + 1))) + self._error_message.show() + return warnings = [] # There might be multiple things wrong. Keep a list of all the stuff we need to warn about. - # Check if there is enough material. Any failure in these results in a warning. - material_length_1 = self._json_printer_state["heads"][0]["extruders"][0]["active_material"]["length_remaining"] - if material_length_1 != -1 and print_information.materialLengths[0] > material_length_1: - warnings.append("not_enough_material_1") + for index in range(0, self._num_extruders): + # Check if there is enough material. Any failure in these results in a warning. + material_length = self._json_printer_state["heads"][0]["extruders"][index]["active_material"]["length_remaining"] + if material_length != -1 and print_information.materialLengths[index] > material_length: + warnings.append(i18n_catalog.i18nc("@label", "Not enough material for spool {0}.").format(index+1)) - material_length_2 = self._json_printer_state["heads"][0]["extruders"][1]["active_material"]["length_remaining"] - if material_length_2 != -1 and print_information.materialLengths[1] > material_length_2: - warnings.append("not_enough_material_2") - - # Check if the right cartridges are loaded. Any failure in these results in a warning. - extruder_manager = cura.Settings.ExtruderManager.getInstance() - if print_information.materialLengths[0] != 0: - variant = extruder_manager.getExtruderStack(0).findContainer({"type": "variant"}) - if variant: - if variant.getName() != self._json_printer_state["heads"][0]["extruders"][0]["hotend"]["id"]: - warnings.append("hotend_1") + # Check if the right cartridges are loaded. Any failure in these results in a warning. + extruder_manager = cura.Settings.ExtruderManager.getInstance() + if print_information.materialLengths[index] != 0: + variant = extruder_manager.getExtruderStack(0).findContainer({"type": "variant"}) + if variant: + if variant.getName() != self._json_printer_state["heads"][0]["extruders"][index]["hotend"]["id"]: + warnings.append(i18n_catalog.i18nc("@label", "Different PrintCore selected for extruder {0}".format(index + 1))) material = extruder_manager.getExtruderStack(0).findContainer({"type": "material"}) if material: - if material.getMetaDataEntry("GUID") != self._json_printer_state["heads"][0]["extruders"][0]["active_material"]["GUID"]: - warnings.append("wrong_material_1") - - if print_information.materialLengths[1] != 0: - variant = extruder_manager.getExtruderStack(1).findContainer({"type": "variant"}) - if variant: - if variant.getName() != self._json_printer_state["heads"][0]["extruders"][1]["hotend"]["id"]: - warnings.append("hotend_2") - - material = extruder_manager.getExtruderStack(1).findContainer({"type": "material"}) - if material: - if material.getMetaDataEntry("GUID") != self._json_printer_state["heads"][0]["extruders"][1]["active_material"]["GUID"]: - warnings.append("wrong_material_2") + if material.getMetaDataEntry("GUID") != self._json_printer_state["heads"][0]["extruders"][index]["active_material"]["GUID"]: + warnings.append(i18n_catalog.i18nc("@label", "Different material selected for extruder {0}").format(index + 1)) if warnings: text = i18n_catalog.i18nc("@label", "A number of configurations are mismatched. Are you sure you wish to print with the selected configuration?") detailed_text = "
    " - if "not_enough_material_1" in warnings: - detailed_text += "
  • " + i18n_catalog.i18nc("@label", "Not enough material for spool 1.") + "
  • " - if "not_enough_material_2" in warnings: - detailed_text += "
  • " + i18n_catalog.i18nc("@label", "Not enough material for spool 2.") + "
  • " - if "hotend_1" in warnings: - detailed_text += "
  • " + i18n_catalog.i18nc("@label", - "Different PrintCore selected for extruder 1") + "
  • " - if "hotend_2" in warnings: - detailed_text += "
  • " + i18n_catalog.i18nc("@label", - "Different PrintCore selected for extruder 2") + "
  • " - if "wrong_material_1" in warnings: - detailed_text += "
  • " + i18n_catalog.i18nc("@label", - "Different material selected for extruder 1") + "
  • " - if "wrong_material_2" in warnings: - detailed_text += "
  • " + i18n_catalog.i18nc("@label", - "Different material selected for extruder 1") + "
  • " + for warning in warnings: + detailed_text += "
  • " + warning + "
  • " detailed_text += "
" Application.getInstance().messageBox(i18n_catalog.i18nc("@window:title", "Mismatched configuration"),