LegacyUM3 now handles warnings & errors again

CL-541
This commit is contained in:
Jaime van Kessel 2017-11-23 13:37:59 +01:00
parent 96d5c7152b
commit 8b8d67b3a8
5 changed files with 166 additions and 11 deletions

View file

@ -5,12 +5,13 @@ from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant, pyqtSlot
class MaterialOutputModel(QObject): class MaterialOutputModel(QObject):
def __init__(self, guid, type, color, brand, parent = None): def __init__(self, guid, type, color, brand, name, parent = None):
super().__init__(parent) super().__init__(parent)
self._guid = guid self._guid = guid
self._type = type self._type = type
self._color = color self._color = color
self._brand = brand self._brand = brand
self._name = name
@pyqtProperty(str, constant = True) @pyqtProperty(str, constant = True)
def guid(self): def guid(self):
@ -26,4 +27,8 @@ class MaterialOutputModel(QObject):
@pyqtProperty(str, constant=True) @pyqtProperty(str, constant=True)
def color(self): def color(self):
return self._color return self._color
@pyqtProperty(str, constant=True)
def name(self):
return self._name

View file

@ -21,6 +21,7 @@ class AuthState(IntEnum):
class NetworkedPrinterOutputDevice(PrinterOutputDevice): class NetworkedPrinterOutputDevice(PrinterOutputDevice):
authenticationStateChanged = pyqtSignal() authenticationStateChanged = pyqtSignal()
def __init__(self, device_id, address: str, properties, parent = None): def __init__(self, device_id, address: str, properties, parent = None):
super().__init__(device_id = device_id, parent = parent) super().__init__(device_id = device_id, parent = parent)
self._manager = None self._manager = None
@ -41,6 +42,9 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
self._cached_multiparts = {} self._cached_multiparts = {}
def requestWrite(self, nodes, file_name=None, filter_by_machine=False, file_handler=None, **kwargs):
raise NotImplementedError("requestWrite needs to be implemented")
def setAuthenticationState(self, authentication_state): def setAuthenticationState(self, authentication_state):
if self._authentication_state != authentication_state: if self._authentication_state != authentication_state:
self._authentication_state = authentication_state self._authentication_state = authentication_state

View file

@ -11,6 +11,7 @@ MYPY = False
if MYPY: if MYPY:
from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
from cura.PrinterOutput.PrinterOutputController import PrinterOutputController from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
from cura.PrinterOutput.ExtruderOuputModel import ExtruderOutputModel
class PrinterOutputModel(QObject): class PrinterOutputModel(QObject):

View file

@ -5,13 +5,19 @@ from UM.i18n import i18nCatalog
from UM.OutputDevice.OutputDevice import OutputDevice from UM.OutputDevice.OutputDevice import OutputDevice
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer, pyqtSignal, QUrl from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer, pyqtSignal, QUrl
from PyQt5.QtQml import QQmlComponent, QQmlContext from PyQt5.QtQml import QQmlComponent, QQmlContext
from enum import IntEnum # For the connection state tracking.
from UM.Logger import Logger from UM.Logger import Logger
from UM.Signal import signalemitter from UM.Signal import signalemitter
from UM.Application import Application from UM.Application import Application
import os import os
from enum import IntEnum # For the connection state tracking.
from typing import List, Optional
MYPY = False
if MYPY:
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
i18n_catalog = i18nCatalog("cura") i18n_catalog = i18nCatalog("cura")
@ -32,7 +38,7 @@ class PrinterOutputDevice(QObject, OutputDevice):
def __init__(self, device_id, parent = None): def __init__(self, device_id, parent = None):
super().__init__(device_id = device_id, parent = parent) super().__init__(device_id = device_id, parent = parent)
self._printers = [] self._printers = [] # type: List[PrinterOutputModel]
self._monitor_view_qml_path = "" self._monitor_view_qml_path = ""
self._monitor_component = None self._monitor_component = None
@ -62,20 +68,19 @@ class PrinterOutputDevice(QObject, OutputDevice):
def _update(self): def _update(self):
pass pass
def _getPrinterByKey(self, key): def _getPrinterByKey(self, key) -> Optional["PrinterOutputModel"]:
for printer in self._printers: for printer in self._printers:
if printer.key == key: if printer.key == key:
return printer return printer
return None return None
def requestWrite(self, nodes, file_name = None, filter_by_machine = False, file_handler = None): def requestWrite(self, nodes, file_name = None, filter_by_machine = False, file_handler = None, **kwargs):
raise NotImplementedError("requestWrite needs to be implemented") raise NotImplementedError("requestWrite needs to be implemented")
@pyqtProperty(QObject, notify = printersChanged) @pyqtProperty(QObject, notify = printersChanged)
def activePrinter(self): def activePrinter(self) -> Optional["PrinterOutputModel"]:
if len(self._printers): if len(self._printers):
return self._printers[0] return self._printers[0]
return None return None

