bambutools
bambutools contains a collection of methods used as tools (mostly internal).
Classes:
| Name | Description |
|---|---|
AMSControlCommand |
AMS Control Commands enum |
AMSDryFanStatus |
AMS drying fan status extracted from bits 18-21 of ams_info. |
AMSDrySubStatus |
AMS drying sub-status extracted from bits 22-25 of ams_info. |
AMSHeatingState |
AMS Drying/Heater states extracted from bits 4-7 of ams_info. |
AMSModel |
AMS model enum |
AMSSeries |
AMS Series enum |
AMSUserSetting |
AMS User Settings enum |
ActiveTool |
The currently active extruder index. |
AirConditioningMode |
The mode the printer's air conditioning sub system is in. |
DetectorSensitivity |
Sensitivity level for X-Cam AI vision detectors (spaghetti, pile-up, clump, air-print). |
ExtruderInfoState |
Consolidated logical states for extruder sensor status. |
ExtruderStatus |
Operational states for physical extruders. |
NozzleDiameter |
Nozzle Diameter enum |
NozzleFlowType |
Canonical nozzle flow families used by BambuStudio/Orca nozzle identifiers. |
NozzleMaterialCode |
Canonical material codes used in encoded nozzle identifiers. |
NozzleType |
Canonical cross-model nozzle material type from telemetry. |
PlateType |
Used by |
PrintOption |
Print Option enum |
PrinterModel |
Printer model enum |
PrinterSeries |
Printer Series enum |
ServiceState |
This enum is used by |
TrayState |
Operational status of the filament tray. |
Functions:
| Name | Description |
|---|---|
build_nozzle_identifier |
Build a canonical Bambu-style nozzle identifier. |
decodeError |
Decodes a raw print_error integer into a full HMS dictionary. |
decodeHMS |
Decodes the raw HMS list from telemetry into a structured list of dictionaries. |
getAMSHeatingState |
Decodes the AMS drying/heater state from bits 4-7 of the ams_info value. |
getAMSModelBySerial |
Returns the hardware model based on the serial number prefix. |
getAMSSeriesByModel |
Returns the AMS series enum based on the provided model. |
getPrinterModelBySerial |
Returns the Printer model enum based on the provided serial #. |
getPrinterSeriesByModel |
Returns the Printer series enum based on the provided model. |
get_file_md5 |
Generates an MD5 hex hash for a given file. |
jsonSerializer |
Module-level JSON serializer for use with |
nozzle_type_to_telemetry |
Convert canonical |
parseAMSInfo |
Extracts all documented telemetry attributes from the AMS info hex string. |
parseAMSStatus |
Maps the ams_status code to human-readable descriptions. |
parseExtruderInfo |
Decodes the extruder 'info' bit-packed status using unique ExtruderInfoState names. |
parseExtruderStatus |
Decodes the operational extruder state using the exhaustive Enum map. |
parseRFIDStatus |
Can be used to parse |
parseStage |
Maps stg_cur numeric codes to human-readable print stages. |
parse_nozzle_identifier |
Parse a Bambu-style nozzle identifier into flow family, material, and diameter. |
parse_nozzle_type |
Resolve a nozzle type from cross-model telemetry strings or encoded IDs. |
scaleFanSpeed |
Scales proprietary 0-15 fan speed values to a 0-100 percentage. |
sortFileTreeAlphabetically |
Sorts a dict of file/directory nodes hierarchically. |
unpackTemperature |
Unpacks a 32-bit packed temperature integer into a tuple of (Actual, Target). |
AMSControlCommand
Bases: Enum
AMS Control Commands enum
AMSDryFanStatus
Bases: IntEnum
AMS drying fan status extracted from bits 18-21 of ams_info. Two independent fans (fan1: bits 18-19, fan2: bits 20-21). Mapped from BambuStudio's DryFanStatus enum.
AMSDrySubStatus
Bases: IntEnum
AMS drying sub-status extracted from bits 22-25 of ams_info. Indicates the specific phase of the drying cycle. Mapped from BambuStudio's DrySubStatus enum.
AMSHeatingState
Bases: IntEnum
AMS Drying/Heater states extracted from bits 4-7 of ams_info. Mapped directly from BambuStudio's DryStatus enum. Only supported on AMS 2 Pro (N3F) and AMS HT (N3S) models.
AMSModel
Bases: IntEnum
AMS model enum
AMSSeries
Bases: Enum
AMS Series enum
AMSUserSetting
Bases: Enum
AMS User Settings enum
ActiveTool
Bases: IntEnum
The currently active extruder index.
SINGLE_EXTRUDER (-1): Standard single-toolhead architecture (X1/P1/A1).RIGHT_EXTRUDER (0): The primary/right toolhead in H2D (Dual Extruder) systems.LEFT_EXTRUDER (1): The secondary/left toolhead in H2D (Dual Extruder) systems.NOT_ACTIVE (15): The multi-extruder system is in a transitional state.
AirConditioningMode
Bases: IntEnum
The mode the printer's air conditioning sub system is in.
NOT_SUPPORTED (-1): This printer is not equipped with this feature.COOL_MODE (0): The printer is currently not heating. The top vent may be open if the exhaust fan is running.HEAT_MODE (1): The printer is actively heating the chamber with the recirculation fan active.
DetectorSensitivity
Bases: Enum
Sensitivity level for X-Cam AI vision detectors (spaghetti, pile-up, clump, air-print).
The string value is sent directly in the halt_print_sensitivity MQTT field.
ExtruderInfoState
Bases: IntEnum
Consolidated logical states for extruder sensor status. Values represent unique state IDs to prevent bitmask collisions.
ExtruderStatus
Bases: IntEnum
Operational states for physical extruders. Values are mapped directly from the Bambu Studio source code (BBL_EXTRUDER_STATE).
NozzleDiameter
Bases: Enum
Nozzle Diameter enum
NozzleFlowType
Bases: Enum
Canonical nozzle flow families used by BambuStudio/Orca nozzle identifiers.
Encoded as the second character in identifiers such as HS00-0.4.
NozzleMaterialCode
Bases: Enum
Canonical material codes used in encoded nozzle identifiers.
Encoded as characters 3-4 in identifiers such as HS00-0.4.
NozzleType
Bases: Enum
Canonical cross-model nozzle material type from telemetry.
This enum intentionally models only material/type categories that appear in
telemetry and accessory APIs. Encoded variant identifiers such as HS01
are parsed via parse_nozzle_identifier() / parse_nozzle_type().
PlateType
Bases: Enum
Used by BambuPrinter.print_3mf_file to specify which plate should be used when
starting a print job.
PrintOption
Bases: Enum
Print Option enum
PrinterModel
Bases: Enum
Printer model enum
PrinterSeries
Bases: Enum
Printer Series enum
ServiceState
Bases: Enum
This enum is used by bambu-printer-manager to track the underlying state
of the mqtt connection to the printer.
TrayState
Bases: IntEnum
Operational status of the filament tray.
build_nozzle_identifier
build_nozzle_identifier(
flow_type: NozzleFlowType, nozzle_type: NozzleType, diameter: float | str
) -> str
Build a canonical Bambu-style nozzle identifier.
Examples
HS00-0.4, HH01-0.6, HU00-0.4
Source code in src/bpm/bambutools.py
def build_nozzle_identifier(
flow_type: NozzleFlowType, nozzle_type: NozzleType, diameter: float | str
) -> str:
"""
Build a canonical Bambu-style nozzle identifier.
Examples
--------
`HS00-0.4`, `HH01-0.6`, `HU00-0.4`
"""
material = _TYPE_TO_MATERIAL_CODE.get(nozzle_type)
if material is None:
raise ValueError(f"Unsupported nozzle_type for encoded ID: {nozzle_type}")
if flow_type not in {
NozzleFlowType.STANDARD,
NozzleFlowType.HIGH_FLOW,
NozzleFlowType.TPU_HIGH_FLOW,
}:
raise ValueError(f"Unsupported flow_type for encoded ID: {flow_type}")
if isinstance(diameter, float):
diameter_str = f"{diameter:.1f}"
else:
diameter_str = str(diameter)
return f"H{flow_type.value}{material.value}-{diameter_str}"
decodeError
staticmethod
Decodes a raw print_error integer into a full HMS dictionary.
Source code in src/bpm/bambutools.py
@staticmethod
def decodeError(error: int) -> dict:
"""
Decodes a raw print_error integer into a full HMS dictionary.
"""
if error == 0:
return {}
raw_hex = f"{error:08X}".upper()
wiki_slug = "-".join(raw_hex[i : i + 4] for i in range(0, 8, 4))
res = {
"code": f"HMS_{wiki_slug}",
"msg": "Unknown HMS Error",
"module": "System",
"severity": "Error",
"is_critical": False,
"type": "device_error",
"url": f"https://e.bambulab.com/?e={raw_hex}",
}
real_module = (error >> 24) & 0xFF
module_map = {
0x03: "Mainboard",
0x05: "AMS",
0x12: "AMS",
0x07: "Toolhead",
0x0B: "Webcam",
0x10: "HMS",
}
res["module"] = module_map.get(real_module, "System")
msg_list = HMS_STATUS.get("data", {}).get("device_error", {}).get("en", [])
modules = ["03", "05", "07", "0B", "0C", "10", "12"]
if raw_hex[:2] in modules:
modules.remove(raw_hex[:2])
modules.insert(0, raw_hex[:2])
for module in modules:
current_hex = f"{module}{raw_hex[2:]}"
for entry in msg_list:
if entry.get("ecode", "").upper() == current_hex.upper():
res["msg"] = entry.get("intro", res["msg"])
break
if res["msg"] != "Unknown HMS Error":
break
mask = (error >> 16) & 0xFF
if mask in (0x00, 0x01):
res["severity"] = "Fatal" if mask == 0x00 else "Error"
res["is_critical"] = True
elif mask == 0x02:
res["severity"] = "Warning"
res["is_critical"] = False
else:
res["severity"] = "Info"
res["is_critical"] = False
return res
decodeHMS
staticmethod
Decodes the raw HMS list from telemetry into a structured list of dictionaries.
Source code in src/bpm/bambutools.py
@staticmethod
def decodeHMS(hms_list: list) -> list[dict]:
"""
Decodes the raw HMS list from telemetry into a structured list of dictionaries.
"""
decoded_errors = []
for item in hms_list:
if isinstance(item, dict) and isinstance(item.get("code"), str):
decoded_errors.append(item)
continue
try:
attr = int(item.get("attr", 0))
code = int(item.get("code", 0))
except (AttributeError, ValueError, TypeError):
continue
if attr == 0:
continue
ecode = f"{attr:08X}{code:08X}"
wiki_slug = "-".join(ecode[i : i + 4] for i in range(0, 16, 4))
res = {
"code": f"HMS_{wiki_slug}",
"msg": "Unknown HMS Error",
"module": "System",
"severity": "Error",
"is_critical": False,
"type": "device_hms",
"url": f"https://e.bambulab.com/?e={ecode}",
}
mid = (attr >> 24) & 0xFF
mask = (attr >> 16) & 0xFF
module_map = {
0x03: "Mainboard",
0x05: "AMS",
0x12: "AMS",
0x07: "Toolhead",
0x0B: "Webcam",
0x10: "HMS",
}
res["module"] = module_map.get(mid, "System")
msg_list = HMS_STATUS.get("data", {}).get("device_hms", {}).get("en", [])
for entry in msg_list:
if entry.get("ecode", "").upper() == ecode:
res["msg"] = entry.get("intro", res["msg"])
break
if mask in (0x00, 0x01):
res["severity"], res["is_critical"] = (
("Fatal" if mask == 0x00 else "Error"),
True,
)
elif mask == 0x02:
res["severity"] = "Warning"
else:
res["severity"] = "Info"
decoded_errors.append(res)
return decoded_errors
getAMSHeatingState
staticmethod
getAMSHeatingState(ams_info: int) -> AMSHeatingState
Decodes the AMS drying/heater state from bits 4-7 of the ams_info value.
This implementation follows BambuStudio's DevFilaSystem parsing logic, extracting DryStatus from the info field.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
int
|
Numeric AMS info value containing drying status in bits 4-7. |
required |
Returns:
| Type | Description |
|---|---|
AMSHeatingState
|
AMSHeatingState enum representing the current drying/heater state. |
AMSHeatingState
|
Only AMS 2 Pro (N3F) and AMS HT (N3S) support active drying states. |
Source code in src/bpm/bambutools.py
@staticmethod
def getAMSHeatingState(ams_info: int) -> AMSHeatingState:
"""
Decodes the AMS drying/heater state from bits 4-7 of the ams_info value.
This implementation follows BambuStudio's DevFilaSystem parsing logic,
extracting DryStatus from the info field.
Args:
ams_info: Numeric AMS info value containing drying status in bits 4-7.
Returns:
AMSHeatingState enum representing the current drying/heater state.
Only AMS 2 Pro (N3F) and AMS HT (N3S) support active drying states.
"""
# Extract DryStatus from bits 4-7 (right-shift by 4, mask 0x0F)
dry_status = (ams_info >> 4) & 0x0F
return AMSHeatingState(dry_status)
getAMSModelBySerial
staticmethod
getAMSModelBySerial(serial: str) -> AMSModel
Returns the hardware model based on the serial number prefix.
Source code in src/bpm/bambutools.py
@staticmethod
def getAMSModelBySerial(serial: str) -> AMSModel:
"""
Returns the hardware model based on the serial number prefix.
"""
prefix = serial[:3].upper()
if prefix == "19C":
return AMSModel.AMS_2_PRO
if prefix == "19F":
return AMSModel.AMS_HT
if prefix == "006":
return AMSModel.AMS_1
if prefix == "03C":
return AMSModel.AMS_LITE
return AMSModel.UNKNOWN
getAMSSeriesByModel
staticmethod
Returns the AMS series enum based on the provided model.
Source code in src/bpm/bambutools.py
@staticmethod
def getAMSSeriesByModel(model: AMSModel) -> AMSSeries:
"""
Returns the AMS series enum based on the provided model.
"""
if model in (AMSModel.AMS_1, AMSModel.AMS_LITE):
return AMSSeries.GEN_1
if model in (AMSModel.AMS_HT, AMSModel.AMS_2_PRO):
return AMSSeries.GEN_2
return AMSSeries.UNKNOWN
getPrinterModelBySerial
staticmethod
getPrinterModelBySerial(serial: str) -> PrinterModel
Returns the Printer model enum based on the provided serial #.
Source code in src/bpm/bambutools.py
@staticmethod
def getPrinterModelBySerial(serial: str) -> PrinterModel:
"""
Returns the Printer model enum based on the provided serial #.
"""
mapping = {
"00M": PrinterModel.X1C,
"00W": PrinterModel.X1,
"03W": PrinterModel.X1E,
"01S": PrinterModel.P1P,
"01P": PrinterModel.P1S,
"030": PrinterModel.A1_MINI,
"039": PrinterModel.A1,
"22E": PrinterModel.P2S,
"093": PrinterModel.H2S,
"094": PrinterModel.H2D,
}
prefix = serial[:3]
return mapping.get(prefix, PrinterModel.UNKNOWN)
getPrinterSeriesByModel
staticmethod
getPrinterSeriesByModel(model: PrinterModel) -> PrinterSeries
Returns the Printer series enum based on the provided model.
get_file_md5
staticmethod
get_file_md5(file_path: str | Path) -> str
Generates an MD5 hex hash for a given file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str | Path
|
The path to the file (string or Path object). |
required |
Returns:
| Type | Description |
|---|---|
str
|
The 32-character MD5 hexadecimal string. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If the file does not exist. |
Source code in src/bpm/bambutools.py
@staticmethod
def get_file_md5(file_path: str | Path) -> str:
"""
Generates an MD5 hex hash for a given file.
Args:
file_path: The path to the file (string or Path object).
Returns:
The 32-character MD5 hexadecimal string.
Raises:
FileNotFoundError: If the file does not exist.
"""
path = Path(file_path)
if not path.is_file():
raise FileNotFoundError(f"No file found at: {path}")
md5_hash = hashlib.md5()
with path.open("rb") as f:
for chunk in iter(lambda: f.read(65536), b""):
md5_hash.update(chunk)
return md5_hash.hexdigest().upper()
jsonSerializer
Module-level JSON serializer for use with json.dumps(default=jsonSerializer).
Handles dataclasses, objects with __dict__, and falls back to str().
Skips MQTT clients, threads, and mappingproxy instances that cannot be
serialized meaningfully.
Source code in src/bpm/bambutools.py
def jsonSerializer(obj: Any) -> Any:
"""
Module-level JSON serializer for use with `json.dumps(default=jsonSerializer)`.
Handles dataclasses, objects with `__dict__`, and falls back to `str()`.
Skips MQTT clients, threads, and `mappingproxy` instances that cannot be
serialized meaningfully.
"""
try:
if isinstance(obj, Thread):
return ""
if getattr(obj.__class__, "__module__", "").startswith("paho.mqtt"):
return ""
if str(obj.__class__).replace("<class '", "").replace("'>", "") == "mappingproxy":
return ""
return getattr(obj, "__dict__", str(obj))
except Exception:
return ""
nozzle_type_to_telemetry
nozzle_type_to_telemetry(value: NozzleType) -> str
parseAMSInfo
staticmethod
parseAMSInfo(info_hex: str) -> dict
Extracts all documented telemetry attributes from the AMS info hex string.
Based on BambuStudio's DevFilaSystemParser::ParseAmsInfo implementation. Complete bit field mapping (32-bit integer): - Bits 0-3: AMS type (1=AMS, 2=AMS_LITE, 3=AMS_2_PRO/N3F, 4=AMS_HT/N3S) - Bits 4-7: Dry status (OFF/CHECKING/DRYING/COOLING/STOPPING/ERROR/etc) - Bits 8-11: Extruder ID (for H2D toolhead assignment) - Bits 18-19: Dry fan 1 status (OFF=0, ON=1) - Bits 20-21: Dry fan 2 status (OFF=0, ON=1) - Bits 22-25: Dry sub-status (OFF/HEATING/DEHUMIDIFY)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
Hexadecimal string representation of AMS info value |
required |
Returns:
| Type | Description |
|---|---|
dict
|
Dictionary with all extracted telemetry fields |
Source code in src/bpm/bambutools.py
@staticmethod
def parseAMSInfo(info_hex: str) -> dict:
"""
Extracts all documented telemetry attributes from the AMS info hex string.
Based on BambuStudio's DevFilaSystemParser::ParseAmsInfo implementation.
Complete bit field mapping (32-bit integer):
- Bits 0-3: AMS type (1=AMS, 2=AMS_LITE, 3=AMS_2_PRO/N3F, 4=AMS_HT/N3S)
- Bits 4-7: Dry status (OFF/CHECKING/DRYING/COOLING/STOPPING/ERROR/etc)
- Bits 8-11: Extruder ID (for H2D toolhead assignment)
- Bits 18-19: Dry fan 1 status (OFF=0, ON=1)
- Bits 20-21: Dry fan 2 status (OFF=0, ON=1)
- Bits 22-25: Dry sub-status (OFF/HEATING/DEHUMIDIFY)
Args:
info_hex: Hexadecimal string representation of AMS info value
Returns:
Dictionary with all extracted telemetry fields
"""
info = int(info_hex, 16)
ams_type = info & 0x0F # Bits 0-3
dry_status = (info >> 4) & 0x0F # Bits 4-7
extruder_id = (info >> 8) & 0x0F # Bits 8-11
dry_fan1_status = (info >> 18) & 0x03 # Bits 18-19
dry_fan2_status = (info >> 20) & 0x03 # Bits 20-21
dry_sub_status = (info >> 22) & 0x0F # Bits 22-25
ret = {
"ams_type": AMSModel(ams_type) if ams_type in range(5) else AMSModel.UNKNOWN,
"heater_state": AMSHeatingState(dry_status),
"extruder_id": extruder_id,
"dry_fan1_status": AMSDryFanStatus(dry_fan1_status),
"dry_fan2_status": AMSDryFanStatus(dry_fan2_status),
"dry_sub_status": AMSDrySubStatus(dry_sub_status),
}
# print(f"\r\n{ret}\r\n")
return ret
parseAMSStatus
staticmethod
Maps the ams_status code to human-readable descriptions.
Source code in src/bpm/bambutools.py
@staticmethod
def parseAMSStatus(status_int: int) -> str:
"""
Maps the ams_status code to human-readable descriptions.
"""
main_status = (status_int >> 8) & 0xFF
status_map = {
0x00: "Idle",
0x01: "Filament Changing",
0x02: "RFID Identifying",
0x03: "Assist/Engaged",
0x04: "Calibration",
0x10: "Self Check",
0x20: "Debug",
0xFF: "Unknown",
}
return status_map.get(main_status, "Idle")
parseExtruderInfo
staticmethod
parseExtruderInfo(info_int: int) -> ExtruderInfoState
Decodes the extruder 'info' bit-packed status using unique ExtruderInfoState names.
Source code in src/bpm/bambutools.py
@staticmethod
def parseExtruderInfo(info_int: int) -> ExtruderInfoState:
"""
Decodes the extruder 'info' bit-packed status using unique ExtruderInfoState names.
"""
if not (info_int & 0x08):
return ExtruderInfoState.NO_NOZZLE
if info_int & 0x02:
return ExtruderInfoState.LOADED
if info_int & 0x04:
return ExtruderInfoState.BUFFER_LOADED
return ExtruderInfoState.EMPTY
parseExtruderStatus
staticmethod
parseExtruderStatus(stat_int: int) -> ExtruderStatus
Decodes the operational extruder state using the exhaustive Enum map.
Source code in src/bpm/bambutools.py
@staticmethod
def parseExtruderStatus(stat_int: int) -> ExtruderStatus:
"""
Decodes the operational extruder state using the exhaustive Enum map.
"""
working_bits = (stat_int >> 8) & 0x03
if working_bits in (0x02, 0x03):
return ExtruderStatus.ACTIVE
if stat_int & 0x01:
return ExtruderStatus.HEATING
return ExtruderStatus.IDLE
parseRFIDStatus
staticmethod
Can be used to parse ams_rfid_status
Source code in src/bpm/bambutools.py
parseStage
staticmethod
Maps stg_cur numeric codes to human-readable print stages.
Source code in src/bpm/bambutools.py
@staticmethod
def parseStage(stage_int: int) -> str:
"""
Maps stg_cur numeric codes to human-readable print stages.
"""
stage_map = {
-1: "",
0: "",
1: "Auto bed leveling",
2: "Heatbed preheating",
3: "Sweeping XY mech mode",
4: "Changing filament",
5: "M400 pause",
6: "Filament runout pause",
7: "Heating hotend",
8: "Calibrating extrusion",
9: "Scanning bed surface",
10: "Inspecting first layer",
11: "Identifying build plate",
12: "Calibrating Micro Lidar",
13: "Homing toolhead",
14: "Cleaning nozzle tip",
15: "Temp check",
16: "Paused by user",
17: "Front cover falling",
18: "Lidar calibration (alt)",
19: "Calibrating flow",
20: "Nozzle temp malfunction",
21: "Bed temp malfunction",
22: "Filament unloading",
23: "Skip step pause",
24: "Filament loading",
25: "Motor noise calibration",
26: "AMS lost pause",
27: "Fan speed pause",
28: "Chamber control error",
29: "Cooling chamber",
30: "Custom Gcode pause",
31: "Motor noise showoff",
32: "Nozzle cover pause",
33: "Cutter error pause",
34: "First layer error pause",
35: "Nozzle clog pause",
36: "Absolute accuracy pre-check",
37: "Chamber control",
38: "Absolute accuracy post-check",
39: "Nozzle Offset Calibration",
40: "Bed level high temperature",
41: "Check quick release",
42: "Check door and cover",
43: "Laser calibration",
44: "Check platform",
45: "Check birdeye camera position",
46: "Calibrate birdeye camera",
47: "Bed level phase 1",
48: "Bed level phase 2",
49: "Heating chamber",
50: "Heated bed cooling",
51: "Print calibration lines",
52: "Check material",
53: "Calibrating live view camera",
54: "Waiting for heatbed temperature",
55: "Check material position",
56: "Calibrating cutter model offset",
57: "Measuring surface",
58: "Thermal preconditioning",
70: "Leading filament",
71: "Reached toolhead",
72: "Grabbing filament",
73: "Purging",
74: "Homing toolhead",
75: "Returning to AMS",
76: "Cutting",
77: "Tool switching",
100: "Printing",
255: "Completed",
}
return stage_map.get(stage_int, f"Stage [{stage_int}]")
parse_nozzle_identifier
parse_nozzle_identifier(nozzle_id: str) -> tuple[NozzleFlowType, NozzleType, str]
Parse a Bambu-style nozzle identifier into flow family, material, and diameter.
Supported encoded formats include values such as HS00-0.4, HH01-0.6,
and HU00-0.4.
Returns
tuple[NozzleFlowType, NozzleType, str]
A tuple of (flow_type, nozzle_type, diameter).
Unknown/unsupported parts are returned as UNKNOWN enum values.
Source code in src/bpm/bambutools.py
def parse_nozzle_identifier(nozzle_id: str) -> tuple[NozzleFlowType, NozzleType, str]:
"""
Parse a Bambu-style nozzle identifier into flow family, material, and diameter.
Supported encoded formats include values such as `HS00-0.4`, `HH01-0.6`,
and `HU00-0.4`.
Returns
-------
tuple[NozzleFlowType, NozzleType, str]
A tuple of `(flow_type, nozzle_type, diameter)`.
Unknown/unsupported parts are returned as `UNKNOWN` enum values.
"""
if not nozzle_id:
return (NozzleFlowType.UNKNOWN, NozzleType.UNKNOWN, "")
clean = nozzle_id.strip()
if "-" in clean:
encoded, diameter = clean.split("-", 1)
else:
encoded, diameter = clean, ""
if len(encoded) < 4:
return (NozzleFlowType.UNKNOWN, NozzleType.UNKNOWN, diameter)
flow = _FLOW_CODE_TO_TYPE.get(encoded[1], NozzleFlowType.UNKNOWN)
material_code = encoded[2:4]
nozzle_type = _MATERIAL_CODE_TO_TYPE.get(material_code, NozzleType.UNKNOWN)
return (flow, nozzle_type, diameter)
parse_nozzle_type
parse_nozzle_type(value: str | None) -> NozzleType
Resolve a nozzle type from cross-model telemetry strings or encoded IDs.
Supports direct telemetry values (for example hardened_steel) and encoded
forms (for example HH01-0.4, HS00, HU05).
Source code in src/bpm/bambutools.py
def parse_nozzle_type(value: str | None) -> NozzleType:
"""
Resolve a nozzle type from cross-model telemetry strings or encoded IDs.
Supports direct telemetry values (for example `hardened_steel`) and encoded
forms (for example `HH01-0.4`, `HS00`, `HU05`).
"""
if value is None:
return NozzleType.UNKNOWN
clean = value.strip()
if not clean:
return NozzleType.UNKNOWN
telemetry_key = clean.lower()
if telemetry_key in _NOZZLE_TYPE_TELEMETRY_TO_ENUM:
return _NOZZLE_TYPE_TELEMETRY_TO_ENUM[telemetry_key]
if clean in _MATERIAL_CODE_TO_TYPE:
return _MATERIAL_CODE_TO_TYPE[clean]
_, nozzle_type, _ = parse_nozzle_identifier(clean)
if nozzle_type != NozzleType.UNKNOWN:
return nozzle_type
try:
return NozzleType[clean.upper()]
except (KeyError, ValueError):
return NozzleType.UNKNOWN
scaleFanSpeed
staticmethod
Scales proprietary 0-15 fan speed values to a 0-100 percentage.
sortFileTreeAlphabetically
staticmethod
Sorts a dict of file/directory nodes hierarchically.
Source code in src/bpm/bambutools.py
@staticmethod
def sortFileTreeAlphabetically(source) -> dict:
"""
Sorts a dict of file/directory nodes hierarchically.
"""
def sort_node_list(node_list):
for item in node_list:
if item.get("id", "").endswith("/") and "children" in item:
item["children"] = sort_node_list(item["children"])
return sorted(
node_list,
key=lambda i: (not i.get("id", "").endswith("/"), i.get("name", "").lower()),
)
source["children"] = sort_node_list(source["children"])
return source
unpackTemperature
staticmethod
Unpacks a 32-bit packed temperature integer into a tuple of (Actual, Target).