bambutools
Classes:
| Name | Description |
|---|---|
AMSControlCommand |
AMS Control Commands enum |
AMSHeatingState |
Heater-to-Dryer states. |
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. |
ExtruderInfoState |
Consolidated logical states for extruder sensor status. |
ExtruderStatus |
Operational states for physical extruders. |
NozzleDiameter |
Nozzle Diameter enum |
NozzleType |
Nozzle Type enum |
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 |
|---|---|
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 Heater state from the AMS Info attribute |
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. |
parseAMSInfo |
Extracts all established telemetry attributes from the info integer. |
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. |
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
AMSHeatingState
Bases: IntEnum
Heater-to-Dryer states. Mapped from telemetry values and decimal shifts.
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.
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
NozzleType
Bases: Enum
Nozzle Type enum
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.
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 Heater state from the AMS Info attribute
Source code in src/bpm/bambutools.py
@staticmethod
def getAMSHeatingState(ams_info: int) -> AMSHeatingState:
"""
Decodes the AMS Heater state from the AMS Info attribute
"""
# 1. Primary Power Threshold
if ams_info < 2000 and ams_info != 1002:
return AMSHeatingState.NO_POWER
# 2. Extract Universal Remainder (Strips 99-point model offset)
status_rem = ams_info % 100
is_high_power = ams_info >= 100000
# 3. High Power Bus Logic
if is_high_power:
# 142113, 142123, 142024
if status_rem in [13, 23, 24]:
return AMSHeatingState.HEATING
# 142103, 142014
return AMSHeatingState.POSTHEATING
# 4. Local Bus Logic (+10 / +20 transitions)
if status_rem in [13, 24]:
return AMSHeatingState.PREHEATING
if status_rem == 23:
return AMSHeatingState.HEATING
return AMSHeatingState.IDLE
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.
parseAMSInfo
staticmethod
Extracts all established telemetry attributes from the info integer. Verified offsets: 0, 4, 8, 17, 18, 20, 22.
Source code in src/bpm/bambutools.py
@staticmethod
def parseAMSInfo(info: int) -> dict:
"""
Extracts all established telemetry attributes from the info integer.
Verified offsets: 0, 4, 8, 17, 18, 20, 22.
"""
extruder_id = (info >> 8) & 0x0F
# 11 and 10 == 1 and 0
# 8 and 7 == 1 and 0
if extruder_id in (8, 11):
h2d_toolhead_index = 1
else:
h2d_toolhead_index = 0
ret = {
"extruder_id": extruder_id,
"h2d_toolhead_index": h2d_toolhead_index,
"heater_state": getAMSHeatingState(info),
}
# 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",
37: "Chamber control",
38: "Chamber pre-heat (Legacy)",
39: "Nozzle Offset Calibration",
49: "Heating chamber",
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}]")
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).