Merge branch 'STAR-322_cloud-connection' of github.com:Ultimaker/Cura into STAR-322_cloud-connection

This commit is contained in:
Daniel Schiavini 2018-12-04 16:15:19 +01:00
commit 54744b46a7
11 changed files with 123 additions and 32 deletions

View file

@ -527,6 +527,12 @@ class MachineManager(QObject):
return self._global_container_stack.getMetaDataEntry("um_network_key", "")
return ""
@pyqtProperty(str, notify=printerConnectedStatusChanged)
def activeMachineCloudKey(self) -> str:
if self._global_container_stack:
return self._global_container_stack.getMetaDataEntry("um_cloud_cluster_id", "")
return ""
@pyqtProperty(str, notify = printerConnectedStatusChanged)
def activeMachineNetworkGroupName(self) -> str:
if self._global_container_stack:

View file

@ -288,8 +288,10 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
for updated_job_id in set(current_jobs).intersection(remote_jobs):
self._updateUM3PrintJobOutputModel(current_jobs[updated_job_id], remote_jobs[updated_job_id])
# TODO: properly handle removed and updated printers
self.printJobsChanged.emit()
# We only have to update when jobs are added or removed
# updated jobs push their changes via their outputmodel
if len(removed_job_ids) > 0 or len(new_job_ids) > 0:
self.printJobsChanged.emit()
def _addPrintJob(self, job: CloudClusterPrintJob) -> None:
try:

View file

@ -1,7 +1,8 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from threading import Timer
from typing import Dict, List
from typing import Dict, List, Optional
from PyQt5.QtCore import QTimer
from UM import i18nCatalog
from UM.Logger import Logger
@ -9,7 +10,6 @@ from UM.Message import Message
from UM.Signal import Signal
from cura.CuraApplication import CuraApplication
from plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient import CloudApiClient
from .CloudOutputDevice import CloudOutputDevice
from .Models import CloudCluster, CloudErrorObject
@ -39,23 +39,27 @@ class CloudOutputDeviceManager:
self._account = application.getCuraAPI().account
self._account.loginStateChanged.connect(self._getRemoteClusters)
self._api = CloudApiClient(self._account, self._onApiError)
# When switching machines we check if we have to activate a remote cluster.
application.globalContainerStackChanged.connect(self._connectToActiveMachine)
self._on_cluster_received = Signal()
self._on_cluster_received.connect(self._getRemoteClusters)
self.update_timer = QTimer(CuraApplication.getInstance())
self.update_timer.setInterval(self.CHECK_CLUSTER_INTERVAL * 1000)
self.update_timer.setSingleShot(False)
self.update_timer.timeout.connect(self._on_cluster_received.emit)
## Gets all remote clusters from the API.
def _getRemoteClusters(self) -> None:
Logger.log("i", "Retrieving remote clusters")
if self._account.isLoggedIn:
self._api.getClusters(self._onGetRemoteClustersFinished)
# Only start the polling thread after the user is authenticated
# Only start the polling timer after the user is authenticated
# The first call to _getRemoteClusters comes from self._account.loginStateChanged
timer = Timer(5.0, self._on_cluster_received.emit)
timer.start()
self.update_timer.start()
## Callback for when the request for getting the clusters. is finished.
def _onGetRemoteClustersFinished(self, clusters: List[CloudCluster]) -> None:
@ -85,7 +89,7 @@ class CloudOutputDeviceManager:
self._output_device_manager.addOutputDevice(device)
self._remote_clusters[cluster.cluster_id] = device
device.connect() # TODO: remove this
self._connectToActiveMachine()
self._connectToActiveMachine(cluster.cluster_id, cluster.host_name)
## Remove a CloudOutputDevice
# \param cluster: The cluster that was removed
@ -94,11 +98,16 @@ class CloudOutputDeviceManager:
del self._remote_clusters[cluster.cluster_id]
## Callback for when the active machine was changed by the user.
def _connectToActiveMachine(self) -> None:
def _connectToActiveMachine(self, cluster_id: Optional[str] = None, host_name: Optional[str] = None) -> None:
active_machine = CuraApplication.getInstance().getGlobalContainerStack()
if not active_machine:
return
# TODO: Remove this once correct pairing has been added (see below).
if cluster_id:
active_machine.setMetaDataEntry("um_cloud_cluster_id", cluster_id)
active_machine.setMetaDataEntry("connect_group_name", host_name)
# Check if the stored cluster_id for the active machine is in our list of remote clusters.
stored_cluster_id = active_machine.getMetaDataEntry("um_cloud_cluster_id")
if stored_cluster_id in self._remote_clusters.keys():

View file

@ -7,7 +7,7 @@
"author": "Samuel Pinches",
"manufacturer": "Alfawise",
"file_formats": "text/x-gcode",
"preferred_quality_type": "fine",
"preferred_quality_type": "fast",
"machine_extruder_trains":
{
"0": "alfawise_u20_extruder_0"
@ -53,9 +53,6 @@
"material_bed_temperature": {
"default_value": 50
},
"layer_height": {
"default_value": 0.15
},
"layer_height_0": {
"default_value": 0.2
},

View file

@ -7,7 +7,7 @@
"author": "Samuel Pinches",
"manufacturer": "JGAurora",
"file_formats": "text/x-gcode",
"preferred_quality_type": "fine",
"preferred_quality_type": "fast",
"machine_extruder_trains":
{
"0": "jgaurora_a1_extruder_0"
@ -53,9 +53,6 @@
"material_bed_temperature": {
"default_value": 67
},
"layer_height": {
"default_value": 0.15
},
"layer_height_0": {
"default_value": 0.12
},

View file

@ -9,7 +9,7 @@
"file_formats": "text/x-gcode",
"platform": "jgaurora_a5.stl",
"platform_offset": [-242, -101, 273],
"preferred_quality_type": "fine",
"preferred_quality_type": "fast",
"machine_extruder_trains":
{
"0": "jgaurora_a5_extruder_0"
@ -55,9 +55,6 @@
"material_bed_temperature": {
"default_value": 67
},
"layer_height": {
"default_value": 0.15
},
"layer_height_0": {
"default_value": 0.12
},

View file

@ -7,7 +7,7 @@
"author": "Samuel Pinches",
"manufacturer": "JGAurora",
"file_formats": "text/x-gcode",
"preferred_quality_type": "fine",
"preferred_quality_type": "fast",
"machine_extruder_trains":
{
"0": "jgaurora_z_603s_extruder_0"
@ -53,9 +53,6 @@
"material_bed_temperature": {
"default_value": 55
},
"layer_height": {
"default_value": 0.15
},
"layer_height_0": {
"default_value": 0.2
},

View file

@ -0,0 +1,26 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.4
import UM 1.2 as UM
import Cura 1.0 as Cura
Instantiator {
model: UM.ContainerStacksModel {
filter: {"type": "machine", "um_cloud_cluster_id": "*"}
}
MenuItem {
// iconSource: UM.Theme.getIcon("printer_single") TODO: use cloud icon here
text: model.metadata["connect_group_name"]
checkable: true
checked: true // cloud printers are only listed if they are actually online
exclusiveGroup: group;
onTriggered: Cura.MachineManager.setActiveMachine(model.id);
}
onObjectAdded: menu.insertItem(index, object)
onObjectRemoved: menu.removeItem(object)
}

View file

@ -37,6 +37,23 @@ Menu
visible: networkPrinterMenu.count > 0
}
MenuItem
{
text: catalog.i18nc("@label:category menu label", "Cloud enabled printers")
enabled: false
visible: cloudPrinterMenu.count > 0
}
CloudPrinterMenu
{
id: cloudPrinterMenu
}
MenuSeparator
{
visible: cloudPrinterMenu.count > 0
}
MenuItem
{
text: catalog.i18nc("@label:category menu label", "Local printers")

View file

@ -115,15 +115,16 @@ UM.PreferencesPage
currentIndex:
{
var idx = -1;
for(var i = 0; i < settingVisibilityPresetsModel.items.length; ++i)
{
if(settingVisibilityPresetsModel.items[i].presetId == settingVisibilityPresetsModel.activePreset)
{
currentIndex = i;
return;
idx = i;
break;
}
}
return -1
return idx;
}
onActivated:

View file

@ -50,6 +50,46 @@ Column
}
}
Label
{
text: catalog.i18nc("@label", "Cloud connected printers")
visible: cloudPrintersModel.items.length > 0
leftPadding: UM.Theme.getSize("default_margin").width
height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0
renderType: Text.NativeRendering
font: UM.Theme.getFont("medium")
color: UM.Theme.getColor("text_medium")
verticalAlignment: Text.AlignVCenter
}
Repeater
{
id: cloudPrinters
model: UM.ContainerStacksModel
{
id: cloudPrintersModel
filter:
{
"type": "machine",
"um_cloud_cluster_id": "*"
}
}
delegate: MachineSelectorButton
{
text: model.metadata["connect_group_name"]
checked: Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"]
outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
Connections
{
target: Cura.MachineManager
onActiveMachineNetworkGroupNameChanged: checked = Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"]
}
}
}
Label
{
text: catalog.i18nc("@label", "Preset printers")
@ -71,7 +111,9 @@ Column
id: virtualPrintersModel
filter:
{
"type": "machine", "um_network_key": null
"type": "machine",
"um_network_key": null,
"um_cloud_cluster_id": null
}
}