Simplify always-true authEnabled ternary and localSettings truthiness
checks in SettingsPage.tsx. Remove commented-out auth re-setup guard
and its dead _existing_setting/_user_count queries from auth.py.
Add clarifying comments to firmware_check.py api_key logs (model
identifier, not a secret).
Remove vestigial _debug_logging_enabled and _debug_logging_enabled_at
globals from support.py (written but never read; DB is queried directly).
Simplify hue classification in PrintersPage.tsx and colors.ts by removing
always-true h < 345 checks and dead 'Unknown' fallbacks. Narrow
getWifiStrength param type to remove always-false null guard.
- Replace number inputs with select dropdowns for retry attempts,
retry delay, and connection timeout to avoid auto-save race conditions
- Move connection timeout inside the FTP retry toggle section
- Add ftp_timeout to backend settings schema and integer parsing list
so the value actually persists (was silently dropped before)
Closes#275
Implement accurate per-filament usage tracking for Spoolman integration,
similar to OpenSpoolman v0.3.0. This replaces the previous single-spool
reporting with multi-material aware tracking.
Features:
- Parse G-code from 3MF files at print start to build per-layer,
per-filament cumulative extrusion maps
- Store tracking data in new `active_print_spoolman` database table
(survives server restarts for long prints)
- Report accurate partial usage when prints fail/cancel based on
actual layer progress and G-code data
- Add "Disable AMS Weight Sync" setting to prevent AMS percentage-based
weight estimates from overwriting Spoolman's granular tracking
- Add "Report Partial Usage for Failed Prints" toggle (only shown when
weight sync is disabled)
- Use Spoolman's filament density instead of defaults for mm-to-grams
conversion
- Prefer tray_uuid over tag_uid for spool identification
Camera streams on macOS Safari were failing with "FetchEvent.respondWith
received an error: Load failed" because the Service Worker was intercepting
MJPEG streaming responses. Safari has known issues handling continuous
streaming responses through Service Workers.
- Add exclusion for /camera/stream and /camera/snapshot URLs in SW fetch handler
- Bump cache version to v24 to force SW update on clients
The camera components already have robust error handling with reconnect logic,
so bypassing the SW for these endpoints is safe and improves performance.
The plate detection alert popup (shown when objects are detected on
build plate and print is paused) was visible to all users. Now it
only shows to users who have the printers:control permission.
- Added hasPermission('printers:control') check before showing alert
- When auth disabled: all users see it (backward compatible)
- When auth enabled: only users with printers:control permission see it
Addresses #244
Date input for scheduled prints was swapping month and day for European
users because:
1. EU format only accepted "/" separator, not "." which is common in
European locales (e.g., "5.2.2026" for Feb 5th)
2. System format fell back to new Date() which interprets ambiguous
dates in US format
Changes:
- Added splitDateParts() helper to accept /, ., and - separators
- Updated parseDateInput() to use proper locale detection for system
format instead of relying on Date constructor
- All explicit formats (us, eu, iso) now accept any of the three
separators
Closes#233
The FilamentHoverCard positioning logic now accounts for the fixed 56px
header when calculating available space above the trigger element.
Previously, when hovering over AMS slots near the top of the page, the
hover card would appear above the slot but go behind the navigation bar.
Now it correctly detects there isn't enough usable space and flips to
show below the slot instead.
Closes#259
- Changed the 401 handling in request() to only clear the auth token when the error message indicates the token is actually invalid
- Previously: ANY 401 response cleared the token (could cause cascading failures)
- Now: Only clears on specific messages like "Token has expired", "Could not validate credentials", etc.
- "Authentication required" (which might be a timing issue) no longer clears the token
Closes#257
The tray_info_idx field is a filament TYPE identifier (e.g., "GFA00" for
generic PLA), not unique per spool. When multiple AMS trays are loaded
with the same filament type, the previous code used find() which always
returned the first match regardless of color.
Now checks if tray_info_idx is unique among available trays:
- If unique: use that tray as definitive match (existing behavior)
- If not unique: fall back to color matching among matching trays
Fixed in both backend (print_scheduler.py) and frontend (useFilamentMapping.ts).
Closes#245
- SSDP proxy for cross-network setups: select slicer network interface for automatic printer discovery via SSDP relay
- FTP proxy now listens on privileged port 990 (matching Bambu Studio expectations) instead of 9990
- For systemd: requires `AmbientCapabilities=CAP_NET_BIND_SERVICE` capability
- Automatic directory permission checking at startup with clear error messages for Docker/bare metal
When multiple AMS trays have the same filament type and color, Bambuddy
now uses the tray_info_idx attribute from the 3MF file to identify the
exact spool selected during slicing. This ensures the correct tray is
used rather than just picking the first match.
Matching priority: tray_info_idx > exact color > similar color > type-only
Closes#245
When multiple AMS trays have the same filament type and color, Bambuddy
now uses the tray_info_idx attribute from the 3MF file to identify the
exact spool selected during slicing. This ensures the correct tray is
used rather than just picking the first match.
Matching priority: tray_info_idx > exact color > similar color > type-only
Closes#245
Header action buttons were overflowing outside the screen on iPhone/mobile
devices because the header containers used fixed horizontal layouts.
Changed both pages to use the responsive pattern from PrintersPage:
- Headers stack vertically on mobile (flex-col), horizontal on sm+ (sm:flex-row)
- Button containers use flex-wrap to allow wrapping on narrow screens
- Added gap-4 between title and buttons when stacked
Closes#255
When editing a queue item, the scheduled time was being displayed in UTC
instead of the user's local timezone. This caused confusion where:
- User selects April 2, 2:00 PM local time
- After saving, it appears shifted by their timezone offset
- Month/day could appear swapped due to the timezone difference
The fix converts the UTC time from the server to local time when
populating the datetime-local input, using toDateTimeLocalValue()
instead of toISOString().slice(0, 16).
Closes#233
The queue was showing "Printing" even when the printer was paused.
Now fetches real-time printer state for active print jobs and displays
"Paused" with a yellow badge when the printer state is PAUSE/PAUSED.
Changes:
- Add printerState prop to StatusBadge and SortableQueueItem components
- Fetch printer statuses for printers with active jobs using useQueries
- Show pause icon and yellow badge when printing but printer is paused
- Add "paused" translation key for queue status (en, de, ja)
Closes#249
The filament_used_grams field already contains the total filament for
the entire print job (all items combined). The code was incorrectly
multiplying this value by quantity, causing inflated filament totals.
Example: A print with 26 objects using 126g total was being calculated
as 126g * 26 = 3,276g instead of the correct 126g.
Fixes:
- backend/app/api/routes/archives.py: Archive stats endpoint
- backend/app/api/routes/metrics.py: Prometheus metrics endpoint
- frontend/src/components/FilamentTrends.tsx: Trends chart calculations
Closes#229