re-implemented abort & pause for legacy um3

CL-541
This commit is contained in:
Jaime van Kessel 2017-11-24 11:26:30 +01:00
parent 57406100ef
commit 57de028608
8 changed files with 61 additions and 38 deletions

View file

@ -98,7 +98,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
if id(reply) in self._cached_multiparts: if id(reply) in self._cached_multiparts:
del self._cached_multiparts[id(reply)] del self._cached_multiparts[id(reply)]
def _put(self, target: str, data: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]]): def put(self, target: str, data: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]]):
if self._manager is None: if self._manager is None:
self._createNetworkManager() self._createNetworkManager()
request = self._createEmptyRequest(target) request = self._createEmptyRequest(target)
@ -107,7 +107,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
if onFinished is not None: if onFinished is not None:
self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished
def _get(self, target: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]]): def get(self, target: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]]):
if self._manager is None: if self._manager is None:
self._createNetworkManager() self._createNetworkManager()
request = self._createEmptyRequest(target) request = self._createEmptyRequest(target)
@ -116,13 +116,13 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
if onFinished is not None: if onFinished is not None:
self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished
def _delete(self, target: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]]): def delete(self, target: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]]):
if self._manager is None: if self._manager is None:
self._createNetworkManager() self._createNetworkManager()
self._last_request_time = time() self._last_request_time = time()
pass pass
def _post(self, target: str, data: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]], onProgress: Callable = None): def post(self, target: str, data: str, onFinished: Optional[Callable[[Any, QNetworkReply], None]], onProgress: Callable = None):
if self._manager is None: if self._manager is None:
self._createNetworkManager() self._createNetworkManager()
request = self._createEmptyRequest(target) request = self._createEmptyRequest(target)
@ -133,7 +133,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
if onFinished is not None: if onFinished is not None:
self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished
def _postForm(self, target: str, header_data: str, body_data: bytes, onFinished: Optional[Callable[[Any, QNetworkReply], None]], onProgress: Callable = None): def postForm(self, target: str, header_data: str, body_data: bytes, onFinished: Optional[Callable[[Any, QNetworkReply], None]], onProgress: Callable = None):
if self._manager is None: if self._manager is None:
self._createNetworkManager() self._createNetworkManager()
request = self._createEmptyFormRequest(target) request = self._createEmptyFormRequest(target)

View file

@ -1,7 +1,7 @@
# Copyright (c) 2017 Ultimaker B.V. # Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, pyqtSlot
MYPY = False MYPY = False
if MYPY: if MYPY:
from cura.PrinterOutput.PrinterOutputController import PrinterOutputController from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
@ -80,5 +80,6 @@ class PrintJobOutputModel(QObject):
self._state = new_state self._state = new_state
self.stateChanged.emit() self.stateChanged.emit()
@pyqtSlot(str)
def setState(self, state): def setState(self, state):
self._output_controller.setJobState(self, state) self._output_controller.setJobState(self, state)

View file

@ -1,4 +1,5 @@
# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
MYPY = False MYPY = False
if MYPY: if MYPY:
@ -8,11 +9,13 @@ if MYPY:
class PrinterOutputController: class PrinterOutputController:
def __init__(self): def __init__(self, output_device):
self.can_pause = True self.can_pause = True
self.can_abort = True self.can_abort = True
self.can_pre_heat_bed = True self.can_pre_heat_bed = True
self.can_control_manually = True self.can_control_manually = True
self._output_device = output_device
def setTargetHotendTemperature(self, printer: "PrinterOutputModel", extruder: "ExtruderOuputModel", temperature: int): def setTargetHotendTemperature(self, printer: "PrinterOutputModel", extruder: "ExtruderOuputModel", temperature: int):
# TODO: implement # TODO: implement

View file

@ -177,19 +177,19 @@ class PrinterOutputModel(QObject):
@pyqtProperty(bool, constant=True) @pyqtProperty(bool, constant=True)
def canPause(self): def canPause(self):
if self._controller: if self._controller:
return self.can_pause return self._controller.can_pause
return False return False
# Does the printer support abort at all # Does the printer support abort at all
@pyqtProperty(bool, constant=True) @pyqtProperty(bool, constant=True)
def canAbort(self): def canAbort(self):
if self._controller: if self._controller:
return self.can_abort return self._controller.can_abort
return False return False
# Does the printer support manual control at all # Does the printer support manual control at all
@pyqtProperty(bool, constant=True) @pyqtProperty(bool, constant=True)
def canControlManually(self): def canControlManually(self):
if self._controller: if self._controller:
return self.can_control_manually return self._controller.can_control_manually
return False return False

View file

@ -21,8 +21,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
def _update(self): def _update(self):
if not super()._update(): if not super()._update():
return return
self._get("printers/", onFinished=self._onGetPrintersDataFinished) self.get("printers/", onFinished=self._onGetPrintersDataFinished)
self._get("print_jobs/", onFinished=self._onGetPrintJobsFinished) self.get("print_jobs/", onFinished=self._onGetPrintJobsFinished)
def _onGetPrintJobsFinished(self, reply: QNetworkReply): def _onGetPrintJobsFinished(self, reply: QNetworkReply):
status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)

View file

@ -16,6 +16,8 @@ from PyQt5.QtNetwork import QNetworkRequest
from PyQt5.QtCore import QTimer, QCoreApplication from PyQt5.QtCore import QTimer, QCoreApplication
from PyQt5.QtWidgets import QMessageBox from PyQt5.QtWidgets import QMessageBox
from .LegacyUM3PrinterOutputController import LegacyUM3PrinterOutputController
from time import time from time import time
import json import json
@ -74,6 +76,8 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
self.setIconName("print") self.setIconName("print")
self._output_controller = LegacyUM3PrinterOutputController(self)
def _onAuthenticationStateChanged(self): def _onAuthenticationStateChanged(self):
# We only accept commands if we are authenticated. # We only accept commands if we are authenticated.
if self._authentication_state == AuthState.Authenticated: if self._authentication_state == AuthState.Authenticated:
@ -143,7 +147,7 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
continue # If it's not readonly, it's created by user, so skip it. continue # If it's not readonly, it's created by user, so skip it.
file_name = "none.xml" file_name = "none.xml"
self._postForm("materials", "form-data; name=\"file\";filename=\"%s\"" % file_name, xml_data.encode(), onFinished=None) self.postForm("materials", "form-data; name=\"file\";filename=\"%s\"" % file_name, xml_data.encode(), onFinished=None)
except NotImplementedError: except NotImplementedError:
# If the material container is not the most "generic" one it can't be serialized an will raise a # If the material container is not the most "generic" one it can't be serialized an will raise a
@ -241,7 +245,7 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
return return
file_name = "%s.gcode.gz" % Application.getInstance().getPrintInformation().jobName file_name = "%s.gcode.gz" % Application.getInstance().getPrintInformation().jobName
self._postForm("print_job", "form-data; name=\"file\";filename=\"%s\"" % file_name, compressed_gcode, self.postForm("print_job", "form-data; name=\"file\";filename=\"%s\"" % file_name, compressed_gcode,
onFinished=self._onPostPrintJobFinished) onFinished=self._onPostPrintJobFinished)
return return
@ -392,8 +396,8 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
self._checkAuthentication() self._checkAuthentication()
# We don't need authentication for requesting info, so we can go right ahead with requesting this. # We don't need authentication for requesting info, so we can go right ahead with requesting this.
self._get("printer", onFinished=self._onGetPrinterDataFinished) self.get("printer", onFinished=self._onGetPrinterDataFinished)
self._get("print_job", onFinished=self._onGetPrintJobFinished) self.get("print_job", onFinished=self._onGetPrintJobFinished)
def _resetAuthenticationRequestedMessage(self): def _resetAuthenticationRequestedMessage(self):
if self._authentication_requested_message: if self._authentication_requested_message:
@ -415,7 +419,7 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
def _verifyAuthentication(self): def _verifyAuthentication(self):
Logger.log("d", "Attempting to verify authentication") Logger.log("d", "Attempting to verify authentication")
# This will ensure that the "_onAuthenticationRequired" is triggered, which will setup the authenticator. # This will ensure that the "_onAuthenticationRequired" is triggered, which will setup the authenticator.
self._get("auth/verify", onFinished=self._onVerifyAuthenticationCompleted) self.get("auth/verify", onFinished=self._onVerifyAuthenticationCompleted)
def _onVerifyAuthenticationCompleted(self, reply): def _onVerifyAuthenticationCompleted(self, reply):
status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
@ -438,7 +442,7 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
def _checkAuthentication(self): def _checkAuthentication(self):
Logger.log("d", "Checking if authentication is correct for id %s and key %s", self._authentication_id, self._getSafeAuthKey()) Logger.log("d", "Checking if authentication is correct for id %s and key %s", self._authentication_id, self._getSafeAuthKey())
self._get("auth/check/" + str(self._authentication_id), onFinished=self._onCheckAuthenticationFinished) self.get("auth/check/" + str(self._authentication_id), onFinished=self._onCheckAuthenticationFinished)
def _onCheckAuthenticationFinished(self, reply): def _onCheckAuthenticationFinished(self, reply):
if str(self._authentication_id) not in reply.url().toString(): if str(self._authentication_id) not in reply.url().toString():
@ -511,7 +515,7 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
self._authentication_key = None self._authentication_key = None
self._authentication_id = None self._authentication_id = None
self._post("auth/request", self.post("auth/request",
json.dumps({"application": "Cura-" + Application.getInstance().getVersion(), json.dumps({"application": "Cura-" + Application.getInstance().getVersion(),
"user": self._getUserName()}).encode(), "user": self._getUserName()}).encode(),
onFinished=self._onRequestAuthenticationFinished) onFinished=self._onRequestAuthenticationFinished)
@ -542,7 +546,7 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
Logger.log("w", "Received an invalid print job state message: Not valid JSON.") Logger.log("w", "Received an invalid print job state message: Not valid JSON.")
return return
if printer.activePrintJob is None: if printer.activePrintJob is None:
print_job = PrintJobOutputModel(output_controller=None) print_job = PrintJobOutputModel(output_controller=self._output_controller)
printer.updateActivePrintJob(print_job) printer.updateActivePrintJob(print_job)
else: else:
print_job = printer.activePrintJob print_job = printer.activePrintJob
@ -567,7 +571,7 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
return return
if not self._printers: if not self._printers:
self._printers = [PrinterOutputModel(output_controller=None, number_of_extruders=self._number_of_extruders)] self._printers = [PrinterOutputModel(output_controller=self._output_controller, number_of_extruders=self._number_of_extruders)]
self.printersChanged.emit() self.printersChanged.emit()
# LegacyUM3 always has a single printer. # LegacyUM3 always has a single printer.

View file

@ -0,0 +1,13 @@
# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
class LegacyUM3PrinterOutputController(PrinterOutputController):
def __init__(self, output_device):
super().__init__(output_device)
def setJobState(self, job: "PrintJobOutputModel", state: str):
data = "{\"target\": \"%s\"}" % state
self._output_device.put("print_job/state", data, onFinished=None)

View file

@ -263,18 +263,17 @@ Item
property string lastJobState: "" property string lastJobState: ""
visible: printerConnected && activePrinter.canPause visible: printerConnected && activePrinter.canPause
enabled: (!userClicked) && printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands && enabled: (!userClicked) && printerConnected && printerAcceptsCommands && activePrintJob != null &&
(["paused", "printing"].indexOf(Cura.MachineManager.printerOutputDevices[0].jobState) >= 0) (["paused", "printing"].indexOf(activePrintJob.state) >= 0)
text: { text: {
var result = ""; var result = "";
if (!printerConnected) if (!printerConnected || activePrintJob == null)
{ {
return ""; return "";
} }
var jobState = Cura.MachineManager.printerOutputDevices[0].jobState;
if (jobState == "paused") if (activePrintJob.state == "paused")
{ {
return catalog.i18nc("@label:", "Resume"); return catalog.i18nc("@label:", "Resume");
} }
@ -285,14 +284,17 @@ Item
} }
onClicked: onClicked:
{ {
var current_job_state = Cura.MachineManager.printerOutputDevices[0].jobState if(activePrintJob == null)
if(current_job_state == "paused")
{ {
Cura.MachineManager.printerOutputDevices[0].setJobState("print"); return // Do nothing!
} }
else if(current_job_state == "printing") if(activePrintJob.state == "paused")
{ {
Cura.MachineManager.printerOutputDevices[0].setJobState("pause"); activePrintJob.setState("print");
}
else if(activePrintJob.state == "printing")
{
activePrintJob.setState("pause");
} }
} }
@ -304,8 +306,8 @@ Item
id: abortButton id: abortButton
visible: printerConnected && activePrinter.canAbort visible: printerConnected && activePrinter.canAbort
enabled: printerConnected && activePrinter.acceptsCommands && enabled: printerConnected && printerAcceptsCommands && activePrintJob != null &&
(["paused", "printing", "pre_print"].indexOf(Cura.MachineManager.printerOutputDevices[0].jobState) >= 0) (["paused", "printing", "pre_print"].indexOf(activePrintJob.state) >= 0)
height: UM.Theme.getSize("save_button_save_to_button").height height: UM.Theme.getSize("save_button_save_to_button").height
@ -324,7 +326,7 @@ Item
text: catalog.i18nc("@label", "Are you sure you want to abort the print?") text: catalog.i18nc("@label", "Are you sure you want to abort the print?")
standardButtons: StandardButton.Yes | StandardButton.No standardButtons: StandardButton.Yes | StandardButton.No
Component.onCompleted: visible = false Component.onCompleted: visible = false
onYes: Cura.MachineManager.printerOutputDevices[0].setJobState("abort") onYes: activePrintJob.setState("abort")
} }
} }
} }