Consistent naming, some bug fixes

This commit is contained in:
ChrisTerBeke 2019-07-29 17:24:10 +02:00
parent ddd282eef3
commit 1aa70748af
6 changed files with 70 additions and 132 deletions

View file

@ -75,7 +75,7 @@ class DiscoveredPrinter(QObject):
def readableMachineType(self) -> str:
from cura.CuraApplication import CuraApplication
machine_manager = CuraApplication.getInstance().getMachineManager()
# In LocalClusterOutputDevice, when it updates a printer information, it updates the machine type using the field
# In NetworkOutputDevice, when it updates a printer information, it updates the machine type using the field
# "machine_variant", and for some reason, it's not the machine type ID/codename/... but a human-readable string
# like "Ultimaker 3". The code below handles this case.
if self._hasHumanReadableMachineTypeName(self._machine_type):

View file

@ -118,7 +118,7 @@ class GlobalStack(CuraContainerStack):
## \sa configuredConnectionTypes
def removeConfiguredConnectionType(self, connection_type: int) -> None:
configured_connection_types = self.configuredConnectionTypes
if connection_type in self.configured_connection_types:
if connection_type in configured_connection_types:
# Store the values as a string.
configured_connection_types.remove(connection_type)
self.setMetaDataEntry("connection_type", ",".join([str(c_type) for c_type in configured_connection_types]))

View file

@ -6,7 +6,6 @@ from PyQt5.QtCore import QTimer
from UM import i18nCatalog
from UM.Logger import Logger
from UM.Message import Message
from UM.Signal import Signal
from cura.API import Account
from cura.CuraApplication import CuraApplication
@ -54,13 +53,32 @@ class CloudOutputDeviceManager:
self._running = False
## Starts running the cloud output device manager, thus periodically requesting cloud data.
def start(self):
if self._running:
return
self._account.loginStateChanged.connect(self._onLoginStateChanged)
# When switching machines we check if we have to activate a remote cluster.
self._application.globalContainerStackChanged.connect(self._connectToActiveMachine)
self._update_timer.timeout.connect(self._getRemoteClusters)
self._onLoginStateChanged(is_logged_in = self._account.isLoggedIn)
## Stops running the cloud output device manager.
def stop(self):
if not self._running:
return
self._account.loginStateChanged.disconnect(self._onLoginStateChanged)
# When switching machines we check if we have to activate a remote cluster.
self._application.globalContainerStackChanged.disconnect(self._connectToActiveMachine)
self._update_timer.timeout.disconnect(self._getRemoteClusters)
self._onLoginStateChanged(is_logged_in = False)
## Force refreshing connections.
def refreshConnections(self) -> None:
pass
self._connectToActiveMachine()
## Called when the uses logs in or out
def _onLoginStateChanged(self, is_logged_in: bool) -> None:
Logger.log("d", "Log in state changed to %s", is_logged_in)
if is_logged_in:
if not self._update_timer.isActive():
self._update_timer.start()
@ -74,18 +92,13 @@ class CloudOutputDeviceManager:
## Gets all remote clusters from the API.
def _getRemoteClusters(self) -> None:
Logger.log("d", "Retrieving remote clusters")
self._api.getClusters(self._onGetRemoteClustersFinished)
## Callback for when the request for getting the clusters. is finished.
def _onGetRemoteClustersFinished(self, clusters: List[CloudClusterResponse]) -> None:
online_clusters = {c.cluster_id: c for c in clusters if c.is_online} # type: Dict[str, CloudClusterResponse]
removed_devices, added_clusters, updates = findChanges(self._remote_clusters, online_clusters)
Logger.log("d", "Parsed remote clusters to %s", [cluster.toDict() for cluster in online_clusters.values()])
Logger.log("d", "Removed: %s, added: %s, updates: %s", len(removed_devices), len(added_clusters), len(updates))
# Remove output devices that are gone
for device in removed_devices:
if device.isConnected():
@ -136,12 +149,7 @@ class CloudOutputDeviceManager:
# The newly added machine is automatically activated.
self._application.getMachineManager().addMachine(machine_type_id, group_name)
active_machine = CuraApplication.getInstance().getGlobalContainerStack()
if not active_machine:
return
active_machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key)
self._connectToOutputDevice(device, active_machine)
self._connectToActiveMachine()
## Callback for when the active machine was changed by the user or a new remote cluster was found.
def _connectToActiveMachine(self) -> None:
@ -182,31 +190,12 @@ class CloudOutputDeviceManager:
## Connects to an output device and makes sure it is registered in the output device manager.
def _connectToOutputDevice(self, device: CloudOutputDevice, active_machine: GlobalStack) -> None:
device.connect()
self._output_device_manager.addOutputDevice(device)
active_machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key)
active_machine.addConfiguredConnectionType(device.connectionType.value)
self._output_device_manager.addOutputDevice(device)
## Handles an API error received from the cloud.
# \param errors: The errors received
@staticmethod
def _onApiError(errors: List[CloudError] = None) -> None:
Logger.log("w", str(errors))
## Starts running the cloud output device manager, thus periodically requesting cloud data.
def start(self):
if self._running:
return
self._account.loginStateChanged.connect(self._onLoginStateChanged)
# When switching machines we check if we have to activate a remote cluster.
self._application.globalContainerStackChanged.connect(self._connectToActiveMachine)
self._update_timer.timeout.connect(self._getRemoteClusters)
self._onLoginStateChanged(is_logged_in = self._account.isLoggedIn)
## Stops running the cloud output device manager.
def stop(self):
if not self._running:
return
self._account.loginStateChanged.disconnect(self._onLoginStateChanged)
# When switching machines we check if we have to activate a remote cluster.
self._application.globalContainerStackChanged.disconnect(self._connectToActiveMachine)
self._update_timer.timeout.disconnect(self._getRemoteClusters)
self._onLoginStateChanged(is_logged_in = False)

View file

@ -20,7 +20,7 @@ from ..UltimakerNetworkedPrinterOutputDevice import UltimakerNetworkedPrinterOut
I18N_CATALOG = i18nCatalog("cura")
class LocalClusterOutputDevice(UltimakerNetworkedPrinterOutputDevice):
class NetworkOutputDevice(UltimakerNetworkedPrinterOutputDevice):
activeCameraUrlChanged = pyqtSignal()

View file

@ -15,9 +15,10 @@ from UM.Version import Version
from cura.CuraApplication import CuraApplication
from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice
from cura.Settings.GlobalStack import GlobalStack
from .ClusterApiClient import ClusterApiClient
from .LocalClusterOutputDevice import LocalClusterOutputDevice
from .NetworkOutputDevice import NetworkOutputDevice
from .ManualPrinterRequest import ManualPrinterRequest
@ -38,9 +39,10 @@ class NetworkOutputDeviceManager:
def __init__(self) -> None:
# Persistent dict containing the networked clusters.
self._discovered_devices = {} # type: Dict[str, LocalClusterOutputDevice]
self._discovered_devices = {} # type: Dict[str, NetworkOutputDevice]
self._output_device_manager = CuraApplication.getInstance().getOutputDeviceManager()
# TODO: move zeroconf stuff to own class
self._zero_conf = None # type: Optional[Zeroconf]
self._zero_conf_browser = None # type: Optional[ServiceBrowser]
self._service_changed_request_queue = None # type: Optional[Queue]
@ -55,30 +57,6 @@ class NetworkOutputDeviceManager:
self.addedNetworkCluster.connect(self._onAddDevice)
self.removedNetworkCluster.connect(self._onRemoveDevice)
## Force reset all network device connections.
def refreshConnections(self):
active_machine = CuraApplication.getInstance().getGlobalContainerStack()
if not active_machine:
return
um_network_key = active_machine.getMetaDataEntry("um_network_key")
for key in self._discovered_devices:
if key == um_network_key:
if not self._discovered_devices[key].isConnected():
Logger.log("d", "Attempting to connect with [%s]" % key)
# It should already be set, but if it actually connects we know for sure it's supported!
active_machine.addConfiguredConnectionType(self._discovered_devices[key].connectionType.value)
self._discovered_devices[key].connect()
self._discovered_devices[key].connectionStateChanged.connect(self._onDeviceConnectionStateChanged)
else:
self._onDeviceConnectionStateChanged(key)
else:
if self._discovered_devices[key].isConnected():
Logger.log("d", "Attempting to close connection with [%s]" % key)
self._discovered_devices[key].close()
self._discovered_devices[key].connectionStateChanged.disconnect(
self._onDeviceConnectionStateChanged)
## Start the network discovery.
def start(self):
# The ZeroConf service changed requests are handled in a separate thread so we don't block the UI.
@ -145,7 +123,6 @@ class NetworkOutputDeviceManager:
if not address:
address = self._discovered_devices[key].ipAddress
self._onRemoveDevice(key)
# TODO: self.resetLastManualDevice()
if address in self._manual_instances:
manual_printer_request = self._manual_instances.pop(address)
@ -155,6 +132,33 @@ class NetworkOutputDeviceManager:
if manual_printer_request.callback is not None:
CuraApplication.getInstance().callLater(manual_printer_request.callback, False, address)
## Force reset all network device connections.
def refreshConnections(self):
self._connectToActiveMachine()
## Callback for when the active machine was changed by the user or a new remote cluster was found.
def _connectToActiveMachine(self):
active_machine = CuraApplication.getInstance().getGlobalContainerStack()
if not active_machine:
return
for device_id in self._discovered_devices:
CuraApplication.getInstance().getOutputDeviceManager().removeOutputDevice(device_id)
stored_network_key = active_machine.getMetaDataEntry("um_network_key")
if stored_network_key in self._discovered_devices:
device = self._discovered_devices[stored_network_key]
self._connectToOutputDevice(device, active_machine)
## Add a device to the current active machine.
@staticmethod
def _connectToOutputDevice(device: PrinterOutputDevice, active_machine: GlobalStack) -> None:
device.connect()
active_machine.setMetaDataEntry("um_network_key", device.key)
active_machine.setMetaDataEntry("group_name", device.name)
active_machine.addConfiguredConnectionType(device.connectionType.value)
CuraApplication.getInstance().getOutputDeviceManager().addOutputDevice(device)
## Handles an API error received from the cloud.
# \param errors: The errors received
def _onApiError(self, errors) -> None:
@ -212,7 +216,7 @@ class NetworkOutputDeviceManager:
if cluster_size == -1:
return
device = LocalClusterOutputDevice(key, address, properties)
device = NetworkOutputDevice(key, address, properties)
CuraApplication.getInstance().getDiscoveredPrintersModel().addDiscoveredPrinter(
ip_address=address,
@ -225,26 +229,15 @@ class NetworkOutputDeviceManager:
self._discovered_devices[device.getId()] = device
self.discoveredDevicesChanged.emit()
global_container_stack = CuraApplication.getInstance().getGlobalContainerStack()
if global_container_stack and device.getId() == global_container_stack.getMetaDataEntry("um_network_key"):
# Ensure that the configured connection type is set.
CuraApplication.getInstance().getOutputDeviceManager().addOutputDevice(device)
global_container_stack.addConfiguredConnectionType(device.connectionType.value)
device.connect()
device.connectionStateChanged.connect(self._onDeviceConnectionStateChanged)
self._connectToActiveMachine()
## Remove a device.
def _onRemoveDevice(self, device_id: str) -> None:
device = self._discovered_devices.pop(device_id, None)
if device:
if not device:
return
if device.isConnected():
device.disconnect()
try:
device.connectionStateChanged.disconnect(self._onDeviceConnectionStateChanged)
except TypeError:
# Disconnect already happened.
pass
CuraApplication.getInstance().getDiscoveredPrintersModel().removeDiscoveredPrinter(device.address)
self.discoveredDevicesChanged.emit()
@ -285,20 +278,6 @@ class NetworkOutputDeviceManager:
for request in reschedule_requests:
self._service_changed_request_queue.put(request)
## Callback handler for when the connection state of a networked device has changed.
def _onDeviceConnectionStateChanged(self, key: str) -> None:
if key not in self._discovered_devices:
return
if self._discovered_devices[key].isConnected():
um_network_key = CuraApplication.getInstance().getGlobalContainerStack().getMetaDataEntry("um_network_key")
if key != um_network_key:
return
CuraApplication.getInstance().getOutputDeviceManager().addOutputDevice(self._discovered_devices[key])
# TODO: self.checkCloudFlowIsPossible(None)
else:
CuraApplication.getInstance().getOutputDeviceManager().removeOutputDevice(key)
## Handler for zeroConf detection.
# Return True or False indicating if the process succeeded.
# Note that this function can take over 3 seconds to complete. Be careful calling it from the main thread.
@ -347,48 +326,18 @@ class NetworkOutputDeviceManager:
self.removedNetworkCluster.emit(str(name))
return True
def _associateActiveMachineWithPrinterDevice(self, printer_device: Optional[PrinterOutputDevice]) -> None:
if not printer_device:
return
Logger.log("d", "Attempting to set the network key of the active machine to %s", printer_device.key)
machine_manager = CuraApplication.getInstance().getMachineManager()
global_container_stack = machine_manager.activeMachine
if not global_container_stack:
return
for machine in machine_manager.getMachinesInGroup(global_container_stack.getMetaDataEntry("group_id")):
machine.setMetaDataEntry("um_network_key", printer_device.key)
machine.setMetaDataEntry("group_name", printer_device.name)
# Delete old authentication data.
Logger.log("d", "Removing old authentication id %s for device %s",
global_container_stack.getMetaDataEntry("network_authentication_id", None), printer_device.key)
machine.removeMetaDataEntry("network_authentication_id")
machine.removeMetaDataEntry("network_authentication_key")
# Ensure that these containers do know that they are configured for network connection
machine.addConfiguredConnectionType(printer_device.connectionType.value)
## Create a machine instance based on the discovered network printer.
def _createMachineFromDiscoveredPrinter(self, key: str) -> None:
discovered_device = self._discovered_devices.get(key)
if discovered_device is None:
Logger.log("e", "Could not find discovered device with key [%s]", key)
return
group_name = discovered_device.getProperty("name")
machine_type_id = discovered_device.getProperty("printer_type")
Logger.log("i", "Creating machine from network device with key = [%s], group name = [%s], printer type = [%s]",
key, group_name, machine_type_id)
CuraApplication.getInstance().getMachineManager().addMachine(machine_type_id, group_name)
# connect the new machine to that network printer
self._associateActiveMachineWithPrinterDevice(discovered_device)
# ensure that the connection states are refreshed.
self.refreshConnections()
self._connectToActiveMachine()
## Load the user-configured manual devices from Cura preferences.
def _getStoredManualInstances(self) -> Dict[str, ManualPrinterRequest]:

View file

@ -13,7 +13,7 @@ from .Models.ClusterMaterial import ClusterMaterial
from .Models.LocalMaterial import LocalMaterial
if TYPE_CHECKING:
from .Network.LocalClusterOutputDevice import LocalClusterOutputDevice
from .Network.NetworkOutputDevice import NetworkOutputDevice
## Asynchronous job to send material profiles to the printer.
@ -21,9 +21,9 @@ if TYPE_CHECKING:
# This way it won't freeze up the interface while sending those materials.
class SendMaterialJob(Job):
def __init__(self, device: "LocalClusterOutputDevice") -> None:
def __init__(self, device: "NetworkOutputDevice") -> None:
super().__init__()
self.device = device # type: LocalClusterOutputDevice
self.device = device # type: NetworkOutputDevice
## Send the request to the printer and register a callback
def run(self) -> None: