fix(printer): 修复A1打印发送,绕过bambulabs_api的ftp URL问题,改用sdcard路径
This commit is contained in:
@@ -75,7 +75,7 @@
|
||||
"gui.output.printer.ip": "IP Address",
|
||||
"gui.output.printer.access_code": "Access Code",
|
||||
"gui.output.printer.serial": "Serial",
|
||||
"gui.output.printer.send.tooltip": "Send the generated 3MF to an A1 printer over LAN and start printing",
|
||||
"gui.output.printer.send.tooltip": "Send the generated 3MF to an A1 printer over LAN and start printing (LAN only — computer and printer must be on the same local network)",
|
||||
|
||||
"gui.dialog.individual_batch.title": "Individual Batch Mode",
|
||||
"gui.dialog.individual_batch.text": "Individual batch mode treats every input row as a separate build.\n\nExample: if you add 20 single-plate 3MF files and set copies to 5, Build 3MF will create 20 separate packed files. Each output contains only that source file repeated 5 times.\n\nThis is useful for quickly batch-converting many independent 3MF jobs into multi-copy SwapMod packs. It does not combine all input files into one 3MF.",
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
"gui.output.printer.ip": "IP 地址",
|
||||
"gui.output.printer.access_code": "访问码",
|
||||
"gui.output.printer.serial": "序列号",
|
||||
"gui.output.printer.send.tooltip": "通过局域网将生成的 3MF 发送到 A1 打印机并开始打印",
|
||||
"gui.output.printer.send.tooltip": "通过局域网将生成的 3MF 发送到 A1 打印机并开始打印(仅支持本地局域网,电脑与打印机需在同一网络下)",
|
||||
|
||||
"gui.dialog.individual_batch.title": "独立批处理模式",
|
||||
"gui.dialog.individual_batch.text": "独立批处理模式将每一行输入作为独立的构建任务。\n\n示例:如果你添加了 20 个单板 3MF 文件并设置份数为 5,点击\"构建 3MF\"将创建 20 个独立的打包文件。每个输出文件仅包含该源文件重复 5 次的内容。\n\n这个功能适用于快速将大量独立的 3MF 作业批量转换为多份数的 SwapMod 包。它不会将所有输入文件合并到一个 3MF 中。",
|
||||
|
||||
@@ -4,6 +4,7 @@ from __future__ import annotations
|
||||
from pathlib import Path
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class PrinterConfig:
|
||||
"""打印机连接配置。"""
|
||||
@@ -11,32 +12,94 @@ class PrinterConfig:
|
||||
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 文件上传至打印机并开始打印。
|
||||
"""将 3MF 文件上传至 A1 打印机并通过局域网开始打印。
|
||||
|
||||
发送前会检查打印机状态;正忙则拒绝发送。
|
||||
⚠️ 仅支持本地局域网,电脑与打印机必须在同一网络下。
|
||||
|
||||
Args:
|
||||
file_path: 要发送的 3MF 文件路径
|
||||
config: 打印机连接配置
|
||||
|
||||
Returns:
|
||||
True 表示成功,False 表示失败
|
||||
True 表示成功
|
||||
|
||||
Raises:
|
||||
ImportError: bambulabs_api 未安装
|
||||
Exception: 连接或上传失败
|
||||
RuntimeError: 打印机正忙或上传/打印失败
|
||||
"""
|
||||
# 延迟导入,避免在没有 bambulabs_api 时报错
|
||||
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}")
|
||||
printer.start_print(file_name, plate_number=1)
|
||||
|
||||
# 使用 A1 专用的 MQTT 指令开始打印,而非内置的 start_print
|
||||
_start_print_for_a1(printer, file_name, plate_number=1)
|
||||
return True
|
||||
finally:
|
||||
printer.disconnect()
|
||||
|
||||
Reference in New Issue
Block a user