Browse Source

Add built-in filament name lookup table for nozzle rack and AMS tooltips (#300)

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.
maziggy 3 months ago
parent
commit
9484f263ab
2 changed files with 104 additions and 2 deletions
  1. 1 1
      CHANGELOG.md
  2. 103 1
      backend/app/api/routes/cloud.py

+ 1 - 1
CHANGELOG.md

@@ -23,7 +23,7 @@ All notable changes to Bambuddy will be documented in this file.
 - **H2 Series — Single-Nozzle Hover Card** ([#300](https://github.com/maziggy/bambuddy/issues/300)) — H2D/H2S printers with a single nozzle now show extended nozzle details (wear, serial, max temp) on hover over the temperature card. Backend changed from H2C-only (>2 nozzles) to all H2 series (any nozzle_info present).
 - **H2C Nozzle Rack — Translate Type Codes & Add Flow Info** ([#300](https://github.com/maziggy/bambuddy/issues/300)) — Raw nozzle type codes (e.g. "HS", "HH01") are now translated to human-readable names: material (Hardened Steel, Stainless Steel, Tungsten Carbide) and flow type (High Flow, Standard). New "Flow" row in the hover card. Translations added in all 4 locales (en, de, ja, it).
 - **H2C Nozzle Rack — Show Filament Material in Hover Card** ([#300](https://github.com/maziggy/bambuddy/issues/300)) — Nozzle hover card now shows the loaded filament material type (e.g. "PLA", "PETG") alongside the color swatch, captured from MQTT nozzle info data.
-- **H2C Nozzle Rack — Resolve Filament Names From Cloud & Local Profiles** ([#300](https://github.com/maziggy/bambuddy/issues/300)) — Nozzle rack hover card previously showed raw filament IDs like "GFU99" instead of human-readable names. Now resolves filament names with a 3-tier fallback: Bambu Cloud preset lookup → local slicer profiles (matching by `setting_id` in the imported OrcaSlicer JSON) → raw ID fallback. Uses the same cloud lookup mechanism as AMS trays. Local profiles work without cloud authentication for users who import their slicer presets.
+- **H2C Nozzle Rack — Resolve Filament Names From Cloud & Local Profiles** ([#300](https://github.com/maziggy/bambuddy/issues/300)) — Nozzle rack hover card previously showed raw filament IDs like "GFU99" instead of human-readable names. Now resolves filament names with a 4-tier fallback: Bambu Cloud preset lookup → local slicer profiles → built-in filament name table (86 known Bambu filament codes) → raw ID fallback. The built-in table resolves names like "Bambu ASA", "Generic TPU", "Generic PLA" when the cloud API returns 400 for certain filament IDs. Also benefits AMS tray tooltips.
 - **H2C Nozzle Rack Compact Layout** ([#300](https://github.com/maziggy/bambuddy/issues/300)) — Redesigned nozzle rack from a 2×3 grid to a compact single-row layout with bottom accent bars (green = mounted, gray = docked). Temperature cards are thinner, rack card is wider (flex-[2]), and all cards vertically centered.
 - **Firmware Version Badge on Printer Card** ([#311](https://github.com/maziggy/bambuddy/issues/311)) — Printer cards now show a firmware version badge (when firmware checking is enabled). Green with checkmark when up to date, orange with download icon when an update is available. Clicking the badge opens a firmware info modal showing release notes (auto-expanded when up to date) or the existing update workflow. Badge and modal respect `firmware:read` and `firmware:update` permissions. Translations added in all 4 locales.
 - **Auto-Detect Subnet for Printer Discovery** — Docker users no longer need to manually enter a subnet in the Add Printer dialog. Bambuddy auto-detects available network subnets and pre-selects the first one. When multiple subnets are available (e.g., eth0 + wlan0), a dropdown lets users choose. Falls back to manual text input if no subnets are detected.

+ 103 - 1
backend/app/api/routes/cloud.py

@@ -307,6 +307,97 @@ _filament_cache: dict[str, dict] = {}
 _filament_cache_time: float = 0
 FILAMENT_CACHE_TTL = 300  # 5 minutes
 
+# Built-in filament ID → name mapping (fallback when cloud API and local profiles
+# don't have the entry). Based on Bambu Lab's known filament catalogue.
+_BUILTIN_FILAMENT_NAMES: dict[str, str] = {
+    "GFA00": "Bambu PLA Basic",
+    "GFA01": "Bambu PLA Matte",
+    "GFA02": "Bambu PLA Metal",
+    "GFA05": "Bambu PLA Silk",
+    "GFA06": "Bambu PLA Silk+",
+    "GFA07": "Bambu PLA Marble",
+    "GFA08": "Bambu PLA Sparkle",
+    "GFA09": "Bambu PLA Tough",
+    "GFA11": "Bambu PLA Aero",
+    "GFA12": "Bambu PLA Glow",
+    "GFA13": "Bambu PLA Dynamic",
+    "GFA15": "Bambu PLA Galaxy",
+    "GFA16": "Bambu PLA Wood",
+    "GFA50": "Bambu PLA-CF",
+    "GFB00": "Bambu ABS",
+    "GFB01": "Bambu ASA",
+    "GFB02": "Bambu ASA-Aero",
+    "GFB50": "Bambu ABS-GF",
+    "GFB51": "Bambu ASA-CF",
+    "GFB60": "PolyLite ABS",
+    "GFB61": "PolyLite ASA",
+    "GFB98": "Generic ASA",
+    "GFB99": "Generic ABS",
+    "GFC00": "Bambu PC",
+    "GFC01": "Bambu PC FR",
+    "GFC99": "Generic PC",
+    "GFG00": "Bambu PETG Basic",
+    "GFG01": "Bambu PETG Translucent",
+    "GFG02": "Bambu PETG HF",
+    "GFG50": "Bambu PETG-CF",
+    "GFG60": "PolyLite PETG",
+    "GFG96": "Generic PETG HF",
+    "GFG97": "Generic PCTG",
+    "GFG98": "Generic PETG-CF",
+    "GFG99": "Generic PETG",
+    "GFL00": "PolyLite PLA",
+    "GFL01": "PolyTerra PLA",
+    "GFL03": "eSUN PLA+",
+    "GFL04": "Overture PLA",
+    "GFL05": "Overture Matte PLA",
+    "GFL06": "Fiberon PETG-ESD",
+    "GFL50": "Fiberon PA6-CF",
+    "GFL51": "Fiberon PA6-GF",
+    "GFL52": "Fiberon PA12-CF",
+    "GFL53": "Fiberon PA612-CF",
+    "GFL54": "Fiberon PET-CF",
+    "GFL55": "Fiberon PETG-rCF",
+    "GFL95": "Generic PLA High Speed",
+    "GFL96": "Generic PLA Silk",
+    "GFL98": "Generic PLA-CF",
+    "GFL99": "Generic PLA",
+    "GFN03": "Bambu PA-CF",
+    "GFN04": "Bambu PAHT-CF",
+    "GFN05": "Bambu PA6-CF",
+    "GFN06": "Bambu PPA-CF",
+    "GFN08": "Bambu PA6-GF",
+    "GFN96": "Generic PPA-GF",
+    "GFN97": "Generic PPA-CF",
+    "GFN98": "Generic PA-CF",
+    "GFN99": "Generic PA",
+    "GFP95": "Generic PP-GF",
+    "GFP96": "Generic PP-CF",
+    "GFP97": "Generic PP",
+    "GFP98": "Generic PE-CF",
+    "GFP99": "Generic PE",
+    "GFR98": "Generic PHA",
+    "GFR99": "Generic EVA",
+    "GFS00": "Bambu Support W",
+    "GFS01": "Bambu Support G",
+    "GFS02": "Bambu Support For PLA",
+    "GFS03": "Bambu Support For PA/PET",
+    "GFS04": "Bambu PVA",
+    "GFS05": "Bambu Support For PLA/PETG",
+    "GFS06": "Bambu Support for ABS",
+    "GFS97": "Generic BVOH",
+    "GFS98": "Generic HIPS",
+    "GFS99": "Generic PVA",
+    "GFT01": "Bambu PET-CF",
+    "GFT02": "Bambu PPS-CF",
+    "GFT97": "Generic PPS",
+    "GFT98": "Generic PPS-CF",
+    "GFU00": "Bambu TPU 95A HF",
+    "GFU01": "Bambu TPU 95A",
+    "GFU02": "Bambu TPU for AMS",
+    "GFU98": "Generic TPU for AMS",
+    "GFU99": "Generic TPU",
+}
+
 
 async def _enrich_from_local_presets(
     unresolved_ids: list[str],
@@ -361,6 +452,17 @@ async def _enrich_from_local_presets(
     except Exception as e:
         logger.warning("Failed to search local presets for filament info: %s", e)
 
+    # Phase 4: Fall back to built-in filament name table for any still without a name
+    for fid in unresolved_ids:
+        if fid not in result or not result[fid].get("name"):
+            name = _BUILTIN_FILAMENT_NAMES.get(fid, "")
+            if name:
+                # Preserve K value from earlier phases if available
+                existing_k = result.get(fid, {}).get("k")
+                info = {"name": name, "k": existing_k}
+                _filament_cache[fid] = info
+                result[fid] = info
+
     # Fill remaining unresolved with empty entries
     for fid in unresolved_ids:
         if fid not in result:
@@ -408,7 +510,7 @@ async def get_filament_info(
     Get filament preset info (name and K value) for multiple setting IDs.
 
     Used to enrich AMS tray and nozzle rack tooltips with preset data.
-    Lookup order: cache → cloud → local profiles → empty fallback.
+    Lookup order: cache → cloud → local profiles → built-in table → empty fallback.
     """
     import time