- Virtual printer appears in Bambu Studio/Orca Slicer via SSDP discovery
- Secure TLS/MQTT communication with auto-generated certificates
- Queue mode (pending uploads) or auto-start mode
- Configurable access code for authentication
- Docker support with network_mode: host and certificate persistence
- Fix backup/restore for virtual printer settings (auto-save no longer overwrites)
- Add fuzzy color matching for filament comparison
Colors within RGB threshold of 40 are considered a match, fixing
cases where 3MF and printer report slightly different hex values
for the same filament color (e.g., beige #F5F5DC vs #FCECD6)
- Add POST /printers/{id}/refresh-status endpoint
Sends MQTT pushall command to request fresh AMS data from printer
- Improve Re-read button in filament check section
- Now triggers backend refresh before refetching status
- More prominent styling with text label and border
- 500ms delay after pushall to allow printer to respond
- Add AMS slot labels to matched filament display
Shows location like "PLA (AMS-B Slot 3)" instead of just "PLA"
- Add color hex tooltips on filament color circles
New Features (0.1.6b)
Smart Plugs
- Tasmota device discovery - Auto-detect network and scan for Tasmota devices. Supports devices with/without authentication.
- Switchbar quick access - Sidebar widget for controlling smart plugs from anywhere. Shows real-time status and power consumption.
Timelapse
- Timelapse editor - Trim, speed adjustment (0.25x-4x), and music overlay with FFmpeg server-side processing.
Printer Discovery & Cards
- Docker subnet scanning - Auto-detect Docker environment and enable subnet input for discovering printers
- Printer model mapping - Show friendly names (X1C, H2D, P1S) instead of raw SSDP codes
- Detailed status stages - Show heater states and print status stages on printer cards
- Dual nozzle temperature - Fixed display for H2D printers
Archives & Projects
- AMS filament preview - Reprint modal shows filament comparison (type + color match indicators)
- File type badges - GCODE (green) or SOURCE (orange) badges on archive cards
- Project filament colors - Display filament swatches from assigned archives
- BOM filter - "Hide done" toggle for completed items
- Projects in backup/restore - Include projects, BOM items, and attachments
- Attachment validation - File type validation for project attachments
Maintenance
- Custom maintenance types - No longer auto-assign to all printers; manual per-printer assignment
- Delete printer options - Choose to keep or delete archives when deleting a printer
UI Improvements
- Project card design - Enhanced with gradients, shadows, and glow effects
- Confirmation modals - Replace browser confirm dialogs with styled modals
- Default timelapse speed - Changed from 2x to 1x
---
Bug Fixes
- Notifications sent when printer offline - Fixed notification module
- Camera stream stopping - Increased timeouts, added auto-reconnection with exponential backoff
- A1/P1 camera streaming - Fixed with extended timeouts and lower FPS cap; removed deprecated -stimeout option
- Attachment uploads not persisting - Fixed SQLAlchemy JSON column mutation detection
- Total print hours calculation - Now includes all prints, not just completed
- Mock state bug - Fixed in test fixtures
- Features:
- Tasmota device discovery: Auto-detect network and scan for Tasmota devices
in Add Smart Plug modal. Supports devices with/without authentication.
- Switchbar: Quick access widget in sidebar footer for controlling smart plugs
from anywhere in the app. Shows real-time status and power consumption.
- AMS Filament Preview:
- Add GET /archives/{id}/filament-requirements endpoint to extract
filament data from archived 3MF slice_info.config
- Show filament comparison in reprint modal when printer is selected
- Compare both filament type AND color with visual indicators:
- Green checkmark: Type and color match
- Yellow warning: Same type, different color
- Orange warning: Different type or empty slot
- Handle AMS-HT units (id >= 128) and virtual tray (slot 254)
- Normalize color formats between API (RRGGBBAA) and 3MF (#RRGGBB)
- File Type Badge:
- Archive cards show GCODE (green) or SOURCE (orange) badge
- Helps users identify which files have print data vs source-only
- Badge appears next to printer name in card content area
- Camera Stream Stability:
- Increase ffmpeg read timeout from 10s to 30s
- Add ffmpeg RTSP options: -timeout, -buffer_size, -max_delay
- Add frontend auto-reconnection with exponential backoff (2s-30s)
- Show reconnection UI with countdown and attempt counter
- Add TimelapseEditorModal component with visual timeline scrubber
- Add timelapse processing endpoints (info, thumbnails, process)
- Add TimelapseProcessor service using FFmpeg for video processing
- Support trim (start/end), speed (0.25x-4x), and audio overlay
- Add Edit button to TimelapseViewer
- Fix browser caching with timestamp query parameter
- Change default timelapse playback speed from 2x to 1x
- Detect Docker environment automatically via /.dockerenv and cgroup
- Show subnet input field in Add Printer dialog when running in Docker
- Scan IP range for Bambu printer ports (8883 MQTT, 990 FTPS)
- Query SSDP to get printer name/serial/model from discovered IPs
- Map raw SSDP model codes to friendly names (BL-P001→X1C, O1D→H2D)
1. "Unknown Status (255)" bug
File: backend/app/services/printer_manager.py:291-293
Problem: A1/P1 printers send stg_cur=255 when idle (unlike X1 which uses -1). The code treated 255 as a valid stage number and returned "Unknown stage (255)".
Fix: Changed the condition from if state.stg_cur >= 0: to if 0 <= state.stg_cur < 255: so that 255 is now treated as "no calibration stage" (same as -1).
2. AMS humidity/temp displaced on mobile
File: frontend/src/pages/PrintersPage.tsx:1164-1212
Problem: The AMS row used a rigid horizontal flex layout that didn't adapt to narrow mobile screens, causing humidity/temperature indicators to be displaced.
Fix:
- Added flex-wrap to allow wrapping on very narrow screens
- Added ml-auto to humidity/temp section to keep it right-aligned
- Added max-w-[60px] sm:max-w-none to truncate long filament names on mobile
- Changed gap from fixed gap-3 to responsive gap-2 sm:gap-3
Tests Added
4 new unit tests for get_derived_status_name:
- test_stg_cur_255_returns_none - Verifies A1/P1 idle state
- test_stg_cur_negative_one_returns_none_when_idle - Verifies X1 idle state
- test_valid_stage_returns_name - Verifies valid stages work
- test_stg_cur_zero_returns_printing - Verifies printing state
All 382 tests pass.
prints (not just completed), matching get_printer_total_hours behavior
- Add option to keep or delete archives when deleting a printer
- Custom maintenance types no longer auto-assign to all printers
- Add UI to manually assign/remove custom maintenance types per printer
- Add backend endpoints for assigning types to printers and removing items
- Exclude static/assets from large file pre-commit check
- Fix A1/P1 camera streaming with extended timeouts and lower FPS cap
prints (not just completed), matching get_printer_total_hours behavior
- Add option to keep or delete archives when deleting a printer
- Custom maintenance types no longer auto-assign to all printers
- Add UI to manually assign/remove custom maintenance types per printer
- Add backend endpoints for assigning types to printers and removing items
- Exclude static/assets from large file pre-commit check
- Use extruder_info[0].temp for right nozzle instead of nozzle_temper field which incorrectly mirrors left nozzle
- Gate dual nozzle parsing with has_h2d_extruder_info to prevent single nozzle printers showing two temps
- Add nozzle_heating calculation for single nozzle printers
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add getStatusDisplay() helper in frontend to format status nicely
- Add get_derived_status_name() in backend to compute status from:
- stg_cur calibration stages (bed leveling, vibration comp, etc.)
- Temperature data when stg_cur unavailable (heating heatbed/nozzle)
- Include stg_cur and stg_cur_name in WebSocket broadcasts
- Update broadcast status key to detect heating phase changes
Printer cards now show: "Heating heatbed", "Heating nozzle", "Preparing",
"Auto bed leveling", "Cleaning nozzle tip", and 60+ other stage names
instead of just "Printing" or "Idle".
Release Notes for 0.1.5
Highlights
This release focuses on stability improvements and bug fixes, with major fixes for browser freezing and UI responsiveness issues.
Bug Fixes
- Browser freeze on print completion - Fixed a critical issue where the browser would freeze when a print completed with the camera stream open. The fix uses buffered camera frames instead of spawning duplicate ffmpeg processes.
- Printer status "timelapse" effect - Fixed an issue where navigating to the printer page after a print completed showed metrics animating slowly from mid-print values to the final state. Printer status messages now bypass the throttled queue for immediate updates.
- Timelapse auto-download - Complete rewrite with retry mechanism and support for multiple storage paths.
- Timelapse detection for H2D - Fixed detection using the correct ipcam.timelapse field instead of xcam.timelapse.
- Reprint from archive - Fixed bug where the print button sent the slicer source file instead of the sliced gcode.
- Import shadowing bugs - Fixed ArchiveService import shadowing causing "cannot access local variable" errors.
New Features
- Failure reason detection - Automatically detects failure reasons from HMS errors (filament runout, layer shift, clogged nozzle)
- Hide failed prints filter - Toggle to hide failed/aborted prints with localStorage persistence
- Docker test suite - Comprehensive tests for build, backend, frontend, and integration
- Pre-commit hooks - Ruff linter and formatter for code quality
- Code quality tests - Static analysis to catch import shadowing bugs automatically
Changes
- Timelapse viewer default playback speed changed from 0.5x to 2x
- Archive badges now show "cancelled" for aborted prints
- WebSocket throttle reduced to 100ms for smoother updates
- Added ffmpeg to Docker image
Upgrading
cd bambuddy && git pull && docker compose up -d --build
Or use the auto-update feature in Settings.
Highlights
This release focuses on stability improvements and bug fixes, with major fixes for browser freezing and UI responsiveness issues.
Bug Fixes
- Browser freeze on print completion - Fixed a critical issue where the browser would freeze when a print completed with the camera stream open. The fix uses buffered camera frames instead of spawning duplicate ffmpeg processes.
- Printer status "timelapse" effect - Fixed an issue where navigating to the printer page after a print completed showed metrics animating slowly from mid-print values to the final state. Printer status messages now bypass the throttled queue for immediate updates.
- Timelapse auto-download - Complete rewrite with retry mechanism and support for multiple storage paths.
- Timelapse detection for H2D - Fixed detection using the correct ipcam.timelapse field instead of xcam.timelapse.
- Reprint from archive - Fixed bug where the print button sent the slicer source file instead of the sliced gcode.
- Import shadowing bugs - Fixed ArchiveService import shadowing causing "cannot access local variable" errors.
New Features
- Failure reason detection - Automatically detects failure reasons from HMS errors (filament runout, layer shift, clogged nozzle)
- Hide failed prints filter - Toggle to hide failed/aborted prints with localStorage persistence
- Docker test suite - Comprehensive tests for build, backend, frontend, and integration
- Pre-commit hooks - Ruff linter and formatter for code quality
- Code quality tests - Static analysis to catch import shadowing bugs automatically
Changes
- Timelapse viewer default playback speed changed from 0.5x to 2x
- Archive badges now show "cancelled" for aborted prints
- WebSocket throttle reduced to 100ms for smoother updates
- Added ffmpeg to Docker image
Upgrading
cd bambuddy && git pull && docker compose up -d --build
Or use the auto-update feature in Settings.
When navigating to the printer page after a print completed, status
metrics would animate slowly from mid-print values to final state.
Root cause: The message queue processed messages one at a time with 16ms
delays. If 50+ status updates queued during a print, they took 800ms+ to
process, causing multiple throttle windows and the visual "timelapse".
Solution: Handle printer_status messages directly without queueing.
They're already throttled (100ms) so don't need queue rate limiting.
Other message types still use the queue.
Root cause: When a print completed with the camera stream popup open,
spawning a second ffmpeg process for finish photo capture caused a
conflict that froze the browser tab and video window.
Solution: Buffer the last frame from active camera streams. When
capturing finish photo, use the buffered frame if a stream is active
instead of spawning a new ffmpeg process.
Backend changes:
- camera.py: Added _last_frames buffer and get_buffered_frame() helper
- main.py: Photo capture uses buffered frame when stream is active
- main.py: Moved slow operations to background tasks (energy calc,
photo capture, smart plug, notifications, maintenance)
- archive.py: Fixed sync file write blocking event loop (asyncio.to_thread)
- printers.py: Added debug endpoint to simulate print completion
Frontend changes:
- useWebSocket.ts: Throttled printer status updates (100ms) to prevent
UI overload from rapid WebSocket messages
- useWebSocket.ts: Debounced archive invalidations (3s) to prevent
cascade of re-renders on print completion
- useWebSocket.test.ts: Updated tests for throttled/debounced handlers
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend (backend/app/api/routes/archives.py):
- Added filament_colors extraction from slice_info.config in 3MF files
- Maps filament IDs (1-based) to tool numbers (0-based)
Frontend (frontend/src/components/GcodeViewer.tsx):
1. Multi-color support: Pass extrusionColor as array of CSS color strings for multi-color prints
2. Bambu T-command filtering: Filter out special Bambu commands (T255, T1000, T1001, T65535, T65279) that corrupt tool state
3. Initial tool: Prepend T0 to ensure initial tool is set correctly
4. Disable gradient: Set disableGradient: true for multi-color to preserve actual filament colors (the gradient was turning black into gray/white)
5. Disable topLayerColor: Don't set topLayerColor for multi-color (it overrides per-tool colors)
Key fixes for Bambu G-code compatibility:
- Bambu uses special T commands (T1000, T65535, etc.) that aren't real tool changes
- The gcode-preview library's brightness gradient was modifying colors based on layer index
Commit message suggestion:
Add multi-color filament support to G-code viewer
- Extract filament colors from 3MF slice_info.config
- Pass color array to gcode-preview for tool-based coloring
- Filter Bambu special T commands (T1000, T65535, etc.)
- Disable gradient to preserve actual filament colors
When a print completes, multiple WebSocket messages are sent rapidly
(print_complete, archive_updated, etc.). Each was immediately invalidating
the archives query, causing a cascade of rapid re-renders that crashed
the browser tab.
Added debounced query invalidation to useWebSocket.ts:
- Multiple invalidation requests within 100ms are coalesced into one
- Uses requestAnimationFrame to avoid blocking the main thread
- Properly cleans up timeouts on unmount
- Cache connected state in ref to prevent flicker when status
briefly becomes undefined during query refetches
- Use cached value for shouldHide calculation instead of raw status
- Replace manual error database with 853 codes from ha-bambulab
(Source: https://github.com/greghesp/ha-bambulab)
- Filter out unknown HMS error codes from display
(Printers sometimes send duplicate/undocumented codes for same error)
- Update HMS badge count to only show known errors
- Export filterKnownHMSErrors helper for reuse across components
- Add ~80 HMS error code descriptions covering:
- 0300 series: temperature, fan, motor, force sensor, build plate errors
- 0500 series: storage, network, module communication, camera errors
- 0700 series: AMS communication, filament, hotend matching errors
- 0C00 series: toolhead camera, lidar, AI detection errors
- 1200 series: external spool errors
- Fix 0500_0400_0002_0043 description (toolhead camera dirty, not file system)
- Always link to HMS home page (wiki.bambulab.com/en/hms/home) instead of
specific error pages that may not exist
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- The failure analysis service was only querying status == "failed"
- Changed all queries to include both failed AND aborted: status.in_(["failed", "aborted"])
- File: backend/app/services/failure_analysis.py
Issue 2: Cannot clear failed flag in edit mode
- Added status field to ArchiveUpdate schema (backend)
- Added status to API client type (frontend)
- Added status dropdown to EditArchiveModal with options: Completed, Failed, Cancelled, Printing
- When status changes to "completed", failure_reason is automatically cleared
- File changes:
- backend/app/schemas/archive.py - added status field
- frontend/src/api/client.ts - added status to updateArchive type
- frontend/src/components/EditArchiveModal.tsx - added status dropdown
This release focuses on stability improvements, particularly around timelapse handling and Docker support.
Bug Fixes
- Timelapse auto-download - Complete rewrite with retry mechanism (5s, 10s, 20s delays) and support for multiple FTP paths. Now works reliably with printers in LAN-only mode that have incorrect clocks.
- Browser tab crash - Fixed rapid re-render cascade that could crash the browser tab on print completion
- Timelapse detection for H2D - Fixed detection for H2D printers which send timelapse status in ipcam.timelapse instead of xcam.timelapse
- Reprint from archive - Fixed critical bug where the print button sent the slicer source file instead of the sliced gcode file
- Import shadowing bugs - Fixed "cannot access local variable" errors in archive service
New Features
- Automatic failure reason detection - Automatically detects and records failure reasons from HMS error codes (filament runout, layer shift, clogged nozzle)
- Hide failed prints filter - New toggle to hide failed/aborted prints from the archive view (persists across sessions)
- Docker test suite - Comprehensive automated tests for Docker builds
Improvements
- Timelapse viewer default speed changed to 2x
- Archive badges now show "cancelled" for user-stopped prints
- WebSocket messages optimized (smaller payloads)
- Pre-commit hooks added for code quality (ruff)
Docker
- Added ffmpeg for video processing
- Fixed build warnings
- Comprehensive Docker documentation added to README
- Initialize i18n in test setup to suppress 'NO_I18NEXT_INSTANCE' warning
- Update AMSHistoryModal tests to use actual translated text
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>