From 4cfa5f655a1b2ac1fb9309e132c8f9eb8f4617a9 Mon Sep 17 00:00:00 2001 From: maziggy Date: Sat, 16 May 2026 15:27:08 +0200 Subject: [PATCH] Updated CHANGELOG --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc0ee9b2e..ddd123252 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ All notable changes to Bambuddy will be documented in this file. ## [0.2.5b1] - Unreleased +## [0.2.4.1] - 2026-05-16 + ### Changed - **Support bundle audited for new features — adds OIDC, 2FA, API keys, library/inventory/queue/maintenance totals, slicer-API reachability, GitHub backup status, per-printer Obico flag; also redacts two settings that were leaking and fixes a reachability-check architecture bug** — The `support-info.json` block in support bundles auto-includes the `settings` table (with sensitive-key redaction), so settings-stored features like LDAP, Obico globals, integrated slicing URLs, Tailscale, and queue-drying already flowed through. What was missing was anything stored in **dedicated tables**, which had grown substantially without the bundle being updated. Triaging the recent OIDC / 2FA / group bugs (#1292, #1297) and the X1C slicer investigation involved repeatedly asking reporters for information that should have been in the bundle. New blocks added to `_collect_support_info` in `backend/app/api/routes/support.py`: **`auth`** — OIDC providers (cleartext `name`, `is_enabled`, `scopes`, `email_claim`, `require_email_verified`, `auto_create_users`, `auto_link_existing_accounts`, `has_default_group`, `has_icon`, `linked_user_count`; `client_id`/`client_secret`/`issuer_url` stay out of the bundle), 2FA counts (`users_with_totp`, `email_otp_codes_pending`), API key counts (`total` / `enabled` / `expired`), long-lived token counts (`total` / `active`), group counts (`system` / `custom`). **`library`** — `library_files_total`, `library_files_in_trash`, `library_folders_total`, `external_folders_total`, `external_links_total`, `makerworld_imports_total`. **`inventory`** — `spools_internal`, `k_profiles_internal`, `k_profiles_spoolman`. **`queue`** — `pending_total`, `manual_start_pending`, `oldest_pending_age_seconds` (catches items stuck because their target printer is offline or filament doesn't match). **`maintenance`** — `items_total`, `items_enabled`. **`integrations.github_backup`** — `configs_total`, `providers_used` dict (github/gitea/forgejo/gitlab), `schedule_enabled_count`, `last_failure_count`. **`integrations.slicer_api`** — `enabled`, `preferred`, `bambu_studio_url_set`, `orcaslicer_url_set`, plus an actual 2-second HTTP reachability ping (`bambu_studio_reachable`, `orcaslicer_reachable`) to differentiate "URL empty" from "URL misconfigured" from "service down". **Per-printer `obico_enabled`** flag added to each entry in `printers[]`, parsed from `obico_enabled_printers` setting via a new `_parse_obico_enabled_printers` helper that tolerates legacy comma-separated formats. **Plus three smaller but important fixes caught while testing the bundle against a real instance**: (1) **`mqtt_broker` value was leaking** — the keyword-substring redaction filter at `support.py:850` had no entry that matched the `mqtt_broker` setting name, so the broker IP (e.g. `192.168.255.16`) was appearing in cleartext. Added `broker` to `sensitive_keys`. (2) **`virtual_printer_tailscale_auth_key` was leaking** — same reason, no keyword in the filter matched `_auth_key`. Added `auth_key` to the keyword set, AND added a value-prefix safety net (`tskey-`) so any FUTURE Tailscale setting with an unexpected name still auto-redacts when its value starts with the Tailscale auth-key prefix. (3) **Slicer-API reachability check was always returning `null` / `false` even when the slicer was up** — two root causes stacked. First, the old code passed `info["settings"]` (already redacted) into `_collect_slicer_api_info`, so when `bambu_studio_api_url` had been redacted to `"[REDACTED]"`, the httpx call hit that literal string and crashed; when the setting was empty, the URL came through as `""` and the function returned `None`. Second — caught on the next round of testing — even after switching to read directly from `Settings.value`, the check only looked at the DB row, but the real slicer routes (`archives.py:3174-3180`, `library.py`) resolve the URL with a three-level precedence: DB setting → `app_settings.bambu_studio_api_url` (which reads the `BAMBU_STUDIO_API_URL` env var) → built-in default `http://localhost:3001`. Most installations run the sidecar on the default port or via env var, so the DB-only check returned `null` even when the slicer was up and reachable. The collector now mirrors the route's exact resolution path. The block now also reports `bambu_studio_url_set_in_db: bool` and `bambu_studio_url_source: "db" | "env_or_default" | "unset"` so triage can see WHICH layer supplied the URL — separates "user explicitly configured it" from "they're using the default port" without leaking the URL itself. Two regression tests pin both layers: `test_reachability_uses_unredacted_url` (no `"[REDACTED]"` ever reaches `_check_url_reachable`) and `test_env_var_fallback_url_pinged_when_db_setting_empty` (DB empty + env-var-set URL is actually pinged and reported reachable). All new collectors are wrapped in `try/except` so a single failure on one block can't blank the rest of the bundle. OIDC provider names are passed in cleartext deliberately — they're login-button labels (`PocketID`, `Authentik`, `Google`, etc.), not secrets, and provider-specific behavior (Azure handles claims differently from Authentik) is exactly the kind of detail that makes SSO bugs triagable in one round-trip instead of three. 13 new unit tests in `backend/tests/unit/test_support_helpers.py` cover the obico-parser edge cases, slicer-API reachability with mocked httpx (including the "404 = reachable" decision, the un-redacted-URL regression, AND the env-var-fallback regression), auth-info OIDC-cleartext-but-no-secrets contract, the GitHub-backup provider/failure aggregation, and the new `mqtt_broker` / `virtual_printer_tailscale_auth_key` / value-prefix-based redactions. @@ -95,6 +97,8 @@ All notable changes to Bambuddy will be documented in this file. - **Printer card: smart-plug live wattage now rounded to whole watts** ([#1266](https://github.com/maziggy/bambuddy/issues/1266), reported by @Carter3DP) — The printer card's smart-plug status badge rendered `plugStatus.energy.power` raw, so plugs that report fractional watts (Kauf PLF12 via ESPHome / Home Assistant in the reporter's case, but any MQTT plug pushing a float can hit this) showed values like `14.123456789012` W and overflowed the card width. `SmartPlugCard` and `SwitchbarPopover` already wrapped the same field in `Math.round()`; only the printer-card badge was missing the round. Single-line fix at `frontend/src/pages/PrintersPage.tsx:4569`. +## [0.2.4] - 2026-05-11 + ### Added - **Build-plate icon on archive cards + uniform printer/model line** ([#1253](https://github.com/maziggy/bambuddy/issues/1253), reported by @tonygauderman) — Archive cards now show an OrcaSlicer-style bed icon in the printer/model row indicating which build plate the print was sliced for (Cool / Cool SuperTack / Engineering / High Temp / Textured PEI / Smooth PEI), with the full plate name in the hover tooltip. Closes the gap where users had to remember which plate matched a re-print or open the source 3MF in a slicer just to read the bed setting. **Card row also unified:** archives with a real Bambuddy-printer association used to render as `H2D-1 GCODE …` while slicer-only uploads rendered as `Sliced for X1C GCODE …` — same line, two different shapes. Dropped the `Sliced for ` prefix so both render as a uniform ` [bed-icon] GCODE ` row, scanning the same regardless of provenance. **Backend:** new `bed_type` column on `print_archives` (idempotent `ALTER TABLE` migration; SQLite + Postgres safe), populated from `curr_bed_type` in `Metadata/slice_info.config` (per-plate metadata, the authoritative source — that's the bed type that actually got sent to the printer for the exported plate) with a fallback to `Metadata/project_settings.config`'s top-level `curr_bed_type` for older 3MF shapes. Wired through both code paths that produce archive responses: `archive_to_response()` (the hand-rolled dict converter at `archives.py:97` — easy to miss, the schema-only change is silently dropped by Pydantic since the route bypasses `from_attributes`) and the `/rescan` endpoint, so old archives can be re-parsed by the user via the existing per-archive Rescan button. Newly-ingested archives get the value automatically. **Backfill script:** `scripts/backfill_archive_bed_type.py` (with `--dry-run`) re-opens every NULL archive's 3MF on disk and populates the column — opt-in for users who want their entire history covered without waiting for natural turnover. Auto-loads `.env` from project root *before* importing backend modules (since `core/config.py:52` reads `DATABASE_URL` from `os.environ` at import time, not from `pydantic-settings` at `Settings()` time), prints the resolved DB URL with credentials redacted on every run so operators can confirm they're hitting the intended database (Postgres / SQLite — Bambuddy supports both per #1219's `DATABASE_URL` pathway), and calls `init_db()` itself before querying so the migration applies even if the script is run against a database the backend hasn't touched yet. **Frontend:** 6 OrcaSlicer-style PNGs ship in `frontend/public/img/bed/` (under `/img/` because that path was already statically mounted at `main.py:5244`; the `/bed-icons/` toplevel attempted first hit the SPA catch-all and returned `index.html` as `text/html`, which the browser then rendered nothing for). New `utils/bedType.ts` maps slicer strings (case-insensitive) to icon + human-readable label; covers Bambu Studio and OrcaSlicer's diverging spellings for the same physical plate (e.g. `Cool Plate` ↔ `PC Plate`, `Cool Plate (SuperTack)` ↔ `Supertack Plate` ↔ `Bambu Cool Plate SuperTack`). Renders on both card-grid view and list view in `ArchivesPage.tsx`. Unmapped or NULL `bed_type` simply omits the icon, so cards stay clean for archives created before this change. Note on icon mapping: `bed_pei.png` → Textured PEI, `bed_pei_cool.png` → Smooth PEI is a best-guess from the OrcaSlicer asset names — swap the two paths in `bedType.ts` if a future user reports the icons reversed for their plate. @@ -1093,7 +1097,9 @@ All notable changes to Bambuddy will be documented in this file. - **Bed Cooled Notification** ([#378](https://github.com/maziggy/bambuddy/issues/378)) — New notification event that fires when the print bed cools below a configurable threshold (default 35°C) after a print completes. Useful for knowing when it's safe to remove parts. A background task polls the bed temperature every 15 seconds after print completion and sends a notification when it drops below the threshold. Automatically cancels if a new print starts or the printer disconnects. The threshold is configurable in Settings → Notifications. Includes a customizable notification template with printer name, bed temperature, and threshold variables. - **Spool Inventory — AMS Slot Assignment** — Assign inventory spools to AMS slots for filament tracking. Hover over any non-Bambu-Lab AMS slot to assign or unassign spools. The assign modal filters out Bambu Lab spools (tracked via RFID) and spools already assigned to other slots. Bambu Lab spool slots automatically hide assign/unassign UI since they are managed by the AMS. When a Bambu Lab spool is inserted into a slot with a manual assignment, the assignment is automatically unlinked. - **Spool Inventory — Remaining Weight Editing** — Edit the remaining filament weight when adding or editing a spool. The new "Remaining Weight" field in the Additional section shows current weight (label weight minus consumed) with a max reference. Edits are stored as `weight_used` internally. -- **Spool Inventory — Unified 3MF-Based Usage Tracking** ([#336](https://github.com/maziggy/bambuddy/issues/336)) — All spools (Bambu Lab and third-party) now use 3MF slicer estimates as the primary tracking source. Per-filament `used_g` data from the archived 3MF file provides precise per-spool consumption. For failed or aborted prints, per-layer G-code analysis provides accurate partial usage up to the exact failure layer, with linear progress scaling as fallback. AMS remain% delta is the final fallback for G-code-only prints without an archived 3MF. Slot-to-tray mapping uses queue `ams_mapping` for queue-initiated prints and the printer's `tray_now` state for single-filament non-queue prints, ensuring the correct physical spool is always tracked. + +- **Spool +- Inventory — Unified 3MF-Based Usage Tracking** ([#336](https://github.com/maziggy/bambuddy/issues/336)) — All spools (Bambu Lab and third-party) now use 3MF slicer estimates as the primary tracking source. Per-filament `used_g` data from the archived 3MF file provides precise per-spool consumption. For failed or aborted prints, per-layer G-code analysis provides accurate partial usage up to the exact failure layer, with linear progress scaling as fallback. AMS remain% delta is the final fallback for G-code-only prints without an archived 3MF. Slot-to-tray mapping uses queue `ams_mapping` for queue-initiated prints and the printer's `tray_now` state for single-filament non-queue prints, ensuring the correct physical spool is always tracked. - **Notification Templates — Filament Usage Variables** ([#336](https://github.com/maziggy/bambuddy/issues/336)) — `print_complete`, `print_failed`, and `print_stopped` notification events now expose `{filament_grams}` (total grams, scaled by progress for partial prints), `{filament_details}` (per-filament breakdown with AMS slot info, e.g. "AMS-A T1 PLA: 12.4g | AMS-A T3 PETG: 2.8g"), and `{progress}` (completion percentage for failed/stopped prints). The `{filament_details}` variable includes the AMS unit and tray position for each filament used, with "Ext" shown for external spool holders. Falls back to type-only format (e.g. "PLA: 10.0g") when usage tracking data is unavailable. Webhook payloads include `filament_used`, `filament_details`, and `progress` fields. Per-slot filament data is stored in archive `extra_data` for downstream use. - **Printer Status Summary Bar — Next Available & Availability Count** ([#354](https://github.com/maziggy/bambuddy/issues/354)) — The status bar on the Printers page now shows an availability count ("X available") alongside the printing/offline counts, and a "Next available" indicator showing which printing printer will finish soonest — with printer name, mini progress bar, completion percentage, and remaining time. Useful for print farms to quickly identify the next free printer. Updates in real-time via WebSocket. Translated in all 4 locales (en, de, ja, it). - **Nozzle-Aware AMS Filament Mapping for Dual-Nozzle Printers** ([#318](https://github.com/maziggy/bambuddy/issues/318)) — On dual-nozzle printers (H2D, H2D Pro), each AMS unit is physically connected to either the left or right nozzle. Bambuddy now reads nozzle assignments from the 3MF file (`filament_nozzle_map` + `physical_extruder_map` in `project_settings.config`) and constrains filament matching to only AMS trays connected to the correct nozzle via `ams_extruder_map`. Applies to the print scheduler, reprint modal, queue modal, and multi-printer selection. Falls back gracefully to unfiltered matching when no trays exist on the target nozzle. The filament mapping UI shows L/R nozzle badges for dual-nozzle prints. Translated in all 4 locales (en, de, ja, it).