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]
|
||||
CuraBuildType = ""
|
||||
CuraDebugMode = False
|
||||
CuraSDKVerion = ""
|
||||
CuraSDKVersion = ""
|
||||
|
||||
|
||||
class CuraApplication(QtApplication):
|
||||
|
|
|
@ -30,7 +30,7 @@ class ExtruderConfigurationModel(QObject):
|
|||
self.extruderConfigurationChanged.emit()
|
||||
|
||||
@pyqtProperty(QObject, fset = setMaterial, notify = extruderConfigurationChanged)
|
||||
def material(self) -> MaterialOutputModel:
|
||||
def activeMaterial(self) -> MaterialOutputModel:
|
||||
return self._material
|
||||
|
||||
def setHotendID(self, hotend_id: Optional[str]) -> None:
|
||||
|
@ -52,7 +52,7 @@ class ExtruderConfigurationModel(QObject):
|
|||
message_chunks = []
|
||||
message_chunks.append("Position: " + str(self._position))
|
||||
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("HotendID: " + self.hotendID if self.hotendID else "empty")
|
||||
return " ".join(message_chunks)
|
||||
|
|
|
@ -48,7 +48,7 @@ class ExtruderOutputModel(QObject):
|
|||
|
||||
@pyqtProperty(QObject, notify = extruderConfigurationChanged)
|
||||
def activeMaterial(self) -> Optional["MaterialOutputModel"]:
|
||||
return self._extruder_configuration.material
|
||||
return self._extruder_configuration.activeMaterial
|
||||
|
||||
def updateActiveMaterial(self, material: Optional["MaterialOutputModel"]):
|
||||
self._extruder_configuration.setMaterial(material)
|
||||
|
|
|
@ -7,6 +7,7 @@ from typing import Optional, TYPE_CHECKING
|
|||
if TYPE_CHECKING:
|
||||
from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
|
||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
||||
from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
|
||||
|
||||
|
||||
class PrintJobOutputModel(QObject):
|
||||
|
@ -17,6 +18,7 @@ class PrintJobOutputModel(QObject):
|
|||
keyChanged = pyqtSignal()
|
||||
assignedPrinterChanged = pyqtSignal()
|
||||
ownerChanged = pyqtSignal()
|
||||
configurationChanged =pyqtSignal()
|
||||
|
||||
def __init__(self, output_controller: "PrinterOutputController", key: str = "", name: str = "", parent=None) -> None:
|
||||
super().__init__(parent)
|
||||
|
@ -29,6 +31,17 @@ class PrintJobOutputModel(QObject):
|
|||
self._assigned_printer = None # type: Optional[PrinterOutputModel]
|
||||
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)
|
||||
def owner(self):
|
||||
return self._owner
|
||||
|
|
|
@ -27,13 +27,14 @@ Component
|
|||
{
|
||||
id: activePrintersLabel
|
||||
font: UM.Theme.getFont("large")
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||
anchors.right:parent.right
|
||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||
anchors
|
||||
{
|
||||
margins: UM.Theme.getSize("default_margin").width
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
text: Cura.MachineManager.printerOutputDevices[0].name
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
|
|
@ -28,7 +28,8 @@ Component
|
|||
id: activePrintersLabel
|
||||
font: UM.Theme.getFont("large")
|
||||
|
||||
anchors {
|
||||
anchors
|
||||
{
|
||||
top: parent.top
|
||||
topMargin: UM.Theme.getSize("default_margin").height * 2 // a bit more spacing to give it some breathing room
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
|
@ -71,25 +72,28 @@ Component
|
|||
|
||||
ScrollView
|
||||
{
|
||||
id: printerScrollView
|
||||
anchors.margins: UM.Theme.getSize("default_margin").width
|
||||
anchors.top: activePrintersLabel.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: UM.Theme.getSize("default_lining").width // To ensure border can be drawn.
|
||||
anchors.rightMargin: UM.Theme.getSize("default_lining").width
|
||||
anchors.right: parent.right
|
||||
id: queuedPrintJobs
|
||||
|
||||
anchors
|
||||
{
|
||||
margins: UM.Theme.getSize("default_margin").width
|
||||
top: activePrintersLabel.bottom
|
||||
left: parent.left
|
||||
leftMargin: UM.Theme.getSize("default_lining").width // To ensure border can be drawn.
|
||||
rightMargin: UM.Theme.getSize("default_lining").width
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
ListView
|
||||
{
|
||||
anchors.fill: parent
|
||||
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)
|
||||
height: 125 * screenScaleFactor
|
||||
|
||||
|
|
|
@ -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 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.PrinterOutputModel import PrinterOutputModel
|
||||
from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
|
||||
|
@ -478,6 +480,23 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||
def _createPrintJobModel(self, data: Dict[str, Any]) -> PrintJobOutputModel:
|
||||
print_job = PrintJobOutputModel(output_controller=ClusterUM3PrinterOutputController(self),
|
||||
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)
|
||||
self._print_jobs.append(print_job)
|
||||
return print_job
|
||||
|
@ -488,6 +507,24 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||
print_job.updateState(data["status"])
|
||||
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:
|
||||
# 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.
|
||||
|
@ -523,24 +560,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||
|
||||
material_data = extruder_data["material"]
|
||||
if extruder.activeMaterial is None or extruder.activeMaterial.guid != material_data["guid"]:
|
||||
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"
|
||||
|
||||
material = MaterialOutputModel(guid=material_data["guid"], type=material_type,
|
||||
brand=brand, color=color, name=name)
|
||||
material = self._createMaterialOutputModel(material_data)
|
||||
extruder.updateActiveMaterial(material)
|
||||
|
||||
def _removeJob(self, job: PrintJobOutputModel) -> bool:
|
||||
|
|
|
@ -12,14 +12,16 @@ Item
|
|||
|
||||
width: Math.round(parent.width / 2)
|
||||
height: childrenRect.height
|
||||
|
||||
Label
|
||||
{
|
||||
id: materialLabel
|
||||
text: printCoreConfiguration.activeMaterial != null ? printCoreConfiguration.activeMaterial.name : ""
|
||||
text: printCoreConfiguration.activeMaterial != null ? printCoreConfiguration.activeMaterial.name : ":("
|
||||
elide: Text.ElideRight
|
||||
width: parent.width
|
||||
font: UM.Theme.getFont("very_small")
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
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