New feature: Publish BamBuddy events to external MQTT brokers for integration
with Home Assistant, Node-RED, and other automation platforms.
Backend changes:
- New MQTTRelayService (backend/app/services/mqtt_relay.py) with paho-mqtt
- MQTT settings added to AppSettings schema (enabled, broker, port, auth, TLS)
- New /settings/mqtt/status endpoint for connection status
- Event hooks in main.py, print_queue.py, print_scheduler.py, maintenance.py, smart_plugs.py
- PrinterInfo class and get_printer() method added to PrinterManager
- MQTT reconfiguration added to backup/restore flow
- Printer status throttled to 1 update/sec to avoid flooding
Frontend changes:
- New "Network" tab in Settings (between Filament and API Keys)
- FTP Retry settings moved from General to Network tab
- MQTT configuration card with broker, port, TLS toggle, auth fields
- Port auto-populates when TLS toggled (1883 ↔ 8883)
- Connection status indicator (green/red dot) in tab and card header
- Real-time status polling when on Network tab
Published topics:
- bambuddy/status - Online/offline
- bambuddy/printers/{serial}/status - Printer state (throttled)
- bambuddy/printers/{serial}/print/* - Print lifecycle
- bambuddy/printers/{serial}/ams/changed - AMS changes
- bambuddy/queue/* - Queue events
- bambuddy/maintenance/* - Maintenance alerts
- bambuddy/smart_plugs/* - Plug state/energy
- bambuddy/archive/* - Archive events
Tests:
- Added MQTT settings and status endpoint tests
Closes#78
- Moved BAMBU_HEX_COLORS mapping and getColorName()/hexToColorName() functions to a shared location
- Exported functions for use across components
- Updated modals to use shared colors:
- ReprintModal.tsx - removed ~100 lines of duplicate color code, now imports from utils/colors
- AddToQueueModal.tsx - same cleanup
- EditQueueItemModal.tsx - same cleanup
- Added AMS mapping to EditQueueItemModal:
- Added state for showFilamentMapping, isRefreshing, manualMappings
- Added queries for filament requirements and printer status
- Added loadedFilaments, filamentComparison, amsMapping memos
- Added collapsible filament mapping UI section (same as other modals)
- Initializes manualMappings from existing item.ams_mapping
- Submits ams_mapping when saving changes
- Backend changes:
- Added ams_mapping field to PrintQueueItemUpdate schema
- Updated update_queue_item route to serialize ams_mapping to JSON
- Frontend API client:
- Added ams_mapping to PrintQueueItemUpdate interface
- Changed "Print" to "Reprint" on archive card button (ArchivesPage.tsx:690)
- Bumped service worker to v22
- Comprehensive hex-based color mapping (~200 Bambu colors from CSV)
- Fixed tooltips to use Bambu color lookup
- Widened modals (max-w-md → max-w-lg)
- Adjusted grid layout to fit long color names
- Service worker bumped to v21
Pending changes in bambuddy repo:
- CHANGELOG.md, README.md
- backend/app/api/routes/print_queue.py
- backend/tests/integration/test_print_queue_api.py
- frontend components (ReprintModal, AddToQueueModal, EditQueueItemModal)
- sw.js (v21)
- ReprintModal: Dropdown to override auto-matched AMS slots
- AddToQueueModal: Collapsible filament mapping section
- Backend: Store ams_mapping in print queue, apply when print starts
- Color names in dropdowns (decoded from Bambu codes or derived from hex)
- Blue ring indicator for manually selected vs auto-matched slots
- Status indicators: green (match), yellow (type only), orange (not found)
Closes#76
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add time format utilities to date.ts (applyTimeFormat, formatDateTime,
formatTimeOnly, TimeFormat type)
- PrintersPage: Pass timeFormat to formatETA for printer card ETA display
- ArchivesPage: Add timeFormat prop to ArchiveCard for archive timestamps
- AMSHistoryModal: Apply timeFormat to chart labels, axis ticks, and tooltip
- ProjectDetailPage: Use formatDateTime for timeline dates
- QueuePage: Pass timeFormat to formatRelativeTime for scheduled prints
- SystemInfoPage: Use formatDateTime for boot time display
- NotificationLogViewer: Apply timeFormat to notification timestamps
- Bump service worker cache version to v17
Closes#75
- Add size-aware rendering to Dashboard component, passing widget size
(1/4, 1/2, full) to component render functions
- PrintCalendar: Dynamic cell sizing using ResizeObserver to fill
available width, shows 3/6/12 months based on widget size
- SuccessRateWidget: Per-printer breakdown at larger sizes
- TimeAccuracyWidget: Per-printer breakdown at larger sizes
- FilamentTypesWidget: Grid layout at larger sizes
- FailureAnalysisWidget: More failure reasons at larger sizes
- Bump service worker cache version
- New BatchProjectModal component for assigning archives to projects
- "Project" button in selection toolbar (next to Tags)
- Select a project to assign all selected archives at once
- "Remove from project" option to clear assignments in bulk
- Proper query invalidation for Projects page and Project Detail page
Closes#70
- Add light toggle button next to camera button at bottom of card
- Custom ChamberLight SVG icon with on/off states (yellow fill + rays when on)
- Backend endpoint: POST /printers/{id}/chamber-light?on=true|false
- Optimistic UI update for instant feedback
- Works on all Bambu Lab printers (X1, P1, A1, H2D)
- H2D dual chamber lights controlled together
Closes#67
Multi-color prints store comma-separated values in filament_color (e.g.,
"#FFFFFF,#43403D") and filament_type (e.g., "PLA, PLA-S"). The project
cards were displaying these raw strings instead of splitting them into
individual badges.
- Split comma-separated colors into individual color swatches
- Split comma-separated materials into individual text badges
- Deduplicate both to avoid showing "PLA" multiple times
Problem: The backend stores timestamps in UTC, but when sending them to the frontend without timezone indicators, JavaScript interprets them inconsistently. Users saw UTC times displayed directly instead of converted to their local timezone (e.g., America/New_York).
Solution implemented:
1. Created /frontend/src/utils/date.ts with utilities:
- parseUTCDate(dateStr) - Parses backend timestamps as UTC by appending 'Z' to strings without timezone indicators
- formatDate(dateStr, options) - Formats UTC timestamps to local date/time
- formatDateOnly(dateStr, options) - Formats UTC timestamps to local date-only
2. Updated 15 frontend files to use the new utilities:
- ArchivesPage.tsx - Archive cards and list view dates
- PrintersPage.tsx - Last print date
- SettingsPage.tsx - API key last used date
- QueuePage.tsx - Scheduled print times
- ProjectDetailPage.tsx - Due dates and timeline
- ProfilesPage.tsx - Relative time display
- CalendarView.tsx - Calendar grouping by local date
- NotificationLogViewer.tsx - Log timestamps
- NotificationProviderCard.tsx - Last success date
- AMSHistoryModal.tsx - Chart data timestamps
- FilamentTrends.tsx - Usage data grouping
- PrinterQueueWidget.tsx - Queue item dates
Resolves FTP transfer failures on A1/A1 Mini printers caused by SSL
session reuse incompatibility. Also adds configurable FTP timeout
setting for slow WiFi connections.
Changes:
- Add SSL session reuse bypass for A1/A1 Mini printers (auto-detected)
- Add printer_model parameter to FTP functions for model detection
- Add configurable FTP timeout (10-120s, default 30s) in Settings
- Update all FTP callers: archiving, reprint, timelapse, firmware upload
Technical details:
- A1/A1 Mini printers don't support vsFTPd's SSL session reuse
- X1C/P1S continue to use session reuse as required by their FTP server
- ImplicitFTP_TLS now accepts skip_session_reuse flag
- BambuFTPClient auto-detects A1/A1 Mini and sets flag accordingly
Added:
- Archive list view: edit/delete buttons and context menu with full feature parity
- Archive object count display on cards (extracted from 3MF metadata)
- Cross-view archive highlighting: click in calendar/project to highlight in card view
- Context menu button (⋮) on cards and list rows for easy access
- Spoolman: clear location when spools are removed from AMS
Fixed:
- QR code endpoint 500 error (added qrcode[pil] dependency)
CameraPage no longer receives WebSocket messages - it was creating a second WebSocket connection that would also try to process print_complete events.
- Improved stall detection:
Now continues checking even when in error state.
Also triggers reconnect if the stream process died (!status.active)
Added console logging to help debug: Stream issue detected: stalled=X, active=X, reconnecting...
Features:
- Add print options UI to reprint modal (bed leveling, flow calibration,
vibration calibration, first layer inspection, timelapse)
- Collapsible "Print Options" section with toggle switches
- Default values: bed leveling=on, vibration_cali=on, others=off
Fixes:
- Fix AMS mapping format to match Bambu Studio exactly
- Use slot_id from 3MF to position tray IDs correctly
- Fill unused slots with -1 placeholder
- Add ams_mapping2 with detailed {ams_id, slot_id} pairs
- Fix print command format for proper printer recognition
- Add auto_bed_leveling, cfg, extrude_cali_flag, nozzle_offset_cali
- Use American spelling "bed_leveling" (not British "bed_levelling")
- Match sequence_id format from official apps
- Prevent duplicate tray assignment in filament matching
This resolves the "stuck at filament change" issue on multi-color reprints
affecting X1C and other multi-AMS printer configurations.
Features:
- Add wiki_url field to MaintenanceType for custom type documentation links
- Add printer_model to MaintenanceStatus for model-specific URL mapping
- Display external link icon next to maintenance item names
- Map system maintenance types to Bambu Lab wiki pages by printer model:
- Lubricate Linear Rails, Clean Nozzle/Hotend, Check Belt Tension
- Clean Carbon Rods (X1/P1 only), Clean Build Plate, Check PTFE Tube
- HEPA/Carbon Filter, Left Nozzle Rail (H2 series)
- Add Documentation Link input to custom type create/edit forms
Bug fix:
- Fix 500 error when assigning maintenance type to printer (lazy loading)
Database:
- Add migration for wiki_url column on maintenance_types table
- Add /api/v1/support/debug-logging endpoints to toggle debug log level
- Add /api/v1/support/bundle endpoint to generate ZIP with system info and logs
- Debug logging state persists across restarts via Settings database
- Add debug logging indicator banner in Layout with real-time duration timer
- Add Support & Troubleshooting section to System Information page
- Privacy protection:
- Filter sensitive settings (emails, keys, tokens, URLs, configs)
- Sanitize paths to remove usernames
- Remove hostname from collected data
- Replace IP addresses with [IP] and emails with [EMAIL] in logs
- Add privacy info panel explaining what data is/isn't collected
- Require debug logging to be enabled before downloading support bundle
Enables checking and uploading firmware updates for printers operating
in LAN-only mode without Bambu Cloud connectivity.
Features:
- Automatic firmware version checking against Bambu Lab servers
- Orange "Update" badge on printer cards when updates available
- Firmware update modal with version info and release notes
- One-click firmware upload to printer SD card via FTP
- Real-time upload progress (actual bytes transferred)
- Step-by-step instructions for triggering update from printer
- Local firmware caching for faster re-uploads
- Supports all Bambu Lab printer models
New files:
- backend/app/services/firmware_check.py - Version checking service
- backend/app/services/firmware_update.py - Upload orchestration
- backend/app/api/routes/firmware.py - REST API endpoints
Also includes:
- FTP upload progress callback support
- 10-minute upload timeout protection
- Firmware cache directory in .gitignore
- Correct SSDP model codes: C11=P1P, C12=P1S, N7=P2S, C13=X1E
- Fix serial prefixes based on actual Bambu serial format
- Add confirmation modal for pending upload discard
- Sort model dropdown alphabetically, remove internal codes
- Add "Setup Required" warning with link to wiki documentation
- Update wiki with certificate installation and platform setup guides
Features:
- Configurable printer model for virtual printer emulation
- Supports X1 series (X1C, X1, X1E), P series (P1S, P1P, P2S),
A1 series (A1, A1 Mini), and H2 series (H2D, H2C, H2S)
- Dropdown in Settings > Virtual Printer to select model
- Model affects SSDP discovery and slicer compatibility
- Model change restarts virtual printer services automatically
Backend:
- Added VIRTUAL_PRINTER_MODELS mapping in manager.py
- Added virtual_printer_model setting in database
- New GET /api/v1/settings/virtual-printer/models endpoint
- Updated PUT /api/v1/settings/virtual-printer to accept model
Frontend:
- Added model dropdown to VirtualPrinterSettings component
- Status display shows selected model name
- Model change disabled while virtual printer is running
Tests:
- Added 3 unit tests for model configuration
- Updated frontend test mocks for getModels API
Features:
- Resizable printer cards (S/M/L/XL) with toolbar controls on Printers page
- Queue Only mode for staging prints without automatic scheduling
- "Queue Only" option in add/edit queue modals
- Purple "Staged" badge and Play button to release to queue
- manual_start field in database with migration
Fixes:
- Improved camera stream stuck detection with automatic reconnection
Tests:
- Added 16 integration tests for print queue API endpoints
- Controls section: New section before Filaments with fan status and printer controls
- Part cooling fan (Fan icon, cyan)
- Auxiliary fan (Wind icon, blue)
- Chamber fan (AirVent icon, green)
- Stop/Pause/Resume buttons moved from Temperature section
- Real-time updates: Fan speeds now broadcast via WebSocket
- Backend: Parse MQTT fan data (cooling_fan_speed, big_fan1_speed, big_fan2_speed)
- Convert 0-15 scale to 0-100%
- Always-visible badges with dynamic coloring based on fan state
- Removed horizontal dividers before Controls and Filaments sections
- New APIBrowser component with full OpenAPI schema integration
- Fetches and parses /openapi.json automatically
- Groups endpoints by API tags (printers, archives, settings, etc.)
- Expandable endpoint sections with color-coded method badges
- Path parameter, query parameter, and JSON body editors
- Auto-populates request body with schema examples
- Live API request execution with response display
- Response shows status code, timing, and formatted JSON
- Copy response button with clipboard fallback
- Search to filter endpoints across all categories
- Expand All / Collapse All buttons
- Link to Swagger UI (/docs)
- Two-column layout for API Keys tab
- Left: API key management + webhook documentation
- Right: API Browser with dedicated test key input
- Parameter validation
- Shows warning for missing required parameters
- Validates before sending requests to avoid 422 errors
- UX improvements
- "Use in API Browser" button on newly created keys
- Responsive layout (stacked on mobile, side-by-side on xl+)
- Track number of items per print job (default: 1)
- Project stats now show total items vs print jobs
- Progress bar counts items toward target, not just archives
- "Items Printed" field in archive edit modal
Backend:
- Added quantity field to PrintArchive model
- Database migration for quantity column
- Updated project stats to use SUM(quantity)
- Updated backup/restore to include quantity
- Updated CSV/Excel export with quantity field
Frontend:
- Added quantity input to EditArchiveModal
- Updated ProjectsPage to display total_items
- Updated ProjectDetailPage stats
- Fixed project delete not refreshing the list
- Link to Spoolman: Manually link existing Spoolman spools to AMS trays
- Hover over AMS slot to see "Link to Spoolman" button
- Select from list of unlinked Spoolman spools
- Automatically sets extra.tag field in Spoolman
- Spool UUID display: View and copy Bambu Lab spool UUID in AMS hover card
- Shows first 8 chars with copy button (full UUID to clipboard)
- Fallback copy method for HTTP contexts
- Sync feedback: Shows synced count and skipped spools with reasons
- Expandable list when more than 5 skipped
- Color swatches for identification
- Fixed Spoolman 400 Bad Request: extra field values must be valid JSON
- Updated documentation (wiki, website)
- Skip Objects Modal:
- Object ID markers overlaid on preview image (grid layout)
- Large prominent ID badges to match printer display
- Info banner explaining to match IDs with printer screen
- Layer warning when skip unavailable (layer <= 1)
- Red badge on button showing skipped count
- Preview image now shown when paused (not just running)
- Close with ESC key or click outside modal
- Full light/dark theme support
- Backend:
- Extract object positions from 3MF (include_positions=True)
- API returns x/y coordinates for objects (when available)
- Parse s_obj from printer MQTT for skipped state persistence
- Cover URL available in PAUSE/PAUSED states
- Tests:
- Added test for objects with position data
- Auto-resize to fit video resolution on first open
- Persist window size and position to localStorage
- Restore saved window state for subsequent opens