MartinNYHC 6ebd6734d0 Merge pull request #1383 from maziggy/0.2.4.1
**Bambuddy v0.2.4.1**

⚠ **Upgrade Notes — Read Before Updating**

Almost everyone is upgrading from 0.2.4. 0.2.4.1 is a patch release: stability and correctness fixes built on the same code base as 0.2.4, no schema breaks, no Docker entrypoint changes, no Vite/proxy quirks. The in-app Apply Update button in Settings → System → Updates resolves to the latest stable tag and works for all users — no flags needed.

Make a backup before upgrading via Settings → Backup → Create Backup. Native install with update.sh snapshots the database automatically and rolls back on failure. Docker and fully-manual paths don't.

**Docker**

docker compose pull
docker compose up -d

docker-compose.yml doesn't need refreshing — none of the entrypoint, volume, or env-var conventions changed since 0.2.4.

**Native install — recommended path**

sudo BRANCH=main /opt/bambuddy/install/update.sh

**Native install — manual path**

sudo systemctl stop bambuddy
cd /opt/bambuddy
sudo -u bambuddy git fetch origin --tags
sudo -u bambuddy git checkout main
sudo /opt/bambuddy/venv/bin/pip install -r requirements.txt
sudo systemctl start bambuddy

**Behaviour changes to know about**

- Reprint stats are now per-event, not per-archive. Re-printing a file no longer overwrites the source archive's totals; Quick Stats and the per-archive Print Log gain an orange N prints badge with a per-run breakdown (successful + failed). If you already had a reprint that overwrote stats in 0.2.4, the existing archive row keeps its current numbers — but every new print event from 0.2.4.1 onward writes a separate PrintLogEntry, so totals start adding correctly again. (#1378)

