filament_ids.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. """Utility functions for converting between filament_id and setting_id formats.
  2. Bambu printers use two ID formats for filament presets:
  3. - **filament_id** (aka tray_info_idx): e.g. "GFL05", "GFG02", "GFA00"
  4. Reported by printer firmware (RFID tags, AMS status).
  5. - **setting_id**: e.g. "GFSL05", "GFSG02", "GFSA00"
  6. Used by BambuStudio / Bambu Cloud API to resolve presets.
  7. The only difference for official Bambu filaments is an "S" inserted after "GF".
  8. User presets (starting with "P") use the same ID in both contexts.
  9. """
  10. def filament_id_to_setting_id(filament_id: str) -> str:
  11. """Convert filament_id → setting_id (e.g. "GFL05" → "GFSL05").
  12. - Already a setting_id ("GFS…") → returned unchanged.
  13. - User presets ("P…") → returned unchanged.
  14. - Empty / unknown → returned unchanged.
  15. """
  16. if not filament_id:
  17. return filament_id
  18. # User presets start with "P" - leave unchanged
  19. if filament_id.startswith("P"):
  20. return filament_id
  21. # Official Bambu presets: GFx## -> GFSx##
  22. if filament_id.startswith("GF") and len(filament_id) >= 4:
  23. # Already a setting_id (has S after GF)
  24. if filament_id[2] == "S":
  25. return filament_id
  26. return f"GFS{filament_id[2:]}"
  27. return filament_id
  28. def setting_id_to_filament_id(setting_id: str) -> str:
  29. """Convert setting_id → filament_id (e.g. "GFSL05" → "GFL05").
  30. - Already a filament_id ("GF" without "S") → returned unchanged.
  31. - User presets ("P…") → returned unchanged.
  32. - Empty / unknown → returned unchanged.
  33. """
  34. if not setting_id:
  35. return setting_id
  36. # User presets start with "P" - leave unchanged
  37. if setting_id.startswith("P"):
  38. return setting_id
  39. # Setting_id format: GFSx## -> GFx## (remove the "S")
  40. if setting_id.startswith("GFS") and len(setting_id) >= 5:
  41. return f"GF{setting_id[3:]}"
  42. return setting_id
  43. def normalize_slicer_filament(slicer_filament: str | None) -> tuple[str, str]:
  44. """Normalize a slicer_filament value into (tray_info_idx, setting_id).
  45. The slicer_filament field on a spool can be stored in either format:
  46. - filament_id: "GFL05" (from RFID tag scan)
  47. - setting_id: "GFSL05" or "GFSL05_07" (from cloud preset picker)
  48. Returns (tray_info_idx, setting_id) with version suffixes stripped.
  49. """
  50. raw = slicer_filament or ""
  51. if not raw:
  52. return ("", "")
  53. # Strip version suffix (e.g. "GFSL05_07" → "GFSL05")
  54. base = raw.split("_")[0] if "_" in raw else raw
  55. tray_info_idx = setting_id_to_filament_id(base)
  56. sid = filament_id_to_setting_id(base)
  57. return (tray_info_idx, sid)