- 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
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
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
- 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
- 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