Commit Graph
780 Commits
Author SHA1 Message Date
maziggy efcb6cd74a build(deps-dev): bump ajv from 6.12.6 to 6.14.0 in /frontend in the npm_and_yarn group across 1 directory 2026-02-23 09:31:53 +01:00
maziggy 8e6a959eef Redact IP addresses from support bundle debug logs 2026-02-23 09:24:53 +01:00
maziggy 5164152088 Fix external spool mapping inverted on H2C (#492)
On H2C/H2D dual-nozzle printers, tray_now=254 is sent generically for both
external spools. The direct ID comparison always matched Ext-L (id=254),
never Ext-R (id=255). Now uses active_extruder to disambiguate: extruder
1 (left) → Ext-L, extruder 0 (right) → Ext-R.
2026-02-23 08:57:35 +01:00
maziggy 6da12a8ad2 Fix wrong documentation link for "Lubricate Carbon Rods" on P2S (#490)
The maintenance page linked P2S "Lubricate Carbon Rods" to the
belt-tension wiki page instead of the XYZ axis lubrication page.
2026-02-23 08:30:28 +01:00
maziggy 3c72f7cb22 Show inventory sidebar item for both Spoolman and internal inventory
Previously the Inventory sidebar item was hidden when Spoolman was
enabled. Now it always shows — when Spoolman is active, /inventory
embeds the Spoolman web UI in the content area via iframe; when
disabled, it renders the internal inventory page as before.
2026-02-23 08:23:35 +01:00
maziggy 77677cb07f Add clear-plate dot indicator on sidebar Printers icon
When a printer has pending queue items and is in FINISH/FAILED state
awaiting plate clearing, a yellow dot now appears on the Printers
sidebar icon. Uses useQueries to check statuses of printers with
pending queue items from the existing WebSocket-warmed React Query
cache — no new backend endpoints or additional polling needed.
2026-02-23 08:13:29 +01:00
maziggy d5c9f2b9ea Moved Spoolbuddy frontend to Bambuddy 2026-02-23 07:58:00 +01:00
maziggy 9381edf0cb Removed new Spoolbuddy frontend 2026-02-22 18:01:01 +01:00
maziggy 38af5df050 Add filament override for model-based queue assignment (#486)
When scheduling a print to "any printer" (model-based assignment),
users can now override the 3MF's original filament choices per slot.
The override dropdown shows compatible filaments loaded across all
printers of the selected model, filtered by type and nozzle (H2D).
The scheduler matches against overridden type/color instead of the
original 3MF values, preferring printers with exact color matches.

Backend:
- New GET /printers/available-filaments endpoint (aggregates loaded
  filaments across printers of a model, includes extruder_id for
  dual-nozzle nozzle-aware filtering)
- New filament_overrides JSON column on print_queue table
- Scheduler applies overrides before AMS mapping, clears tray_info_idx
  on overridden slots so color matching takes priority
- Printer selection prefers printers with most override color matches

Frontend:
- New FilamentOverride component with per-slot override dropdowns
- Type-filtered options (PLA slots only show PLA)
- Nozzle-aware filtering (H2D: only shows filaments on correct extruder)
- Integrated into PrintModal for model-based queue mode

Tests:
- 11 backend unit tests (color match counting, override application)
- 12 frontend tests (rendering, type/nozzle filtering, interactions)

i18n: All 6 locales (en, de, fr, it, ja, pt-BR)
2026-02-22 16:43:16 +01:00
maziggy aeca15b585 Add SpoolBuddy integration as optional filament management add-on
SpoolBuddy turns a Raspberry Pi 4B with a PN5180 NFC reader and
NAU7802 scale into a filament management station that integrates
with Bambuddy via REST API and WebSocket.

Backend: SpoolBuddyDevice model, 10 REST endpoints (/spoolbuddy/*),
6 WebSocket broadcast types, background offline-detection watchdog.

RPi daemon: asyncio service with concurrent NFC polling (300ms,
MIFARE Classic + Bambu HKDF key derivation), scale reading (10 SPS,
5-sample moving average, stability detection), and 10s heartbeat
with exponential backoff reconnect.

Frontend: kiosk-optimized 1024x600 UI at /spoolbuddy with Dashboard
(live weight + NFC spool detection), AMS Overview, Inventory,
Printers, and Settings pages. useSpoolBuddyState reducer hook
driven by WebSocket CustomEvents.

i18n: all 6 locales (en, de, fr, it, ja, pt-BR).
2026-02-22 15:27:54 +01:00
maziggy e450c3b728 Add visual spool grouping and optional brand/subtype in quick-add (#480)
Group toggle in inventory toolbar collapses identical unused/unassigned
spools into expandable rows/cards with count badges. Grouping key uses
material, subtype, brand, color, and label weight. Brand and subtype
fields now appear in quick-add mode as optional (no asterisk, no
validation). Quantity field restricted to quick-add mode only.
2026-02-22 10:05:03 +01:00
maziggy 0e87c377e6 Add developer LAN mode detection and warning banner
Parse the MQTT "fun" field bit 0x20000000 to detect whether connected
printers have Developer LAN Mode enabled. Show a persistent orange
warning banner when any printer lacks it, since newer firmware silently
rejects MQTT write commands without developer mode.

- Parse fun field into developer_mode on PrinterState
- Add /printers/developer-mode-warnings lightweight polling endpoint
- Include developer_mode in printer status API and support bundle
- Orange banner with affected printer names and wiki link
- Translations for all 6 locales (en, de, fr, it, ja, pt-BR)
- 7 backend + 4 frontend tests
2026-02-21 12:06:16 +01:00
maziggy 16fa84bc16 Add bulk spool addition and stock spools
Add Quick Add mode to the spool form for simplified entry (material +
color + weight only), and a quantity field (1-100) for creating multiple
identical spools at once. Stock spools (no slicer profile) are computed
rather than stored — any spool without slicer_filament shows an amber
"Stock" badge. New filter chips (All/Stock/Configured) on the inventory
page. Backend bulk endpoint creates N spools in one transaction.

Backend:
- SpoolBulkCreate schema with quantity validation (1-100)
- POST /inventory/spools/bulk endpoint

Frontend:
- Quick Add toggle in SpoolFormModal (create mode only)
- Quantity field in FilamentSection (both modes)
- bulkCreateSpools API method and bulkCreateMutation
- Stock column (hidden by default) and stock filter chips
- Inline error rendering moved into FilamentSection
- CellCtx extended with t() for translatable cell content

Tests:
- 13 backend tests (schema validation + endpoint logic)
- 10 frontend tests (validateForm quickAdd + UI behavior)

i18n: 6 locales (en, de, fr, it, ja, pt-BR)
Docs: CHANGELOG, README, website features, wiki inventory
2026-02-21 10:39:18 +01:00
maziggy 7d46b44561 Fix PCTG filament misidentified as PC (#478) 2026-02-21 10:01:26 +01:00
maziggy 839be41133 Fix support bundle leaking personal data (#473)
The log sanitizer only used regex patterns, missing arbitrary user-chosen
strings (printer names, usernames). Tasmota smart plug credentials were
logged verbatim in URLs by httpx.

- Make _sanitize_log_content() database-aware: query Printer names/serials,
  User usernames, and Bambu Cloud email for exact-string replacement
  (longest-first, skip <3 chars to prevent over-redaction)
- Fix serial regex leaking first 3 chars (remove capture group partial
  redaction), add case-insensitive flag
- Move Tasmota credentials from URL-embedded (http://user:pass@host) to
  httpx auth= parameter so they never appear in logs
- Add URL credentials regex as defense-in-depth for user:pass@ in logs
- Add 'username' and 'path' to settings sensitive_keys filter (catches
  smtp_username, slicer_binary_path in support-info.json)
2026-02-21 08:17:59 +01:00
KeyboredandMartinNYHC 8b081dbd9a Allow external materials/brands to be used when adding spool (#455)
* feat(spool-form): enhance brand and material selection in color section

* feat(spool-form): change input field behavoiur when deleting all chars, fix scroll menu theming

* feat(spool-form): add available materials to SpoolFormModal and FilamentSection

* refactor(ColorSection): remove unnecessary hasCatalogMatch variable

* feat(SpoolFormModal): add bilateral brand and material filtering logic

* feat(ColorCatalogSettings): improve input field sizes and layout for color and material selection

* Refactor colorCatalog settings and dependencies, allow custom materials, fix ml-12 marging, show catalog colors on brand/material selection

* Refactor ColorCatalogSettings and ColorSection components; remove  onBlur logic in FilamentSection

* Prioritize exact matches in search results

* Added inventory.useCustomMaterial to locales

* Remove unused filteredCatalogColors logic and update button rendering; update types file to import Printer and SpoolKProfile

* Fix indentation for useCustomMaterial

* Refactor showCatalogSection logic to only depend on matched catalog colors

* Remove extra newline before brand dropdown

* Clean up ColorSection.tsx by removing blank lines

Removed unnecessary blank lines in ColorSection.tsx.

* Ensure material property is a string in ColorSection component

---------

Co-authored-by: MartinNYHC <mz@v8w.de>
2026-02-20 18:34:24 +01:00
maziggy 6ab48fa338 Updated CI 2026-02-20 18:28:34 +01:00
maziggy 1404242e0c Fix cost tracking issues 2026-02-20 16:31:16 +01:00
MartinNYHC 965000c3ca Merge branch '0.2.1b2' into feature/cost_tracker 2026-02-20 16:26:01 +01:00
Wesley Reuel Marques SilvaandMartinNYHC ceb2de7164 Adding the energy cost from 2 to 3 decimal precision (#416)
* Adding the energy cost from 2 to 3 decimal precision

* Complying with pr

* Complying with PR

* Complying with PR

* Fix energy cost display precision in ProjectDetailPage

* Change energy cost formatting to two decimal places

* Change decimal precision for energy cost display

---------

Co-authored-by: MartinNYHC <mz@v8w.de>
2026-02-20 16:23:00 +01:00
Keybored 85645ce184 Merge branch '0.2.1b2' into feature/cost_tracker 2026-02-20 15:44:34 +01:00
maziggy 40403ae584 Fix inventory date format and AMS-HT slot labels (#463)
Two bugs in the inventory page:

1. Dates always displayed as DD/MM/YY regardless of the user's date
   format setting. The page had a local formatDate() hardcoding en-GB
   locale. Replaced with the shared formatDateOnly() from utils/date.ts.

2. AMS-HT slot locations showed accented characters (e.g., "Á1") instead
   of proper labels (e.g., "HT-A"). The code used String.fromCharCode(65
   + ams_id), which produces garbled chars for AMS-HT IDs (128+). Now
   uses the shared formatSlotLabel() from utils/amsHelpers.ts.
2026-02-20 15:22:44 +01:00
Matteo Parenti 9f19e8a2ff Add currency symbol, hide projected cost for no costs configured, add cost rounding to decimal point, fixed isExternal logic 2026-02-20 11:36:26 +01:00
maziggy e4e6e9f8c4 Decouples file uploads and print start commands so that they run in the background asynchronously. When a print is started, the print modal no longer waits for the print to upload and start. Instead, a new toast-based UI appears with the status of prints being dispatched. Prints being dispatched can be cancelled during upload. If cancelled, the partially-uploaded gcode is deleted from the printer automatically before the FTP connection is closed.
This allows users sending particularly large prints to slow printers such as the P1-series to start a print and then move onto another task in Bambuddy immediately (such as starting more prints on more printers). It also gives the user visibility into what's happening instead of a loading indicator appearing for an indefinite period of time.

The new toast-based UI uses websockets to update in real time. It will also appear for other users / instances of Bambuddy, not just the user who started the prints, allowing more transparency and handling cases where the user closes the page and then comes back wanting to know the status of the dispatching.

fix: review fixes for background dispatch PR #408

- Restore missing imports in main.py (inventory, print_log, virtual_printers, mqtt_smart_plug_service)
- Guard voidresp() for A1 printers to prevent hang after upload
- Don't fail upload on voidresp() error since data transfer already completed
- Add ams_mapping to register_expected_print calls for Spoolman usage tracking
- Fix cancel_job TOCTOU race by using single lock acquisition
- Fix batch counter reset TOCTOU by re-checking condition inside second lock
- Add backgroundDispatch translations to fr.ts and pt-BR.ts
- Remove dead upload_progress_callback definitions
- Skip redundant "Print queued" toast in reprint mode (dispatch toast handles it)
- 5 backend tests: cancel_job single-lock TOCTOU, batch reset re-check,
  job lifecycle
- 2 FTP regression tests: voidresp error handling (upload-loop fix),
  A1 model voidresp skip
- 1 frontend test: reprint toast suppression
- CHANGELOG: background dispatch feature + test coverage entries
- README: add background dispatch to Scheduling & Automation
- Website: add feature item to Automation section
- Wiki: add Background Print Dispatch section to print-queue.md
2026-02-20 09:26:50 +01:00
Ryan Ewen 060b253669 Update frontend build 2026-02-20 08:51:21 +01:00
Ryan Ewen 360607c327 Fix conflicting var name 2026-02-20 08:51:13 +01:00
Ryan Ewen 4a625c1ef2 Add background print dispatching + tests 2026-02-20 08:51:13 +01:00
Matteo Parenti 071c2c702a Refactor cost calculation logic to utilize pre-fetched spool usage costs and remove redundant imports; update InventoryPage to adjust cost display format 2026-02-19 18:22:07 +01:00
MartinNYHC 380edfc249 Merge branch '0.2.1b2' into feature/cost_tracker 2026-02-19 17:08:26 +01:00
maziggy d71e56c3e6 Minor layout improvements 2026-02-19 17:08:07 +01:00
Matteo Parenti 8043bb18ba Refactor cost calculation logic to prioritize spool usage history and update schema validation for cost_per_kg 2026-02-19 16:55:25 +01:00
MartinNYHC c72366c9d3 Merge branch '0.2.1' into feature/cost_tracker 2026-02-19 16:30:28 +01:00
Keybored 0e50285860 Merge branch '0.2.1b' into feature/cost_tracker 2026-02-19 16:25:27 +01:00
maziggy 2f51bec40d feat: add "Include beta updates" setting to filter prerelease notifications
Users on the Docker `latest` tag were seeing update notifications for beta
releases (e.g. v0.2.1b) they couldn't install. The update checker now fetches
/releases instead of /releases/latest and filters by parse_version() prerelease
detection. A new toggle in Settings (default: off) lets users opt in to beta
notifications.
2026-02-19 16:15:01 +01:00
maziggy 5e6c04f303 fix: queue stuck on "Busy" for "Any Model" jobs (#435)
When a print was queued with "Any [Model]", the queue widget only
queried items with printer_id=X after dispatch, missing the next
pending model-based item (printer_id IS NULL, target_model="P1S").
The "Clear Plate & Start Next" button never appeared, leaving the
scheduler stuck reporting "Busy".

Add optional target_model query parameter to GET /queue/. When
combined with printer_id, uses OR logic to also return unassigned
items whose target_model matches. The frontend now passes the
printer's model through PrinterQueueWidget to this query.
2026-02-19 14:22:28 +01:00
Matteo Parenti 04ffca204f Add cost tracking for spools and usage history 2026-02-19 14:13:18 +01:00
maziggy 7b39026429 fix: resolve PFUS preset IDs causing slicer slot resets + fill level for new spools
BambuStudio actively resets AMS slots configured with unrecognized PFUS*
(user-local) preset IDs. Replace PFUS* with generic Bambu filament IDs
(e.g. GFL99 for PLA) in both the slot configure and inventory assignment
endpoints. When the slot already has a recognized cloud-synced preset for
the same material, reuse it to preserve K-profile calibration.

Also fix fill level bar not showing for brand new spools (weight_used=0)
by changing the condition from weight_used > 0 to weight_used != null.
2026-02-19 12:54:15 +01:00
maziggy d24e7cdf84 feat: multiple virtual printers with dedicated bind IPs + dual bind/detect ports (#445)
Multiple Virtual Printers:
- Each VP gets a dedicated bind IP with independent FTP, MQTT, SSDP, and Bind services
- New VirtualPrinter DB model, CRUD API (/api/virtual-printers), React UI
- VirtualPrinterList, VirtualPrinterCard, VirtualPrinterAddDialog components
- Per-instance TLS certificates (shared CA), 11 printer models, all 4 modes
- Auto-incremented serial suffixes, network interface override per VP

Dual Bind/Detect Ports (#445):
- Listen on both ports 3000 and 3002 for slicer bind/detect handshake
- Different BambuStudio/OrcaSlicer versions use different ports
- Applies to BindServer (server mode) and SlicerProxyManager (proxy mode)
- Updated Dockerfile, docker-compose.yml, firewall rules in wiki

Also:
- Rewrote VP test suite for new multi-instance architecture (75 tests)
- Rewritten "How it works" section with 3-step workflow explanation
- Updated all 5 locales (en, de, ja, fr, it)
- Updated wiki and website for multi-VP + dual ports
- New multi-VP screenshot
2026-02-19 11:22:28 +01:00
maziggy cb3363733e fix: remove dead PAUSED printer state checks (#447)
The printer only sends PAUSE via MQTT gcode_state, never PAUSED.
Removed all unreachable PAUSED comparisons from frontend (4 files)
and backend (2 files).
2026-02-19 09:42:11 +01:00
maziggy df83250ff8 feat: add dedicated clear_plate permission + full-page group editor (#446)
Add a new `printers:clear_plate` permission so admins can grant
plate-clearing ability without full `printers:control` access.
Existing groups with `printers:control` automatically receive the
new permission on startup via migration.

Replace the cramped permission modal in Settings with a dedicated
full-page group editor (`/groups/new`, `/groups/:id/edit`) featuring
search filtering, select all/clear all, category-level toggles,
and a responsive 2-column permission grid. Remove dead GroupsPage
code that was never routed.

- Backend: new Permission enum, category, defaults, endpoint guard, migration
- Frontend: GroupEditPage, updated routes, removed modal from SettingsPage
- Tests: 10 backend + 10 frontend tests for new permission and editor
- Docs: updated wiki (auth, printer-control, API), website, changelog
- i18n: added group editor keys to all 6 locale files (en/de/ja/fr/pt-BR/it)
2026-02-19 09:11:42 +01:00
maziggy 9e317bd775 Fix npm audit high-severity minimatch ReDoS (GHSA-3ppc-4f35-3m26)
by adding an npm override for minimatch@^10.2.1 in package.json.
2026-02-19 08:23:53 +01:00
maziggy bf33e6e16a Suppress the new minimatch ReDoS audit finding (GHSA-3ppc-4f35-3m26,
high) by changing audit-level from "high" to "critical" in .npmrc. Like
the existing ajv suppression, minimatch is a transitive dev dependency of
eslint/vitest with no non-breaking fix available — the ReDoS requires
untrusted glob patterns which never occur in linting/testing configs.
2026-02-19 08:19:11 +01:00
maziggy ec751424b6 Fix AMS slot mapping for A1 Mini (#364)
Add color-matching fallback for slot-to-tray mapping on printers that
don't provide the MQTT mapping field (snow encoding) or reject request
topic subscription. Matches 3MF filament slot colors against AMS tray
colors to resolve the correct physical tray. Returns no match when
colors are ambiguous (duplicate tray colors) to safely fall through
to existing fallbacks.

Mapping priority chain: print_cmd → MQTT snow → queue → color match →
tray_now → slot_id-1.
2026-02-19 07:56:15 +01:00
MartinNYHC bb4902ad53 Merge branch '0.2.1b' into add-H2D-Pro-png 2026-02-18 17:16:12 +01:00
MartinNYHC 1d636c9a16 Merge branch '0.2.1b' into refactor-all-pages 2026-02-18 16:54:55 +01:00
MartinNYHC 181364c687 Merge branch '0.2.1b' into feature/brazilianPortugueseTranslation 2026-02-18 16:41:00 +01:00
maziggy a903816b8a fix(slicer): token-based auth for Open in Slicer downloads (#433)
Slicer protocol handlers (bambustudio://, orcaslicer://) launch the
slicer app which fetches files via HTTP but cannot send auth headers.
The global auth middleware returned 401, causing "importing failed."

Add short-lived, single-use download tokens: the frontend fetches a
token via authenticated POST, then builds a /dl/{token}/{filename} URL
the slicer can access without auth headers. Tokens are validated
server-side (5-min expiry, single-use). Applies to archive files,
source 3MFs, and library files.

Also fix platform-specific URL formats to match slicer source code:
- macOS: bambustudioopen:// with encodeURIComponent
- Windows/Linux: bambustudio://open?file= (was wrongly using macOS scheme on Linux)
- OrcaSlicer: orcaslicer://open?file=
2026-02-18 16:37:35 +01:00
MartinNYHC 1c068d2a2f Merge branch '0.2.1b' into feature/use_remaining_filament 2026-02-18 14:59:47 +01:00
maziggy 11d9c98b55 fix(inventory): require brand and subtype in spool form (#417)
The spool add/edit modal allowed saving without brand or subtype,
causing incomplete tray_sub_brands when assigned to AMS slots.
BambuStudio then failed to recognize the filament profile.

Brand and Subtype are now mandatory with validation errors on submit.
2026-02-18 14:59:03 +01:00
Wesley Reuel Marques Silva f657e4c433 Merge branch '0.2.1b' into feature/brazilianPortugueseTranslation 2026-02-18 13:33:50 +00:00