# Bambuddy v0.2.2.1
## Virtual Printer — Breaking Changes
▎ Action required for existing Virtual Printer users. Please follow the migration guide before updating.
The Virtual Printer FTP server now binds directly to port 990 instead of using an iptables redirect from 990 → 9990. This fixes FTP being routed to the wrong VP when running multiple virtual printers on different bind IPs (#735).
What you need to do:
- Native/systemd: Remove old iptables redirect rules (990 → 9990) and verify CAP_NET_BIND_SERVICE is set in the systemd service.
- Docker (bridge network): Change port mapping from 990:9990 to 990:990 in docker-compose.yml.
- Docker (host network): Remove old iptables redirect rules on the host. No other changes needed.
- Unraid/Synology/TrueNAS: Remove any iptables rules you added for 990 → 9990.
Detailed instructions can be found here -> https://github.com/maziggy/bambuddy/blob/0.2.2.1/docs/migration-vp-ftp-port.md
Proxy mode now supports cross-VLAN/subnet printing (#757) with transparent TCP proxying for FTP (990), file transfer (6000), and camera streaming (322). If you use proxy mode behind a firewall, ensure ports 6000 and 322 are open between the slicer and Bambuddy.
X1C/X1 compatibility is fixed — both server mode (corrected SSDP model codes BL-P001/BL-P002) and proxy mode (end-to-end TLS passthrough preserving the printer's real certificate). Existing VPs are automatically migrated on startup.
## Highlights
- Virtual Printer Overhaul (#735, #757) — Major rework of Virtual Printer networking. FTP, proxy mode, and X1C compatibility all significantly improved. Existing VP users: action required — see below.
- Select Plates to Queue (#777) — Multi-plate 3MF files now support selecting a subset of plates to queue, with per-plate checkboxes.
- HMS Error Visibility (#772) — Red "Problem" counter in the status bar, amber/red status pips, and HMS-first sorting for print farms.
- Per-User Email Notifications (#693) — When Advanced Authentication is enabled, individual users can now receive email notifications for their own print jobs. Contributed by @cadtoolbox.
- Spool Rotation During AMS Drying — Added a "Rotate spool during drying" checkbox to the manual drying popover for AMS 2 Pro and AMS-HT units.
## New Features
- SpoolBuddy OTA Updates — SpoolBuddy devices can now be updated directly from the Settings → Updates tab without SSH access. Click "Check for Updates" to see if a newer version is available, then "Apply Update" to trigger the update. The daemon picks up the command via its heartbeat, pulls the latest code from GitHub, installs dependencies, and restarts automatically via systemd. Live progress is shown in the UI with status messages from the device. The status bar at the bottom automatically checks for updates every 5 minutes and shows a prominent message when one is available. Requires the device to be online.
- Select Plates to Queue (#777) — Multi-plate 3MF files now support selecting a subset of plates to queue, instead of only "one plate" or "all plates". In add-to-queue mode, each plate has a checkbox for multi-select, with a "Select All / Deselect All" toggle. Reprint and edit modes remain single-select.
- Camera Image Rotation (#672) — Added per-printer camera rotation (0°, 90°, 180°, 270°) for cameras mounted in portrait or upside-down orientations. Configurable in Settings → Camera for each printer. Rotation applies to live stream, embedded viewer, stream overlay, and notification snapshots.
- Per-User Email Notifications (#693) — When Advanced Authentication is enabled, individual users can now receive email notifications for their own print jobs. Contributed by @cadtoolbox.
- Quick Print Speed Control (#256) — Speed control badge on the printer card with Silent/Standard/Sport/Ludicrous presets.
- Spool Name Column & Filter in Filament Inventory (#740) — Added a "Spool" column and spool name filter dropdown.
- Spool Rotation During AMS Drying — Added a "Rotate spool during drying" checkbox to the manual drying popover for AMS 2 Pro and AMS-HT units.
- Admin Set Default Nav-Menu Order (#761) — Admins can set their sidebar menu order as the default for new users. Contributed by @cadtoolbox.
- Add Total Cost to Projects (#733) — Projects page now shows total cost (material + energy + BOM). Contributed by @Keybored02.
- Material Mismatch & Insufficient Filament Checks (#720) — Warns on filament type/profile mismatch and insufficient material before printing. Contributed by @Keybored02.
- Rework Archive Duplicates Tagging (#718) — Smarter duplicate detection (name + SHA256), reprint counter tags, parent print links. Contributed by @Keybored02.
## Improved
- HMS Error Visibility on Printers Page (#772) — Red "Problem" counter in the status summary bar, red/amber status pips for errors/warnings, amber progress bars for paused prints, and HMS-first sorting.
- Home Assistant Notifications (#750) — Added support for HA notify services. Contributed by @mrtncode.
- Print Command Response Verification (#737) — Monitors whether the printer responds within 15 seconds after sending a print command; logs a warning if silently ignored.
- Compact Assign Spool Modal (#725) — 3-column grid layout showing more spools without scrolling.
- Reformatted AMS Drying Presets Table (#732) — Grouped by AMS type with inline unit labels.
- Redesigned Bug Report Debug Log Flow — Interactive 3-step flow instead of a fixed 30-second timer.
## Fixed
- Queue Print Command Not Reaching Printer (#778) — Fixed repeated MQTT reconnection cycles on printers that reject request topic subscription.
- AMS Slot Search Shows Unrelated Profiles (#681) — Search filter now correctly applies to saved presets.
- AMS Spools Removed After Printer Restart (#765) — Skips slot clearing on shutdown messages.
- Carbon Rod Lubrication Maintenance Task Incorrect (#755) — Removed incorrect lubrication task for carbon rods.
- Spurious "Job Waiting for Filament" Notification (#753) — Skips waiting notification when all printers are just busy.
- File Rename Removes Extension (#751) — Extension is now non-editable.
- Ntfy Notifications Fail With Non-ASCII Characters (#742) — Fixed UTF-8 encoding for header values.
- Print Complete Notification Not Firing (#736) — Added 45-second timeout on photo capture.
- Camera Window Overlapping Modals (#738) — Lowered camera z-index.
- Webhook Notifications Missing Camera Snapshot (#679) — Added base64-encoded image field to webhook payloads.
- White Filament Color Swatches Invisible in Light Theme (#726) — Changed to dark border across all views.
- Mobile Sidebar Not Scrollable — Added overflow scrolling.
- Send Bambu RFID Tags to Spoolman & Manual Mode Unlink (#719) — Proper RFID identifiers sent to Spoolman, unlink button in manual mode, fixed location clearing for generic spools. Contributed by @shrunbr.
- SpoolBuddy Daemon Reports Stale Version — Version now read from backend APP_VERSION instead of hardcoded string.
- Native Install Missing CAP_NET_BIND_SERVICE — Fixed systemd template for VP proxy on native installs.
- UserEmailPreference Model Not Registered — Fixed SQLAlchemy model import order.
## Security
- Bump pyOpenSSL 25.3.0 → 26.0.0 — Fixes CVE-2026-27448 and CVE-2026-27459.
- Bump pyasn1 0.6.2 → 0.6.3 — Fixes CVE-2026-30922.
- Bump flatted 3.4.1 → 3.4.2 — Fixes GHSA-rf6f-7fwh-wjgh (dev dependency).
## Contributors
Thank you to everyone who contributed to this release!
- @cadtoolbox — Admin default nav-menu order (#761), Per-user email notifications (#693)
- @Keybored02 — Total cost in Projects (#733), Material mismatch checks (#720), Archive duplicates rework (#718)
- @mrtncode — Home Assistant notify services (#750)
- @shrunbr — Bambu RFID tags to Spoolman & manual unlink (#719)
And thanks to everyone who reported issues and provided feedback!
The OTA update feature added update_status and update_message to the
SpoolBuddyDevice model but no ALTER TABLE migration, causing
"no such column: spoolbuddy_devices.update_status" on existing databases.
The OTA update feature added update_status and update_message to the
SpoolBuddyDevice model but no ALTER TABLE migration, causing
"no such column: spoolbuddy_devices.update_status" on existing databases.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Main had VP #735 hotfix commits that were also on dev. All conflicts
resolved by keeping 0.2.2.1 (superset of main). Verified: 2098 backend
tests pass, frontend builds clean, no conflict markers remain.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
pyOpenSSL 25.3.0 → 26.0.0 (CVE-2026-27448, CVE-2026-27459)
pyasn1 0.6.2 → 0.6.3 (CVE-2026-30922)
No breaking changes — Python 3.7 drop is irrelevant (we use 3.13),
cryptography >=46.0.0 requirement already satisfied (we have 46.0.5),
and we don't use set_tlsext_servername_callback (the behavioral change).
The SpoolBuddy layout now auto-checks for daemon updates every 5
minutes and shows "Update available: v{version}" in the status bar.
Removed the beta toggle since SpoolBuddy follows Bambuddy's release
channel. The daemon version is now read from backend APP_VERSION
instead of a stale hardcoded string.
The daemon had a hardcoded __version__ = "0.2.2b1" that was never
bumped, causing the update check to always show an update available.
Changed to read APP_VERSION from backend/app/core/config.py at import
time so the daemon version stays in sync automatically.
SpoolBuddy devices can now be updated from Settings → Updates without
SSH access. The daemon picks up an "update" command via its existing
heartbeat, runs git fetch/reset + pip install, reports progress back
to the backend, then exits for systemd to restart with the new code.
Backend: update_status/update_message fields, trigger + status endpoints
Daemon: _perform_update() handler, report_update_status() API method
Frontend: "Apply Update" button with live progress in UpdatesTab
When targeting a specific printer, the scheduler's power-on-wait loop
created new MQTT clients on each attempt. Each new client re-tried the
request topic subscription, which some brokers (e.g. A1) reject by
disconnecting. This caused a 170s thrash loop leaving the connection
fragile, so the eventual print command silently failed to reach the
printer.
Cache request topic support per serial number at the class level so
new client instances inherit the knowledge and skip the subscription.
Multi-plate 3MF files now support selecting a subset of plates to queue
via checkboxes, instead of the binary "one plate" or "all plates" toggle.
In add-to-queue mode, each plate gets a checkbox for multi-select with a
Select All / Deselect All toggle. Reprint and edit modes remain single-select.
The saved preset bypassed the search filter entirely, so when a slot's
DB mapping was stale (e.g. previously Matte, now physically Silk), the
old preset always appeared regardless of search query. Remove the search
bypass — saved/current presets still bypass the printer model filter but
must match the search text like all other presets.
Add visual indicators so printers with HMS errors stand out in large
print farms:
- Red "Problem" counter in the status summary bar
- Status pip turns red (fatal/serious) or amber (warning) for HMS errors
- Progress bar turns amber when a print is paused
- Status sort prioritizes printers with HMS errors at the top
When a printer shuts down it sends a final MQTT message with
tray_exist_bits=0 and power_on_flag=false. The tray_exist_bits
clearing code processed this all-zero value, wiping every AMS
slot's filament data. On reconnect, the auto-unlink check saw
empty tray data (no color, no type) and deleted all spool
assignments as "fingerprint mismatch".
Fix: skip tray_exist_bits slot clearing when power_on_flag is
false. Defaults to true when absent for backwards compatibility.
Adds 3 regression tests covering shutdown preservation, genuine
removal still working, and missing power_on_flag fallback.
Replace fixed 30-second debug log collection with an interactive
3-step flow: start logging, reproduce the issue, stop & submit.
Users now control timing instead of racing a countdown.
Backend: split _collect_debug_logs() into POST /start-logging and
POST /stop-logging endpoints; add debug_logs field to submit request.
Frontend: 3-step progress indicator with elapsed timer, pulsing
active state, and 5-minute auto-stop. Updated all 7 locale files.
Add a "Rotate spool during drying" checkbox to the manual drying popover
for AMS 2 Pro and AMS-HT units. The firmware-level rotate_tray field was
already sent (hardcoded to false) — this makes it user-configurable.
The checkbox defaults to unchecked and resets each time the popover opens.
Firmware silently disables rotation if filament is currently loaded.
When all matching printers were busy and a job was queued with ASAP
timing, the scheduler immediately fired a "Job Waiting for Filament"
notification even though the job was just waiting for a printer to
finish — no user action required.
Added _is_busy_only() check to skip the waiting notification when the
only reason is "Busy". Notifications still fire for actionable reasons
(missing filament, offline, wrong color). Also renamed the default
notification template title to "Queue Job Waiting" and updated
descriptions across all 7 locales.
Renaming a file in the File Manager included the extension in the
editable text, letting users accidentally strip it and break the file.
The rename modal now separates the base name from the extension
(.3mf, .gcode, .gcode.3mf), showing the extension as a non-editable
gray suffix and re-appending it on save.