The remaining_time from printer state is in minutes (from mc_remaining_time),
but _format_duration() expects seconds. This caused "17h 47m" to display as
"17m" in milestone notifications.
Closes#157
- Add USB camera type to external camera service
- Auto-detect available V4L2 devices on Linux
- New API endpoint: GET /api/v1/printers/usb-cameras
- Use ffmpeg for USB camera capture and streaming
- Add "USB Camera (V4L2)" option in Settings UI
- Debounce camera URL input to avoid saving on every keystroke
Closes#143
Automatically detect if objects are on the build plate before printing
and pause the print immediately if detected.
Features:
- Per-printer toggle to enable/disable plate detection
- Multi-reference calibration: store up to 5 reference images per printer
for different plate types (textured, smooth, high-temp, etc.)
- Automatic print pause when objects detected at print start
- Push notification and WebSocket alert when print is paused
- ROI (Region of Interest) calibration UI with sliders to adjust
detection area
- Reference management: view thumbnails, add labels, delete references
- Works with both built-in and external cameras
- Uses buffered camera frames when stream is active (no blocking)
- Split button UI: main button opens modal, chevron toggles on/off
- Green visual indicator when plate detection is enabled
- Included in backup/restore
The on_print_progress notification method existed but was never called.
Added milestone tracking in on_printer_status_change that:
- Tracks last notified milestone per printer
- Detects when progress crosses 25%, 50%, 75% thresholds
- Sends notification via notification_service.on_print_progress()
- Resets tracking when progress drops below 5% (new print)
Closes#157
Printers without an SD card store files in the root folder `/` instead of
`/cache`. Added root folder to search paths in both main.py and bambu_ftp.py
so 3MF files can be found regardless of storage configuration.
Closes#146
Features:
- Export single project as ZIP containing project.json and all files
from linked library folders
- Export all projects as JSON (metadata only) for bulk backup
- Import from ZIP (creates folders and extracts files) or JSON
- New /api/v1/projects/import/file endpoint for file uploads
- Frontend buttons on Projects page and Project Detail page
- BOM items are now fully editable (not just checkbox toggle)
When spools were removed from AMS slots, Bambuddy continued showing them
as loaded. Fixed for both old and new AMS models:
- Old AMS: Allow empty values to overwrite slot data during merge
(tray_type, tray_color, tag_uid, etc. were being skipped)
- New AMS (AMS 2 Pro): Parse tray_exist_bits bitmask to detect empty
slots and clear their data accordingly
Added 3 unit tests for AMS data merging behavior.
Closes#147
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 support for external network cameras (MJPEG, RTSP, HTTP snapshot)
that replace a printer's built-in camera when configured.
Features:
- Live streaming on printers page (replaces built-in camera)
- Finish photo capture from external camera on print complete
- Layer-based timelapse: captures frame on each layer change,
stitches to MP4 video on print completion
Backend changes:
- Add external_camera_url, external_camera_type, external_camera_enabled
fields to Printer model with database migration
- New external_camera.py service: MJPEG/RTSP/snapshot frame capture,
connection testing, MJPEG stream generation
- New layer_timelapse.py service: TimelapseSession management,
layer-by-layer frame capture, ffmpeg video stitching
- Add on_layer_change callback to MQTT client and printer manager
- Update camera routes with external camera streaming and tracking
- Update print lifecycle hooks for timelapse start/stitch/cancel
- Add external camera fields to backup/restore
- Rate limiting for external camera streams (prevents browser freeze)
Frontend changes:
- Add external camera configuration UI in Settings > Camera
- Per-printer enable toggle, URL input, type selector, test button
- Toast notification on save
Closes#143
- 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
Home Assistant integrations may report units in different cases (e.g., "w"
instead of "W", "kwh" instead of "kWh"). The sensor entity filter was using
case-sensitive comparison, causing valid energy sensors to not appear in
the Energy Monitoring dropdown.
Changed unit comparison to case-insensitive matching in list_sensor_entities().
Closes#119
P2S printer creates fallback archives without thumbnails/metadata because
FTP couldn't find 3MF files. The P2S uses different directory structure
(/data/Metadata/) and doesn't have a /cache directory.
Changes:
- Add P2S to SKIP_SESSION_REUSE_MODELS for SSL compatibility
- Add /data/ and /data/Metadata/ to 3MF download paths
- Update fallback search to try multiple directories instead of just /cache
- Add /data paths to FTP storage scan directories
Closes#146
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
- Add "Recalculate Costs" button to Dashboard that updates all archive
costs using current filament prices (Issue #120)
- Track reprints and add cost to existing archive total on completion,
so statistics accurately reflect total filament expenditure
Closes#120
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)
Quick Stats "Print Time" now uses actual elapsed time (`completed_at - started_at`) instead of slicer estimates;
cancelled prints only count time actually printed
Closes#137
- 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.