Dual-nozzle H2D/H2D Pro: filament matching now respects nozzle assignments
from the 3MF file. Each AMS unit feeds a specific nozzle (L/R), and the
scheduler/frontend constrain matching to only trays on the correct nozzle.
Falls back to unfiltered matching when no trays exist on the target nozzle.
L/R badges shown in the filament mapping UI. Translated in en/de/ja/it.
Fix AMS slot config overwritten on startup: on_ams_change unconditionally
unlinked BL spool assignments on every MQTT pushall, then re-assigned them
sending ams_filament_setting without setting_id — clearing the printer's
filament preset. Now compares spool RFID identifiers before unlinking.
Fix BL spool detection false positives: removed tray_info_idx from detection
logic in both backend is_bambu_lab_spool() and frontend isBambuLabSpool().
Third-party spools using Bambu generic presets had GF-prefixed tray_info_idx
values, causing misidentification. Now uses only tray_uuid and tag_uid.
SQLite WAL mode with 5s busy timeout reduces "database is locked" errors.
download_to_file() returned True when retrbinary transferred 0 bytes
without raising an exception. This caused the /cover endpoint to hit
the empty file check and raise HTTP 500 instead of retrying or
returning 404.
Now treats 0-byte downloads as failures, allowing the cover endpoint's
retry logic to work and falling back to 404 if all attempts fail.
The CodeQL cleanup in "Housekeeping" (2b11efd) bulk-narrowed except
clauses across 50+ files, breaking FTP uploads on ALL printer models.
ftplib.error_perm (550 errors) is not a subclass of ftplib.error_reply,
so diagnose_storage() CWD failures escaped the handler and prevented
STOR from ever executing — causing 100% upload failure and HTTP 500s
on /api/v1/archives/{id}/reprint and /api/v1/library/files/{id}/print.
FTP fixes:
- Remove diagnose_storage() from upload hot path
- Change all except (OSError, ftplib.error_reply) to
except (OSError, ftplib.Error) across bambu_ftp.py
Exception handling reverts (9 files):
- Revert narrowed except clauses back to except Exception in route
handlers and service code where broad catches are intentional
defensive programming (archive parsing, HTTP clients, 3MF/ZIP
processing, Home Assistant, firmware checks)
- Keep narrow exceptions only where safe (single-op blocks like
int(), file.unlink(), socket.close())
- Remove unused XMLParseError imports from archive.py, threemf_tools.py
Closes#287
The A1 printer's FTP server hangs when Python's storbinary() calls
voidresp() to wait for the server's completion response. This caused
upload timeouts on A1 and A1 Mini printers.
Fix contributed by an A1 user - replaces storbinary() with manual
chunked transfer using transfercmd() + sendall():
- Uses 1MB chunks (CHUNK_SIZE constant) for better throughput
- Sets explicit 120s socket timeout on data connection
- Manually closes connection after transfer, avoiding voidresp() hang
Applied to all printer models since the manual approach is compatible
with X1C/P1S/P1P as well (transfercmd is what storbinary uses internally).
User feedback indicated A1 Mini with current firmware works with prot_p
(protected/SSL data channel), not prot_c as previously assumed. Different
A1 firmware versions have different FTP SSL behavior.
Changes:
- Remove hardcoded assumption that A1 models need prot_c
- Try prot_p first for all models (including A1/A1 Mini)
- If upload/download fails on A1 models, automatically retry with prot_c
- Cache working mode per printer IP for subsequent operations
- Add force_prot_c parameter for explicit mode control
This makes FTP work across A1 firmware versions:
- New firmware: prot_p succeeds, cached
- Old firmware: prot_p fails → prot_c fallback succeeds, cached
The FTP code called prot_p() (protected data channel) for all printers,
but for A1/A1 Mini it didn't wrap the data connection in SSL. This
mismatch caused an immediate EOFError - server expected encrypted data
but received plain data.
Fix:
- Use prot_c() (clear/unencrypted data channel) for A1/A1 Mini
- Use prot_p() (protected/encrypted data channel) for X1C/P1S/etc
- Removed non-functional ftplib._SSLSocket = None workaround
A1/A1 Mini: control channel encrypted (implicit TLS), data channel clear
X1C/P1S/etc: both channels encrypted with SSL session reuse
Closes#271
Removed P1S and P1P from SKIP_SESSION_REUSE_MODELS
- These printers use vsFTPd which requires SSL session reuse on data channel
- Only A1/A1 Mini should skip session reuse (they have issues with SSL on data channel)
- P1S/P1P were incorrectly added in commit 9969005, causing EOFError on FTP upload
Closes#266
The fix for A1/P1S FTP uploads (commit 82a6025) was accidentally broken in
commit 9969005 which removed the skip_session_reuse parameter from the
ImplicitFTP_TLS constructor. This caused P2S (and other models in
SKIP_SESSION_REUSE_MODELS) to still use SSL on the data channel, resulting
in "426 Failure reading network stream" errors.
The fix was implemented in commit b96ecfa on test/issue_174 branch but
never merged to main. This cherry-picks that fix.
Also includes:
- Storage diagnostics for debugging upload issues
- Better FTP error logging with specific error codes (553, 550, 552)
- Improved error messages in print scheduler
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Printers without an SD card store files in the root folder `/` instead of
`/cache`. Added root folder to search paths in both main.py and bambu_ftp.py
so 3MF files can be found regardless of storage configuration.
Closes#146
P2S printer creates fallback archives without thumbnails/metadata because
FTP couldn't find 3MF files. The P2S uses different directory structure
(/data/Metadata/) and doesn't have a /cache directory.
Changes:
- Add P2S to SKIP_SESSION_REUSE_MODELS for SSL compatibility
- Add /data/ and /data/Metadata/ to 3MF download paths
- Update fallback search to try multiple directories instead of just /cache
- Add /data paths to FTP storage scan directories
Closes#146
The previous fix only skipped SSL session reuse for A1 printers but
still wrapped the data channel in SSL. VREmma's testing (issue #31)
showed that A1 printers need the data channel to not be SSL-wrapped
at all - they timeout waiting for transfer completion responses.
The fix:
- X1C/P1S: SSL with session reuse on data channel (required by vsFTPd)
- A1/A1 Mini: No SSL on data channel (control channel remains encrypted)
This matches VREmma's working fix (c723f25) which set ftplib._SSLSocket
to None, but implemented properly within the ImplicitFTP_TLS class.
Fixes#31
Thanks VREmma!
Resolves FTP transfer failures on A1/A1 Mini printers caused by SSL
session reuse incompatibility. Also adds configurable FTP timeout
setting for slow WiFi connections.
Changes:
- Add SSL session reuse bypass for A1/A1 Mini printers (auto-detected)
- Add printer_model parameter to FTP functions for model detection
- Add configurable FTP timeout (10-120s, default 30s) in Settings
- Update all FTP callers: archiving, reprint, timelapse, firmware upload
Technical details:
- A1/A1 Mini printers don't support vsFTPd's SSL session reuse
- X1C/P1S continue to use session reuse as required by their FTP server
- ImplicitFTP_TLS now accepts skip_session_reuse flag
- BambuFTPClient auto-detects A1/A1 Mini and sets flag accordingly
Enables checking and uploading firmware updates for printers operating
in LAN-only mode without Bambu Cloud connectivity.
Features:
- Automatic firmware version checking against Bambu Lab servers
- Orange "Update" badge on printer cards when updates available
- Firmware update modal with version info and release notes
- One-click firmware upload to printer SD card via FTP
- Real-time upload progress (actual bytes transferred)
- Step-by-step instructions for triggering update from printer
- Local firmware caching for faster re-uploads
- Supports all Bambu Lab printer models
New files:
- backend/app/services/firmware_check.py - Version checking service
- backend/app/services/firmware_update.py - Upload orchestration
- backend/app/api/routes/firmware.py - REST API endpoints
Also includes:
- FTP upload progress callback support
- 10-minute upload timeout protection
- Firmware cache directory in .gitignore
- AMS "Unexpected format" warnings fixed - P1S/P1P send partial updates without full tray list (per https://github.com/Doridian/OpenBambuAPI/blob/main/mqtt.md). Now handled correctly.
- FTP improvements:
- Added timeouts (60s download, 30s listing)
- Better logging at INFO level
- Shows what files exist in /cache
- Fallback archive - When 3MF can't be downloaded, creates minimal archive so prints are tracked