filament_ids.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. """Utility functions for converting between filament_id and setting_id formats, and shared filament constants.
  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. MATERIAL_TEMPS: dict[str, tuple[int, int]] = {
  11. "PLA": (190, 230),
  12. "PETG": (220, 260),
  13. "ABS": (240, 270),
  14. "ASA": (240, 270),
  15. "TPU": (200, 240),
  16. "PA": (260, 290),
  17. "PC": (250, 280),
  18. "PVA": (190, 210),
  19. "PLA-CF": (210, 240),
  20. "PETG-CF": (240, 270),
  21. "PA-CF": (270, 300),
  22. }
  23. GENERIC_FILAMENT_IDS: dict[str, str] = {
  24. "PLA": "GFL99",
  25. "PETG": "GFG99",
  26. "ABS": "GFB99",
  27. "ASA": "GFB98",
  28. "PC": "GFC99",
  29. "PA": "GFN99",
  30. "NYLON": "GFN99",
  31. "TPU": "GFU99",
  32. "PVA": "GFS99",
  33. "HIPS": "GFS98",
  34. "PLA-CF": "GFL98",
  35. "PETG-CF": "GFG98",
  36. "PA-CF": "GFN98",
  37. "PETG HF": "GFG96",
  38. }
  39. def filament_id_to_setting_id(filament_id: str) -> str:
  40. """Convert filament_id → setting_id (e.g. "GFL05" → "GFSL05").
  41. - Already a setting_id ("GFS…") → returned unchanged.
  42. - User presets ("P…") → returned unchanged.
  43. - Empty / unknown → returned unchanged.
  44. """
  45. if not filament_id:
  46. return filament_id
  47. # User presets start with "P" - leave unchanged
  48. if filament_id.startswith("P"):
  49. return filament_id
  50. # Official Bambu presets: GFx## -> GFSx##
  51. if filament_id.startswith("GF") and len(filament_id) >= 4:
  52. # Already a setting_id (has S after GF)
  53. if filament_id[2] == "S":
  54. return filament_id
  55. return f"GFS{filament_id[2:]}"
  56. return filament_id
  57. def setting_id_to_filament_id(setting_id: str) -> str:
  58. """Convert setting_id → filament_id (e.g. "GFSL05" → "GFL05").
  59. - Already a filament_id ("GF" without "S") → returned unchanged.
  60. - User presets ("P…") → returned unchanged.
  61. - Empty / unknown → returned unchanged.
  62. """
  63. if not setting_id:
  64. return setting_id
  65. # User presets start with "P" - leave unchanged
  66. if setting_id.startswith("P"):
  67. return setting_id
  68. # Setting_id format: GFSx## -> GFx## (remove the "S")
  69. if setting_id.startswith("GFS") and len(setting_id) >= 5:
  70. return f"GF{setting_id[3:]}"
  71. return setting_id
  72. def normalize_slicer_filament(slicer_filament: str | None) -> tuple[str, str]:
  73. """Normalize a slicer_filament value into (tray_info_idx, setting_id).
  74. The slicer_filament field on a spool can be stored in either format:
  75. - filament_id: "GFL05" (from RFID tag scan)
  76. - setting_id: "GFSL05" or "GFSL05_07" (from cloud preset picker)
  77. Returns (tray_info_idx, setting_id) with version suffixes stripped.
  78. """
  79. raw = slicer_filament or ""
  80. if not raw:
  81. return ("", "")
  82. # Strip version suffix (e.g. "GFSL05_07" → "GFSL05")
  83. base = raw.split("_")[0] if "_" in raw else raw
  84. tray_info_idx = setting_id_to_filament_id(base)
  85. sid = filament_id_to_setting_id(base)
  86. return (tray_info_idx, sid)