Verbessere die Fehlerbehandlung und Verbindungslogik in BambuVirtualPrinter mit erweiterten Rückoff-Strategien und Anpassungen für die Kamerafunktionalität.
This commit is contained in:
parent
c5c6ed037e
commit
a8cf4957ec
@ -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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user