Allow users to manually set external URLs for archives from Printables,
Thingiverse, or other sources. The Globe button now opens the external
link when set, falling back to auto-detected MakerWorld URL.
- Add external_url field to PrintArchive model with migration
- Add input field to archive edit modal
- Update Globe button: external_url > makerworld_url > disabled
- Include external_url in backup/restore
- Add API test for external_url update
- Update docs (changelog, wiki, website)
Closes#151
- Add checkbox selection for individual files
- Add Select All / Deselect All buttons
- Download single file directly, multiple files as ZIP archive
- Add POST /printers/{id}/files/download-zip endpoint
- Clear selection after successful download
- Support bulk delete for multiple files
- Update docs (changelog, wiki, website)
Closes#144
File Manager improvements (#121):
- New option to create folder from ZIP filename (e.g., MyProject.zip → MyProject/)
- Upload modal now accepts all file types, not just ZIP files
- Updated drop zone text to clarify all files are supported
- Both options can be combined: create folder + preserve internal structure
Camera zoom/pan improvements (#132):
- Pan range now based on actual container size instead of fixed pixels
- Users can pan across the entire zoomed image at any zoom level
- Added pinch-to-zoom gesture for mobile (two fingers)
- Added single finger pan when zoomed in on touch devices
- Pan while pinching to reposition zoom focus
- Both EmbeddedCameraViewer and standalone CameraPage updated
Status badges (Connected/Offline, HMS errors, maintenance, success/failed)
were using bambu-green which follows the user's accent color theme. This
caused confusing UX - e.g., "Connected" appearing red with a red accent.
Added fixed semantic status colors that never change with theme:
- status-ok: #22c55e (green) - success, online, OK states
- status-error: #ef4444 (red) - failed, offline, error states
- status-warning: #f59e0b (amber) - warnings, pending states
Updated components:
- PrintersPage: connection badge, HMS errors, maintenance, WiFi signal
- SmartPlugCard/SwitchbarPopover: plug connectivity status
- StatsPage: success/failed counts, failure rate, time accuracy
- QueuePage: queue item statuses (pending, completed, failed)
- ArchivesPage: failed/aborted archive badge
- ProjectDetailPage: child status, timeline events, BOM checklist
- CompareArchivesModal: archive completion status
- NotificationProviderCard: last success/error status
Closes#136
Features:
- ZIP file support in File Manager (Issue #121): Upload ZIP files to
automatically extract contents with option to preserve folder structure
- Delete operation loading indicator: Shows progress during folder/file
deletion operations
Fixed:
- Print time stats using actual elapsed time instead of slicer estimates
(Issue #137)
- Skip objects modal overflow with scrollable list for many objects
(Issue #134)
Removed:
- Duplicate badge feature from File Manager (per user request)
Tests:
- Added ZIP extraction backend tests (5 tests)
- Added ConfirmModal loading state frontend tests (5 tests)
- Add search parameter to /ha/entities endpoint for searching all entities
- Replace entity dropdown with searchable combobox (type to filter)
- Default shows switch/light/input_boolean; search queries all domains
- Make all three energy sensor dropdowns searchable (Power, Energy Today, Total)
- Each dropdown filters by entity_id or friendly_name
- Shows entity details (name, id, state, unit) in dropdown options
Fixes issue where HA plugs with non-standard entity naming couldn't
find their related power/energy sensors.
Root Cause: The generic webhook sent a JSON payload with custom field names plus timestamp and source fields. Mattermost/Slack webhooks only accept {"text": "..."}
format and reject unknown fields with HTTP 400.
Users just need to select "Slack / Mattermost" from the Payload Format dropdown when configuring their Mattermost webhook.
Closes#133
Home Assistant smart plugs can now use separate sensor entities for
energy monitoring, enabling energy tracking for plugs that expose
power/energy data as separate sensors (Tapo, IKEA Zigbee2mqtt, etc.).
Features:
- Configure dedicated power (W), today (kWh), and total (kWh) sensors
- New API endpoint GET /api/v1/smart-plugs/ha/sensors lists available sensors
- Falls back to switch entity attributes if no sensors configured
- Print energy tracking now works for HA plugs (not just Tasmota)
Backend:
- Added ha_power_entity, ha_energy_today_entity, ha_energy_total_entity
fields to SmartPlug model
- Updated get_energy() to fetch from configured sensor entities
- Added _get_plug_energy() helper to handle both plug types
- Updated backup/restore to include new fields
- Added database migration for new columns
Frontend:
- Added energy sensor dropdowns in AddSmartPlugModal (shown for HA plugs)
- Dropdowns filtered by unit (W/kW for power, kWh/Wh for energy)
Tests:
- Added 4 new integration tests for HA energy sensor functionality
Docs:
- Updated README with new feature
- Updated CHANGELOG with 0.1.6b11 entry
- New useMultiPrinterFilamentMapping hook for parallel printer status fetching
- Per-printer custom slot configuration with "Custom mapping" checkbox
- Auto-configure using RFID data to match filaments by type/color
- Match status indicator (exact/partial/missing) under each printer
- Re-read button to refresh loaded filaments
- New setting: "Expand custom mapping by default" in Settings → Filament
- FilamentMapping component now accepts defaultExpanded prop
Frontend:
- PrinterSelector: Inline mapping editor for each selected printer
- PrintModal: Fetches settings, auto-expands mapping when setting enabled
- SettingsPage: Toggle for per_printer_mapping_expanded
Backend:
- Added per_printer_mapping_expanded to AppSettings schema
- Added boolean parsing in settings routes
- Added integration tests for new setting
Closes#104
that allows viewing and filtering application logs in real-time.
Features:
- Start/Stop live streaming with 2-second auto-refresh
- Filter by log level (DEBUG, INFO, WARNING, ERROR)
- Text search across messages and logger names
- Clear logs with one click
- Expandable multi-line log entries (stack traces, etc.)
- Auto-scroll to follow new entries
Closes#87
- Print from File Manager with plate selection, AMS mapping, and print options. Closes#94
- Add to queue without creating archive (reduces clutter)
- Queue displays library file name, thumbnail, and print time
Fixes:
Queue items from File Manager now reference library files directly instead of
creating archives upfront. Archives are created automatically when prints start.
Added ability to send prints or queue items to multiple printers at once:
- Checkbox selection for multiple printers in reprint and add-to-queue modes
- "Select all" / "Clear" buttons for quick printer selection
- Same filament slot mapping applies to all selected printers
- Progress indicator during multi-printer submission (e.g., "Sending 2/3...")
- Info message: "Slot mapping below applies to all N printers"
- Ideal for print farms with identical filament configurations
Implementation:
- Added multi-select props to PrinterSelector component
- Added computeAmsMapping() utility function for imperative AMS mapping
- Updated PrintModal to handle array of selected printers
- Created unified PrintModal.test.tsx replacing three separate test files
Closes#104
Users can now choose how camera streams open via Settings → General → Camera:
- "New Window" (default): Opens camera in a separate browser window
- "Embedded": Shows camera as a draggable, resizable overlay on the main screen
The embedded camera viewer features:
- Draggable header to reposition anywhere on screen
- Resizable via bottom-right corner handle
- Position and size persist to localStorage across sessions
- Minimize/maximize toggle
- Auto-reconnect with exponential backoff on stream errors
- Stall detection for frozen streams
Closes#105
Manually configure AMS slots for third-party or generic filaments:
1. Hover over an AMS slot on the printer card
2. Click the menu button (:material-dots-vertical:) that appears
3. Select **Configure Slot**
4. Choose a filament preset from your Bambu Studio cloud presets
5. Select a matching K profile (pressure advance calibration)
6. Optionally set a custom color using the color picker
7. Click **Configure Slot** to apply
**Color Picker Features:**
- Enter custom hex codes or color names (e.g., "brown", "FF8800")
- Live preview of selected color
- Expandable color picker in Configure AMS Slot modal:
- 8 basic colors shown by default
- 24 additional colors available via expand button
- Tests for ConfigureAmsSlotModal component
- Tests for AMS change callback
- Updated README with AMS slot configuration feature
- Wiki documentation for Configure AMS Slot feature
- Multi plate issue where plate names showed incorrect. #93
- Items from Queue end up as "source" files in archive. #107
- Added env variable support to change network port. #108
Docs -> https://wiki.bambuddy.cool/getting-started/docker/?h=port#custom-port
┌─────────────────────────┬───────────────────────────────────────────────────────────┐
│ File │ Fix │
├─────────────────────────┼───────────────────────────────────────────────────────────┤
│ CameraPage.tsx:75 │ Copy imgRef.current to a variable before cleanup │
├─────────────────────────┼───────────────────────────────────────────────────────────┤
│ useWebSocket.ts:121 │ Add processMessageQueue to useCallback dependencies │
├─────────────────────────┼───────────────────────────────────────────────────────────┤
│ SpoolmanSettings.tsx:89 │ Add eslint-disable comment (intentional debounce pattern) │
├─────────────────────────┼───────────────────────────────────────────────────────────┤
│ MQTTDebugModal.tsx:95 │ Wrap logs in useMemo to prevent recreating on each render │
├─────────────────────────┼───────────────────────────────────────────────────────────┤
│ Layout.tsx:166 │ Wrap navItemsMap and extLinksMap in useMemo │
├─────────────────────────┼───────────────────────────────────────────────────────────┤
│ KProfilesView.tsx:715 │ Wrap getProfileKey in useCallback │
├─────────────────────────┼───────────────────────────────────────────────────────────┤
│ GcodeViewer.tsx:171 │ Add eslint-disable comment (intentional behavior) │
└─────────────────────────┴───────────────────────────────────────────────────────────┘
Docker Integration Test Fix
The /api/v1/settings endpoint was returning 404 because:
1. The route was defined at /settings/ (with trailing slash)
2. Curl without -L doesn't follow redirects
3. The catch-all route was intercepting API paths
Fixes:
- Added routes for both with and without trailing slash in settings.py and notification_templates.py
- Updated catch-all in main.py to raise proper HTTPException for API routes
Test Results
- Frontend lint: 0 errors, 0 warnings
- TypeScript: No errors
- Backend unit tests: 264 passed
- Backend integration tests: 309 passed
When reprinting a multi-plate 3MF file exported with "All sliced file",
the system now asks which plate to print and only maps filaments for
that specific plate.
Backend changes:
- Add GET /archives/{id}/plates endpoint to list available plates
with thumbnails, print times, and per-plate filament requirements
- Add GET /archives/{id}/plate-thumbnail/{index} for plate thumbnails
- Update GET /archives/{id}/filament-requirements to accept plate_id
query parameter for filtering filaments by plate
- Add plate_id field to ReprintRequest schema
- Update POST /archives/{id}/reprint to use plate_id from request body
instead of auto-detecting (maintains backward compatibility)
Frontend changes:
- Add getArchivePlates API method
- Update getArchiveFilamentRequirements to accept optional plateId
- Update reprintArchive to accept plate_id in options
- Add plate selection UI to ReprintModal when multi-plate 3MF detected
- Show plate thumbnails, names, and filament counts in selection grid
- Require plate selection before printing multi-plate files
- Filter filament requirements to show only selected plate's filaments
Tests:
- Add unit tests for multi-plate slice_info.config parsing
- Add unit tests for plate detection from gcode files
- Add integration tests for new plate endpoints
- Add plug_type field to SmartPlug model ("tasmota" or "homeassistant")
- Add ha_entity_id field for Home Assistant entity reference
- Add global HA settings (ha_url, ha_token, ha_enabled) in Settings
- Create homeassistant_service.py with REST API calls for entity control
- Update smart_plug_manager to dispatch to correct service by plug_type
- Add HA entity discovery endpoint (/ha/entities)
- Add HA connection test endpoint (/ha/test-connection)
- Add Home Assistant tab in AddSmartPlugModal with entity dropdown
- Add HA settings section in Settings → Network tab
- Filter already-configured entities from dropdown
- Update backup/restore to include plug_type and ha_entity_id
- Add frontend tests for HA plug rendering
- Add backend integration tests for HA endpoints
- Update README and CHANGELOG
Closes#91
- 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
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
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)
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.
- 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
- 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