mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-09-30 03:01:21 +02:00
Updated CHANGELOG
This commit is contained in:
@@ -18,6 +18,8 @@ All notable changes to Bambuddy will be documented in this file.
|
||||
- **Slice modal: pick the build plate (#1337, reported by @digitalskies)** — Slicing a plain STL through the integrated slicer always defaulted to whatever `curr_bed_type` lived in the chosen process preset (typically `Cool Plate`), which the slicer CLI then rejected for high-temp filaments with `Plate 1: Cool Plate does not support filament 1`. The user had no way to switch plates short of cloning the process preset in BambuStudio, which defeats the point of the in-app slicer. The Slice modal now exposes a `Build plate` dropdown with the six canonical BambuStudio / OrcaSlicer plates (Cool Plate, Cool Plate SuperTack, Engineering Plate, High Temp Plate, Textured PEI Plate, Smooth PEI Plate) plus an explicit `Auto (use process preset)` option that preserves the previous behavior. The dropdown sits between Process profile and Filament rows so it stays visible regardless of how many filament slots the picked plate uses (a long filament list would otherwise push it off the modal's `max-h-[85vh]` scroll viewport) and is **always enabled** — including when the user picks a Printer Preset Bundle from the top BundlePicker. When the user picks a specific plate, the new `bed_type` field on `SliceRequest` ([`backend/app/schemas/slicer.py`](backend/app/schemas/slicer.py)) flows through the dispatcher via two paths: (1) **resolved-preset path** — the route helper `_patch_process_bed_type` in [`backend/app/api/routes/library.py`](backend/app/api/routes/library.py) overwrites `curr_bed_type` on the resolved process JSON before forwarding to the sidecar (no preset cloning required); (2) **bundle dispatch path** — `slice_with_bundle` in [`backend/app/services/slicer_api.py`](backend/app/services/slicer_api.py) adds a `bedType` form field to the sidecar multipart so the sidecar can pass `--curr_bed_type` through to the CLI, which lets the override take effect even though Bambuddy can't patch the bundle's process JSON locally (the sidecar materialises it from the stored .bbscfg). Sidecar versions that don't recognise the field silently no-op — the slice still runs, just with the bundle's default plate; the slicer-API fork at maziggy/orca-slicer-api will need the matching change for the bundle path to take full effect. **i18n parity:** 8 new keys (`slice.bedType.{label,auto,coolPlate,coolPlateSuperTack,engineering,highTemp,texturedPEI,smoothPEI}`) added to all 8 locales — full German translation, English fallbacks elsewhere per project convention. **Regression tests:** 4 in [`test_slice_request_bed_type.py`](backend/tests/unit/test_slice_request_bed_type.py) (`bed_type` defaults to None, accepts the six canonical strings, rejects overlong input via the schema's `max_length=64`; `_patch_process_bed_type` overwrites an existing value, adds the field when missing, and returns the input unchanged for malformed JSON or non-dict roots), 4 in [`test_library_slice_api.py`](backend/tests/integration/test_library_slice_api.py) (resolved-preset path: with `bed_type` set, the sidecar receives `"curr_bed_type": "Textured PEI Plate"` in the presetProfile multipart part; without it, `curr_bed_type` stays out of the body entirely. bundle dispatch path: `bedType` form field carries the override through to the sidecar; omitting `bed_type` keeps the form field out of the request so the bundle's own `curr_bed_type` is preserved), 2 in [`SliceModal.test.tsx`](frontend/src/__tests__/components/SliceModal.test.tsx) (dropdown selection puts `bed_type` on the request; leaving it on Auto omits the field). 59 backend slice tests + 34 SliceModal tests pass; build and i18n parity script clean.
|
||||
|
||||
### Fixed
|
||||
- **In-app updater no longer fails with "Failed to fetch updates" when a tag on the remote was re-pointed** — Symptom on native installs upgrading from 0.2.4: clicking *Settings → System → Updates → Apply Update* aborted with `Git fetch failed: From https://github.com/maziggy/bambuddy ... ! [rejected] v0.2.1 -> v0.2.1 (would clobber existing tag)` even though `origin/main` and the target release tag fetched cleanly. `_perform_update` in [`backend/app/api/routes/updates.py:526`](backend/app/api/routes/updates.py) ran `git fetch --prune --tags origin`, which returns a non-zero exit if even one local tag would be overwritten by a moved upstream tag — and any non-zero exit was surfaced to the user as a hard failure, leaving them stuck on the previous release. **Fix:** added `--force` to the fetch invocation so a re-pointed tag on the remote overwrites the local stale copy cleanly; matches the in-app updater's contract ("sync me to the remote"). The native `update.sh` doesn't hit this bug because it fetches without `--tags` at all, but the in-app path can't drop `--tags` — release-tag refs (`v0.2.4b1`, `v0.2.4.1`, …) need to be locally resolvable for the subsequent `git reset --hard`. **Note for users on 0.2.4 upgrading to 0.2.4.1:** the fix is *in* 0.2.4.1, which 0.2.4's updater can't reach. Use the CLI path documented in the release notes for this one upgrade; from 0.2.4.1 onward the in-app button works again. Docker installs are unaffected — they don't go through git. Regression test in [`backend/tests/integration/test_updates_api.py`](backend/tests/integration/test_updates_api.py) asserts `--force` is in the fetch args alongside the existing `--tags` assertion so a future refactor can't quietly drop it.
|
||||
|
||||
- **Print Queue page no longer 404-storms thumbnail / plates / plate-thumbnail when an item points at a soft-deleted archive, and pending queue items for a soft-deleted archive are now cancelled with a clear reason instead of silently stuck-pending forever** ([#1348](https://github.com/maziggy/bambuddy/issues/1348) follow-up) — Symptom: opening the Queue page or any of its sub-views fired `GET /archives/{id}/thumbnail`, `GET /archives/{id}/plates`, and `GET /archives/{id}/plate-thumbnail/{n}` for queue rows pointing at archives that had been soft-deleted (#1343 leaves the row but removes files from disk), all returning 404. Frontend's `onError` handler hid the broken `<img>` so it was visually clean, but the network tab and any pending-print logic still saw three 404s per affected row. Two underlying problems wearing one mask: cosmetic 404 storm, AND functional — a queue item whose 3MF was removed from disk can never actually dispatch, so it sits in `pending` forever with no clue to the user about why. **Two-part fix in the same shape as the print-log followup above:** (1) New helper `_cancel_pending_queue_items(db, archive_id)` in [`backend/app/services/archive.py`](backend/app/services/archive.py) sets `status='cancelled'` + `waiting_reason='Source archive deleted'` on every pending queue item linked to the archive; called from `soft_delete_archive` alongside the existing `_null_print_log_thumbnail_paths` cleanup. Only `pending` is touched — `printing` is a rare race that the printer-side fail-path catches anyway, and completed / failed / cancelled rows are historical audit-trail. Hard-delete is already covered by `ON DELETE CASCADE` on `print_queue.archive_id`. (2) Queue API serializer in [`backend/app/api/routes/print_queue.py:224`](backend/app/api/routes/print_queue.py) now checks `item.archive.deleted_at` before populating any archive-derived field — when soft-deleted, the whole block (`archive_name`, `archive_thumbnail`, `print_time_seconds`, `filament_used_grams`, plate-specific re-reads, …) is skipped and the new `archive_deleted: bool = True` flag on [`PrintQueueItemResponse`](backend/app/schemas/print_queue.py) signals the soft-deleted state. The `archive_thumbnail` suppression alone covers the thumbnail render in [`QueuePage.tsx:434`](frontend/src/pages/QueuePage.tsx), [`CompactHistoryRow.tsx:45`](frontend/src/components/CompactHistoryRow.tsx), and [`QueueTimelineView.tsx:72`](frontend/src/components/QueueTimelineView.tsx) because they all gate on it. The `/plates` query at [`QueuePage.tsx:329`](frontend/src/pages/QueuePage.tsx) was gated on `archive_id` only — `archive_id` is the real FK and stays exposed in the response (the queue scheduler still needs it for audit / dispatch checks), so the query was added a new `&& !item.archive_deleted` clause to respect the new flag. **Regression tests** in [`backend/tests/integration/test_print_queue_api.py`](backend/tests/integration/test_print_queue_api.py): `test_soft_delete_archive_cancels_pending_queue_items` pins the cancel-only-pending behavior (completed rows untouched), `test_queue_api_hides_archive_surface_when_soft_deleted` pins the suppression + `archive_deleted=True` for soft-deleted archives, `test_queue_api_still_exposes_archive_surface_when_live` pins the sanity guard that live archives' fields keep flowing through. All 3 new tests + 146 in the queue/archives/obico sweep pass; ruff clean.
|
||||
|
||||
- **Print log no longer 404-storms on the thumbnail endpoint for entries whose archive was deleted or whose print failed before a thumbnail was extracted** ([#1348](https://github.com/maziggy/bambuddy/issues/1348) follow-up) — Symptom in DevTools when opening Archives → Print Log: a 404 per orphaned entry per render. Visually clean (the `<img onError>` handler in [`frontend/src/pages/ArchivesPage.tsx:3763`](frontend/src/pages/ArchivesPage.tsx) hides the broken image), but noisy and wasteful. **Root cause** in [`backend/app/api/routes/print_log.py:91-113`](backend/app/api/routes/print_log.py): `PrintLogEntry.thumbnail_path` is copied by value from `archive.thumbnail_path` at write-time ([`main.py:3615`](backend/app/main.py)) but the FK on `archive_id` is `ON DELETE SET NULL` (#1378) — so log entries survive archive deletion to preserve stats history, but the cached thumbnail_path string keeps pointing at a file that was removed when the archive's directory was deleted. Same shape for failed prints that recorded an expected thumbnail path before the extractor wrote (or skipped writing) the file. **Two-part fix:** (1) `get_print_log_thumbnail` self-heals when the file is missing — it NULLs `thumbnail_path` on the entry and commits before returning 404, so the frontend's `entry.thumbnail_path && <img>` gate keeps the next page render from re-requesting. (2) New helper `_null_print_log_thumbnail_paths(db, archive_id)` in [`backend/app/services/archive.py`](backend/app/services/archive.py) is called from `soft_delete_archive` and `delete_archive` before the on-disk files are removed — eager clear so future deletes don't cause the one-time storm at all. The route handler covers stragglers (failed prints, files manually moved, etc.). **Regression tests** in [`backend/tests/integration/test_archives_api.py`](backend/tests/integration/test_archives_api.py): `test_soft_delete_clears_thumbnail_path_on_linked_log_entries` pins the eager clear on the soft-delete route, `test_hard_delete_clears_thumbnail_path_before_fk_cascade` pins it on `ArchiveService.delete_archive` (used by the auto-purge sweeper), `test_print_log_thumbnail_route_lazy_nulls_missing_file` pins the route's self-heal for failed-print orphans where the file was never written. All 4 new tests + 61 in the archives/print-log sweep pass; ruff clean.
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
**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.)
|
||||
Reference in New Issue
Block a user