Files
A1SwapModPacker/a1_swap_mod_packer/printer.py
T

106 lines
3.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""打印机发送模块:通过局域网将 3MF 发送到 Bambu A1 并开始打印。"""
from __future__ import annotations
from pathlib import Path
from dataclasses import dataclass
@dataclass
class PrinterConfig:
"""打印机连接配置。"""
ip: str = "" # 打印机 IP 地址
access_code: str = "" # 局域网访问码
serial: str = "" # 打印机序列号
def check_printer_ready(config: PrinterConfig) -> bool:
"""检查打印机是否空闲可接收新任务。
返回 True 表示打印机空闲,False 表示正忙或离线。
"""
from bambulabs_api import Printer as BambuPrinter
from bambulabs_api.states_info import GcodeState
printer = BambuPrinter(config.ip, config.access_code, config.serial)
try:
printer.connect()
state = printer.get_state()
return state == GcodeState.IDLE
except Exception:
return False
finally:
printer.disconnect()
def _start_print_for_a1(printer, file_name: str, plate_number: int = 1) -> None:
"""发送打印机开始打印的 MQTT 指令,使用 A1 专用的 sdcard URL 格式。
bambulabs_api 的 start_print 方法硬编码了 ftp:/// 前缀,
这对 A1 不生效。A1 需要 file:///sdcard/ 前缀。
本函数绕过 start_print,直接构造正确的 MQTT 载荷。
"""
plate_location = f"Metadata/plate_{int(plate_number)}.gcode"
payload = {
"print": {
"command": "project_file",
"param": plate_location,
"file": file_name,
"bed_leveling": True,
"bed_type": "textured_plate",
"flow_cali": True,
"vibration_cali": True,
"url": f"file:///sdcard/{file_name}",
"layer_inspect": False,
"sequence_id": "10000000",
"use_ams": True,
"ams_mapping": [0],
}
}
# 调用名称改写后的私有方法发送原始 JSON 荷载
printer.mqtt_client._PrinterMQTTClient__publish_command(payload)
def send_to_printer(file_path: Path, config: PrinterConfig) -> bool:
"""将 3MF 文件上传至 A1 打印机并通过局域网开始打印。
发送前会检查打印机状态;正忙则拒绝发送。
⚠️ 仅支持本地局域网,电脑与打印机必须在同一网络下。
Args:
file_path: 要发送的 3MF 文件路径
config: 打印机连接配置
Returns:
True 表示成功
Raises:
ImportError: bambulabs_api 未安装
RuntimeError: 打印机正忙或上传/打印失败
"""
from bambulabs_api import Printer as BambuPrinter
from bambulabs_api.states_info import GcodeState
printer = BambuPrinter(config.ip, config.access_code, config.serial)
try:
printer.connect()
# 检查打印机是否空闲
state = printer.get_state()
if state != GcodeState.IDLE:
raise RuntimeError(
f"打印机当前状态为 {state.value}"
f"无法开始新任务。请等待当前打印完成。"
)
file_name = file_path.name
with open(file_path, "rb") as f:
import io
result = printer.upload_file(io.BytesIO(f.read()), file_name)
if "226" not in result:
raise RuntimeError(f"上传文件失败: {result}")
# 使用 A1 专用的 MQTT 指令开始打印,而非内置的 start_print
_start_print_for_a1(printer, file_name, plate_number=1)
return True
finally:
printer.disconnect()