View file

@ -4,6 +4,7 @@ from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
from cura.Settings.ContainerManager import ContainerManager from cura.Settings.ContainerManager import ContainerManager
from cura.Settings.ExtruderManager import ExtruderManager
from UM.Logger import Logger from UM.Logger import Logger
from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerRegistry import ContainerRegistry
@ -13,6 +14,7 @@ from UM.Message import Message
from PyQt5.QtNetwork import QNetworkRequest from PyQt5.QtNetwork import QNetworkRequest
from PyQt5.QtCore import QTimer from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QMessageBox
import json import json
import os # To get the username import os # To get the username
@ -122,8 +124,144 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
# NotImplementedError. We can simply ignore these. # NotImplementedError. We can simply ignore these.
pass pass
# TODO def requestWrite(self, nodes, file_name=None, filter_by_machine=False, file_handler=None, **kwargs):
pass if not self.activePrinter:
# No active printer. Unable to write
return
if self.activePrinter.printerState not in ["idle", ""]:
# Printer is not able to accept commands.
return
if self._authentication_state != AuthState.Authenticated:
# Not authenticated, so unable to send job.
return
# Notify the UI that a switch to the print monitor should happen
Application.getInstance().showPrintMonitor.emit(True)
self.writeStarted.emit(self)
gcode = getattr(Application.getInstance().getController().getScene(), "gcode_list", None)
if gcode is None:
# Unable to find g-code. Nothing to send
return
errors = self._checkForErrors()
if errors:
text = i18n_catalog.i18nc("@label", "Unable to start a new print job.")
informative_text = i18n_catalog.i18nc("@label",
"There is an issue with the configuration of your Ultimaker, which makes it impossible to start the print. "
"Please resolve this issues before continuing.")
detailed_text = ""
for error in errors:
detailed_text += error + "\n"
Application.getInstance().messageBox(i18n_catalog.i18nc("@window:title", "Mismatched configuration"),
text,
informative_text,
detailed_text,
buttons=QMessageBox.Ok,
icon=QMessageBox.Critical,
callback = self._messageBoxCallback
)
return # Don't continue; Errors must block sending the job to the printer.
# There might be multiple things wrong with the configuration. Check these before starting.
warnings = self._checkForWarnings()
if warnings:
text = i18n_catalog.i18nc("@label", "Are you sure you wish to print with the selected configuration?")
informative_text = i18n_catalog.i18nc("@label",
"There is a mismatch between the configuration or calibration of the printer and Cura. "
"For the best result, always slice for the PrintCores and materials that are inserted in your printer.")
detailed_text = ""
for warning in warnings:
detailed_text += warning + "\n"
Application.getInstance().messageBox(i18n_catalog.i18nc("@window:title", "Mismatched configuration"),
text,
informative_text,
detailed_text,
buttons=QMessageBox.Yes + QMessageBox.No,
icon=QMessageBox.Question,
callback=self._messageBoxCallback
)
return
# No warnings or errors, so we're good to go.
self._startPrint()
def _startPrint(self):
# TODO: Implement
Logger.log("i", "Sending print job to printer.")
return
def _messageBoxCallback(self, button):
def delayedCallback():
if button == QMessageBox.Yes:
self._startPrint()
else:
Application.getInstance().showPrintMonitor.emit(False)
# For some unknown reason Cura on OSX will hang if we do the call back code
# immediately without first returning and leaving QML's event system.
QTimer.singleShot(100, delayedCallback)
def _checkForErrors(self):
errors = []
print_information = Application.getInstance().getPrintInformation()
if not print_information.materialLengths:
Logger.log("w", "There is no material length information. Unable to check for errors.")
return errors
for index, extruder in enumerate(self.activePrinter.extruders):
# Due to airflow issues, both slots must be loaded, regardless if they are actually used or not.
if extruder.hotendID == "":
# No Printcore loaded.
errors.append(i18n_catalog.i18nc("@info:status", "No Printcore loaded in slot {slot_number}".format(slot_number=index + 1)))
if index < len(print_information.materialLengths) and print_information.materialLengths[index] != 0:
# The extruder is by this print.
if extruder.activeMaterial is None:
# No active material
errors.append(i18n_catalog.i18nc("@info:status", "No material loaded in slot {slot_number}".format(slot_number=index + 1)))
return errors
def _checkForWarnings(self):
warnings = []
print_information = Application.getInstance().getPrintInformation()
if not print_information.materialLengths:
Logger.log("w", "There is no material length information. Unable to check for warnings.")
return warnings
extruder_manager = ExtruderManager.getInstance()
for index, extruder in enumerate(self.activePrinter.extruders):
if index < len(print_information.materialLengths) and print_information.materialLengths[index] != 0:
# The extruder is by this print.
# TODO: material length check
# Check if the right Printcore is active.
variant = extruder_manager.getExtruderStack(index).findContainer({"type": "variant"})
if variant:
if variant.getName() != extruder.hotendID:
warnings.append(i18n_catalog.i18nc("@label", "Different PrintCore (Cura: {cura_printcore_name}, Printer: {remote_printcore_name}) selected for extruder {extruder_id}".format(cura_printcore_name = variant.getName(), remote_printcore_name = extruder.hotendID, extruder_id = index + 1)))
else:
Logger.log("w", "Unable to find variant.")
# Check if the right material is loaded.
local_material = extruder_manager.getExtruderStack(index).findContainer({"type": "material"})
if local_material:
if extruder.activeMaterial.guid != local_material.getMetaDataEntry("GUID"):
Logger.log("w", "Extruder %s has a different material (%s) as Cura (%s)", index + 1, extruder.activeMaterial.guid, local_material.getMetaDataEntry("GUID"))
warnings.append(i18n_catalog.i18nc("@label", "Different material (Cura: {0}, Printer: {1}) selected for extruder {2}").format(local_material.getName(), extruder.activeMaterial.name, index + 1))
else:
Logger.log("w", "Unable to find material.")
return warnings
def _update(self): def _update(self):
if not super()._update(): if not super()._update():
@ -339,13 +477,15 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
color = containers[0].getMetaDataEntry("color_code") color = containers[0].getMetaDataEntry("color_code")
brand = containers[0].getMetaDataEntry("brand") brand = containers[0].getMetaDataEntry("brand")
material_type = containers[0].getMetaDataEntry("material") material_type = containers[0].getMetaDataEntry("material")
name = containers[0].getName()
else: else:
# Unknown material. # Unknown material.
color = "#00000000" color = "#00000000"
brand = "Unknown" brand = "Unknown"
material_type = "Unknown" material_type = "Unknown"
name = "Unknown"
material = MaterialOutputModel(guid=material_guid, type=material_type, material = MaterialOutputModel(guid=material_guid, type=material_type,
brand=brand, color=color) brand=brand, color=color, name = name)
extruder.updateActiveMaterial(material) extruder.updateActiveMaterial(material)
try: try: