mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-08 07:27:29 -06:00
Cluster monitor page now shows queue instead of added printers
CL-894
This commit is contained in:
parent
d46c754616
commit
78ebdb13f4
9 changed files with 224 additions and 44 deletions
|
@ -123,7 +123,7 @@ except ImportError:
|
||||||
CuraVersion = "master" # [CodeStyle: Reflecting imported value]
|
CuraVersion = "master" # [CodeStyle: Reflecting imported value]
|
||||||
CuraBuildType = ""
|
CuraBuildType = ""
|
||||||
CuraDebugMode = False
|
CuraDebugMode = False
|
||||||
CuraSDKVerion = ""
|
CuraSDKVersion = ""
|
||||||
|
|
||||||
|
|
||||||
class CuraApplication(QtApplication):
|
class CuraApplication(QtApplication):
|
||||||
|
|
|
@ -30,7 +30,7 @@ class ExtruderConfigurationModel(QObject):
|
||||||
self.extruderConfigurationChanged.emit()
|
self.extruderConfigurationChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty(QObject, fset = setMaterial, notify = extruderConfigurationChanged)
|
@pyqtProperty(QObject, fset = setMaterial, notify = extruderConfigurationChanged)
|
||||||
def material(self) -> MaterialOutputModel:
|
def activeMaterial(self) -> MaterialOutputModel:
|
||||||
return self._material
|
return self._material
|
||||||
|
|
||||||
def setHotendID(self, hotend_id: Optional[str]) -> None:
|
def setHotendID(self, hotend_id: Optional[str]) -> None:
|
||||||
|
@ -52,7 +52,7 @@ class ExtruderConfigurationModel(QObject):
|
||||||
message_chunks = []
|
message_chunks = []
|
||||||
message_chunks.append("Position: " + str(self._position))
|
message_chunks.append("Position: " + str(self._position))
|
||||||
message_chunks.append("-")
|
message_chunks.append("-")
|
||||||
message_chunks.append("Material: " + self.material.type if self.material else "empty")
|
message_chunks.append("Material: " + self.activeMaterial.type if self.activeMaterial else "empty")
|
||||||
message_chunks.append("-")
|
message_chunks.append("-")
|
||||||
message_chunks.append("HotendID: " + self.hotendID if self.hotendID else "empty")
|
message_chunks.append("HotendID: " + self.hotendID if self.hotendID else "empty")
|
||||||
return " ".join(message_chunks)
|
return " ".join(message_chunks)
|
||||||
|
|
|
@ -48,7 +48,7 @@ class ExtruderOutputModel(QObject):
|
||||||
|
|
||||||
@pyqtProperty(QObject, notify = extruderConfigurationChanged)
|
@pyqtProperty(QObject, notify = extruderConfigurationChanged)
|
||||||
def activeMaterial(self) -> Optional["MaterialOutputModel"]:
|
def activeMaterial(self) -> Optional["MaterialOutputModel"]:
|
||||||
return self._extruder_configuration.material
|
return self._extruder_configuration.activeMaterial
|
||||||
|
|
||||||
def updateActiveMaterial(self, material: Optional["MaterialOutputModel"]):
|
def updateActiveMaterial(self, material: Optional["MaterialOutputModel"]):
|
||||||
self._extruder_configuration.setMaterial(material)
|
self._extruder_configuration.setMaterial(material)
|
||||||
|
@ -111,4 +111,4 @@ class ExtruderOutputModel(QObject):
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def cancelPreheatHotend(self) -> None:
|
def cancelPreheatHotend(self) -> None:
|
||||||
self._printer._controller.cancelPreheatHotend(self)
|
self._printer._controller.cancelPreheatHotend(self)
|
||||||
|
|
|
@ -7,6 +7,7 @@ from typing import Optional, TYPE_CHECKING
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
|
from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
|
||||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
||||||
|
from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
|
||||||
|
|
||||||
|
|
||||||
class PrintJobOutputModel(QObject):
|
class PrintJobOutputModel(QObject):
|
||||||
|
@ -17,6 +18,7 @@ class PrintJobOutputModel(QObject):
|
||||||
keyChanged = pyqtSignal()
|
keyChanged = pyqtSignal()
|
||||||
assignedPrinterChanged = pyqtSignal()
|
assignedPrinterChanged = pyqtSignal()
|
||||||
ownerChanged = pyqtSignal()
|
ownerChanged = pyqtSignal()
|
||||||
|
configurationChanged =pyqtSignal()
|
||||||
|
|
||||||
def __init__(self, output_controller: "PrinterOutputController", key: str = "", name: str = "", parent=None) -> None:
|
def __init__(self, output_controller: "PrinterOutputController", key: str = "", name: str = "", parent=None) -> None:
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
@ -29,6 +31,17 @@ class PrintJobOutputModel(QObject):
|
||||||
self._assigned_printer = None # type: Optional[PrinterOutputModel]
|
self._assigned_printer = None # type: Optional[PrinterOutputModel]
|
||||||
self._owner = "" # Who started/owns the print job?
|
self._owner = "" # Who started/owns the print job?
|
||||||
|
|
||||||
|
self._configuration = None # type: Optional[ConfigurationModel]
|
||||||
|
|
||||||
|
@pyqtProperty(QObject, notify=configurationChanged)
|
||||||
|
def configuration(self) -> Optional["ConfigurationModel"]:
|
||||||
|
return self._configuration
|
||||||
|
|
||||||
|
def updateConfiguration(self, configuration: Optional["ConfigurationModel"]) -> None:
|
||||||
|
if self._configuration != configuration:
|
||||||
|
self._configuration = configuration
|
||||||
|
self.configurationChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty(str, notify=ownerChanged)
|
@pyqtProperty(str, notify=ownerChanged)
|
||||||
def owner(self):
|
def owner(self):
|
||||||
return self._owner
|
return self._owner
|
||||||
|
|
|
@ -27,13 +27,14 @@ Component
|
||||||
{
|
{
|
||||||
id: activePrintersLabel
|
id: activePrintersLabel
|
||||||
font: UM.Theme.getFont("large")
|
font: UM.Theme.getFont("large")
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors
|
||||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
{
|
||||||
anchors.top: parent.top
|
margins: UM.Theme.getSize("default_margin").width
|
||||||
anchors.left: parent.left
|
top: parent.top
|
||||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
left: parent.left
|
||||||
anchors.right:parent.right
|
right: parent.right
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
}
|
||||||
|
|
||||||
text: Cura.MachineManager.printerOutputDevices[0].name
|
text: Cura.MachineManager.printerOutputDevices[0].name
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,8 @@ Component
|
||||||
id: activePrintersLabel
|
id: activePrintersLabel
|
||||||
font: UM.Theme.getFont("large")
|
font: UM.Theme.getFont("large")
|
||||||
|
|
||||||
anchors {
|
anchors
|
||||||
|
{
|
||||||
top: parent.top
|
top: parent.top
|
||||||
topMargin: UM.Theme.getSize("default_margin").height * 2 // a bit more spacing to give it some breathing room
|
topMargin: UM.Theme.getSize("default_margin").height * 2 // a bit more spacing to give it some breathing room
|
||||||
horizontalCenter: parent.horizontalCenter
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
@ -71,25 +72,28 @@ Component
|
||||||
|
|
||||||
ScrollView
|
ScrollView
|
||||||
{
|
{
|
||||||
id: printerScrollView
|
id: queuedPrintJobs
|
||||||
anchors.margins: UM.Theme.getSize("default_margin").width
|
|
||||||
anchors.top: activePrintersLabel.bottom
|
anchors
|
||||||
anchors.bottom: parent.bottom
|
{
|
||||||
anchors.left: parent.left
|
margins: UM.Theme.getSize("default_margin").width
|
||||||
anchors.leftMargin: UM.Theme.getSize("default_lining").width // To ensure border can be drawn.
|
top: activePrintersLabel.bottom
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_lining").width
|
left: parent.left
|
||||||
anchors.right: parent.right
|
leftMargin: UM.Theme.getSize("default_lining").width // To ensure border can be drawn.
|
||||||
|
rightMargin: UM.Theme.getSize("default_lining").width
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
|
||||||
ListView
|
ListView
|
||||||
{
|
{
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: -UM.Theme.getSize("default_lining").height
|
spacing: -UM.Theme.getSize("default_lining").height
|
||||||
|
|
||||||
model: OutputDevice.printers
|
model: OutputDevice.queuedPrintJobs
|
||||||
|
|
||||||
delegate: PrinterInfoBlock
|
delegate: PrintJobInfoBlock
|
||||||
{
|
{
|
||||||
printer: modelData
|
printJob: modelData
|
||||||
width: Math.min(800 * screenScaleFactor, maximumWidth)
|
width: Math.min(800 * screenScaleFactor, maximumWidth)
|
||||||
height: 125 * screenScaleFactor
|
height: 125 * screenScaleFactor
|
||||||
|
|
||||||
|
@ -102,7 +106,7 @@ Component
|
||||||
PrinterVideoStream
|
PrinterVideoStream
|
||||||
{
|
{
|
||||||
visible: OutputDevice.activePrinter != null
|
visible: OutputDevice.activePrinter != null
|
||||||
anchors.fill:parent
|
anchors.fill: parent
|
||||||
}
|
}
|
||||||
|
|
||||||
onVisibleChanged:
|
onVisibleChanged:
|
||||||
|
|
|
@ -17,6 +17,8 @@ from UM.Scene.SceneNode import SceneNode #For typing.
|
||||||
from UM.Version import Version #To check against firmware versions for support.
|
from UM.Version import Version #To check against firmware versions for support.
|
||||||
|
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication
|
||||||
|
from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
|
||||||
|
from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel
|
||||||
from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState
|
from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState
|
||||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
||||||
from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
|
from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
|
||||||
|
@ -478,6 +480,23 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
||||||
def _createPrintJobModel(self, data: Dict[str, Any]) -> PrintJobOutputModel:
|
def _createPrintJobModel(self, data: Dict[str, Any]) -> PrintJobOutputModel:
|
||||||
print_job = PrintJobOutputModel(output_controller=ClusterUM3PrinterOutputController(self),
|
print_job = PrintJobOutputModel(output_controller=ClusterUM3PrinterOutputController(self),
|
||||||
key=data["uuid"], name= data["name"])
|
key=data["uuid"], name= data["name"])
|
||||||
|
|
||||||
|
configuration = ConfigurationModel()
|
||||||
|
extruders = []
|
||||||
|
for index in range(0, self._number_of_extruders):
|
||||||
|
extruder = ExtruderConfigurationModel()
|
||||||
|
extruder.setPosition(index)
|
||||||
|
try:
|
||||||
|
extruder_data = data["configuration"][index]
|
||||||
|
except IndexError:
|
||||||
|
break
|
||||||
|
|
||||||
|
extruder.setHotendID(extruder_data.get("print_core_id", ""))
|
||||||
|
extruder.setMaterial(self._createMaterialOutputModel(extruder_data.get("material", {})))
|
||||||
|
extruders.append(extruder)
|
||||||
|
configuration.setExtruderConfigurations(extruders)
|
||||||
|
print_job.updateConfiguration(configuration)
|
||||||
|
|
||||||
print_job.stateChanged.connect(self._printJobStateChanged)
|
print_job.stateChanged.connect(self._printJobStateChanged)
|
||||||
self._print_jobs.append(print_job)
|
self._print_jobs.append(print_job)
|
||||||
return print_job
|
return print_job
|
||||||
|
@ -488,6 +507,24 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
||||||
print_job.updateState(data["status"])
|
print_job.updateState(data["status"])
|
||||||
print_job.updateOwner(data["owner"])
|
print_job.updateOwner(data["owner"])
|
||||||
|
|
||||||
|
def _createMaterialOutputModel(self, material_data) -> MaterialOutputModel:
|
||||||
|
containers = ContainerRegistry.getInstance().findInstanceContainers(type="material", GUID=material_data["guid"])
|
||||||
|
if containers:
|
||||||
|
color = containers[0].getMetaDataEntry("color_code")
|
||||||
|
brand = containers[0].getMetaDataEntry("brand")
|
||||||
|
material_type = containers[0].getMetaDataEntry("material")
|
||||||
|
name = containers[0].getName()
|
||||||
|
else:
|
||||||
|
Logger.log("w",
|
||||||
|
"Unable to find material with guid {guid}. Using data as provided by cluster".format(
|
||||||
|
guid=material_data["guid"]))
|
||||||
|
color = material_data["color"]
|
||||||
|
brand = material_data["brand"]
|
||||||
|
material_type = material_data["material"]
|
||||||
|
name = "Empty" if material_data["material"] == "empty" else "Unknown"
|
||||||
|
return MaterialOutputModel(guid=material_data["guid"], type=material_type,
|
||||||
|
brand=brand, color=color, name=name)
|
||||||
|
|
||||||
def _updatePrinter(self, printer: PrinterOutputModel, data: Dict[str, Any]) -> None:
|
def _updatePrinter(self, printer: PrinterOutputModel, data: Dict[str, Any]) -> None:
|
||||||
# For some unknown reason the cluster wants UUID for everything, except for sending a job directly to a printer.
|
# For some unknown reason the cluster wants UUID for everything, except for sending a job directly to a printer.
|
||||||
# Then we suddenly need the unique name. So in order to not have to mess up all the other code, we save a mapping.
|
# Then we suddenly need the unique name. So in order to not have to mess up all the other code, we save a mapping.
|
||||||
|
@ -523,24 +560,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
||||||
|
|
||||||
material_data = extruder_data["material"]
|
material_data = extruder_data["material"]
|
||||||
if extruder.activeMaterial is None or extruder.activeMaterial.guid != material_data["guid"]:
|
if extruder.activeMaterial is None or extruder.activeMaterial.guid != material_data["guid"]:
|
||||||
containers = ContainerRegistry.getInstance().findInstanceContainers(type="material",
|
material = self._createMaterialOutputModel(material_data)
|
||||||
GUID=material_data["guid"])
|
|
||||||
if containers:
|
|
||||||
color = containers[0].getMetaDataEntry("color_code")
|
|
||||||
brand = containers[0].getMetaDataEntry("brand")
|
|
||||||
material_type = containers[0].getMetaDataEntry("material")
|
|
||||||
name = containers[0].getName()
|
|
||||||
else:
|
|
||||||
Logger.log("w",
|
|
||||||
"Unable to find material with guid {guid}. Using data as provided by cluster".format(
|
|
||||||
guid=material_data["guid"]))
|
|
||||||
color = material_data["color"]
|
|
||||||
brand = material_data["brand"]
|
|
||||||
material_type = material_data["material"]
|
|
||||||
name = "Empty" if material_data["material"] == "empty" else "Unknown"
|
|
||||||
|
|
||||||
material = MaterialOutputModel(guid=material_data["guid"], type=material_type,
|
|
||||||
brand=brand, color=color, name=name)
|
|
||||||
extruder.updateActiveMaterial(material)
|
extruder.updateActiveMaterial(material)
|
||||||
|
|
||||||
def _removeJob(self, job: PrintJobOutputModel) -> bool:
|
def _removeJob(self, job: PrintJobOutputModel) -> bool:
|
||||||
|
|
|
@ -12,14 +12,16 @@ Item
|
||||||
|
|
||||||
width: Math.round(parent.width / 2)
|
width: Math.round(parent.width / 2)
|
||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
|
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
id: materialLabel
|
id: materialLabel
|
||||||
text: printCoreConfiguration.activeMaterial != null ? printCoreConfiguration.activeMaterial.name : ""
|
text: printCoreConfiguration.activeMaterial != null ? printCoreConfiguration.activeMaterial.name : ":("
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
width: parent.width
|
width: parent.width
|
||||||
font: UM.Theme.getFont("very_small")
|
font: UM.Theme.getFont("very_small")
|
||||||
}
|
}
|
||||||
|
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
id: printCoreLabel
|
id: printCoreLabel
|
||||||
|
|
140
plugins/UM3NetworkPrinting/PrintJobInfoBlock.qml
Normal file
140
plugins/UM3NetworkPrinting/PrintJobInfoBlock.qml
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
import QtQuick 2.2
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
|
import QtQuick.Controls.Styles 1.4
|
||||||
|
|
||||||
|
import UM 1.3 as UM
|
||||||
|
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
property var printJob: null
|
||||||
|
|
||||||
|
function getPrettyTime(time)
|
||||||
|
{
|
||||||
|
return OutputDevice.formatDuration(time)
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: background
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
// Content on the left of the infobox
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.left
|
||||||
|
right: parent.horizontalCenter
|
||||||
|
margins: UM.Theme.getSize("default_margin").width
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: printJobName
|
||||||
|
text: "printJobName"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: ownerName
|
||||||
|
anchors.top: printJobName.bottom
|
||||||
|
text: "OwnerName"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: totalTimeLabel
|
||||||
|
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
text: printJob != null ? getPrettyTime(printJob.timeTotal) : "3h 12m"
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
// Content on the right side of the infobox.
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.horizontalCenter
|
||||||
|
right: parent.right
|
||||||
|
margins: UM.Theme.getSize("default_margin").width
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: targetPrinterLabel
|
||||||
|
text: "Waiting for: first available"
|
||||||
|
}
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
text: "..."
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
right: parent.right
|
||||||
|
top: parent.top
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrintCore && Material config
|
||||||
|
Row
|
||||||
|
{
|
||||||
|
id: extruderInfo
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
height: childrenRect.height
|
||||||
|
|
||||||
|
spacing: UM.Theme.getSize("default_margin").width
|
||||||
|
|
||||||
|
PrintCoreConfiguration
|
||||||
|
{
|
||||||
|
id: leftExtruderInfo
|
||||||
|
width: Math.round((parent.width - extruderSeperator.width) / 2)
|
||||||
|
printCoreConfiguration: printJob.configuration.extruderConfigurations[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: extruderSeperator
|
||||||
|
width: UM.Theme.getSize("default_lining").width
|
||||||
|
height: parent.height
|
||||||
|
color: lineColor
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintCoreConfiguration
|
||||||
|
{
|
||||||
|
id: rightExtruderInfo
|
||||||
|
width: Math.round((parent.width - extruderSeperator.width) / 2)
|
||||||
|
printCoreConfiguration: printJob.configuration.extruderConfigurations[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
color: "grey"
|
||||||
|
width: 1
|
||||||
|
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.margins: UM.Theme.getSize("default_margin").height
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue