Merge branch '0.2.0b' into 0.2.0b

This commit is contained in:
MartinNYHC
2026-02-15 09:29:28 +01:00
committed by GitHub
6 changed files with 19 additions and 8 deletions
+1
View File
@@ -16,6 +16,7 @@ All notable changes to Bambuddy will be documented in this file.
- **K-Profiles View — Accurate Filament Name Resolution** — K-profile filament names are now resolved from builtin filament tables and user cloud presets (via new `/cloud/filament-id-map` endpoint) instead of showing raw IDs like "GFU99" or "P4d64437". Falls back to extracting names from the profile name field.
### Fixed
- **Stale Inventory Assignments Persist After Switching to Spoolman Mode** — When switching from built-in inventory to Spoolman mode, existing spool-to-AMS-slot assignments were not cleaned up. The printer card hover cards continued showing "Assign Spool" buttons that opened the internal inventory modal, and any prior assignments remained visible. Now bulk-deletes all `SpoolAssignment` records when enabling Spoolman, invalidates the frontend cache so printer cards update immediately, and hides the inventory assign/unassign UI on printer cards while in Spoolman mode.
- **Bulk Archive Delete Leaves Orphaned Database Records** — When bulk-deleting archives, the files were removed from disk before the database commit. If concurrent SQLite writes caused a lock timeout, the commit failed and rolled back — leaving database records pointing to deleted files (broken thumbnails, 404 errors). Fixed by deleting the database record first and only removing files after a successful commit.
- **Model-Specific Maintenance Tasks for Carbon Rods vs Linear Rails** ([#351](https://github.com/maziggy/bambuddy/issues/351)) — Maintenance tasks "Clean Carbon Rods" and "Lubricate Linear Rails" were shown for all printers regardless of motion system. H2 and A1 series use linear rails (not carbon rods), and X1/P1/P2S series use carbon rods (not linear rails). Maintenance types are now classified by rod/rail type: "Lubricate Carbon Rods" and "Clean Carbon Rods" for X1/P1/P2S, "Lubricate Linear Rails" and "Clean Linear Rails" for A1/H2. Stale and duplicate system types are automatically cleaned up on startup. Includes model-specific wiki links and i18n keys for all 4 locales.
- **AMS Slot Configuration Overwritten on Startup** — Bambuddy was resetting AMS slot filament presets on every startup and reconnection. The `on_ams_change` callback unconditionally unlinked Bambu Lab spool assignments on each MQTT push-all response, then re-assigned them by sending `ams_filament_setting` without a `setting_id`, which cleared the printer's filament preset. Now compares spool RFID identifiers (`tray_uuid` / `tag_uid`) before unlinking — if the same spool is still in the slot, the assignment is preserved and no `ams_filament_setting` command is sent.
+11 -2
View File
@@ -6,7 +6,7 @@ from pathlib import Path
from fastapi import APIRouter, Depends, File, UploadFile
from fastapi.responses import JSONResponse, StreamingResponse
from sqlalchemy import select
from sqlalchemy import delete, select
from sqlalchemy.ext.asyncio import AsyncSession
from backend.app.core.auth import RequirePermissionIfAuthEnabled
@@ -258,7 +258,16 @@ async def update_spoolman_settings(
):
"""Update Spoolman integration settings."""
if "spoolman_enabled" in settings:
await set_setting(db, "spoolman_enabled", settings["spoolman_enabled"])
old_val = await get_setting(db, "spoolman_enabled") or "false"
new_val = settings["spoolman_enabled"]
await set_setting(db, "spoolman_enabled", new_val)
# Switching to Spoolman: clear built-in inventory slot assignments
if old_val.lower() != "true" and new_val.lower() == "true":
from backend.app.models.spool_assignment import SpoolAssignment
result = await db.execute(delete(SpoolAssignment))
logger.info("Cleared %d spool assignments on switch to Spoolman mode", result.rowcount)
if "spoolman_url" in settings:
await set_setting(db, "spoolman_url", settings["spoolman_url"])
if "spoolman_sync_mode" in settings:
@@ -91,6 +91,7 @@ export function SpoolmanSettings() {
queryClient.invalidateQueries({ queryKey: ['spoolman-settings'] });
queryClient.invalidateQueries({ queryKey: ['spoolman-status'] });
queryClient.invalidateQueries({ queryKey: ['settings'] });
queryClient.invalidateQueries({ queryKey: ['spool-assignments'] });
showToast(t('settings.toast.settingsSaved'));
},
});
+3 -3
View File
@@ -2926,7 +2926,7 @@ function PrinterCard({
});
} : undefined,
}}
inventory={(() => {
inventory={spoolmanEnabled ? undefined : (() => {
const assignment = onGetAssignment?.(printer.id, ams.id, slotIdx);
return {
assignedSpool: assignment?.spool ? {
@@ -3164,7 +3164,7 @@ function PrinterCard({
});
} : undefined,
}}
inventory={(() => {
inventory={spoolmanEnabled ? undefined : (() => {
const assignment = onGetAssignment?.(printer.id, ams.id, htSlotId);
return {
assignedSpool: assignment?.spool ? {
@@ -3350,7 +3350,7 @@ function PrinterCard({
});
} : undefined,
}}
inventory={(() => {
inventory={spoolmanEnabled ? undefined : (() => {
const assignment = onGetAssignment?.(printer.id, 255, slotTrayId);
return {
assignedSpool: assignment?.spool ? {
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -23,7 +23,7 @@
<!-- Splash screens for iOS -->
<link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
<script type="module" crossorigin src="/assets/index-CEmIWZ6o.js"></script>
<script type="module" crossorigin src="/assets/index-8IRr_Byo.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-CggumZ2v.css">
</head>
<body>