Browse Source

Fixed bug archiving file on print start

Martin Ziegler 6 months ago
parent
commit
a3167562bb
2 changed files with 60 additions and 20 deletions
  1. 36 20
      backend/app/main.py
  2. 24 0
      backend/app/services/bambu_mqtt.py

+ 36 - 20
backend/app/main.py

@@ -1,9 +1,16 @@
 import asyncio
 import asyncio
+import logging
 from datetime import datetime
 from datetime import datetime
 from contextlib import asynccontextmanager
 from contextlib import asynccontextmanager
 from pathlib import Path
 from pathlib import Path
 
 
 from fastapi import FastAPI
 from fastapi import FastAPI
+
+# Configure logging for all modules
+logging.basicConfig(
+    level=logging.INFO,
+    format='%(asctime)s %(levelname)s [%(name)s] %(message)s'
+)
 from fastapi.staticfiles import StaticFiles
 from fastapi.staticfiles import StaticFiles
 from fastapi.responses import FileResponse
 from fastapi.responses import FileResponse
 
 
@@ -67,21 +74,26 @@ async def on_print_start(printer_id: int, data: dict):
         # Build list of possible 3MF filenames to try
         # Build list of possible 3MF filenames to try
         possible_names = []
         possible_names = []
 
 
+        # Bambu printers typically store files as "Name.gcode.3mf"
+        # The subtask_name is usually the best source for the filename
+        if subtask_name:
+            # Try common Bambu naming patterns
+            possible_names.append(f"{subtask_name}.gcode.3mf")
+            possible_names.append(f"{subtask_name}.3mf")
+
         # Try original filename with .3mf extension
         # Try original filename with .3mf extension
         if filename:
         if filename:
-            if filename.endswith(".3mf"):
-                possible_names.append(filename)
-            elif filename.endswith(".gcode"):
-                base = filename.rsplit(".", 1)[0]
+            # Extract just the filename part, not the full path
+            fname = filename.split("/")[-1] if "/" in filename else filename
+            if fname.endswith(".3mf"):
+                possible_names.append(fname)
+            elif fname.endswith(".gcode"):
+                base = fname.rsplit(".", 1)[0]
+                possible_names.append(f"{base}.gcode.3mf")
                 possible_names.append(f"{base}.3mf")
                 possible_names.append(f"{base}.3mf")
             else:
             else:
-                # No extension - try adding .3mf
-                possible_names.append(f"{filename}.3mf")
-                possible_names.append(filename)
-
-        # Try subtask_name with .3mf extension
-        if subtask_name and subtask_name != filename:
-            possible_names.append(f"{subtask_name}.3mf")
+                possible_names.append(f"{fname}.gcode.3mf")
+                possible_names.append(f"{fname}.3mf")
 
 
         # Remove duplicates while preserving order
         # Remove duplicates while preserving order
         seen = set()
         seen = set()
@@ -107,15 +119,19 @@ async def on_print_start(printer_id: int, data: dict):
             temp_path.parent.mkdir(parents=True, exist_ok=True)
             temp_path.parent.mkdir(parents=True, exist_ok=True)
 
 
             for remote_path in remote_paths:
             for remote_path in remote_paths:
-                if await download_file_async(
-                    printer.ip_address,
-                    printer.access_code,
-                    remote_path,
-                    temp_path,
-                ):
-                    downloaded_filename = try_filename
-                    logger.info(f"Downloaded: {remote_path}")
-                    break
+                logger.debug(f"Trying FTP download: {remote_path}")
+                try:
+                    if await download_file_async(
+                        printer.ip_address,
+                        printer.access_code,
+                        remote_path,
+                        temp_path,
+                    ):
+                        downloaded_filename = try_filename
+                        logger.info(f"Downloaded: {remote_path}")
+                        break
+                except Exception as e:
+                    logger.debug(f"FTP download failed for {remote_path}: {e}")
 
 
             if downloaded_filename:
             if downloaded_filename:
                 break
                 break

+ 24 - 0
backend/app/services/bambu_mqtt.py

@@ -1,6 +1,7 @@
 import json
 import json
 import ssl
 import ssl
 import asyncio
 import asyncio
+import logging
 from collections import deque
 from collections import deque
 from datetime import datetime
 from datetime import datetime
 from typing import Callable
 from typing import Callable
@@ -8,6 +9,8 @@ from dataclasses import dataclass, field
 
 
 import paho.mqtt.client as mqtt
 import paho.mqtt.client as mqtt
 
 
+logger = logging.getLogger(__name__)
+
 
 
 @dataclass
 @dataclass
 class MQTTLogEntry:
 class MQTTLogEntry:
@@ -114,6 +117,12 @@ class BambuMQTTClient:
         """Process incoming MQTT message from printer."""
         """Process incoming MQTT message from printer."""
         if "print" in payload:
         if "print" in payload:
             print_data = payload["print"]
             print_data = payload["print"]
+            # Log when we see gcode_state changes
+            if "gcode_state" in print_data:
+                logger.info(
+                    f"[{self.serial_number}] Received gcode_state: {print_data.get('gcode_state')}, "
+                    f"gcode_file: {print_data.get('gcode_file')}, subtask_name: {print_data.get('subtask_name')}"
+                )
             self._update_state(print_data)
             self._update_state(print_data)
 
 
     def _update_state(self, data: dict):
     def _update_state(self, data: dict):
@@ -190,6 +199,13 @@ class BambuMQTTClient:
 
 
         self.state.raw_data = data
         self.state.raw_data = data
 
 
+        # Log state transitions for debugging
+        if "gcode_state" in data:
+            logger.debug(
+                f"[{self.serial_number}] gcode_state: {self._previous_gcode_state} -> {self.state.state}, "
+                f"file: {self.state.gcode_file}, subtask: {self.state.subtask_name}"
+            )
+
         # Detect print start (state changes TO RUNNING with a file)
         # Detect print start (state changes TO RUNNING with a file)
         current_file = self.state.gcode_file or self.state.current_print
         current_file = self.state.gcode_file or self.state.current_print
         is_new_print = (
         is_new_print = (
@@ -206,6 +222,10 @@ class BambuMQTTClient:
         )
         )
 
 
         if (is_new_print or is_file_change) and self.on_print_start:
         if (is_new_print or is_file_change) and self.on_print_start:
+            logger.info(
+                f"[{self.serial_number}] PRINT START detected - file: {current_file}, "
+                f"subtask: {self.state.subtask_name}, is_new: {is_new_print}, is_file_change: {is_file_change}"
+            )
             self.on_print_start({
             self.on_print_start({
                 "filename": current_file,
                 "filename": current_file,
                 "subtask_name": self.state.subtask_name,
                 "subtask_name": self.state.subtask_name,
@@ -218,6 +238,10 @@ class BambuMQTTClient:
             and self.state.state in ("FINISH", "FAILED")
             and self.state.state in ("FINISH", "FAILED")
             and self.on_print_complete
             and self.on_print_complete
         ):
         ):
+            logger.info(
+                f"[{self.serial_number}] PRINT COMPLETE detected - state: {self.state.state}, "
+                f"file: {self._previous_gcode_file or current_file}"
+            )
             self.on_print_complete({
             self.on_print_complete({
                 "status": "completed" if self.state.state == "FINISH" else "failed",
                 "status": "completed" if self.state.state == "FINISH" else "failed",
                 "filename": self._previous_gcode_file or current_file,
                 "filename": self._previous_gcode_file or current_file,