Compare commits
	
		
			2 Commits
		
	
	
		
			fd9ce76275
			...
			a8cf4957ec
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| a8cf4957ec | |||
| c5c6ed037e | 
							
								
								
									
										28
									
								
								__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | def get_settings_defaults(self): | ||||||
|  |     return { | ||||||
|  |         # ...existing code... | ||||||
|  |          | ||||||
|  |         # Add option to disable camera functionality | ||||||
|  |         "disable_camera": False, | ||||||
|  |          | ||||||
|  |         # ...existing code... | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | # ...existing code... | ||||||
|  |  | ||||||
|  | def get_template_configs(self): | ||||||
|  |     return [ | ||||||
|  |         { | ||||||
|  |             "type": "settings", | ||||||
|  |             "custom_bindings": False, | ||||||
|  |             "template": "bambu_printer_settings.jinja2", | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "type": "tab", | ||||||
|  |             "name": "Bambu Printer", | ||||||
|  |             "custom_bindings": True, | ||||||
|  |             "template": "bambu_printer_tab.jinja2", | ||||||
|  |         }, | ||||||
|  |     ] | ||||||
|  |  | ||||||
|  | # ...existing code... | ||||||
| @@ -335,6 +335,16 @@ class BambuVirtualPrinter: | |||||||
|         self._mqtt_connected = False |         self._mqtt_connected = False | ||||||
|         self._bambu_client = None |         self._bambu_client = None | ||||||
|         self._custom_connected = False |         self._custom_connected = False | ||||||
|  |          | ||||||
|  |         # Store initial connection errors to avoid logging the same errors repeatedly | ||||||
|  |         self._connection_error_logged = False | ||||||
|  |         self._camera_error_logged = False | ||||||
|  |         self._last_connection_attempt = 0 | ||||||
|  |         self._connection_retry_backoff = 10  # Start with 10 seconds between retries | ||||||
|  |          | ||||||
|  |         # Track if we should disable camera functionality due to persistent errors | ||||||
|  |         self._disable_camera = self._settings.get_boolean(["disable_camera"]) or False | ||||||
|  |          | ||||||
|         self._bambu_client: BambuClient = self._create_client_connection_async() |         self._bambu_client: BambuClient = self._create_client_connection_async() | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
| @@ -458,6 +468,12 @@ class BambuVirtualPrinter: | |||||||
|             client.subscribe(device_topic) |             client.subscribe(device_topic) | ||||||
|             self._log.debug(f"Subscribed to topic: {device_topic}") |             self._log.debug(f"Subscribed to topic: {device_topic}") | ||||||
|             self._log.info(f"MQTT connection successful. Connected: {self.is_connected}") |             self._log.info(f"MQTT connection successful. Connected: {self.is_connected}") | ||||||
|  |              | ||||||
|  |             # Try to patch client for better error handling after successful connection | ||||||
|  |             try: | ||||||
|  |                 self._patch_bambu_client_for_connection_errors() | ||||||
|  |             except Exception as e: | ||||||
|  |                 self._log.warning(f"Failed to patch BambuClient for better error handling: {str(e)}") | ||||||
|         else: |         else: | ||||||
|             self._mqtt_connected = False |             self._mqtt_connected = False | ||||||
|             self._custom_connected = False |             self._custom_connected = False | ||||||
| @@ -871,21 +887,43 @@ class BambuVirtualPrinter: | |||||||
|             self._log.debug( |             self._log.debug( | ||||||
|                 f"Creating standard BambuClient with local_mqtt: {self._settings.get_boolean(['local_mqtt'])}" |                 f"Creating standard BambuClient with local_mqtt: {self._settings.get_boolean(['local_mqtt'])}" | ||||||
|             ) |             ) | ||||||
|             bambu_client = BambuClient( |              | ||||||
|                 device_type=self._settings.get(["device_type"]), |             # Set up client parameters | ||||||
|                 serial=self._settings.get(["serial"]), |             client_params = { | ||||||
|                 host=self._settings.get(["host"]), |                 "device_type": self._settings.get(["device_type"]), | ||||||
|                 username=( |                 "serial": self._settings.get(["serial"]), | ||||||
|  |                 "host": self._settings.get(["host"]), | ||||||
|  |                 "username": ( | ||||||
|                     "bblp" |                     "bblp" | ||||||
|                     if self._settings.get_boolean(["local_mqtt"]) |                     if self._settings.get_boolean(["local_mqtt"]) | ||||||
|                     else self._settings.get(["username"]) |                     else self._settings.get(["username"]) | ||||||
|                 ), |                 ), | ||||||
|                 access_code=self._settings.get(["access_code"]), |                 "access_code": self._settings.get(["access_code"]), | ||||||
|                 local_mqtt=self._settings.get_boolean(["local_mqtt"]), |                 "local_mqtt": self._settings.get_boolean(["local_mqtt"]), | ||||||
|                 region=self._settings.get(["region"]), |                 "region": self._settings.get(["region"]), | ||||||
|                 email=self._settings.get(["email"]), |                 "email": self._settings.get(["email"]), | ||||||
|                 auth_token=self._settings.get(["auth_token"]), |                 "auth_token": self._settings.get(["auth_token"]), | ||||||
|             ) |             } | ||||||
|  |              | ||||||
|  |             # Add disable_camera parameter if it's enabled in settings | ||||||
|  |             if self._disable_camera: | ||||||
|  |                 self._log.info("Camera functionality is disabled in settings") | ||||||
|  |                 client_params["disable_camera"] = True | ||||||
|  |                 client_params["enable_camera_stream"] = False | ||||||
|  |              | ||||||
|  |             try: | ||||||
|  |                 bambu_client = BambuClient(**client_params) | ||||||
|  |             except TypeError as e: | ||||||
|  |                 # Handle the case where pybambu doesn't support these parameters yet | ||||||
|  |                 if "disable_camera" in str(e) or "enable_camera_stream" in str(e): | ||||||
|  |                     self._log.warning("This version of pybambu doesn't support camera disabling parameters, trying without them") | ||||||
|  |                     if "disable_camera" in client_params: | ||||||
|  |                         del client_params["disable_camera"] | ||||||
|  |                     if "enable_camera_stream" in client_params: | ||||||
|  |                         del client_params["enable_camera_stream"] | ||||||
|  |                     bambu_client = BambuClient(**client_params) | ||||||
|  |                 else: | ||||||
|  |                     raise | ||||||
|          |          | ||||||
|         bambu_client.on_disconnect = self.on_disconnect(bambu_client.on_disconnect) |         bambu_client.on_disconnect = self.on_disconnect(bambu_client.on_disconnect) | ||||||
|         bambu_client.on_connect = self.on_connect(bambu_client.on_connect) |         bambu_client.on_connect = self.on_connect(bambu_client.on_connect) | ||||||
| @@ -898,6 +936,15 @@ class BambuVirtualPrinter: | |||||||
|         while connection_attempts < max_attempts: |         while connection_attempts < max_attempts: | ||||||
|             try: |             try: | ||||||
|                 self._log.info(f"Connection attempt {connection_attempts + 1}/{max_attempts}...") |                 self._log.info(f"Connection attempt {connection_attempts + 1}/{max_attempts}...") | ||||||
|  |                  | ||||||
|  |                 # Check if we need to wait based on backoff | ||||||
|  |                 current_time = time.time() | ||||||
|  |                 if current_time - self._last_connection_attempt < self._connection_retry_backoff: | ||||||
|  |                     wait_time = self._connection_retry_backoff - (current_time - self._last_connection_attempt) | ||||||
|  |                     self._log.debug(f"Waiting {wait_time:.1f}s before retry due to backoff") | ||||||
|  |                     time.sleep(wait_time) | ||||||
|  |                  | ||||||
|  |                 self._last_connection_attempt = time.time() | ||||||
|                 bambu_client.connect(callback=self.new_update) |                 bambu_client.connect(callback=self.new_update) | ||||||
|                  |                  | ||||||
|                 # Wait a moment to verify connection |                 # Wait a moment to verify connection | ||||||
| @@ -905,14 +952,27 @@ class BambuVirtualPrinter: | |||||||
|                  |                  | ||||||
|                 if bambu_client.connected: |                 if bambu_client.connected: | ||||||
|                     self._log.info(f"Bambu connection successful: {bambu_client.connected}") |                     self._log.info(f"Bambu connection successful: {bambu_client.connected}") | ||||||
|  |                     # Reset connection error flags on successful connection | ||||||
|  |                     self._connection_error_logged = False | ||||||
|  |                     self._connection_retry_backoff = 10  # Reset backoff on success | ||||||
|                     break |                     break | ||||||
|                  |                  | ||||||
|                 self._log.warning("Connection attempt failed, retrying...") |                 self._log.warning("Connection attempt failed, retrying...") | ||||||
|                 connection_attempts += 1 |                 connection_attempts += 1 | ||||||
|  |                 # Increase backoff time for future connection attempts | ||||||
|  |                 self._connection_retry_backoff = min(300, self._connection_retry_backoff * 2)  # Cap at 5 minutes | ||||||
|                 time.sleep(retry_delay) |                 time.sleep(retry_delay) | ||||||
|             except Exception as e: |             except Exception as e: | ||||||
|                 self._log.error(f"Error during connection attempt {connection_attempts + 1}: {str(e)}", exc_info=True) |                 if not self._connection_error_logged: | ||||||
|  |                     self._log.error(f"Error during connection attempt {connection_attempts + 1}: {str(e)}", exc_info=True) | ||||||
|  |                     self._connection_error_logged = True | ||||||
|  |                 else: | ||||||
|  |                     self._log.debug(f"Repeated connection error during attempt {connection_attempts + 1}: {str(e)}") | ||||||
|  |                      | ||||||
|                 connection_attempts += 1 |                 connection_attempts += 1 | ||||||
|  |                 # Increase backoff time for future connection attempts | ||||||
|  |                 self._connection_retry_backoff = min(300, self._connection_retry_backoff * 2) | ||||||
|  |                  | ||||||
|                 if connection_attempts < max_attempts: |                 if connection_attempts < max_attempts: | ||||||
|                     time.sleep(retry_delay) |                     time.sleep(retry_delay) | ||||||
|          |          | ||||||
| @@ -922,6 +982,40 @@ class BambuVirtualPrinter: | |||||||
|         self._log.info(f"Custom connection status: {self.is_connected}") |         self._log.info(f"Custom connection status: {self.is_connected}") | ||||||
|         self.sendOk() |         self.sendOk() | ||||||
|  |  | ||||||
|  |     def _patch_bambu_client_for_connection_errors(self): | ||||||
|  |         """Patch the BambuClient instance to handle connection errors gracefully""" | ||||||
|  |         if not self._bambu_client: | ||||||
|  |             return | ||||||
|  |          | ||||||
|  |         # If we need to modify how the library handles connection errors, particularly | ||||||
|  |         # for the Chamber Image functionality, we can patch the relevant methods here | ||||||
|  |          | ||||||
|  |         # Check if the client has chamber image functionality and it's causing errors | ||||||
|  |         if hasattr(self._bambu_client, '_chamber_image_thread') and self._bambu_client._chamber_image_thread: | ||||||
|  |             original_run = None | ||||||
|  |              | ||||||
|  |             # Find the run function in the thread class | ||||||
|  |             if hasattr(self._bambu_client._chamber_image_thread, 'run'): | ||||||
|  |                 original_run = self._bambu_client._chamber_image_thread.run | ||||||
|  |                  | ||||||
|  |                 # Create a wrapper that catches connection errors | ||||||
|  |                 def patched_run(*args, **kwargs): | ||||||
|  |                     try: | ||||||
|  |                         return original_run(*args, **kwargs) | ||||||
|  |                     except ConnectionRefusedError as e: | ||||||
|  |                         # Only log first occurrence to avoid log spam | ||||||
|  |                         if not self._camera_error_logged: | ||||||
|  |                             self._log.warning(f"Chamber image connection refused: {str(e)}. Further errors will be suppressed.") | ||||||
|  |                             self._camera_error_logged = True | ||||||
|  |                         return None | ||||||
|  |                     except Exception as e: | ||||||
|  |                         self._log.error(f"Chamber image error: {str(e)}", exc_info=True) | ||||||
|  |                         return None | ||||||
|  |                  | ||||||
|  |                 # Apply the patched method | ||||||
|  |                 self._bambu_client._chamber_image_thread.run = patched_run | ||||||
|  |                 self._log.debug("Patched chamber image thread to handle connection errors") | ||||||
|  |  | ||||||
|     def publish_mqtt(self, topic, payload): |     def publish_mqtt(self, topic, payload): | ||||||
|         """Publish a message to the MQTT broker""" |         """Publish a message to the MQTT broker""" | ||||||
|         if self._mqtt_client and self._mqtt_connected: |         if self._mqtt_client and self._mqtt_connected: | ||||||
|   | |||||||
							
								
								
									
										17
									
								
								templates/bambu_printer_settings.jinja2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								templates/bambu_printer_settings.jinja2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | <div class="control-group"> | ||||||
|  |     <label class="control-label">{{ _('Connection Options') }}</label> | ||||||
|  |     <div class="controls"> | ||||||
|  |         <label class="checkbox"> | ||||||
|  |             <input type="checkbox" data-bind="checked: settings.plugins.bambu_printer.use_mqtt_bridge"> {{ _('Use MQTT Bridge') }} | ||||||
|  |             <span class="help-block"> | ||||||
|  |                 {{ _('Connect via a MQTT broker that bridges communications from the printer. Useful for connecting to a printer on a different network.') }} | ||||||
|  |             </span> | ||||||
|  |         </label> | ||||||
|  |         <label class="checkbox"> | ||||||
|  |             <input type="checkbox" data-bind="checked: settings.plugins.bambu_printer.disable_camera"> {{ _('Disable Camera Functionality') }} | ||||||
|  |             <span class="help-block"> | ||||||
|  |                 {{ _('Disable camera streaming and image capture to avoid connection errors. Enable this if you see frequent connection refused errors in the logs.') }} | ||||||
|  |             </span> | ||||||
|  |         </label> | ||||||
|  |     </div> | ||||||
|  | </div> | ||||||
		Reference in New Issue
	
	Block a user