- Pending queue items for soft-deleted archives are now auto-cancelled. Soft-deleting an archive (default delete path) removes its files from disk, which makes any pending queue item pointing at it un-dispatchable. From 0.2.4.1 those items get status=cancelled + waiting_reason="Source archive deleted" so you see why the queue item disappeared from pending instead of finding it silently stuck. (#1348 follow-up)

- i18n parity check now blocks English-leak in non-English locale files. The build's parity step (npm run build) now fails CI when a non-English locale entry equals the English source unless explicitly allow-listed as a cognate. 2,377 accumulated English fallbacks across 7 locales were translated in this cycle as the underlying cleanup. No user-visible change today — just no more "Advanced" buttons in your German UI from new keys going forward.

---
  
**Highlights**

0.2.4.1 closes correctness gaps that hit power-users running queues, reprints, and Obico fault detection at the same time. The three biggest are: per-event stats aggregation so reprints add to Quick Stats instead of overwriting (#1378), camera stream no longer freezes when Obico polls the same printer (#1348, reported by @SL666), and multi-color archive cost now charges untracked AMS slots at the default rate instead of reporting near-zero (#1344, reported by @nicktags). Around them: AMS slot configuration that survives Reset Slot on A1 Mini BMCU / P1S Standard AMS, MakerWorld URL import, queue/VP-dispatched prints finally getting layer timelapse, plate detection respecting the external camera setting, firmware checks staying alive when bambulab.com Cloudflare-blocks the page, LDAP manual provisioning, and a narrow API-key permission for the Home Assistant dynamic-tariff integration.

Plus a deep i18n debt cleanup — 2,377 strings translated across 7 locales — and mechanical CI enforcement so the debt can't accumulate again.

---

**New Features**

- Manual LDAP user provisioning from the UI (#1298) — Add LDAP users into Bambuddy without waiting for their first login. Pre-create groups, permissions, and inventory ownership before the user even authenticates once.

- Build-plate override in the SliceModal (#1337) — Pick which build plate (Cool / Cool SuperTack / Engineering / High Temp / Textured PEI / Smooth PEI) to slice for, independent of the source 3MF's embedded plate. The slice respects the override end-to-end (sliced output is bound to the chosen plate, archive metadata records it, printer card thumbnail matches).

- API Keys: narrowly-scoped "Update electricity price" toggle (#1356) — New per-key permission flag exposes a single endpoint POST /api/v1/settings/electricity-price that accepts {"energy_cost_per_kwh": <float>}. Closes the gap where the wiki documented a Home Assistant dynamic-tariff rest_command example that was never deliverable (every key with general SETTINGS_UPDATE is hard-denied for security). The new flag does NOT widen general settings-write access — the broader PATCH /settings route remains denied. Wiki updated; existing keys default off.

- Per-archive Print Log view + clickable "N prints" badge (#1378 follow-up) — Every archive card with more than one print event shows an orange N prints badge with a hover-tooltip breakdown (successful vs failed). Click it (or use the context-menu entry) to open a print log dialog showing every print event for that archive — date, status, duration, filament, cost — with failure_reason text under failed runs. Also embedded as a section at the top of the Edit Archive modal so the history is one click away.

---

**Improved**

- Reset Slot on A1 Mini BMCU / P1S Standard AMS no longer deadlocks Assign Spool (#1322, reported by @RosdasHH) — The empty-detection that gated ams_filament_setting was too cautious; now only short-circuits on state ∈ {9, 10} (firmware's explicit "no spool" codes) so the post-Reset-Slot "spool inserted, state=3, tray_type empty" case fires MQTT and configures the slot. Same Reset Slot click that previously sat in pending state forever now lands cleanly.

- Multi-color archive cost now tops up untracked AMS slots at the default rate (#1344, reported by @nicktags) — A 110 g multi-color print with only one of four trays mapped to inventory used to show $0.01 instead of ~$1.10. Untracked slots now charge at the global default filament cost. Fully-tracked prints are unchanged.

- Plate-detection calibration captures from the configured external camera (#1359, reported by @Andlar94) — On printers with an external RTSP / go2rtc camera enabled, calibration was previously sourcing the reference frame from the built-in chamber camera while the runtime check used the external one — guaranteeing a "Build plate not empty" false-positive on every print. Both paths now share the same external-camera default, with a backend-side derivation so future callers can't drift again.

- Layer timelapse now starts for queue / VP-dispatched prints (#1353, reported by @Andlar94) — The timelapse start_session() call was only on the new-archive code paths. Queue dispatches and VP-dispatched reprints landed on the expected-archive branch and silently lost timelapse. The expected-archive branch now mirrors the same gate.

- Firmware update dialog survives Cloudflare-blocked / transient outages on bambulab.com (#1350, reported by @K1ngJony) — Adds honest browser-like Accept / Accept-Language headers alongside the existing Bambuddy/1.0 UA, persists the resolved buildId to disk (so a single bambulab.com 403 doesn't permanently break download-URL resolution for that session), retries once on 404 (Bambu rebuilt the page), and shows an honest error message when the download endpoint truly can't be reached.

- Subtype dropdown on the Add/Edit Spool form offers CF and GF (#1345) — Adding a third-party PETG-CF / PLA-CF spool no longer requires typing the variant by hand.

- Page-header visual style unified across the app (PR #1272 by @EdwardChamberlain) — Every page now uses the same icon-aligned heading shape.

- OIDC provider icons proxied server-side (PR #1342 by @netscout2001) — Icon fetches no longer expose the issuer's URL via browser request logs / DNS.

- Auto-print start G-code now fires after the printer reaches RUNNING, not before (#1304) — The first RUNNING transition after Bambuddy boots no longer fires an unrelated print-start; users with custom G-code injection get their snippets at the actual start of each print, not the boot of the daemon.

- i18n parity gate now enforces real translations in every locale, not English fallbacks — frontend/scripts/check-i18n-parity.mjs gains a new Check 4 that fails CI when a non-English leaf equals its English source unless explicitly allow-listed as a cognate. The 2,377 accumulated English fallbacks across the 7 non-English locales were translated as the underlying cleanup. Going forward, "English fallbacks per project convention" is not a thing — new keys must be translated in every locale or explicitly added to the per-locale IDENTICAL_TO_EN_ALLOWED cognate list.

- Support bundle records more application state — Adds OIDC providers + 2FA / API key / long-lived token counts, library / inventory / queue / maintenance totals, slicer-API CLI versions, GitHub backup status, per-printer Obico flag. Redacts two settings that were previously included in cleartext and fixes a reachability-check architecture bug. Future triage rarely needs a follow-up "can you also send X" round-trip.

---

**Fixed**

**Stats / Archives / Print Log**

- Reprints (including failed and cancelled ones) no longer overwrite the source archive's statistics (#1378, reported by @IndividualGhost1905) — Statistics are now event-based, not file-based. The existing PrintLogEntry table gains six columns (archive_id, cost, energy_kwh, energy_cost, failure_reason, created_by_id); /archives/stats and /metrics sum from it. Each print completion writes a new row with the run's actual filament / time / cost / energy / status. The cost overwrite at
  usage_tracker.py:633 and energy overwrite at main.py:3625 now both preserve the source archive's first-run values on reprints; the run's actuals are stored on the PrintLogEntry row instead.

- Partial prints record accurate run filament (#1378 follow-up) — Failed / cancelled / stopped reprints no longer record the source archive's slicer estimate verbatim. New _compute_run_filament_grams helper prefers sum of tracked spool deltas, then falls back to estimate × progress%, then None — captured in 14 unit tests across every combination of status × inventory-tracked.

- Print log no longer 404-storms thumbnails for entries whose archive was deleted or whose print failed before extraction (#1348 follow-up) — Two-part fix: route self-heals on first 404 (NULL the cached path on the entry so subsequent renders skip the request) + eager NULL at archive-delete time so future deletes don't fire the one-time storm.

- Soft-deleted archive no longer leaves linked queue items silently stuck in pending forever (#1348 follow-up) — Pending queue items pointing at soft-deleted archives are now cancelled at delete time with waiting_reason="Source archive deleted". Queue API also suppresses the cached archive thumbnail / name / metadata when deleted_at is set, and the queue page's /plates query is gated on a new archive_deleted flag — three 404s per orphaned queue row are now zero.

**Camera**

- Camera stream no longer freezes every ~30s when Obico fault detection is enabled on the same printer (#1348, reported by @SL666) — Obico's _capture_frame was reusing the fan-out broadcaster's buffered frame when available, but falling through to a competing RTSP socket in race windows where the buffer was momentarily empty (stream startup, mid-reconnect). On X1-class firmware that allows only one camera connection, that second socket kicked the live viewer. New is_stream_active() helper now gates the fresh-socket fallback independently of the buffer state — when a viewer is connected, Obico never opens a competing socket.

**AMS / Inventory**

- Bare-tray empty-slot signal on P1S / A1 Mini (#1322 follow-up) — Genuinely-empty AMS slots on these printers send {"id": N} only (no state, no tray_type). The AMS parser now promotes this shape to state=9 so the inventory route's state ∈ {9, 10} short-circuit fires and we don't waste an ams_filament_setting publish that firmware would silently drop.

- AMS slot configuration lands cleanly for spools with no k-profile — The "configure" call no longer 422s when the spool's filament has no calibration profile entry. Affects a long tail of third-party / generic-PLA spools.

- AMS slot configuration lands on firmwares that never report state=11 (#1322 follow-up) — Some older firmwares never report the literal state=11 for loaded; the configure path's gate was too strict. Now treats absence of explicit empty (state ∈ {9, 10}) as loaded.

- Spool removal from AMS on X1C firmware that reports power_on_flag=False while idle (#1365, reported by @an3k) — Empty-slot detection now narrows the skip to zero-bits + power_on_flag=False (the shutdown shape from #765) instead of any power_on_flag=False. Spool pulls between prints now register without a manual Reconnect.

- AssignSpoolModal sits above the mobile sidebar drawer (#1336) — z-index fix; clicking Assign on mobile no longer opens the modal behind the drawer. 

- Catalog color's gradient + effect now applied, not just hex (#1340) — Picking a Bambu Lab gradient or sparkle entry from the colour picker now copies all three colour properties.

- Storage location persists for internal spools (#1291) — Local-mode inventory now writes the storage_location field on save (was Spoolman-only).

**Spoolman**

- AMS-HT range allowed in slot-assignment table (#1274) — The ams_id upper bound was hardcoded at 4; AMS-HT extends the range. Now matches the parser's range.

- External-spool ams_filament_setting uses global tray_id (#1279) — Was sending the local slot ID for external spools; firmware rejects.

- Persist color_name edits without round-tripping the subtype synth fallback (#1319) — Editing the colour name on a Spoolman spool no longer reverts after the next AMS push.

- Restore Spoolman spool ID search + Unassign button (#1336) — Two regressions from the Spoolman inventory UI work that landed in 0.2.4.

- Resolve -1 in ams_mapping to external spool (#1276) — Bambu's multi-color slicer convention; the queue dispatcher now interprets it correctly.

- Per-print 3MF tracking is the only weight writer (#1119) — Removes a competing path that double-wrote weights in Spoolman mode.

- External library lookup filtered by Bambu Lab manufacturer (PR #1330 by @ojimpo) — Stops cross-manufacturer matches polluting the Bambu library picker.

**Virtual Printer / Slicer**

- VP cache preserves AMS / vt_tray / net.info across incremental push_status updates (#1371, reported by @Andlar94) — Slicer no longer needs a printer power-cycle to see AMS info on a queue-mode VP. The bridge's _latest_print_state cache now preserves a small set of sticky keys (ams, vt_tray, ams_extruder_map, mapping, net, ipcam, lights_report) when an incremental push omits them — mirrors what Bambuddy already does for its own internal state.raw_data.

- VP emits FINISH after FTP upload so Print-flow slicers un-wedge (#1280) — BambuStudio's Print-flow path waits for FINISH before clearing its upload progress UI.

- VP broadcasts archive_created so Archives page refreshes live (#1282) — Slicing through the VP now updates the open Archives page without a manual refresh.

- VP queue-mode honours workflow default print options (#1235) — VP-dispatched prints now pick up the user's "Auto-Print start gcode" / "Auto-Off" / etc. defaults consistently.

- Slicer bundle import logs the sidecar's reject reason (#1312 follow-up) — Failed .bbscfg imports now show the upstream error in the Bambuddy log so users can diagnose without curling the sidecar.

**Scheduler / Dispatch**

- Watchdogs no longer falsely treat FINISH → IDLE as "print landed" (#1370, reported by @Martinnygaard) — Queue items dispatched onto a printer that was in FINISH (un-dismissed "Print complete" prompt from a prior job) used to stay stuck at printing forever. The post-dispatch verifier now narrows the "command landed" check to an allow-list of active-print states (PREPARE / SLICING / RUNNING / PAUSE).

- First RUNNING after Bambuddy boots no longer fires a phantom print-start (#1304) — Cold-boot of Bambuddy onto a printer that's mid-print no longer creates a stray archive at the boot moment.

**Camera**

- Plate-detection UI uses the external camera when configured (#1359) — Above under Improved.

- Layer timelapse for queue/VP-dispatched prints (#1353) — Above under Improved.

- Camera fan-out broadcaster buffered frame shared with Obico + /camera/snapshot (#1271) — Reuse path landed in 0.2.4; this cycle's #1348 fix completes the race-free version. Listed for completeness.

**Notifications / Backups**

- Discord webhook accepts legacy discordapp.com URLs (#1363, reported by @mrfoureyed) — Discord's Copy Webhook URL button still emits the legacy hostname; validation now accepts either.

- Backup tab indicator dot for scheduled backups (PR #1338 by @chanakyan-arivumani) — Visual cue when a backup is queued.

**Auth / LDAP / OIDC**

- Manually-assigned groups preserved across LDAP logins (#1292) — LDAP user re-login no longer wipes admin-assigned group memberships.

- Orphan OIDC / MFA rows cleaned up when user is deleted (PR #1295 by @netscout2001) — Deleting a user now cascades to their OIDC binding + TOTP secret rows.

- Password rules shown in user-create form + FE/BE checks aligned (#1303) — Frontend rejected passwords the backend would accept and vice versa; now both apply the same rules and the form shows them.

- External-scan STL thumbnails deferred + Path coerced (#1299) — External library scans no longer block on STL thumbnail rendering; mountpoints expressed as strings work alongside Path objects.

- MakerWorld settings link points to /profiles (#1300) — The "Open Cloud settings" link from the MakerWorld page now goes to the right tab.

**UI / Misc**

- Smart-plug live wattage rounded to whole watts on the printer card (#1266, reported by @Carter3DP) — Plugs reporting fractional watts (ESPHome / HA-bridged) no longer overflow the card.

- Settings UI rendering fields exposed without requiring SETTINGS_READ (#1293) — Non-admin users with narrower scopes can now load the Settings UI; the rendering-only fields (theme, locale) are no longer gated on admin-tier read.

- Bed-jog Z direction inverted on A1 / A1 Mini bed-slingers (#1334) — Up was down on bed-slinger printers; now matches the physical motion.

- Usage tracker: skip remain% fallback for trays not used by the print (#1269, reported by @maugsburger) — Swapping spools in unrelated AMS slots mid-print no longer charges the original spool the full estimate.

- Soft-deleted archives keep their Quick Stats contribution (#1343) — Was already there for archive-level totals; this release locks it in via the new PrintLogEntry event aggregation (#1378) which references log entries by ON DELETE SET NULL, so the contribution survives even a hard delete.

- scan_timelapse picked stale video at false offset (#1278) — Resolved.

---

**Security**

- urllib3 floor raised to 2.7.0 to clear CVE-2026-44431 and CVE-2026-44432. urllib3 is a transitive dependency (none of Bambuddy's top-level deps require >=2.7.0 yet), so the resolver was silently keeping the vulnerable 2.6.x line. requirements.txt now carries an explicit urllib3>=2.7.0 pin.

- Bandit suppression syntax corrected on two verify=False calls in support.py — the two local-sidecar reachability probes used # noqa: S501 (ruff syntax, ignored by bandit) instead of # nosec B501. The probes themselves are unchanged (no payload, no secrets — health-check only) but the local security scan now passes cleanly without false-positive high-severity findings.

---

**Contributors**

Big thanks to everyone who shipped code or filed reproducible bug reports this cycle:

Code: @netscout2001, @EdwardChamberlain, @chanakyan-arivumani, @ojimpo, @maziggy

Reproducible bug reports: @IndividualGhost1905, @SL666, @nicktags, @Andlar94, @RosdasHH, @an3k, @K1ngJony, @Martinnygaard, @Fuechslein, @mrfoureyed, @maugsburger, @Carter3DP

(See CHANGELOG.md for the full per-fix detail.)
2026-05-16 13:54:45 +02:00
…
2026-04-22 20:21:33 +02:00
2026-05-14 14:01:57 +02:00
2026-05-16 13:51:09 +02:00
2026-04-24 09:48:08 +02:00
2026-02-19 16:32:44 +01:00
2026-04-23 17:01:33 +02:00
2026-03-01 18:28:31 +01:00
2026-03-10 10:31:18 +01:00
2026-02-20 15:28:47 +01:00
2026-02-16 10:57:39 +01:00
2026-05-05 10:54:14 +02:00
2026-02-05 10:28:06 +01:00
2026-05-05 10:54:14 +02:00
2026-04-23 16:51:03 +02:00

Bambuddy Logo

Bambuddy

Your printers. No cloud. Your rules.
Self-hosted command center for Bambu Lab — from one A1 to a 40-printer farm.

Release License Stars Issues Discord GitHub Sponsors Sponsors Portal Ko-fi

🎮 Try the Live Demo • Features • Screenshots • Quick Start • Documentation • Discord • Contributing

Live Demo
Spin up your own private Bambuddy in ~10 seconds — no install, no signup, 30-minute session.


"Bambuddy is the companion app that Bambu Lab should have built from day one." — Adam Conway, XDA-Developers

XDA-Developers How-To Geek Fabbaloo Igor's Lab 3Druck FastBlinker

Two leading 3D-printing publications independently concluded that Bambuddy's feature set already exceeds Bambu's own cloud:

"The features seem to exceed those provided by Bambu Lab's own cloud." — Fabbaloo

"The list of functions seems so extensive that it even goes beyond what Bambu Lab offers in its own cloud." — 3Druck.com

📄 See all press coverage →


🌐 NEW: Remote Printing with Proxy Mode

Proxy Mode Architecture

Print from anywhere in the world — Bambuddy's new Proxy Mode acts as a secure relay between your slicer and printer:

  • 🔒 End-to-end TLS encryption — FTP, file transfer, and camera are transparently proxied with the printer's real TLS certificate
  • 🛡️ Optional Tailscale integration — per-VP toggle + Docker socket mount surface the host's Tailscale IP on the VP card, so you know which 100.x.x.x to paste into the slicer when you want a virtual printer reachable over your tailnet (setup). Bambuddy's self-signed CA import is still required on the slicer side: Bambu Studio / OrcaSlicer validate printer TLS against a bundled BBL CA (not the system trust store), and their Add Printer dialog is IP-only (no hostname to match an LE cert against), so a publicly-trusted cert can't help on either dimension. Tailscale's role is the private tunnel (reachability from anywhere, no port forwarding), not cert-import elimination.
  • 🌍 No cloud dependency — Direct connection through your own Bambuddy server
  • 🔑 Uses printer's access code — No additional credentials needed
  • ⚡ Full-speed printing — Transparent TCP proxy, only MQTT is decrypted for IP rewriting

Perfect for remote print farms, traveling makers, or accessing your home printer from work.

👉 Setup Guide →


🍰 NEW: Integrated Slicing — Slice & Print, All In One Place

No desktop slicer required. Drop an STL or 3MF into Bambuddy's File Manager, hit Slice, and the result lands as a ready-to-print .gcode.3mf in the same folder — without ever opening Bambu Studio or Orca Slicer.

  • 🍰 One-click slicing — Slice from any browser. The job runs server-side in a tiny sidecar container, progress streams back as a toast, and the sliced file appears in your library when it's done.
  • 📱 Slice from your phone or tablet — Bambuddy's PWA + the new server-side slicer means you can drop an STL in from mobile and queue a print without ever touching a desktop.
  • 🎒 Bring your own profiles — Import a Printer Preset Bundle (.bbscfg) exported from Bambu Studio: pick a curated printer + process + filament triplet from a dropdown in the Slice dialog, no more juggling JSON files.
  • 🔁 Same dispatch as the rest of Bambuddy — The sliced output flows into the existing queue / plate-picker / AMS-mapping path, so all the regular conveniences (multi-printer dispatch, AMS routing, scheduled prints) just work.

Optional but recommended — drop the slicer-api/ Compose stack next to your Bambuddy install and the Slice button lights up everywhere.

👉 Slicer Integration Guide →


Why Bambuddy?

  • Own your data — All print history stored locally, no cloud dependency
  • Works offline — Uses Developer Mode for direct printer control via local network
  • Full automation — Schedule prints, auto power-off, get notified when done
  • Multi-printer support — Manage your entire print farm from one interface

✨ Features

📦 Print Archive

  • Automatic 3MF archiving with metadata
  • 3D model preview (Three.js)
  • Duplicate detection & full-text search
  • Photo attachments & failure analysis
  • Timelapse editor (trim, speed, music) with automatic AVI-to-MP4 conversion for P1-series printers, manual upload & remove
  • Re-print to any connected printer with AMS mapping (auto-match or manual slot selection, multi-plate support, nozzle-aware matching for dual-nozzle H2D/H2D Pro, Filament Track Switch (FTS) support — when the FTS accessory is installed the per-nozzle filter is suppressed since the FTS routes any AMS slot to either extruder)
  • Plate thumbnail browsing for multi-plate archives (hover to navigate between plates)
  • Archive comparison (side-by-side diff)
  • Tag management (rename/delete across all archives)
  • Per-archive print history — Each archive card shows an N prints badge whenever a model has been printed more than once (reprint + failed retries all counted). Click the badge for the full per-archive Print Log — every individual run with date, status, duration, filament used, cost, and failure reason. Reprints contribute new rows so a failed retry never overwrites the source archive's data — the original 100 g successful print stays visible alongside the 10 g failed reprint, and Quick Stats add up to 110 g across both events.
  • Print Log — Chronological table view of all print activity with columns for date/time, print name, printer, user, status, duration, and filament. Filterable by search, printer, user, status, and date range. Pagination with configurable page size. Clear button removes log entries without affecting archives.

📊 Monitoring & Control

  • Real-time printer status via WebSocket
  • Live camera streaming (MJPEG) & snapshots with multi-viewer support — most Bambu printers only allow one upstream connection, so Bambuddy fans out a single shared stream to all browser tabs / cards / overlays
  • Long-lived camera tokens for Home Assistant / Frigate / kiosks — mint a token from Settings → API Keys, paste it once, capped at 365 days, revocable at any time (no infinite tokens — leaked permanent tokens are unsafe by design)
  • Streaming overlay for OBS - Embeddable page with camera + status for live streaming (/overlay/:printerId), configurable FPS (?fps=30), status-only mode (?camera=false)
  • External camera support (MJPEG, RTSP, HTTP snapshot, USB/V4L2) with layer-based timelapse
  • Build plate empty detection - Auto-pause print if objects detected on plate (multi-reference calibration, ROI adjustment)
  • Fan status monitoring (part cooling, auxiliary, chamber)
  • Printer control (stop, pause, resume, chamber light, print speed, airduct mode for P2S/H2*, build-plate Z-jog with Studio-style not-homed warning)
  • Status badges on printer card: SD Card (green / red), Enclosure Door (green / yellow — X1/P1S/P2S/H2*), Airduct Mode (cooling / heating)
  • Force Refresh menu item — request a full status push from the printer without reconnecting
  • Bulk printer actions (multi-select cards, then stop/pause/resume/clear all — select by state or location)
  • Printer search and filters — live search by name/model/location/serial plus status and location dropdown filters (WebSocket-reactive, mobile-friendly)
  • Resizable printer cards (S/M/L/XL)
  • Skip objects during print
  • AMS slot RFID re-read
  • AMS slot Load / Unload from the printer card — Hover any AMS slot or external spool, click the menu button, and load that tray or unload the currently-loaded one without going to the touchscreen; supports dual-extruder H2D (Ext-L / Ext-R drive their own nozzle)
  • AMS slot configuration (model-filtered presets, K profiles, color picker, pre-population for configured slots)
  • AMS info card (hover for serial number, firmware version) with custom friendly names that persist across printers
  • AMS remote drying — Start, monitor, and stop drying sessions for AMS 2 Pro and AMS-HT directly from the Printers page with filament-based temperature/duration presets, optional spool rotation; automatic PSU detection and HMS power error reporting
  • Queue auto-drying — Automatically dry filament between scheduled prints when humidity exceeds threshold; configurable presets per filament type, optional blocking mode
  • Ambient drying — Automatically keep filament dry on idle printers based on humidity, regardless of whether prints are queued
  • Configurable drying presets per filament type (temperature & duration for AMS 2 Pro and AMS-HT)
  • Dual external spool support for H2D (Ext-L / Ext-R)
  • HMS error monitoring with history and clear errors
  • Print success rates & trends
  • Filament usage tracking
  • Cost analytics & failure analysis
  • AI print-failure detection — Optional integration with a self-hosted Obico ML API: watches each running print's camera feed, smooths scores over time (30-frame warmup + EWM + rolling means), and fires a configurable action once per print (notify / pause / pause-and-off)
  • Per-user statistics filtering (admin permission gated)
  • CSV/Excel export

⏰ Scheduling & Automation

  • Background print dispatch — FTP uploads and print-start commands run in the background with real-time WebSocket progress toasts (per-job upload bars, status badges, cancel button)
  • Print queue with drag-and-drop and timeline schedule view
  • Multi-printer selection (send to multiple printers at once)
  • Batch print quantity (print multiple copies — set quantity in the print/schedule dialog, first copy prints immediately, rest are queued)
  • Staggered batch start (start printers in groups with configurable interval to avoid power spikes — works in both Print and Queue dialogs)
  • Configurable default print options (bed levelling, flow/vibration calibration, first layer inspection, timelapse) in Settings → Workflow
  • Model-based queue assignment (send to "any X1C" for load balancing) with location filtering
  • Filament override for model-based queue (swap filament colors/types before scheduling)
  • Filament validation (only assign to printers with required filaments)
  • Prefer lowest remaining filament (consume partial spools first when multiple match)
  • Per-printer AMS mapping (individual slot configuration for print farms)
  • Scheduled prints (date/time)
  • Shortest Job First scheduling (SJF toggle on queue page — scheduler picks shorter prints first, with starvation guard)
  • Queue Only mode (stage without auto-start)
  • Clear plate confirmation between queued prints (can be disabled in settings for farm workflows)
  • Auto-print G-code injection (per-model start/end snippets for Farmloop, SwapMod, AutoClear, Printflow 3D — toggle per queue item)
  • Smart plug integration (Tasmota, Home Assistant, MQTT, REST/Webhook)
  • REST smart plugs: Control any device with an HTTP API (openHAB, ioBroker, FHEM, Node-RED) with separate power/energy URLs and unit multipliers
  • MQTT smart plugs: Subscribe to Zigbee2MQTT, Shelly, or any MQTT topic for energy monitoring
  • Energy consumption tracking (per-print kWh and cost) — restart-resilient: mid-print backend restarts no longer lose per-print energy
  • Energy statistics by date range (Today / Week / Month / …) in total-consumption mode via hourly lifetime-counter snapshots
  • HA energy sensor support (for plugs with separate power/energy sensors)
  • Auto power-on before print
  • Auto power-off after cooldown

📁 File Manager (Library)

  • Upload and organize sliced files (3MF, gcode, STL)
  • External folder mounting - Mount host directories (NAS, USB, network shares) without copying files
  • STL thumbnail generation - Auto-generate previews for STL files on upload or batch generate for existing files
  • ZIP file extraction with folder structure preservation
  • Option to create folder from ZIP filename
  • Folder structure with drag-and-drop
  • Rename files and folders via context menu
  • Print directly to any printer with full options
  • Add to queue without creating archive upfront
  • Plate selection for multi-plate 3MF files
  • Duplicate detection via file hash
  • Mobile-friendly with always-visible action buttons
  • Server-side Slice button (optional) — slice STL/3MF without a desktop slicer when the slicer-api/ Compose stack is running; the result lands as a new .gcode.3mf in the same folder, with progress shown via a toast tracker that follows the job to completion. Supports importing Bambu Studio Printer Preset Bundles (.bbscfg) so a curated printer + process + filament triplet can be picked in the Slice dialog without re-uploading JSON profiles (details)

🌍 MakerWorld Integration

  • Paste any makerworld.com/models/… URL → preview, plate picker, and import without leaving Bambuddy
  • Per-plate Save or Save & Slice in Bambu Studio / OrcaSlicer (your preferred slicer from Settings)
  • Import all plates button for multi-plate models
  • Auto-creates a "MakerWorld" folder in File Manager; override with any existing folder via the picker
  • Per-plate image gallery with keyboard-navigable lightbox
  • Recent imports sidebar — last 10 MakerWorld imports with one-click jump to File Manager or slicer
  • Remove-from-library for imported plates with confirm modal (no LAN cookie paste, no browser extension)
  • Reuses your existing Bambu Cloud login — no separate OAuth flow or browser extension to install

📁 Projects

  • Group related prints (e.g., "Voron Build")
  • Track plates (print jobs) and parts separately
  • Auto-detect parts count from 3MF files
  • Color-coded project badges
  • Project URL + cover photo — paste a MakerWorld/Printables/Thingiverse link and upload a hero image so each card is immediately recognisable; the URL renders as a one-click link beside the project name
  • Bulk assign archives via multi-select toolbar
  • Import/Export projects as ZIP (includes files) or JSON
  • Print or queue files from linked library folders directly in the project view (resulting archive auto-linked to the project)

🔔 Notifications

  • WhatsApp, Telegram, Discord
  • Email, Pushover, ntfy (with per-event priority — Min / Low / Default / High / Urgent)
  • Home Assistant persistent notifications
  • Custom webhooks
  • Quiet hours & daily digest
  • Customizable message templates with per-filament usage details
  • Print finish photo URL in notifications
  • Filament usage and progress in failed/cancelled print notifications
  • Missing spool assignment warning — Toast and push notification when a print starts with unassigned AMS trays
  • HMS error alerts (AMS, nozzle, etc.)
  • Build plate detection alerts
  • First layer complete alert (with camera snapshot)
  • Bed cooled alerts (configurable threshold)
  • Queue events (waiting, skipped, failed)

🧵 Spool Inventory

  • Built-in spool inventory with AMS slot assignment, usage tracking, and remaining weight management
  • Automatic filament consumption tracking: 3MF slicer estimates for all spools (primary), AMS remain% delta as fallback
  • Mid-print spool reassignment support: uses live assignment if changed during print, snapshot otherwise
  • Per-layer gcode accuracy for partial prints (failed/cancelled), with linear scaling fallback
  • Per-spool cost tracking — Set cost/kg on each spool; costs are automatically calculated at print completion and aggregated to archives. Print modal shows real-time cost preview. Configurable default cost and currency in Settings.
  • Bulk spool addition — Add multiple identical spools at once (quantity 1–100) with a single form submission. Quick Add mode for stock spools that only need material, color, and weight.
  • Spool catalog, color catalog, PA profile matching, and low-stock alerts
  • Multi-colour gradients, transparency, and visual effects — Paste a comma-separated hex list (e.g. from 3dfilamentprofiles.com) to render a spool as a gradient or conic colour wheel; transparency shows through a checkerboard so the alpha you set is the alpha you see; pick a visual effect (sparkle, wood, marble, glow, matte) for the swatch overlay. Same fields are editable on the colour catalog so combos can be reused across spools.
  • Printable spool labels — Generate PDF labels for any selection of spools in four pre-built sizes: AMS holder (30×15 mm), box label (62×29 mm), Avery L7160 sheet (A4, 21 per page), and Avery 5160 sheet (US Letter, 30 per page). Each label shows the colour swatch, brand, material, name, the spool ID (for at-a-glance identification across many similar spools), and a QR code that deep-links straight back to the spool's row in Bambuddy when scanned with a phone. Pick from the inventory page — search, filter by material, multi-select spools, then print or save to PDF.

🔧 Integrations

  • Spoolman filament sync with per-filament usage tracking and fill level display
  • MQTT publishing for Home Assistant, Node-RED, etc.
  • Prometheus metrics - Export printer telemetry for Grafana dashboards
  • Bambu Cloud profile management
  • Local Profiles - Import OrcaSlicer presets (.orca_filament, .bbscfg, .bbsflmt, .zip, .json) without Bambu Cloud
  • K-profiles (pressure advance)
  • GitHub backup - Schedule automatic backups of cloud profiles, k profiles and settings to GitHub
  • Scheduled local backups - Automatic backup snapshots on hourly/daily/weekly schedule with retention management and NAS-mountable output
  • External sidebar links
  • Webhooks & API keys
    • Per-user ownership — each key acts on behalf of its creator
    • Optional cloud-access scope — opt in to let an API key read its owner's Bambu Cloud presets / filament catalogue / device list (off by default)
  • Interactive API browser with live testing

🖨️ Virtual Printer & Remote Printing

  • 🌐 Proxy Mode — Print remotely from anywhere via secure TLS relay
  • 🪞 Live target-printer mirror in non-proxy modes (NEW!) — Immediate / Review / Queue VPs now mirror their target printer's live state to the slicer: AMS slot contents, FTS / dual-extruder routing, k-profiles, AMS load / dry / calibration commands, and the camera stream all flow through the VP. Use the slicer as a full remote for the printer behind the VP without giving up Bambuddy's queue / archive / dispatch features.
  • Emulates a Bambu Lab printer on your network
  • Send prints directly from Bambu Studio/Orca Slicer
  • Configurable printer model (X1C, P1S, A1, H2D, etc.)
  • Archive mode, Review mode, Queue mode, or Proxy mode
  • Queue mode: optional force-color-match so the scheduler refuses to dispatch onto a printer with the wrong filament loaded
  • SSDP discovery (same LAN) or manual IP entry (VPN/remote)
  • Network interface override for multi-NIC/Docker/VPN setups
  • Secure TLS/MQTT/FTP communication

🛠️ Maintenance & Support

  • Maintenance scheduling & tracking
  • Interval reminders (hours/days)
  • Print time accuracy stats
  • File manager for printer storage
  • Firmware update helper with version badge (LAN-only printers) — lists all announced versions with Usable/Unavailable/Installed badges and supports rollback to older firmware
  • Debug logging toggle with live indicator
  • Live application log viewer with filtering
  • Support bundle generator with comprehensive diagnostics (privacy-filtered)
  • In-app bug reporting — Submit bug reports directly from the UI with optional screenshot (upload, paste, or drag & drop), interactive debug log capture (start logging, reproduce at your own pace, stop & submit), and system info. Reports create GitHub issues via a secure relay. Privacy-first: all logs are sanitized and sensitive data (IPs, serials, credentials) is never included.

🔒 Optional Authentication

  • Enable/disable authentication any time
  • Group-based permissions (80+ granular permissions)
  • Default groups: Administrators, Operators, Viewers
  • JWT tokens with secure password hashing
  • Comprehensive API protection (200+ endpoints secured)
  • User management (create, edit, delete, groups)
  • User activity tracking (who uploaded archives, library files, queued prints, started prints)
  • Per-user Bambu Cloud accounts — Each user has their own independent Cloud login for profiles
  • Advanced Auth via Email — SMTP integration for automated user onboarding and self-service password resets
  • Admin creates users with email — system sends secure random password automatically
  • Users can reset their own password from the login screen (no admin needed)
  • Customizable email templates (welcome email, password reset)
  • Two-Factor Authentication (TOTP + Email OTP) — Per-user opt-in 2FA compatible with Google Authenticator, Authy, 2FAS and any standard TOTP app, or a 6-digit code delivered by email. Each user gets 10 single-use backup codes. Brute-force-protected (per-user + per-IP rate limits), replay-protected (same code cannot be accepted twice in the same 30 s window), and the pre-auth token is a single-use DB-backed challenge bound to the browser session via an HttpOnly cookie.
  • Single Sign-On (OIDC / SSO) — Log in via PocketID, Authentik, Keycloak, or any standards-compliant OIDC provider. PKCE (S256) for public clients, email_verified gating, issuer & aud/nonce validation, opt-in account linking via verified email, optional auto-provisioning of new BamBuddy accounts, and strict SSRF hardening on every URL pulled from the OIDC discovery document (scheme + private/loopback/link-local IP checks).
  • Per-user email notifications — Users receive email alerts for their own print jobs (start, complete, failed, stopped) with individual toggle controls

Plus: Configurable slicer (Bambu Studio / OrcaSlicer) • Customizable themes (style, background, accent) • Mobile responsive • Keyboard shortcuts • Multi-language (EN/DE/JA/IT) • Auto updates • Database backup/restore • System info dashboard


🎬 Demo

Live Demo
Spin up your own private Bambuddy with simulated printers and pre-loaded print history. Click around freely — it's your sandbox. ~10 seconds to spawn, 30-minute session, no signup.

Prefer a video walkthrough?

Bambuddy Demo Video
Click to watch the demo on YouTube


📸 Screenshots

Click to expand screenshots

Printers
Real-time printer monitoring with AMS status

Archives
Print archive with 3D preview and project assignment

Reprint AMS Mapping
Re-print with AMS filament mapping preview

Timelapse Editor
Built-in timelapse editor with trim, speed, and music

Projects
Group related prints into projects

Project Detail
Project detail view with assigned archives

Project Detail Timeline
Project timeline and print history

Queue
Print scheduling and queue management

Schedule Print
Schedule prints for specific date and time

Statistics
Customizable statistics dashboard

Maintenance
Maintenance tracking per printer

Maintenance Settings
Configure maintenance types and intervals

Cloud Profiles
Bambu Cloud filament profiles

Cloud Profiles Edit
Edit filament preset settings

K-Profiles
Pressure advance (K-factor) profiles

K-Profiles Edit
Edit K-factor profile settings

Settings
General configuration and integrations

Smart Plugs
Smart plug control and energy monitoring

Notifications
Multi-provider notification system

API Keys
API keys and webhook endpoints

Virtual Printer Settings
Virtual printer configuration

Slicer Virtual Printer
Virtual printer appears in Bambu Studio/Orca Slicer

MQTT Debug Log
MQTT debug logging for troubleshooting

Quick Power Plug
Quick power plug control in sidebar


🚀 Quick Start

Requirements

  • Python 3.10+ (3.11/3.12 recommended)
  • Bambu Lab printer with Developer Mode enabled (see below)
  • "Store sent files on external storage" enabled in Bambu Studio/OrcaSlicer
  • Same local network as printer

Installation

Option A: Pre-built image (fastest)

mkdir bambuddy && cd bambuddy
curl -O https://raw.githubusercontent.com/maziggy/bambuddy/main/docker-compose.yml
docker compose up -d

Option B: Build from source

git clone https://github.com/maziggy/bambuddy.git
cd bambuddy
docker compose up -d --build

Open http://localhost:8000 in your browser.

Multi-architecture support: Pre-built images are available for linux/amd64 and linux/arm64 (Raspberry Pi 4/5).

macOS/Windows users: Docker Desktop doesn't support network_mode: host. Edit docker-compose.yml: comment out network_mode: host and uncomment the ports: section. Printer discovery won't work - add printers manually by IP.

Linux users: If you get "permission denied" errors, either prefix commands with sudo (e.g., sudo docker compose up -d) or add your user to the docker group.

Docker Configuration & Commands

Environment Variables:

Variable Default Description
TZ UTC Your timezone (e.g., America/New_York, Europe/Berlin)
PORT 8000 Port BamBuddy runs on (with host networking mode)
DEBUG false Enable debug logging
LOG_LEVEL INFO Log level: DEBUG, INFO, WARNING, ERROR

Data Persistence:

Volume Purpose
bambuddy.db SQLite database with all your print data (not used with PostgreSQL)
archive/ Archived 3MF files and thumbnails
logs/ Application logs

Updating:

# Pre-built image: just pull the latest
docker compose pull && docker compose up -d

# From source: rebuild after pulling changes
cd bambuddy && git pull && docker compose up -d --build

Daily Beta Builds:

Beta builds with the latest fixes are pushed regularly to the same beta version tag:

# Pull the current beta
docker pull ghcr.io/maziggy/bambuddy:0.2.2b1
# or from Docker Hub
docker pull maziggy/bambuddy:0.2.2b1

Use Watchtower to automatically update when new daily builds are pushed.

Note: Beta builds use version tags like 0.2.2b1 — they are never tagged as latest. Your stable installation won't auto-update to a beta unless you explicitly pull a beta tag.

Useful Commands:

# View logs
docker compose logs -f

# Stop/Start
docker compose down
docker compose up -d

# Shell access
docker compose exec bambuddy /bin/bash

Custom Port:

ports:
  - "3000:8000"  # Access on port 3000

Reverse Proxy (Nginx):

server {
    listen 443 ssl http2;
    server_name bambuddy.yourdomain.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    location / {
        proxy_pass http://localhost:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 86400;
    }
}

Note: WebSocket support is required for real-time printer updates.

Network Mode Host (required for printer discovery and camera streaming):

services:
  bambuddy:
    build: .
    network_mode: host

Note: Docker's default bridge networking cannot receive SSDP multicast packets for automatic printer discovery. When using network_mode: host, Bambuddy auto-detects your network subnet and can discover printers via subnet scanning in the Add Printer dialog.

Manual Installation (Linux/macOS)

# Clone and setup
git clone https://github.com/maziggy/bambuddy.git
cd bambuddy
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

# Run
uvicorn backend.app.main:app --host 0.0.0.0 --port 8000

Open http://localhost:8000 and add your printer!

Need detailed instructions? See the Installation Guide

Enabling Developer Mode

Developer Mode allows third-party software like Bambuddy to control your printer over the local network.

  1. On printer: Settings → Network → LAN Only Mode → Enable
  2. Enable Developer Mode (appears after LAN Only Mode is enabled)
  3. Note the Access Code displayed
  4. Find IP address in network settings
  5. Find Serial Number in device info

Note: Developer Mode disables cloud features but provides full local control. Standard LAN Mode (without Developer Mode) only allows read-only monitoring.

Slicer Settings

In Bambu Studio or OrcaSlicer, enable "Store sent files on external storage" so that print files (3MF) are saved to the printer's SD card. Bambuddy needs these files to extract thumbnails and 3D model previews.

  1. Open Bambu Studio or OrcaSlicer
  2. Go to the Device tab for your printer
  3. In Print Options, enable Store Sent Files on External Storage

📚 Documentation

Full documentation available at wiki.bambuddy.cool:


🖨️ Supported Printers

Series Models
X1 X1, X1 Carbon, X1E
X2 X2D
H2 H2D, H2D Pro, H2C, H2S
P1 P1P, P1S
P2 P2S
A1 A1, A1 Mini

🛠️ Tech Stack

Component Technology
Backend Python, FastAPI, SQLAlchemy
Frontend React, TypeScript, Tailwind CSS
Database SQLite (default) or PostgreSQL
3D Viewer Three.js
Communication MQTT (TLS), FTPS

🤝 Contributing

Contributions welcome! Ways to help:

  1. 📝 Document — Improve the wiki and guides (urgently needed!)
  2. Test — Report issues with your printer model
  3. Translate — Add new languages
  4. Code — Submit PRs for bugs or features

Not sure where to start? Reach out on Discord or email martin@bambuddy.cool — I'll help you find something that fits.

# Development setup
git clone https://github.com/maziggy/bambuddy.git
cd bambuddy

# Backend
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
DEBUG=true uvicorn backend.app.main:app --reload

# Frontend (separate terminal)
cd frontend && npm install && npm run dev

See CONTRIBUTING.md for guidelines.


📄 License

AGPL-3.0 License — see LICENSE for details.


🙏 Acknowledgments

  • SpoolEase by yanshay — early inspiration for NFC-based spool tracking and AMS inventory concepts
  • Bambu Lab for amazing printers
  • The reverse engineering community for protocol documentation
  • All testers and contributors

💖 Support Bambuddy

Bambuddy stays independent because real people support it directly. If Bambuddy makes your printers more useful, please consider:

  • GitHub Sponsors — five recurring tiers from $5/mo (Backer) to $500/mo (Corporate). Supporter+ ($15/mo) get access to a private sponsors space with a monthly newsletter and early release notes. Patron+ ($35/mo) vote on the quarterly roadmap. Sustaining Sponsor+ ($150/mo) get a direct async email line for technical questions (~2-3 business days). Corporate ($500/mo) get priority email response (next business day), README header logo, sitewide footer logo on bambuddy.cool, and Press page placement.
  • Ko-fi — one-time tip or recurring.

Sponsors get listed in BACKERS.md. Need commercial support (SLA, multi-printer consulting)? Email martin@bambuddy.cool.


Made with ❤️ for the 3D printing community

Join our Discord • Report Bug • Request Feature • Documentation

S
Description
Your Bambu Lab. No Cloud. Your Rules. Self-hosted command center for Bambu Lab — from one A1 to an entire print farm.
Readme AGPL-3.0
868 MiB
Languages
Python 39.4%
TypeScript 34.1%
JavaScript 25.8%
Shell 0.5%
HTML 0.1%