Browse Source

Fix VP queue mode missing AMS mapping for printer-specific items (#529)

The print scheduler had two code paths for queue items: model-based
(target_model set) and printer-specific (printer_id set). Only the
model-based path computed ams_mapping before starting the print. VP
queue items assigned to a specific printer went through the
printer-specific path with null ams_mapping, causing the printer to
default to the first AMS slot regardless of what the 3MF required.

Add _compute_ams_mapping_for_printer() call to the printer-specific
path, matching the existing model-based behavior.
maziggy 2 months ago
parent
commit
2284a76381
2 changed files with 13 additions and 3 deletions
  1. 1 1
      CHANGELOG.md
  2. 12 2
      backend/app/services/print_scheduler.py

+ 1 - 1
CHANGELOG.md

@@ -5,7 +5,7 @@ All notable changes to Bambuddy will be documented in this file.
 ## [0.2.1] - Unreleased
 
 ### Fixed
-- **Virtual Printer Queue Sends Wrong Plate ID** ([#529](https://github.com/maziggy/bambuddy/issues/529)) — Files sent to a virtual printer in queue mode always used `plate_id=1`, generating the MQTT path `Metadata/plate_1.gcode`. For multi-plate 3MF files where the actual plate is different (e.g. plate 19), the printer couldn't find the gcode and returned HMS error 0500_4003. Now extracts the plate index from the 3MF's `slice_info.config` before creating the queue item.
+- **Virtual Printer Queue Sends Wrong Plate ID and Ignores AMS Mapping** ([#529](https://github.com/maziggy/bambuddy/issues/529)) — Files sent to a virtual printer in queue mode had two issues. First, `plate_id` was always `1`, generating the wrong MQTT gcode path for multi-plate 3MF files (HMS error 0500_4003). Now extracts the plate index from the 3MF's `slice_info.config`. Second, `ams_mapping` was never computed for printer-specific queue items (VP assigned to a particular printer), so the printer always used the first AMS slot regardless of which filament the 3MF required. The scheduler now computes AMS mapping for all queue items that lack one, not just model-based assignments.
 - **Unnecessary Target Model Selector on "Any" Tab** ([#528](https://github.com/maziggy/bambuddy/issues/528)) — When scheduling a print to "Any {model}", a redundant "Target Model" dropdown appeared even though the G-code is already sliced for a specific printer model. Changing the target model would lead to print failures. The dropdown is now hidden when the sliced model is known (the tab label already shows "Any {model}"). It still appears as a fallback for legacy files without model metadata.
 - **"Clear Plate & Start Next" Button Shown on Printers Without Correct Filament** ([#527](https://github.com/maziggy/bambuddy/issues/527)) — When a print job was queued for "any printer" of a model (e.g., "any H2S"), the "Clear Plate & Start Next" button appeared on ALL printers of that model, including those without the required filament loaded. Clicking it on a printer without the right filament would start a print that fails. The `PrinterQueueWidget` now filters queue items by filament compatibility — it checks the printer's loaded filament types (from AMS and external spools) against the queue item's `required_filament_types` and only shows items the printer can actually print. If no compatible items exist, the widget is hidden.
 - **Manual Spool Weight Overwritten by AMS Auto-Sync** ([#525](https://github.com/maziggy/bambuddy/issues/525)) — When a user manually entered a spool weight (via UI or API), the value was overwritten by the automatic AMS remain% sync that runs on every MQTT update. The AMS remain% is integer-only (~10g resolution for 1kg spool) and can't match precise manual entries. Added a `weight_locked` flag that is automatically set when `weight_used` is explicitly updated via the API. Locked spools are skipped by both the automatic AMS remain% sync and the manual force-sync endpoint. The usage tracker (3MF/gcode delta tracking) is unaffected. Users can re-enable AMS sync by setting `weight_locked: false`.

+ 12 - 2
backend/app/services/print_scheduler.py

@@ -140,6 +140,16 @@ class PrintScheduler:
                             )
                             continue
 
+                    # Compute AMS mapping if not already set
+                    if not item.ams_mapping:
+                        computed_mapping = await self._compute_ams_mapping_for_printer(db, item.printer_id, item)
+                        if computed_mapping:
+                            item.ams_mapping = json.dumps(computed_mapping)
+                            logger.info(
+                                f"Queue item {item.id}: Computed AMS mapping for printer {item.printer_id}: {computed_mapping}"
+                            )
+                            await db.commit()
+
                     # Start the print
                     await self._start_print(db, item)
                     busy_printers.add(item.printer_id)
@@ -429,8 +439,8 @@ class PrintScheduler:
     ) -> list[int] | None:
         """Compute AMS mapping for a printer based on filament requirements.
 
-        This is called for model-based queue items after a printer is assigned,
-        to compute the correct AMS slot mapping for that specific printer's hardware.
+        Called when a queue item has no ams_mapping set — either for model-based
+        items after printer assignment, or printer-specific items (e.g. from VP).
 
         Args:
             db: Database session