diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index 7b74282303..3330426d0a 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -14,9 +14,13 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): def __init__(self, device_id, address: str, properties, parent = None): super().__init__(device_id = device_id, parent = parent) self._manager = None - self._createNetworkManager() - self._last_response_time = time() + self._last_manager_create_time = None + self._recreate_network_manager_time = 30 + self._timeout_time = 10 # After how many seconds of no response should a timeout occur? + + self._last_response_time = None self._last_request_time = None + self._api_prefix = "" self._address = address self._properties = properties @@ -25,10 +29,28 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): self._onFinishedCallbacks = {} def _update(self): - if not self._manager.networkAccessible(): - pass # TODO: no internet connection. + if self._last_response_time: + time_since_last_response = time() - self._last_response_time + else: + time_since_last_response = 0 - pass + if self._last_request_time: + time_since_last_request = time() - self._last_request_time + else: + time_since_last_request = float("inf") # An irrelevantly large number of seconds + + if time_since_last_response > self._timeout_time >= time_since_last_request: + # Go (or stay) into timeout. + self.setConnectionState(ConnectionState.closed) + # We need to check if the manager needs to be re-created. If we don't, we get some issues when OSX goes to + # sleep. + if time_since_last_response > self._recreate_network_manager_time: + if self._last_manager_create_time is None: + self._createNetworkManager() + if time() - self._last_manager_create_time > self._recreate_network_manager_time: + self._createNetworkManager() + + return True def _createEmptyRequest(self, target): url = QUrl("http://" + self._address + self._api_prefix + target) @@ -39,22 +61,35 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): return request def _put(self, target: str, data: str, onFinished: Callable[[Any, QNetworkReply], None]): + if self._manager is None: + self._createNetworkManager() request = self._createEmptyRequest(target) + self._last_request_time = time() reply = self._manager.put(request, data.encode()) self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished def _get(self, target: str, onFinished: Callable[[Any, QNetworkReply], None]): + if self._manager is None: + self._createNetworkManager() request = self._createEmptyRequest(target) + self._last_request_time = time() reply = self._manager.get(request) self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished def _delete(self, target: str, onFinished: Callable[[Any, QNetworkReply], None]): + if self._manager is None: + self._createNetworkManager() + self._last_request_time = time() pass def _post(self, target: str, data: str, onFinished: Callable[[Any, QNetworkReply], None], onProgress: Callable): + if self._manager is None: + self._createNetworkManager() + self._last_request_time = time() pass def _createNetworkManager(self): + Logger.log("d", "Creating network manager") if self._manager: self._manager.finished.disconnect(self.__handleOnFinished) #self._manager.networkAccessibleChanged.disconnect(self._onNetworkAccesibleChanged) @@ -62,12 +97,17 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): self._manager = QNetworkAccessManager() self._manager.finished.connect(self.__handleOnFinished) + self._last_manager_create_time = time() #self._manager.authenticationRequired.connect(self._onAuthenticationRequired) #self._manager.networkAccessibleChanged.connect(self._onNetworkAccesibleChanged) # for debug purposes def __handleOnFinished(self, reply: QNetworkReply): + if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) is None: + # No status code means it never even reached remote. + return + self._last_response_time = time() - # TODO: Check if the message is actually correct + self.setConnectionState(ConnectionState.connected) try: self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())](reply) diff --git a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py index 6e564fef29..8f9a92384f 100644 --- a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py @@ -19,7 +19,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): self._print_jobs = [] def _update(self): - super()._update() + if not super()._update(): + return self._get("printers/", onFinished=self._onGetPrintersDataFinished) self._get("print_jobs/", onFinished=self._onGetPrintJobsFinished) diff --git a/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py b/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py index 63ebd055ad..21b58154a6 100644 --- a/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py @@ -16,7 +16,8 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): self._number_of_extruders = 2 def _update(self): - super()._update() + if not super()._update(): + return self._get("printer", onFinished=self._onGetPrinterDataFinished) self._get("print_job", onFinished=self._onGetPrintJobFinished) diff --git a/plugins/UM3NetworkPrinting/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/UM3OutputDevicePlugin.py index b4ea1663b6..1462fb9373 100644 --- a/plugins/UM3NetworkPrinting/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/UM3OutputDevicePlugin.py @@ -80,7 +80,13 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self._discovered_devices[key].connectionStateChanged.disconnect(self._onDeviceConnectionStateChanged) def _onDeviceConnectionStateChanged(self, key): - pass # TODO + if key not in self._discovered_devices: + return + + if self._discovered_devices[key].isConnected(): + self.getOutputDeviceManager().addOutputDevice(self._discovered_devices[key]) + else: + self.getOutputDeviceManager().removeOutputDevice(key) def stop(self): if self._zero_conf is not None: