diff --git a/CHANGELOG.md b/CHANGELOG.md index e42b4645a..35063d36f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All notable changes to Bambuddy will be documented in this file. ## [0.2.1b] - Not released ### Fixed +- **PAUSED State Never Matched** ([#447](https://github.com/maziggy/bambuddy/issues/447)) — Removed dead `PAUSED` checks across frontend and backend. The printer only sends `PAUSE` via MQTT `gcode_state`, so `PAUSED` comparisons were unreachable code. - **Nozzle Mapping Uses Wrong Source in 3MF Files** — The `extract_nozzle_mapping_from_3mf()` function used `filament_nozzle_map` (user preference) as the primary source for nozzle assignments. BambuStudio's "Auto For Flush" mode overrides user preferences at slice time, so the actual assignment lives in the `group_id` attribute on `` elements in `slice_info.config`. Now uses `group_id` as the primary source and falls back to `filament_nozzle_map` only when `group_id` is not present. - **Print Scheduler Hard-Filters Nozzle When No Trays on Target Nozzle** — On dual-nozzle printers, the scheduler enforced a strict nozzle filter when matching filaments. If a slicer filament was assigned to a nozzle with no AMS trays (e.g., only external spool on left nozzle), the match failed even though the filament existed on the other nozzle. Now falls back to unfiltered matching when no trays exist on the target nozzle. - **Print Scheduler External Spool Ignores Nozzle Assignment** — The external spool fallback in the scheduler always mapped to extruder 0 (right), ignoring the slicer's nozzle assignment. Now uses the 3MF nozzle mapping to select the correct extruder for external spool matches. diff --git a/backend/app/api/routes/printers.py b/backend/app/api/routes/printers.py index 210ad7f8d..85f902f62 100644 --- a/backend/app/api/routes/printers.py +++ b/backend/app/api/routes/printers.py @@ -226,7 +226,7 @@ async def get_printer_status( # Determine cover URL if there's an active print (including paused) cover_url = None - if state.state in ("RUNNING", "PAUSE", "PAUSED") and state.gcode_file: + if state.state in ("RUNNING", "PAUSE") and state.gcode_file: cover_url = f"/api/v1/printers/{printer_id}/cover" # Convert HMS errors to response format diff --git a/backend/app/services/printer_manager.py b/backend/app/services/printer_manager.py index 5829e8552..fadfcc065 100644 --- a/backend/app/services/printer_manager.py +++ b/backend/app/services/printer_manager.py @@ -695,8 +695,8 @@ def printer_state_to_dict(state: PrinterState, printer_id: int | None = None, mo ], } # Add cover URL if there's an active print and printer_id is provided - # Include PAUSE/PAUSED states so skip objects modal can show cover - if printer_id and state.state in ("RUNNING", "PAUSE", "PAUSED") and state.gcode_file: + # Include PAUSE state so skip objects modal can show cover + if printer_id and state.state in ("RUNNING", "PAUSE") and state.gcode_file: result["cover_url"] = f"/api/v1/printers/{printer_id}/cover" else: result["cover_url"] = None diff --git a/frontend/src/components/EmbeddedCameraViewer.tsx b/frontend/src/components/EmbeddedCameraViewer.tsx index 1ff1b124b..831bc6a08 100644 --- a/frontend/src/components/EmbeddedCameraViewer.tsx +++ b/frontend/src/components/EmbeddedCameraViewer.tsx @@ -137,7 +137,7 @@ export function EmbeddedCameraViewer({ printerId, printerName, viewerIndex = 0, }, }); - const isPrintingWithObjects = (status?.state === 'RUNNING' || status?.state === 'PAUSE' || status?.state === 'PAUSED') && (status?.printable_objects_count ?? 0) >= 2; + const isPrintingWithObjects = (status?.state === 'RUNNING' || status?.state === 'PAUSE') && (status?.printable_objects_count ?? 0) >= 2; // Save state to localStorage (printer-specific) useEffect(() => { diff --git a/frontend/src/pages/CameraPage.tsx b/frontend/src/pages/CameraPage.tsx index 4cd7fa6f8..8dd134173 100644 --- a/frontend/src/pages/CameraPage.tsx +++ b/frontend/src/pages/CameraPage.tsx @@ -82,7 +82,7 @@ export function CameraPage() { }, }); - const isPrintingWithObjects = (status?.state === 'RUNNING' || status?.state === 'PAUSE' || status?.state === 'PAUSED') && (status?.printable_objects_count ?? 0) >= 2; + const isPrintingWithObjects = (status?.state === 'RUNNING' || status?.state === 'PAUSE') && (status?.printable_objects_count ?? 0) >= 2; // Update document title useEffect(() => { diff --git a/frontend/src/pages/PrintersPage.tsx b/frontend/src/pages/PrintersPage.tsx index c48b3acdd..d25eee66f 100644 --- a/frontend/src/pages/PrintersPage.tsx +++ b/frontend/src/pages/PrintersPage.tsx @@ -1776,7 +1776,7 @@ function PrinterCard({ // Query for printable objects (for skip functionality) // Fetch when printing with 2+ objects OR when modal is open - const isPrintingWithObjects = (status?.state === 'RUNNING' || status?.state === 'PAUSE' || status?.state === 'PAUSED') && (status?.printable_objects_count ?? 0) >= 2; + const isPrintingWithObjects = (status?.state === 'RUNNING' || status?.state === 'PAUSE') && (status?.printable_objects_count ?? 0) >= 2; const { data: objectsData } = useQuery({ queryKey: ['printableObjects', printer.id], queryFn: () => api.getPrintableObjects(printer.id), @@ -2369,16 +2369,16 @@ function PrinterCard({ {/* Skip Objects button - top right corner, always visible */}