diff --git a/CHANGELOG.md b/CHANGELOG.md index 588438792..5a70c2fbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ All notable changes to Bambuddy will be documented in this file. - **Spool Edit Form Overwrites Usage-Tracked Weight** — Editing any spool field (note, color, material, etc.) sent the full form data back to the server, including `weight_used`. If the frontend cache was stale (e.g., loaded before the last print completed), saving the form would silently reset `weight_used` to the pre-print value, reverting the remaining weight to full. The form now only includes `weight_used` in the update request when the user explicitly changes the weight field. - **K-Profile Auto-Select Fails for Non-BL Spools on Dual-Nozzle Printers** — When assigning a third-party spool to an AMS slot on dual-nozzle printers (H2D, H2D Pro), the MQTT auto-configure step crashed with `'SpoolKProfile' object has no attribute 'extruder_id'`. The K-profile model uses `extruder` (not `extruder_id`). Fixed the attribute name so K-profile matching correctly filters by nozzle on dual-extruder printers. - **Loose Archive Name Matching Could Cause Wrong Archive Reuse** ([#374](https://github.com/maziggy/bambuddy/issues/374)) — The `on_print_start` callback used `ilike('%{name}%')` to find existing "printing" archives, which meant a print named "Clip" could incorrectly match "Cable Clip" or "Clip Stand". This could cause a new print to reuse the wrong archive or skip creating one. Tightened to exact `print_name` match or exact filename variants (`.3mf`, `.gcode.3mf`). +- **Phantom Prints on Power Cycle** ([#374](https://github.com/maziggy/bambuddy/issues/374)) — The print queue uploaded `.3mf` files to the printer's SD card root (`/`) but never deleted them after the print finished. Some printers (e.g. P1S) auto-start files found in the root directory on power cycle, causing ghost prints on every reboot. Now deletes the uploaded file from the SD card after print completion (best-effort, non-blocking). - **Archive Duplicate Badge Misses Name-Based Duplicates** ([#315](https://github.com/maziggy/bambuddy/issues/315)) — The duplicate badge on archive cards only matched by file content hash, so re-sliced prints of the same model (different GCODE, same print name) were not flagged as duplicates. Now also matches by print name (case-insensitive), consistent with the detail view's duplicate detection. ### Improved diff --git a/backend/app/main.py b/backend/app/main.py index 2101a1a94..27fbc66f7 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -2759,6 +2759,31 @@ async def on_print_complete(printer_id: int, data: dict): logging.getLogger(__name__).warning(f"Queue item update failed: {e}") log_timing("Queue item update") + + # Cleanup: delete uploaded file from printer SD card to prevent phantom prints (Issue #374) + # The print scheduler uploads .3mf files to the SD card root (/). Some printers (e.g. P1S) + # auto-start files found in root on power cycle, causing ghost prints. + try: + printer_info = printer_manager.get_printer(printer_id) + if printer_info and subtask_name: + from backend.app.services.bambu_ftp import delete_file_async + + remote_path = f"/{subtask_name}.3mf" + logger.info("Cleaning up uploaded file from printer SD card: %s", remote_path) + delete_result = await delete_file_async( + printer_info.ip_address, + printer_info.access_code, + remote_path, + printer_model=printer_info.model, + ) + if delete_result: + logger.info("Deleted %s from printer %s SD card", remote_path, printer_info.name) + else: + logger.debug("File delete returned False for %s (may not exist)", remote_path) + except Exception as e: + logger.debug("SD card file cleanup failed for printer %s: %s (non-critical)", printer_id, e) + + log_timing("SD card cleanup") logger.info("[CALLBACK] on_print_complete finished for printer %s, archive %s", printer_id, archive_id)