Function-scoped ftp_server meant 67 TLS server start/stop cycles.
Class-scoped reduces to 10. Adds per-test cleanup fixture to reset
failure injections and filesystem between tests. Isolates
test_disconnect_after_server_gone into its own class to prevent
close_all() from nuking other servers' asyncore sockets.
CI only installed requirements.txt, missing pyOpenSSL from
requirements-dev.txt. This caused an ImportError on
TLS_FTPHandler during test collection, blocking all
unit/services tests. Also adds pytest-timeout to dev deps
instead of ad-hoc pip install in CI.
CI only installed requirements.txt, missing pyOpenSSL from
requirements-dev.txt. This caused an ImportError on
TLS_FTPHandler during test collection, blocking all
unit/services tests. Also adds pytest-timeout to dev deps
instead of ad-hoc pip install in CI.
v0.1.9
Bambuddy v0.1.9 Release Notes
**Highlights**
This is the biggest release yet — Advanced Authentication via Email, full H2C/H2D Pro nozzle rack support, OrcaSlicer local profiles, configurable slicer preference, Italian localization, and 50+ bug fixes spanning every printer model.
---
**New Features**
Advanced Authentication via Email (https://github.com/maziggy/bambuddy/pull/322)
- Optional SMTP-based email integration for streamlined user onboarding and self-service password management
- Admins configure SMTP settings and create users with just a username and email — the system generates a secure random password and emails it directly to the new user
- One-click admin password resets from User Management
- Users can reset their own forgotten password from the login screen without contacting an admin
- Customizable email templates for welcome emails and password resets
- Username and email login is case-insensitive
- Can be enabled or disabled independently at any time without affecting existing accounts
Configurable Slicer Preference (https://github.com/maziggy/bambuddy/issues/313)
- New "Preferred Slicer" setting in General settings to choose between Bambu Studio and OrcaSlicer
- Controls the protocol used by all "Open in Slicer" buttons across Archives, 3D Preview, and context menus
- OrcaSlicer uses the orcaslicer://open?file= protocol; default remains Bambu Studio
Local Profiles — OrcaSlicer Import (https://github.com/maziggy/bambuddy/issues/310)
- Import slicer presets from OrcaSlicer without Bambu Cloud
- Supports .orca_filament, .bbscfg, .bbsflmt, .zip, and .json exports
- Resolves OrcaSlicer inheritance chains by fetching base Bambu profiles from GitHub (cached locally with 7-day TTL)
- New "Local Profiles" tab on the Profiles page with drag-and-drop import, search, and expandable details
- Local filament presets appear in AMS slot configuration alongside cloud presets
Hostname Support for Printers (https://github.com/maziggy/bambuddy/issues/290)
- Printers can now be added using hostnames (e.g., printer.local, my-printer.home.lan) in addition to IPv4 addresses
Camera View Controls (https://github.com/maziggy/bambuddy/issues/291)
- Added chamber light toggle and skip objects buttons to embedded camera viewer and standalone camera page
Extended Support Bundle Diagnostics
- Collects comprehensive diagnostic data: printer connectivity, integration status, network interfaces, Python packages, database health, Docker details, WebSocket
connections, and log file info
- All data properly anonymized — no IPs, names, or serials included
---
**Improved**
H2C Nozzle Rack — Full 6-Slot Display (https://github.com/maziggy/bambuddy/issues/300)
- Always shows all 6 rack positions with filled slots and empty placeholders
- Compact single-row layout with bottom accent bars (green = mounted, gray = docked)
- Translates raw nozzle type codes to human-readable names (Hardened Steel, Stainless Steel, Tungsten Carbide, High Flow, Standard)
- Shows loaded filament material and color in hover card
- Resolves filament names with 4-tier fallback: Cloud → Local Profiles → built-in lookup table (86 known Bambu codes) → raw ID
H2 Series — L/R Nozzle Hover Card (https://github.com/maziggy/bambuddy/issues/300)
- New dual-nozzle hover card shows L and R nozzle details side by side (diameter, type, flow, status, wear, max temp, serial)
- Active nozzle highlighted in amber; single-nozzle H2D/H2S printers show extended nozzle details on hover
Firmware Version Badge on Printer Card (https://github.com/maziggy/bambuddy/issues/311)
- Green badge with checkmark when up to date, orange with download icon when update available
- Click opens firmware info modal with release notes; respects firmware:read and firmware:update permissions
Auto-Detect Subnet for Printer Discovery
- Docker users no longer need to manually enter a subnet — auto-detects available networks with dropdown for multiple subnets
Japanese Locale Complete Overhaul
- Restructured ja.ts to match EN/DE structure; translated all 2,083 keys for full parity
Italian Localization (https://github.com/maziggy/bambuddy/pull/309)
- New Italian locale contributed by @Keybored02
---
**Bug Fixes**
- H2C Firmware Downloads Wrong Firmware (https://github.com/maziggy/bambuddy/issues/311) — H2C was mapped to H2D firmware track; added separate h2c API key
- H2D Pro L/R Nozzle Hover Card Swapped (https://github.com/maziggy/bambuddy/issues/300) — Left and right nozzles were swapped in the hover card
- H2C Printer Card Shows H2D Image (https://github.com/maziggy/bambuddy/issues/300) — Added dedicated H2C printer image
- H2C Nozzle Rack Shows Wrong Slots and Missing Colors (https://github.com/maziggy/bambuddy/issues/300) — Fixed mapping by nozzle ID instead of array index; added
fallback for H2C MQTT field names
- Nozzle Rack Hides 0% Wear (https://github.com/maziggy/bambuddy/issues/300) — Now correctly shows "Wear: 0%" for new nozzles
- AMS-HT Mapping Fails for Left Nozzle on H2D Pro (https://github.com/maziggy/bambuddy/issues/318) — Fixed global tray ID calculation for AMS-HT units (ams_id >= 128)
- H2D Pro Prints Fail at ~75% With Extrusion Motor Overload (https://github.com/maziggy/bambuddy/issues/245) — Fixed use_ams type from integer to boolean for H2D series
- Virtual Printer FTP Transfer Fails With Connection Reset (https://github.com/maziggy/bambuddy/issues/58) — Fixed async handler completing while data connection was
still active
- Virtual Printer IP Override Ignored in Server Mode (https://github.com/maziggy/bambuddy/issues/52) — Network interface override now applies to all modes (TLS
certificate, SSDP, service restart)
- Wrong Thumbnail When Reprinting Same Project (https://github.com/maziggy/bambuddy/issues/314) — Cover image cache now cleared on every print start
- Wrong Timelapse Attached to Archive (https://github.com/maziggy/bambuddy/issues/315) — Replaced mtime-based selection with snapshot-diff approach for reliable
timelapse detection
- Calibration Prints Archived (https://github.com/maziggy/bambuddy/issues/315) — Internal printer gcode files under /usr/ now detected and skipped
- Sidebar Links Custom Icons Inverted Colors (https://github.com/maziggy/bambuddy/issues/308) — Removed CSS invert() filter from user-uploaded icons
- Spoolman Creates Duplicate Spools on Startup (https://github.com/maziggy/bambuddy/pull/295) — Cached spool data prevents redundant API calls; added retry logic
- Firmware Badge Shown for Models Without API Data (https://github.com/maziggy/bambuddy/issues/311) — Badge hidden when API returns no firmware data
- Support Bundle Shows 0 AMS Units — Now handles both nested dict and flat list formats for AMS data
- GitHub Backup Description Misleading — Updated to correctly state "complete database"
- Timezone from .env (https://github.com/maziggy/bambuddy/pull/303) — Use TZ from .env instead of hardcoded value
- FTP TLS 1.3 Compatibility (https://github.com/maziggy/bambuddy/pull/305) — Limit FTP server TLS to 1.2 max for broader client compatibility
---
**Testing**
- Mock FTPS Server & FTP Test Suite — 67 automated test cases against a real implicit FTPS mock server covering connection, upload, download, model-specific behavior,
and failure injection
- Nozzle Rack Tests — Backend: 7 tests for MQTT nozzle_info parsing; Frontend: 3 tests for rack card rendering
- Advanced Auth Integration Tests — 27 integration tests covering SMTP config, advanced auth toggle, email login, forgot password, admin password reset, and user
creation
---
**Documentation**
- Advanced Auth via Email — Updated README, website, and wiki with SMTP setup and self-service password guides
- Supported Printers — All 12 Bambu Lab models now listed uniformly (X1, X1C, X1E, P1P, P1S, P2S, A1, A1 Mini, H2D, H2D Pro, H2C, H2S)
- CONTRIBUTING.md — Added i18n conventions and authentication/permissions guide
- Proxy Mode — FTP data channel security warning, passive port documentation, SSDP discovery limitations table
---
**Community Contributors**
Thank you to everyone who contributed to this release!
- @cadtoolbox (Thomas Rambach) — Advanced Authentication via Email (https://github.com/maziggy/bambuddy/pull/322)
- @Keybored02 — Italian localization (https://github.com/maziggy/bambuddy/pull/309)
- @notti (Gernot Vormayr) — FTP TLS 1.2 version limit (https://github.com/maziggy/bambuddy/pull/305)
- @bnap00 (Bharat Parsiya) — Timezone environment variable fix (https://github.com/maziggy/bambuddy/pull/303)
- @bambuman — Spoolman duplicate spool fix (https://github.com/maziggy/bambuddy/pull/295) and Home Assistant environment variables
(https://github.com/maziggy/bambuddy/pull/294)
---
SMTP settings endpoints (GET/POST /auth/smtp, POST /auth/smtp/test)
used Depends(get_current_active_user) which always requires a logged-in
user. Replaced with RequirePermissionIfAuthEnabled to match the pattern
used by all other settings endpoints — accessible when auth is disabled,
permission-gated when auth is enabled.
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).
The Bambu Cloud API returns 400 for many filament IDs (e.g. GFB01,
GFU99, GFL99), causing nozzle rack hover cards to fall back to
abbreviated tray_type values ("ASA", "TPU", "PLA") instead of full
names.
Added a built-in lookup table of 86 known Bambu filament codes as a
Phase 4 fallback in get_filament_info. Resolution order is now:
cache → cloud API → local profiles → built-in table → empty fallback.
GFB01 → "Bambu ASA", GFU99 → "Generic TPU", GFL99 → "Generic PLA",
etc. Also benefits AMS tray tooltips for unresolvable filament IDs.
- Add i18n support to AddSmartPlugModal.tsx
- Add i18n support to ConfigureAmsSlotModal.tsx
- Add i18n support to RichTextEditor.tsx
- Add i18n support to ExternalLinksSettings.tsx
- Replace all hardcoded English strings with t() calls
Co-authored-by: cadtoolbox <12723486+cadtoolbox@users.noreply.github.com>
1. H2C printer card was showing the H2D image — added dedicated
h2c.png and updated getPrinterImage() mapping.
2. Nozzle rack hover card showed raw filament IDs (e.g. "GFU99")
instead of human-readable names. Now resolves names via 3-tier
fallback: Bambu Cloud → local slicer profiles → raw ID.
- Frontend: nozzle rack filament_id values included in cloud
lookup query; NozzleSlotHoverCard displays resolved name.
- Backend: get_filament_info endpoint refactored from cloud-only
to cache → cloud → local profiles. Matches local presets by
setting_id in the imported OrcaSlicer JSON blob.
Three fixes for the H2C nozzle rack reported by testers:
1. Empty slot position: rack nozzles were mapped by sequential array
index instead of by actual nozzle ID (16-21), so a missing slot
always appeared at position 6 instead of its real position. Now
maps each nozzle to its correct rack position via id offset.
2. Missing filament colors/materials: the H2C MQTT payload uses
different field names than H2D — color_m (not filament_colour),
fila_id (not filament_id), sn (not serial_number), tm (not
max_temp). Added fallback field name resolution in the backend
MQTT parser.
3. Medium card layout: the temperature row with nozzle rack overflowed
on medium-sized cards. Added flex-wrap and a 190px flex-basis on
the rack card so it wraps to a second line when space is tight.
AMS-HT global tray ID was calculated as ams_id * 4 (= 512 for unit 128)
but AMS-HT uses the raw ams_id directly since it has a single tray.
The backend misidentified 512 as an external spool, producing wrong
ams_mapping2. Fixed in 4 locations: frontend getGlobalTrayId(), backend
start_print() ams_mapping2 builder, print scheduler, and Spoolman tracking.
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
raw_data["ams"] is stored as a list by the MQTT handler, but the
support info code only checked for a nested dict format. AMS unit
and tray counts were always 0.
- 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
- Show all 6 nozzles including mounted: backend includes all nozzle_info
entries (removes id >= 2 filter), frontend filters to non-empty
- Translate nozzle type codes to full names: HS→Hardened Steel, 00/01/05
mapped to Stainless Steel/Hardened Steel/Tungsten Carbide
- Add flow type to hover card: HH→High Flow, HS→Standard
- Show filament material type in hover card (PLA, PETG etc.) from MQTT
tray_type/filament_type field
- Add filament_type to NozzleRackSlot schema (backend + frontend)
- Add translations (en, de, ja, it): nozzleTungstenCarbide, nozzleFlow,
nozzleHighFlow, nozzleStandardFlow
The wear field was hidden when wear was 0 because the condition
`slot.wear > 0` treated 0 the same as null/unavailable. New nozzles
showed no wear info at all. Removed the > 0 check so "Wear: 0%"
displays correctly while still hiding the field when wear is null
(non-H2C printers).
Timelapse: Replace mtime-based "most recent file" approach with a
snapshot-diff strategy — baseline existing MP4 filenames before waiting,
then detect the new file that appears after encoding. Fixes wrong
timelapse in LAN-only mode where printer clock is unsynchronized.
Falls back to print-name matching if no new file appears after retries.
Calibration: Skip archiving internal printer files under /usr/ (e.g.
/usr/etc/print/auto_cali_for_user.gcode) so calibration prints don't
appear in the archive.
The cover image cache was keyed by subtask_name and never invalidated
between prints. When a user printed the same project name twice with a
different bed layout, the cached thumbnail from the first print was
returned instead of fetching the new one from the printer.
Clear the cover cache for the printer on every print start so the next
cover request downloads a fresh 3MF and extracts the current thumbnail.
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.
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.
H2C was mapped to the "h2d" firmware API key, causing it to check
the H2D firmware page and offer H2D firmware for download. H2C has
its own separate firmware track (01.01.x.x vs H2D's 01.02.x.x).
Changed H2C to use its own "h2c" API key and added the reverse
mapping. Also added missing H2C (O1C) and H2S (O1S) entries to
the printer model ID and 3MF model name maps.
The nozzle_info MQTT array contains L/R nozzle heads (IDs 0, 1) and
rack slots (IDs 16-21). Backend was dumping all entries into nozzle_rack,
and frontend slice(0,6) grabbed L, R, plus only 4 rack slots — cutting
off the last position (e.g. the 0.6mm nozzle) and showing the mounted
nozzle as docked.
Backend: filter nozzle_rack to id >= 2 (rack-only), sort by ID.
Frontend: compact single-row layout with bottom accent bars for
mounted/docked status, wider rack card (flex-[2]), vertically
centered temp cards.