Commit Graph
328 Commits
Author SHA1 Message Date
maziggy 8981c11bac fix: spool form scrollbar flicker in Edge (#364), delete SD card file after print (#374)
Add scrollbar-gutter: stable to spool form modal to prevent scrollbar
layout thrashing on Windows Edge at non-default zoom levels.

Delete uploaded .3mf from printer SD card root after print completion
to prevent phantom prints on power cycle (reported on P1S).
2026-02-16 08:21:09 +01:00
maziggy be569f7577 fix: prevent spool weight corruption, add AMS weight sync, fix extruder_id
Three bugs fixed and one recovery feature added:

1. AMS remain=0 zeroed all spools on printer power-off. The weight sync
   treated 0% remain as "fully consumed," setting weight_used to
   label_weight for every assigned spool. Fix: skip remain=0 in AMS
   weight sync — empty spools are tracked by the usage tracker.

2. Editing any spool field sent stale weight_used from the React Query
   cache back to the server, resetting usage-tracked weight. Fix: only
   include weight_used in PATCH when the user explicitly changes it.

3. K-profile auto-select crashed on dual-nozzle printers for non-BL
   spools with 'SpoolKProfile has no attribute extruder_id'. The model
   attribute is 'extruder', not 'extruder_id'.

4. New "Sync Weights from AMS" button in Settings > Filament Tracking
   (built-in inventory mode) to force-recover spool weights from live
   AMS sensor data. Bypasses the "only increase" guard for explicit
   user-initiated recovery.
2026-02-15 15:47:41 +01:00
maziggy 9babf5d345 fix: spool edit form overwrites usage-tracked weight
When editing a spool (changing note, color, etc.), the form always sent
weight_used back to the server. If the React Query cache held a stale
pre-print value, saving would silently reset remaining weight to full.

Track whether the user explicitly touched the weight field and only
include weight_used in the PATCH request when creating a new spool or
when the weight was intentionally changed.
2026-02-15 15:18:52 +01:00
maziggy 461fcf20e5 Sync 2026-02-15 14:54:03 +01:00
maziggy aa9db501ec Changed the inventory icon from Package (box) to Disc3 (spool/reel shape) 2026-02-15 13:24:00 +01:00
maziggy 27cecbed87 feat: add print log timeline view in archives page
Add a chronological, table-based print log as a 4th view mode in the
Archives page. Log entries are stored in a separate print_log_entries
table — clearing the log never touches archives or queue items.

Backend:
- New PrintLogEntry model with independent table
- GET /print-log/ endpoint with search, printer, user, status, date filters
- DELETE /print-log/ clears only log entries
- Thumbnail serving endpoint for log entries
- write_log_entry() service called on print completion
- Auth: ARCHIVES_READ for viewing, ARCHIVES_DELETE_ALL for clearing

Frontend:
- New 'log' ViewMode with ClipboardList icon toggle
- Filterable/searchable table with pagination (10/25/50/100 rows)
- Colored status badges, duration formatting, filament color swatches
- Clear button with confirmation modal
- All filter state persisted to localStorage
- i18n: EN, DE, JA, FR, IT translations
2026-02-15 13:14:15 +01:00
maziggy 53a4933c36 feat: add bed cooled notification after print completes (#378)
Notify users when the print bed cools below a configurable threshold
(default 35°C) after a print finishes, so they know when to remove parts.

- Backend: DB migration, model, schemas, notification template, service
  method, background cooldown monitor (polls every 15s, 30min timeout)
- Frontend: event toggle in provider card/modal, threshold setting in
  Settings > Notifications, i18n keys for all 5 locales
- Tests: 4 backend + 4 frontend tests
- Docs: README, website, wiki updated
2026-02-15 10:59:07 +01:00
maziggy 045326d8ca fix: disable reprint for archives without 3MF file (#376)
When a print is sent from an external slicer and Bambuddy can't
download the 3MF during auto-archiving, the fallback archive has no
file. Reprinting such archives tried to upload the data directory,
causing a confusing SD card error. Backend now returns a clear 404
for empty file_path and checks is_file() instead of exists(). Frontend
disables Print/Schedule/Open in Slicer for file-less archives with an
explanatory tooltip. Added i18n key in all 5 locales.
2026-02-15 10:28:23 +01:00
maziggy 259c7eaa43 fix: respect disabled update check setting (#367)
Backend /updates/check endpoint now returns early without calling
GitHub API when check_updates is disabled. Settings page no longer
auto-fetches update status when the setting is off. Printer card
firmware badge falls back to showing the current version from MQTT
instead of disappearing when firmware update checks are disabled.
2026-02-15 10:09:22 +01:00
maziggy e1b3329b68 fix: reduce MQTT log noise at INFO level (#365)
Downgrade 58 diagnostic logger.info calls to logger.debug in
bambu_mqtt.py — payload dumps, detector state changes, field
discovery, H2D disambiguation, and periodic status updates no longer
flood logs at the default INFO level. User-initiated actions (print,
stop, calibration, AMS load/unload) remain at INFO. Also suppress
paho-mqtt library INFO messages in production mode.
2026-02-15 09:56:51 +01:00
maziggy 292c5e855c fix: show failed/cancelled badge in archive list view (#365)
The archive grid view displayed a red status badge for failed and
aborted prints, but the list view had no equivalent indicator. Added
an inline badge next to the print name in ArchiveListRow, reusing the
existing i18n keys and status-error styling from the grid view.
2026-02-15 09:40:10 +01:00
maziggy 3c29e200d7 fix: clear inventory spool assignments when switching to Spoolman mode
When enabling Spoolman, stale built-in inventory slot assignments
persisted in the database and the printer card UI still showed
assign/unassign buttons from the internal inventory. Now bulk-deletes
all SpoolAssignment records on mode switch, invalidates the frontend
spool-assignments cache, and hides inventory UI on printer cards while
Spoolman is active.
2026-02-15 09:27:09 +01:00
maziggy 6e56aa7ab3 Inventory UX improvements, color catalog expansion, settings polish
- Replace browser confirm() with styled ConfirmModal for inventory
  delete (danger) and archive (warning) actions
- Expand default color catalog from 258 to 638 entries (6 → 20 brands)
  with measured hex codes from FilamentColors.xyz
- Expand eSUN from 10 generic placeholders to 79 measured colors
  across 10 material lines
- Add built-in inventory note about third-party spool assignment
- Increase Spool/Color Catalog settings card height (400px → 600px)
- Add i18n keys for all new strings (en, de, fr, it, ja)
- Update wiki inventory docs with catalog management details
2026-02-15 09:12:34 +01:00
maziggy 46f2b8ee0d fix: AMS slot configure modal not pre-populating black filament color
The color pre-population logic skipped hex 000000 (black) to guard
against empty/uninitialized slots, but empty slots already don't pass
trayColor to the modal. Removed the unnecessary check so black filament
color is now pre-populated like any other color.
2026-02-15 08:33:59 +01:00
maziggy a37dfaf7fb feat: dual external spool support, AMS slot model filtering & pre-population
Backend:
- Add dual external spool support for H2D (vt_tray as list: Ext-L/Ext-R)
- Add cloud filament ID map endpoint (/cloud/filament-id-map)
- Fix RFID spool data erased by periodic AMS updates (skip tag matcher
  for RFID-tagged trays)
- Fix AMS slot config overwrites RFID spool state
- Fix K-profile selection corrupts existing profiles on X1C/P1S
- Resolve K-profiles filament name via cloud filament ID map
- Update print scheduler and usage tracker for dual external spools

Frontend:
- Add printer model filtering to ConfigureAmsSlotModal (cloud/local/builtin
  presets filtered by @BBL model suffix and compatible_printers)
- Add pre-population for configured slots (preset, color, K-profile)
- Add K-Profiles view with accurate filament name resolution
- Internationalize all ConfigureAmsSlotModal strings (en/de/fr/it/ja — 21 keys)
- Add 5 new ConfigureAmsSlotModal tests (model filtering, pre-selection,
  color pre-population, i18n)
- Update PrintersPage for dual external spool rendering

Docs:
- Update CHANGELOG, README, website features, and wiki AMS docs
2026-02-15 08:04:01 +01:00
maziggy 12e92a301d @rebase markdown-it 2026-02-14 08:15:10 +01:00
maziggy 86a2bb2400 Sync 2026-02-13 16:00:59 +01:00
maziggy d9a701fe8e Sync 2026-02-13 15:57:01 +01:00
maziggy cf91531aa2 Add next-available printer indicator and fix bulk archive delete race condition (#354)
Status summary bar on the Printers page now shows availability count
("X available") and a "Next available" indicator with printer name,
progress bar, percentage, and remaining time for the printer finishing
soonest. Always visible when printers are printing; hidden otherwise.

Fix race condition in bulk archive deletion where files were removed
from disk before the database commit. Concurrent SQLite writes could
cause a lock timeout, rolling back the DB delete while files were
already gone — leaving orphaned records with broken thumbnails. Now
deletes the DB record first and only removes files after a successful
commit.
2026-02-13 13:06:22 +01:00
maziggy cffe7e62bc Fix maintenance tasks showing wrong rod type for printer models (#351)
H2/A1 series have linear rails, not carbon rods. X1/P1/P2S have carbon
rods, not linear rails. Split rod-specific maintenance into model-aware
pairs: "Lubricate/Clean Carbon Rods" for X1/P1/P2S and "Lubricate/Clean
Linear Rails" for A1/H2. Added rod type classification to printer_models
and startup cleanup for stale/duplicate system maintenance types.
2026-02-13 12:23:34 +01:00
maziggy f9b47282a1 Nozzle-aware AMS mapping for dual-nozzle printers, BL spool detection fix, AMS startup fix, SQLite WAL (#318)
Dual-nozzle H2D/H2D Pro: filament matching now respects nozzle assignments
from the 3MF file. Each AMS unit feeds a specific nozzle (L/R), and the
scheduler/frontend constrain matching to only trays on the correct nozzle.
Falls back to unfiltered matching when no trays exist on the target nozzle.
L/R badges shown in the filament mapping UI. Translated in en/de/ja/it.

Fix AMS slot config overwritten on startup: on_ams_change unconditionally
unlinked BL spool assignments on every MQTT pushall, then re-assigned them
sending ams_filament_setting without setting_id — clearing the printer's
filament preset. Now compares spool RFID identifiers before unlinking.

Fix BL spool detection false positives: removed tray_info_idx from detection
logic in both backend is_bambu_lab_spool() and frontend isBambuLabSpool().
Third-party spools using Bambu generic presets had GF-prefixed tray_info_idx
values, causing misidentification. Now uses only tray_uuid and tag_uid.

SQLite WAL mode with 5s busy timeout reduces "database is locked" errors.
2026-02-13 11:48:32 +01:00
maziggy ee2af79f4a Add confirmation modal to skip objects (#346)
Prevent accidentally skipping the wrong object during a print by showing
a warning confirmation dialog with the object name and an irreversible
action warning. Uses the existing ConfirmModal component with warning
variant. Translations added for all 4 locales (en, de, ja, it).
2026-02-13 08:46:15 +01:00
maziggy a6f6df2e34 Sync fixes 2026-02-12 18:23:55 +01:00
maziggy aa87e5598b Add clear plate confirmation between queued prints
The print scheduler previously treated FINISH/FAILED as idle states
and would auto-start the next queued print before the user cleared
the build plate. Now requires explicit user confirmation via a
"Clear Plate & Start Next" button on the printer card. Uses an
in-memory plate-cleared flag — no MQTT command needed since the
scheduler's start_print overrides the printer state.
2026-02-12 08:45:05 +01:00
maziggy 1b5683b3a3 Add "Open in new tab" toggle for external sidebar links (#338)
External links behind reverse proxies (Traefik, nginx) block iframe
embedding via X-Frame-Options/CSP headers. Add a per-link boolean
toggle so users can choose between iframe (default) and new-tab
behavior. Keyboard shortcuts also respect the setting.
2026-02-12 07:51:55 +01:00
maziggy 5787c61f34 Fix printer card cover image not updating between prints
The cover image URL was always /printers/{id}/cover regardless of the
active print, so the browser served its cached image. Now appends the
print name as a cache-busting query parameter and resets load state
when the print changes.
2026-02-12 07:25:22 +01:00
maziggy 13de96127e Fix file downloads showing generic filenames for special characters (#334)
Content-Disposition parser now handles RFC 5987 percent-encoded filenames
(filename*=utf-8''...) used by FastAPI for non-ASCII characters. Applied
to all 7 download endpoints.

Closes #334
2026-02-12 07:19:03 +01:00
maziggy 778d1966af Move email settings under Authentication tab in settings
Rename the "Users" settings tab to "Authentication" and move the
standalone "Global Email" tab into it as an "Email Authentication"
sub-tab. This groups email/SMTP configuration with user management
where it logically belongs.

- Remove top-level email tab from settings tab bar
- Add sub-tab navigation (Users / Email Authentication) inside the
  Authentication tab
- Handle legacy ?tab=email URLs by mapping to users tab + email sub-tab
- Update i18n keys in en/de/ja locales
2026-02-11 08:43:40 +01:00
maziggy 8e09e4fb65 Add additional currency options for cost tracking (#329)
Added HKD, INR, KRW, SEK, NOK, DKK, PLN, BRL, TWD, SGD, NZD, MXN,
CZK, THB, and ZAR to the currency dropdown in settings.
2026-02-11 07:51:20 +01:00
maziggy ea5b9b3011 Post work PR #322 2026-02-10 17:08:34 +01:00
maziggy 0282fbd442 Fix H2D Pro L/R nozzle hover card swap and hide left-only fields (#300)
Nozzle rack id 0 = extruder 0 = right nozzle, id 1 = extruder 1 = left.
The dual-nozzle hover card had them backwards, showing serial number and
max temp on the left column instead of the right. Serial and max temp
are now restricted to the right (removable) nozzle only. Single-nozzle
fallback (H2D, H2C) updated to use the primary nozzle (id 0).
2026-02-10 16:15:53 +01:00
maziggy 94ba65e3bc Fix H2C nozzle rack display and add L/R hover cards (#300)
Rack card now shows 6 rack-only slots (IDs 16-21) with empty placeholders,
excluding L/R hotend nozzles. New DualNozzleHoverCard shows both nozzle
details side-by-side with Active/Idle status. Single-nozzle H2 printers
get extended hover details. Backend stores nozzle_info for all H2 series.
Added i18n keys (en/de/ja) and 10 tests (7 backend + 3 frontend).
2026-02-10 13:40:03 +01:00
maziggy 19289855de Fix firmware badge shown for models without API data (#311)
Printers whose model has no firmware data in Bambu Lab's API (e.g. H2C
on public beta firmware) displayed a misleading green "up to date" badge.
The API returns latest_version=null for these models, so there is nothing
to compare against. Hide the badge when latest_version is not available.

- Add latest_version check to badge render condition in PrintersPage
- Add test for badge hidden when API returns no firmware data
2026-02-10 12:31:14 +01:00
maziggy 31c8334538 Fix misleading GitHub backup description
App Settings card said "excludes sensitive data" but the complete
database is pushed. Changed to "complete database."
2026-02-10 12:00:16 +01:00
maziggy cc7bbd6fbe Firmware version badge on printer cards (#311)
- Show firmware version badge on printer card (green=up to date,
  orange=update available) with click to view release notes or
  start update workflow
- Badge only shown when firmware checking is enabled in settings
- Modal adapts: info-only view when up to date (release notes
  auto-expanded), update workflow when update available
- Gate badge query with firmware:read permission, upload button
  with firmware:update permission
2026-02-10 11:53:42 +01:00
maziggy 516841a7f5 Fix virtual printer IP override ignored in server mode (#52)
The remote_interface_ip setting only worked in proxy mode but was
completely ignored in server modes (immediate/review/print_queue).
Users with multiple NICs (LAN + Tailscale, Docker bridges) got wrong
auto-detected IP in SSDP broadcasts and TLS certificates.
2026-02-10 10:05:35 +01:00
maziggy 8d42b05f62 Add configurable slicer preference — Bambu Studio or OrcaSlicer (#313)
Users can now choose their preferred slicer (Bambu Studio or OrcaSlicer)
in Settings → General. All "Open in Slicer" buttons across Archives,
3D Preview, and context menus use the correct protocol for the selected
slicer. OrcaSlicer uses orcaslicer://open?file=<URL> on all platforms;
Bambu Studio uses bambustudio:// (Windows) or bambustudioopen:// (macOS/
Linux). Default remains Bambu Studio for backward compatibility.
2026-02-10 09:38:06 +01:00
maziggy edf244c469 Add local profiles — import OrcaSlicer presets without Bambu Cloud (#310)
Users who use OrcaSlicer without Bambu Cloud can now import slicer
presets directly into Bambuddy. Supports .orca_filament, .bbscfg,
.bbsflmt, .zip, and .json exports with automatic inheritance resolution
via OrcaSlicer's GitHub base profiles (cached with 7-day TTL).
2026-02-09 17:00:02 +01:00
maziggy 6661bbf866 Add full nozzle rack metrics and per-slot hover cards for H2C printers
Capture 4 additional fields from MQTT nozzle data (max_temp, serial_number,
filament_color, filament_id) and surface them through REST/WebSocket APIs.
Add per-slot hover popover to the NozzleRackCard showing all metrics, filament
color backgrounds on slots, and i18n labels in all 4 locales.
2026-02-09 15:10:49 +01:00
maziggy 8449e1c2e2 Extend support bundle with comprehensive diagnostics
Add 10 new diagnostic sections to _collect_support_info(): printer
connectivity/firmware, integration status (Spoolman, MQTT, HA),
network interfaces (subnets only), Python package versions, database
health, Docker environment, WebSocket connections, and log file info.
All data properly anonymized — no IPs, names, or serials included.
2026-02-09 10:19:48 +01:00
maziggy 48174d3a08 Add H2C nozzle rack support — store and display 6-position tool-changer dock
The H2C printer has a tool-changer with a 6-nozzle rack, but
device.nozzle.info entries beyond index 1 were being dropped due to a
hardcoded 2-nozzle limit. This adds full nozzle rack storage, API
exposure, and a frontend card showing all dock positions.
2026-02-09 09:21:50 +01:00
maziggy 30fba33dcf Fix sidebar link custom icons displaying with inverted colors (#308)
CSS invert() filter was applied to all custom uploaded icons in dark
mode, causing full-color logos to render with wrong colors. Removed
the invert filter from custom icon <img> tags in Layout.tsx and
AddExternalLinkModal.tsx. Preset Lucide icons are unaffected.
2026-02-09 08:35:07 +01:00
maziggy 7e5f494304 Complete Japanese locale overhaul: restructure and translate all keys
Restructured ja.ts from a divergent format (different nesting, 12
structural conflicts, 48 namespaces) to match EN/DE structure exactly
(41 namespaces, 0 conflicts). Translated all 2,083 EN keys into
Japanese — previously 1,366 keys were missing and silently falling
back to English via i18next fallbackLng.
2026-02-08 09:29:48 +01:00
maziggy 9cbd66593e Show Spoolman fill level for AMS Lite and external spools (#293)
AMS Lite units (A1 series) have no weight sensor and always report 0%
fill level. When a spool is linked to Spoolman with weight data, use
Spoolman's remaining weight as a fallback. External spools also show
fill level from Spoolman data instead of always showing unknown.

Backend: Enrich GET /spoolman/spools/linked response with
remaining_weight and filament_weight alongside spool ID.

Frontend: Add getSpoolmanFillLevel() helper. Update regular AMS, HT
AMS, and external spool fill computations to use Spoolman fallback
when AMS reports 0%. Show "(Spoolman)" indicator in hover card when
fill data comes from Spoolman.
2026-02-08 08:47:18 +01:00
maziggy 8511ce2c47 Add camera view controls: chamber light toggle & skip objects (fixes #291)
- Extract SkipObjectsModal from PrintersPage into reusable component
- Add chamber light toggle and skip objects buttons to EmbeddedCameraViewer
  and CameraPage header bars
- Add printerStatus query to camera views (React Query deduplicates with
  existing PrintersPage query)
- Fix camera/stop 401 when auth enabled: replace sendBeacon with
  fetch + keepalive + auth headers in both camera components
- Add camera.chamberLight i18n key (en, de, ja)
- Add AuthProvider to CameraPage test wrapper
2026-02-07 17:09:44 +01:00
maziggy 5803c8ceb1 Added missing toast messages to Spoolman settings 2026-02-06 14:12:12 +01:00
maziggy dc82b5ff2a Refactor Spoolman per-filament tracking (PR #277 follow-up)
Extract Spoolman tracking from main.py into dedicated service module,
DRY up repeated helpers, add i18n for new settings UI, and add tests.

- Move ~460 lines from main.py to services/spoolman_tracking.py
- Extract _resolve_spool_tag, _resolve_global_tray_id, build_ams_tray_lookup helpers
- Replace fragile tuple return in get_spoolman_settings() with dict
- Wire 4 new UI strings through i18n (en/de/ja)
- Add 42 backend unit tests (spoolman tracking helpers + 3MF parsing)
- Add 6 frontend tests for weight sync and partial usage toggles
- Update CHANGELOG, wiki, and website docs

Closes PR #277
2026-02-06 10:03:27 +01:00
maziggy 905e1762de Fix FTP settings UI: add selects, persist connection timeout
- 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
2026-02-06 09:20:33 +01:00
maziggy 46ba5ff417 Fix Bandit detection and update Trivy to v0.69.1
- Fix defusedxml import style in print_queue.py to be recognized by Bandit
  (use `import defusedxml.ElementTree as ET` not `from defusedxml import`)
- Update Trivy scanner version from 0.65.0 to 0.69.1
2026-02-05 17:50:16 +01:00
maziggy 00caf3ee1a Fix date format parsing for queue scheduling (#233)
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
2026-02-05 08:00:34 +01:00