From 9754aa5397b494b699b119b7e3fefe4f2f5a633a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 21 Dec 2017 13:16:44 +0100 Subject: [PATCH] Material & hotend updated callback is enabled for LegacyUM3 again CL-541 --- cura/PrinterOutputDevice.py | 15 ++- cura/Settings/MachineManager.py | 116 ++++++++++-------- .../LegacyUM3OutputDevice.py | 15 ++- .../UM3OutputDevicePlugin.py | 3 +- 4 files changed, 91 insertions(+), 58 deletions(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 458d0a1080..b4e67f6297 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -3,15 +3,14 @@ from UM.i18n import i18nCatalog from UM.OutputDevice.OutputDevice import OutputDevice -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer, pyqtSignal, QUrl -from PyQt5.QtQml import QQmlComponent, QQmlContext +from PyQt5.QtCore import pyqtProperty, QObject, QTimer, pyqtSignal +from PyQt5.QtWidgets import QMessageBox from UM.Logger import Logger from UM.Signal import signalemitter from UM.Application import Application -import os from enum import IntEnum # For the connection state tracking. from typing import List, Optional @@ -36,6 +35,12 @@ class PrinterOutputDevice(QObject, OutputDevice): connectionStateChanged = pyqtSignal(str) acceptsCommandsChanged = pyqtSignal() + # Signal to indicate that the material of the active printer on the remote changed. + materialIdChanged = pyqtSignal() + + # # Signal to indicate that the hotend of the active printer on the remote changed. + hotendIdChanged = pyqtSignal() + def __init__(self, device_id, parent = None): super().__init__(device_id = device_id, parent = parent) @@ -59,6 +64,10 @@ class PrinterOutputDevice(QObject, OutputDevice): self._connection_state = ConnectionState.closed + def materialHotendChangedMessage(self, callback): + Logger.log("w", "materialHotendChangedMessage needs to be implemented, returning 'Yes'") + callback(QMessageBox.Yes) + def isConnected(self): return self._connection_state != ConnectionState.closed and self._connection_state != ConnectionState.error diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index e78c0b9d97..50ab26f9df 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -117,7 +117,7 @@ class MachineManager(QObject): self._auto_hotends_changed = {} self._material_incompatible_message = Message(catalog.i18nc("@info:status", - "The selected material is incompatible with the selected machine or configuration."), + "The selected material is incompatible with the selected machine or configuration."), title = catalog.i18nc("@info:title", "Incompatible Material")) containers = ContainerRegistry.getInstance().findInstanceContainers(id = self.activeMaterialId) @@ -135,21 +135,21 @@ class MachineManager(QObject): activeStackValidationChanged = pyqtSignal() # Emitted whenever a validation inside active container is changed stacksValidationChanged = pyqtSignal() # Emitted whenever a validation is changed - blurSettings = pyqtSignal() # Emitted to force fields in the advanced sidebar to un-focus, so they update properly + blurSettings = pyqtSignal() # Emitted to force fields in the advanced sidebar to un-focus, so they update properly outputDevicesChanged = pyqtSignal() def _onOutputDevicesChanged(self) -> None: - '''for printer_output_device in self._printer_output_devices: + for printer_output_device in self._printer_output_devices: printer_output_device.hotendIdChanged.disconnect(self._onHotendIdChanged) - printer_output_device.materialIdChanged.disconnect(self._onMaterialIdChanged)''' + printer_output_device.materialIdChanged.disconnect(self._onMaterialIdChanged) self._printer_output_devices = [] for printer_output_device in Application.getInstance().getOutputDeviceManager().getOutputDevices(): if isinstance(printer_output_device, PrinterOutputDevice): self._printer_output_devices.append(printer_output_device) - #printer_output_device.hotendIdChanged.connect(self._onHotendIdChanged) - #printer_output_device.materialIdChanged.connect(self._onMaterialIdChanged) + printer_output_device.hotendIdChanged.connect(self._onHotendIdChanged) + printer_output_device.materialIdChanged.connect(self._onMaterialIdChanged) self.outputDevicesChanged.emit() @@ -169,58 +169,70 @@ class MachineManager(QObject): def totalNumberOfSettings(self) -> int: return len(ContainerRegistry.getInstance().findDefinitionContainers(id = "fdmprinter")[0].getAllKeys()) - def _onHotendIdChanged(self, index: Union[str, int], hotend_id: str) -> None: - if not self._global_container_stack: + def _onHotendIdChanged(self): + if not self._global_container_stack or not self._printer_output_devices: + return + + active_printer_model = self._printer_output_devices[0].activePrinter + if not active_printer_model: return - containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(type = "variant", definition = self._global_container_stack.definition.getId(), name = hotend_id) - if containers: # New material ID is known - extruder_manager = ExtruderManager.getInstance() - machine_id = self.activeMachineId - extruders = extruder_manager.getMachineExtruders(machine_id) - matching_extruder = None - for extruder in extruders: - if str(index) == extruder.getMetaDataEntry("position"): - matching_extruder = extruder - break - if matching_extruder and matching_extruder.variant.getName() != hotend_id: - # Save the material that needs to be changed. Multiple changes will be handled by the callback. - self._auto_hotends_changed[str(index)] = containers[0]["id"] - self._printer_output_devices[0].materialHotendChangedMessage(self._materialHotendChangedCallback) - else: - Logger.log("w", "No variant found for printer definition %s with id %s" % (self._global_container_stack.definition.getId(), hotend_id)) + change_found = False + machine_id = self.activeMachineId + extruders = sorted(ExtruderManager.getInstance().getMachineExtruders(machine_id), + key=lambda k: k.getMetaDataEntry("position")) - def _onMaterialIdChanged(self, index: Union[str, int], material_id: str): - if not self._global_container_stack: + for extruder_model, extruder in zip(active_printer_model.extruders, extruders): + containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(type="variant", + definition=self._global_container_stack.definition.getId(), + name=extruder_model.hotendID) + if containers: + # The hotend ID is known. + machine_id = self.activeMachineId + if extruder.variant.getName() != extruder_model.hotendID: + change_found = True + self._auto_hotends_changed[extruder.getMetaDataEntry("position")] = containers[0]["id"] + + if change_found: + # A change was found, let the output device handle this. + self._printer_output_devices[0].materialHotendChangedMessage(self._materialHotendChangedCallback) + + def _onMaterialIdChanged(self): + if not self._global_container_stack or not self._printer_output_devices: return - definition_id = "fdmprinter" - if self._global_container_stack.getMetaDataEntry("has_machine_materials", False): - definition_id = self.activeQualityDefinitionId - extruder_manager = ExtruderManager.getInstance() - containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(type = "material", definition = definition_id, GUID = material_id) - if containers: # New material ID is known - extruders = list(extruder_manager.getMachineExtruders(self.activeMachineId)) - matching_extruder = None - for extruder in extruders: - if str(index) == extruder.getMetaDataEntry("position"): - matching_extruder = extruder - break + active_printer_model = self._printer_output_devices[0].activePrinter + if not active_printer_model: + return - if matching_extruder and matching_extruder.material.getMetaDataEntry("GUID") != material_id: - # Save the material that needs to be changed. Multiple changes will be handled by the callback. - if self._global_container_stack.definition.getMetaDataEntry("has_variants") and matching_extruder.variant: - variant_id = self.getQualityVariantId(self._global_container_stack.definition, matching_extruder.variant) - for container in containers: - if container.get("variant") == variant_id: - self._auto_materials_changed[str(index)] = container["id"] - break - else: - # Just use the first result we found. - self._auto_materials_changed[str(index)] = containers[0]["id"] - self._printer_output_devices[0].materialHotendChangedMessage(self._materialHotendChangedCallback) - else: - Logger.log("w", "No material definition found for printer definition %s and GUID %s" % (definition_id, material_id)) + change_found = False + machine_id = self.activeMachineId + extruders = sorted(ExtruderManager.getInstance().getMachineExtruders(machine_id), + key=lambda k: k.getMetaDataEntry("position")) + + for extruder_model, extruder in zip(active_printer_model.extruders, extruders): + if extruder_model.activeMaterial is None: + continue + containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(type="material", + definition=self._global_container_stack.definition.getId(), + GUID=extruder_model.activeMaterial.guid) + if containers: + # The material is known. + if extruder.material.getMetaDataEntry("GUID") != extruder_model.activeMaterial.guid: + change_found = True + if self._global_container_stack.definition.getMetaDataEntry("has_variants") and extruder.variant: + variant_id = self.getQualityVariantId(self._global_container_stack.definition, + extruder.variant) + for container in containers: + if container.get("variant") == variant_id: + self._auto_materials_changed[extruder.getMetaDataEntry("position")] = container["id"] + break + else: + # Just use the first result we found. + self._auto_materials_changed[extruder.getMetaDataEntry("position")] = containers[0]["id"] + if change_found: + # A change was found, let the output device handle this. + self._printer_output_devices[0].materialHotendChangedMessage(self._materialHotendChangedCallback) def _materialHotendChangedCallback(self, button): if button == QMessageBox.No: diff --git a/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py b/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py index d0b8f139f1..ce87eaba16 100644 --- a/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py @@ -404,7 +404,6 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): Logger.log("d", "While trying to verify the authentication state, we got a forbidden response. Our own auth state was %s. ", self._authentication_state) - print(reply.readAll()) self.setAuthenticationState(AuthState.AuthenticationDenied) self._authentication_failed_message.show() elif status_code == 200: @@ -533,6 +532,17 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): Logger.log("w", "Got status code {status_code} while trying to get printer data".format(status_code=status_code)) + def materialHotendChangedMessage(self, callback): + Application.getInstance().messageBox(i18n_catalog.i18nc("@window:title", "Sync with your printer"), + i18n_catalog.i18nc("@label", + "Would you like to use your current printer configuration in Cura?"), + i18n_catalog.i18nc("@label", + "The PrintCores and/or materials on your printer differ from those within your current project. For the best result, always slice for the PrintCores and materials that are inserted in your printer."), + buttons=QMessageBox.Yes + QMessageBox.No, + icon=QMessageBox.Question, + callback=callback + ) + def _onGetPrinterDataFinished(self, reply): status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) if status_code == 200: @@ -547,6 +557,9 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): firmware_version = self._properties.get(b"firmware_version", b"").decode("utf-8") self._printers = [PrinterOutputModel(output_controller=self._output_controller, number_of_extruders=self._number_of_extruders, firmware_version=firmware_version)] self._printers[0].setCamera(NetworkCamera("http://" + self._address + ":8080/?action=stream")) + for extruder in self._printers[0].extruders: + extruder.activeMaterialChanged.connect(self.materialIdChanged) + extruder.hotendIDChanged.connect(self.hotendIdChanged) self.printersChanged.emit() # LegacyUM3 always has a single printer. diff --git a/plugins/UM3NetworkPrinting/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/UM3OutputDevicePlugin.py index 2e1fe4db6f..6bd1c24464 100644 --- a/plugins/UM3NetworkPrinting/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/UM3OutputDevicePlugin.py @@ -235,8 +235,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): # Check what kind of device we need to add; Depending on the firmware we either add a "Connect"/"Cluster" # or "Legacy" UM3 device. cluster_size = int(properties.get(b"cluster_size", -1)) - # TODO: For debug purposes; force it to be legacy printer. - #device = LegacyUM3OutputDevice.LegacyUM3OutputDevice(name, address, properties) + if cluster_size > 0: device = ClusterUM3OutputDevice.ClusterUM3OutputDevice(name, address, properties) else: