diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 259770857d..fc514d1fca 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -40,8 +40,9 @@ I18N_CATALOG = i18nCatalog("cura") # Note that this device represents a single remote cluster, not a list of multiple clusters. class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice): - # The interval with which the remote clusters are checked - CHECK_CLUSTER_INTERVAL = 10.0 # seconds + # The interval with which the remote cluster is checked. + # We can do this relatively often as this API call is quite fast. + CHECK_CLUSTER_INTERVAL = 8.0 # seconds # The minimum version of firmware that support print job actions over cloud. PRINT_JOB_ACTIONS_MIN_VERSION = Version("5.3.0") diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index b31f1efa47..731716478b 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -43,6 +43,7 @@ class CloudOutputDeviceManager: self._update_timer = QTimer() self._update_timer.setInterval(int(self.CHECK_CLUSTER_INTERVAL * 1000)) self._update_timer.setSingleShot(False) + self._update_timer.timeout.connect(self._getRemoteClusters) # Ensure we don't start twice. self._running = False @@ -57,7 +58,6 @@ class CloudOutputDeviceManager: if not self._update_timer.isActive(): self._update_timer.start() self._getRemoteClusters() - self._update_timer.timeout.connect(self._getRemoteClusters) ## Stops running the cloud output device manager. def stop(self): @@ -67,7 +67,6 @@ class CloudOutputDeviceManager: if self._update_timer.isActive(): self._update_timer.stop() self._onGetRemoteClustersFinished([]) # Make sure we remove all cloud output devices. - self._update_timer.timeout.disconnect(self._getRemoteClusters) ## Force refreshing connections. def refreshConnections(self) -> None: diff --git a/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterOutputDevice.py b/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterOutputDevice.py index b892f3bafe..698995c664 100644 --- a/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterOutputDevice.py @@ -26,6 +26,9 @@ from .Models.Http.ClusterPrintJobStatus import ClusterPrintJobStatus # Currently used for local networking and cloud printing using Ultimaker Connect. # This base class primarily contains all the Qt properties and slots needed for the monitor page to work. class UltimakerNetworkedPrinterOutputDevice(NetworkedPrinterOutputDevice): + + META_NETWORK_KEY = "um_network_key" + META_CLUSTER_ID = "um_cloud_cluster_id" # Signal emitted when the status of the print jobs for this cluster were changed over the network. printJobsChanged = pyqtSignal() @@ -195,6 +198,8 @@ class UltimakerNetworkedPrinterOutputDevice(NetworkedPrinterOutputDevice): ## Check if we're still connected by comparing the last timestamps for network response and the current time. # This implementation is similar to the base NetworkedPrinterOutputDevice, but is tweaked slightly. + # Re-connecting is handled automatically by the output device managers in this plugin. + # TODO: it would be nice to have this logic in the managers, but connecting those with signals causes crashes. def _checkStillConnected(self) -> None: time_since_last_response = time() - self._time_of_last_response if time_since_last_response > self.NETWORK_RESPONSE_CONSIDER_OFFLINE: @@ -202,9 +207,24 @@ class UltimakerNetworkedPrinterOutputDevice(NetworkedPrinterOutputDevice): if self.key in CuraApplication.getInstance().getOutputDeviceManager().getOutputDeviceIds(): CuraApplication.getInstance().getOutputDeviceManager().removeOutputDevice(self.key) elif self.connectionState == ConnectionState.Closed: - self.setConnectionState(ConnectionState.Connected) - if self.key not in CuraApplication.getInstance().getOutputDeviceManager().getOutputDeviceIds(): - CuraApplication.getInstance().getOutputDeviceManager().addOutputDevice(self) + self._reconnectForActiveMachine() + + ## Reconnect for the active output device. + # Does nothing if the device is not meant for the active machine. + def _reconnectForActiveMachine(self) -> None: + active_machine = CuraApplication.getInstance().getGlobalContainerStack() + if not active_machine: + return + + # Try for local network device. + stored_device_id = active_machine.getMetaDataEntry(self.META_NETWORK_KEY) + if self.key == stored_device_id: + CuraApplication.getInstance().getOutputDeviceManager().addOutputDevice(self) + + # Try for cloud device. + stored_cluster_id = active_machine.getMetaDataEntry(self.META_CLUSTER_ID) + if self.key == stored_cluster_id: + CuraApplication.getInstance().getOutputDeviceManager().addOutputDevice(self) def _responseReceived(self) -> None: self._time_of_last_response = time()