Files
cadSet/docs/build_cnc_first_integration_checklist.py
T

568 lines
37 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.
from pathlib import Path
from docx import Document
from docx.enum.section import WD_SECTION
from docx.enum.table import WD_CELL_VERTICAL_ALIGNMENT, WD_TABLE_ALIGNMENT
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from docx.shared import Inches, Pt, RGBColor
OUT = Path("/Users/jerry/linkhand/CadSet/docs/CNC机床系统对接技术需求清单.docx")
BLUE = "1F4E78"
LIGHT_BLUE = "DCE6F1"
PALE_BLUE = "EEF4F8"
GRAY = "666666"
LIGHT_GRAY = "F2F2F2"
GREEN = "E2F0D9"
AMBER = "FFF2CC"
RED = "FCE4D6"
WHITE = "FFFFFF"
BLACK = "111111"
def set_cell_shading(cell, fill):
tc_pr = cell._tc.get_or_add_tcPr()
shd = tc_pr.find(qn("w:shd"))
if shd is None:
shd = OxmlElement("w:shd")
tc_pr.append(shd)
shd.set(qn("w:fill"), fill)
def set_cell_margins(cell, top=90, start=110, bottom=90, end=110):
tc = cell._tc
tc_pr = tc.get_or_add_tcPr()
tc_mar = tc_pr.first_child_found_in("w:tcMar")
if tc_mar is None:
tc_mar = OxmlElement("w:tcMar")
tc_pr.append(tc_mar)
for margin, value in (("top", top), ("start", start), ("bottom", bottom), ("end", end)):
node = tc_mar.find(qn(f"w:{margin}"))
if node is None:
node = OxmlElement(f"w:{margin}")
tc_mar.append(node)
node.set(qn("w:w"), str(value))
node.set(qn("w:type"), "dxa")
def set_repeat_table_header(row):
tr_pr = row._tr.get_or_add_trPr()
tbl_header = OxmlElement("w:tblHeader")
tbl_header.set(qn("w:val"), "true")
tr_pr.append(tbl_header)
def keep_row_together(row):
tr_pr = row._tr.get_or_add_trPr()
cant_split = OxmlElement("w:cantSplit")
tr_pr.append(cant_split)
def set_table_fixed_width(table, widths):
table.autofit = False
table.alignment = WD_TABLE_ALIGNMENT.CENTER
tbl_pr = table._tbl.tblPr
tbl_layout = tbl_pr.find(qn("w:tblLayout"))
if tbl_layout is None:
tbl_layout = OxmlElement("w:tblLayout")
tbl_pr.append(tbl_layout)
tbl_layout.set(qn("w:type"), "fixed")
for row in table.rows:
for idx, width in enumerate(widths):
row.cells[idx].width = Inches(width)
tc_pr = row.cells[idx]._tc.get_or_add_tcPr()
tc_w = tc_pr.find(qn("w:tcW"))
if tc_w is None:
tc_w = OxmlElement("w:tcW")
tc_pr.append(tc_w)
tc_w.set(qn("w:w"), str(int(width * 1440)))
tc_w.set(qn("w:type"), "dxa")
def set_run(run, size=10.5, bold=False, color=BLACK, font="Arial"):
run.font.name = font
run._element.get_or_add_rPr().rFonts.set(qn("w:eastAsia"), font)
run.font.size = Pt(size)
run.bold = bold
run.font.color.rgb = RGBColor.from_string(color)
def add_text(paragraph, text, size=10.5, bold=False, color=BLACK):
run = paragraph.add_run(text)
set_run(run, size=size, bold=bold, color=color)
return run
def add_bullet(doc, text, level=0, bold_prefix=None):
p = doc.add_paragraph(style="List Bullet" if level == 0 else "List Bullet 2")
p.paragraph_format.space_after = Pt(3)
p.paragraph_format.line_spacing = 1.12
if bold_prefix and text.startswith(bold_prefix):
add_text(p, bold_prefix, bold=True)
add_text(p, text[len(bold_prefix):])
else:
add_text(p, text)
return p
def add_checkbox_line(doc, text, note=None):
p = doc.add_paragraph()
p.paragraph_format.left_indent = Inches(0.15)
p.paragraph_format.first_line_indent = Inches(-0.15)
p.paragraph_format.space_after = Pt(3)
add_text(p, "☐ ", size=11.5, bold=True, color=BLUE)
add_text(p, text, bold=True)
if note:
add_text(p, f" {note}", color=GRAY)
def add_callout(doc, label, text, fill=PALE_BLUE):
table = doc.add_table(rows=1, cols=1)
set_table_fixed_width(table, [6.5])
cell = table.cell(0, 0)
set_cell_shading(cell, fill)
set_cell_margins(cell, top=120, start=150, bottom=120, end=150)
p = cell.paragraphs[0]
p.paragraph_format.space_after = Pt(0)
add_text(p, f"{label}", bold=True, color=BLUE)
add_text(p, text)
doc.add_paragraph().paragraph_format.space_after = Pt(1)
def add_requirement_table(doc, rows):
table = doc.add_table(rows=1, cols=4)
table.style = "Table Grid"
widths = [0.72, 1.63, 2.55, 1.60]
set_table_fixed_width(table, widths)
headers = ["优先级", "向对方要什么", "具体内容", "拿到后用于什么"]
for i, text in enumerate(headers):
cell = table.rows[0].cells[i]
set_cell_shading(cell, BLUE)
set_cell_margins(cell)
cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
p = cell.paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
add_text(p, text, size=9.5, bold=True, color=WHITE)
set_repeat_table_header(table.rows[0])
for priority, ask, details, usage in rows:
row = table.add_row()
keep_row_together(row)
cells = row.cells
values = [priority, ask, details, usage]
fill = GREEN if priority == "必须" else (AMBER if priority == "建议" else WHITE)
for i, value in enumerate(values):
cell = cells[i]
set_cell_margins(cell)
cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
if i == 0:
set_cell_shading(cell, fill)
p = cell.paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.CENTER if i == 0 else WD_ALIGN_PARAGRAPH.LEFT
add_text(p, value, size=9.2, bold=(i in (0, 1)))
return table
def add_response_table(doc, rows):
table = doc.add_table(rows=1, cols=3)
table.style = "Table Grid"
set_table_fixed_width(table, [2.35, 2.15, 2.0])
for i, text in enumerate(["请确认", "对方填写/勾选", "附件或联系人"]):
cell = table.rows[0].cells[i]
set_cell_shading(cell, BLUE)
set_cell_margins(cell)
p = cell.paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
add_text(p, text, size=9.5, bold=True, color=WHITE)
set_repeat_table_header(table.rows[0])
for item, options in rows:
row = table.add_row()
keep_row_together(row)
cells = row.cells
for cell in cells:
set_cell_margins(cell, top=110, bottom=110)
cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
add_text(cells[0].paragraphs[0], item, size=9.3, bold=True)
add_text(cells[1].paragraphs[0], options, size=9.3)
add_text(cells[2].paragraphs[0], "________________", size=9.3, color=GRAY)
return table
def setup_document():
doc = Document()
section = doc.sections[0]
section.page_width = Inches(8.5)
section.page_height = Inches(11)
section.top_margin = Inches(0.65)
section.bottom_margin = Inches(0.65)
section.left_margin = Inches(0.72)
section.right_margin = Inches(0.72)
section.header_distance = Inches(0.3)
section.footer_distance = Inches(0.3)
styles = doc.styles
normal = styles["Normal"]
normal.font.name = "Arial"
normal._element.rPr.rFonts.set(qn("w:eastAsia"), "Arial")
normal.font.size = Pt(10.5)
normal.font.color.rgb = RGBColor.from_string(BLACK)
normal.paragraph_format.space_after = Pt(5)
normal.paragraph_format.line_spacing = 1.12
for name, size, before, after in (
("Heading 1", 16, 14, 7),
("Heading 2", 12.5, 10, 5),
("Heading 3", 11, 7, 3),
):
style = styles[name]
style.font.name = "Arial"
style._element.rPr.rFonts.set(qn("w:eastAsia"), "Arial")
style.font.size = Pt(size)
style.font.bold = True
style.font.color.rgb = RGBColor.from_string(BLUE)
style.paragraph_format.space_before = Pt(before)
style.paragraph_format.space_after = Pt(after)
style.paragraph_format.keep_with_next = True
for list_name in ("List Bullet", "List Bullet 2", "List Number"):
style = styles[list_name]
style.font.name = "Arial"
style._element.rPr.rFonts.set(qn("w:eastAsia"), "Arial")
style.font.size = Pt(10.5)
header = section.header
p = header.paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.RIGHT
add_text(p, "CNC 机床首次系统对接|资料与接口清单", size=8.5, color=GRAY)
footer = section.footer
p = footer.paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
add_text(p, "供机床制造商、三菱 CNC 技术人员及项目对接人共同确认", size=8, color=GRAY)
return doc
def build():
doc = setup_document()
p = doc.add_paragraph()
p.paragraph_format.space_before = Pt(8)
p.paragraph_format.space_after = Pt(3)
add_text(p, "CNC 机床系统对接技术需求清单", size=23, bold=True, color=BLUE)
p = doc.add_paragraph()
p.paragraph_format.space_after = Pt(12)
add_text(p, "目标:把数字零件模型接入实际机床,完成加工程序生成、程序传输、试切验证和加工结果回收。", size=11.5, color=GRAY)
add_callout(
doc,
"先说结论",
"第一次对接不需要把所有工业接口都拿到。最低闭环只需要四类东西:①准确的机床与 CNC 型号;"
"②机床专用编程资料;③一个可上传 NC 程序的通道;④一批已在该机床验证过的样例。"
"如果还要监控加工状态,再增加一个只读数据接口。",
GREEN,
)
doc.add_heading("1. 先找对人:三菱不一定等于机床厂", level=1)
add_bullet(doc, "机床制造商/集成商:掌握机床结构、轴配置、刀库、夹具、机床专用 M 代码、PLC 梯形图和安全联锁。")
add_bullet(doc, "三菱 CNC 或代理商:掌握控制器型号、系统版本、选件、通信软件、SDK、授权和标准接口。")
add_bullet(doc, "现场工艺/操作人员:掌握真实刀具、材料、转速进给、装夹、对刀、零点和已验证加工程序。")
add_callout(doc, "对接要求", "请甲方安排以上三类人员至少各一位。只找其中一方,通常拿不全资料。", AMBER)
doc.add_heading("2. 第一批必须拿到的材料", level=1)
required_rows = [
("必须", "设备身份资料", "机床品牌/完整型号/序列号;三菱 CNC 控制器系列和完整型号;系统软件版本;已安装选件清单。最好提供铭牌、控制柜和系统信息页面照片。", "决定能用哪些手册、接口和软件,避免按错型号开发。"),
("必须", "机床能力表", "车床/铣床/加工中心;轴数与轴名称;各轴行程;主轴数量、最高转速;最大进给;刀库类型和容量;是否有旋转轴、探针、自动对刀。", "确定模型是否可加工、工序怎么拆、刀路和后处理怎么生成。"),
("必须", "编程资料", "该型号 CNC 的编程/操作手册;机床厂专用操作手册;支持的 G/M/T/S 代码;自定义 M 代码;宏变量、坐标系、刀补和程序格式说明。", "生成该机床能真正执行的 NC 程序。"),
("必须", "已验证样例包", "至少 3~10 个已加工成功的样件,每个样件尽量包含 STEP/二维图、NC 程序、材料、毛坯、刀具表、装夹说明、坐标原点及最终检测结果。", "建立正确后处理和参数基线,比只有说明书更有效。"),
("必须", "程序传输方式", "确认机床当前如何收发加工程序:以太网软件、FTP、共享目录、串口、USB 或其他;提供网络配置方法、账号权限、目录规则和文件名限制。", "打通“生成程序→送入机床”的最小闭环。"),
("建议", "CAM/后处理资料", "现用 CAM 名称和版本;现有后处理器;后处理配置;机床仿真模型/运动学文件;程序头尾模板。", "优先复用成熟后处理,减少试切风险。"),
("建议", "刀具与工艺资料", "真实刀具/刀柄清单、刀具编号、长度直径范围;常用材料与毛坯;推荐转速进给、冷却方式、余量、公差和粗糙度。", "把几何模型转换成可执行工艺,而不是只生成外形。"),
("建议", "备份与恢复资料", "当前 CNC 参数、刀补、宏变量、PLC/梯形图及机床厂数据的备份方式;试验前完整备份;恢复负责人。", "调试异常时可恢复,避免影响生产。"),
]
add_requirement_table(doc, required_rows)
doc.add_heading("3. 接口怎么问:不用一上来就说“把 API 都给我”", level=1)
add_callout(
doc,
"正确问法",
"请对方根据实际 CNC 型号勾选已经安装、可以授权或可以新增的通道。我们的优先顺序是:"
"先解决程序文件传输,再解决只读监控,最后才考虑自动写变量或远程控制。",
PALE_BLUE,
)
doc.add_heading("3.1 上传和下载加工程序(第一优先级)", level=2)
add_checkbox_line(doc, "NC Explorer", "三菱官方工具,可通过以太网在电脑与多台 CNC 间操作加工程序文件;需确认该控制器是否支持。")
add_checkbox_line(doc, "FTP / 共享目录 / 机床厂文件服务", "如果机床已经开放,提供 IP、端口、目录、账号、字符编码和文件名规则。")
add_checkbox_line(doc, "RS-232C / USB", "可作为初期人工导入或旧机型兜底,但不适合长期自动闭环。")
add_checkbox_line(doc, "机床厂自带 DNC/MDC/MES 软件", "提供产品名称、接口文档和第三方接入方法。")
doc.add_heading("3.2 读取运行状态和加工结果(第二优先级)", level=2)
add_checkbox_line(doc, "MTConnect", "适合读取运行、报警、状态等数据;通常为只读,安全性高,适合第一阶段监控。")
add_checkbox_line(doc, "OPC UA / NC Machine Tool Connector", "适合统一采集机床数据;需确认 OPC UA 服务器、节点表、证书、许可证和实际开放变量。")
add_checkbox_line(doc, "NC Monitor2 或甲方现有监控平台", "如果只需要人工远程查看,可先使用现成工具;若要系统接入,仍需确认是否提供数据接口。")
add_checkbox_line(doc, "数据库/文件导出", "若没有实时接口,可先通过班次 CSV、报警日志或加工结果文件实现离线回传。")
doc.add_heading("3.3 读写 CNC 数据或做深度集成(第三优先级)", level=2)
add_checkbox_line(doc, "FCSB1224W000 开发包(SDK", "三菱 CNC 通信软件的开发版;需索取安装包、许可证、参考手册、头文件/库和 C#/C++ 示例。")
add_checkbox_line(doc, "FCSB1224W100 运行库", "部署自行开发的 Windows 程序时可能需要;版本应与 SDK 和 CNC 兼容。")
add_checkbox_line(doc, "SLMP / PLC 设备访问", "仅在机床厂确实开放 PLC 设备映射时考虑;必须索取设备地址表、读写权限和联锁说明。")
add_checkbox_line(doc, "机床厂专用 API", "若机床厂对三菱 CNC 做过二次开发,应优先获取其 API,而不是绕过机床安全逻辑直接写控制器。")
add_callout(
doc,
"安全边界",
"第一阶段只申请“程序上传”和“状态读取”。不要直接申请自动启动主轴、循环启动、写 PLC 或修改 CNC 参数。"
"远程启动必须经过机床厂安全评审、现场联锁和甲方书面批准。",
RED,
)
doc.add_heading("4. 每一种接口要对方同时交付什么", level=1)
api_rows = [
("必须", "兼容性确认", "适用 CNC 型号、系统版本、所需硬件/选件、是否已安装、许可证数量和有效期。", "防止拿到软件但现场不能用。"),
("必须", "开发资料", "API/协议手册、数据字典、错误码、示例程序、SDK/运行库安装包、版本说明。", "完成可维护的接口开发。"),
("必须", "连接参数", "IP、端口、协议版本、账号/证书、读写权限、超时、并发和频率限制。", "建立测试连接。"),
("必须", "测试环境", "一台可调试机床或离线仿真环境;测试账号;允许上传的测试目录;测试窗口。", "不在生产机上盲调。"),
("建议", "现场支持", "机床厂电气/PLC 工程师、三菱 CNC 工程师、操作员的联系人和联合调试时间。", "遇到权限、联锁和型号差异时及时定位。"),
]
add_requirement_table(doc, api_rows)
doc.add_heading("5. 给甲方/制造商的回填表", level=1)
p = doc.add_paragraph()
add_text(p, "请对方直接填写或勾选;不确定的项目可写“待三菱/机床厂确认”。", color=GRAY)
response_rows = [
("机床制造商、型号、序列号", "填写完整型号"),
("三菱 CNC 型号与系统版本", "填写/附系统页面照片"),
("机床类型与轴配置", "车 / 铣 / 加工中心;3/4/5 轴"),
("现用 CAM 与后处理器", "有 / 无;名称和版本"),
("现有程序传输方式", "NC Explorer / FTP / DNC / RS-232C / USB / 其他"),
("可否提供通信 SDK", "FCSB1224W000 / 其他 / 不支持"),
("可否提供只读数据接口", "MTConnect / OPC UA / 其他 / 不支持"),
("可否提供测试环境", "离线仿真 / 测试机 / 生产机测试窗口"),
("可否提供已验证样例包", "数量:____;包含 STEP+NC+刀具+材料:是 / 否"),
("机床厂技术联系人", "机械 / 电气PLC / 工艺"),
("三菱或代理商技术联系人", "CNC / 通信软件 / 授权"),
]
add_response_table(doc, response_rows)
doc.add_heading("6. 第一次会议照着问的 12 个问题", level=1)
questions = [
"这台机床的完整型号是什么?三菱 CNC 的完整型号和系统版本是什么?",
"机床是几轴?各轴行程、主轴、刀库和可加工范围是多少?",
"现在工程师用什么 CAM 和后处理器生成程序?能否提供现有后处理?",
"能否给 3~10 套已经加工成功的完整样例,而不只是 NC 文件?",
"机床现在通过什么方式接收和导出加工程序?",
"是否支持 NC Explorer?现场是否已经配置以太网?",
"这个型号是否支持 FCSB1224W000?许可证、SDK 和运行库由谁提供?",
"是否已经有 MTConnect、OPC UA、MDC、MES 或机床监控系统?",
"我们能读取哪些数据:运行状态、当前程序、坐标、刀具、报警、主轴负载、加工结果?",
"第一阶段能否提供测试机或仿真环境,并允许只上传程序、不自动启动?",
"试验前谁负责备份 CNC 参数、PLC、宏变量和刀补?出现问题谁负责恢复?",
"机床厂、三菱、现场工艺三方各由谁负责,何时可以联合调试?",
]
for i, question in enumerate(questions, 1):
p = doc.add_paragraph(style="List Number")
p.paragraph_format.space_after = Pt(3)
add_text(p, question)
doc.add_heading("7. 建议甲方首批打包提供的文件夹", level=1)
add_callout(
doc,
"一个压缩包即可",
"01_设备铭牌与系统照片;02_机床与 CNC 手册;03_GM代码和机床专用说明;"
"04_已验证样例;05_CAM与后处理;06_刀具材料工艺;07_通信软件与接口文档;"
"08_网络与测试环境;09_联系人。",
LIGHT_BLUE,
)
doc.add_heading("8. CAD、CAM 与机床数字模型资料", level=1)
add_callout(
doc,
"为什么必须补这一部分",
"STEP 只能说明零件几何,不能直接告诉机床如何装夹、选刀和运动。"
"要稳定生成 NC 程序,还需要机床、刀具、夹具、毛坯和坐标系数据。",
PALE_BLUE,
)
cadcam_rows = [
("必须", "零件数据规范", "确认接收 STEP AP203/AP214/AP242 中哪一种;长度单位;坐标方向;模型原点;实体/装配要求;允许的几何修复;二维图、尺寸公差和表面粗糙度如何提供。", "建立统一输入标准,避免比例、方向、基准和公差信息丢失。"),
("必须", "机床运动学", "各线性轴和旋转轴名称、正方向、行程、零点、回转中心、轴顺序、软限位、主轴方向;五轴机需提供 RTCP/TCP 相关配置。", "建立正确后处理和碰撞仿真。"),
("必须", "坐标与对刀规则", "机床坐标、工件坐标 G54~G59/扩展坐标、程序零点、对刀点、刀长/刀径补偿号规则、探针和自动对刀流程。", "保证程序中的坐标与现场实际一致。"),
("必须", "刀具与刀柄模型", "实际刀具、刀柄、延长杆和刀盘的清单及 STEP/尺寸;刀位号、刀补号、最大直径长度重量、相邻刀位限制。", "选刀、计算切削参数并检查刀具/刀柄碰撞。"),
("必须", "夹具与工作区模型", "工作台、卡盘、虎钳、软爪、尾座、第四/第五轴、探针及主要防护区域的 STEP 或关键尺寸。", "规划装夹、可达性和碰撞检查。"),
("必须", "毛坯和材料规则", "常用棒料、板料、锻件、铸件规格;材料牌号;毛坯余量;硬度和热处理状态;是否允许自动推荐替代材料。", "生成合理工序、刀路和切削参数。"),
("建议", "机床仿真模型", "机床厂/CAM 使用的数字机床包、运动学文件、碰撞体、控制器定义和现有仿真项目。", "缩短虚拟调试和后处理验证周期。"),
]
add_requirement_table(doc, cadcam_rows)
doc.add_heading("9. 后处理器和 NC 程序规则", level=1)
post_rows = [
("必须", "程序格式限制", "程序号格式、文件扩展名、字符编码、行号、注释规则、最大文件大小、程序存储路径、子程序路径及程序调用层级限制。", "确保文件能够被控制器识别和加载。"),
("必须", "标准代码清单", "实际支持的 G/M/T/S/F 代码、固定循环、极坐标/坐标旋转、刀补、螺纹、刚性攻丝、高速高精功能及版本差异。", "限制程序生成器只能使用现场支持的指令。"),
("必须", "机床厂专用逻辑", "换刀、开关门、夹紧松开、卡盘/尾座、冷却、排屑、探针、托盘等自定义 M 代码;执行前置条件和互锁。", "避免使用通用 M 代码猜测机床动作。"),
("必须", "程序头尾模板", "提供一份机床厂认可的开头、换刀段、工序切换、异常退出和结束模板;明确安全位置和模态复位要求。", "统一安全启动与结束逻辑。"),
("必须", "后处理验收样例", "选择典型 2.5D、孔系、曲面或车削样件;提供 CAM 刀路、输出 NC、仿真结果和现场实际程序的对照。", "验证后处理输出与现场一致。"),
("建议", "控制器高级选件", "确认高速加工、五轴联动、刀尖点控制、前瞻、样条/NURBS、宏程序等功能是否购买并启用。", "避免生成未授权或不支持的功能。"),
]
add_requirement_table(doc, post_rows)
doc.add_heading("10. 需要读取的数据点清单", level=1)
add_callout(
doc,
"让对方逐项标注",
"每个数据点请填写:是否可读、来自哪个接口、字段/节点地址、数据类型、单位、刷新周期、时间戳、"
"枚举含义、无效值和报警条件。不要只回复“支持 OPC UA”或“支持 API”。",
AMBER,
)
datapoint_rows = [
("必须", "设备与连接状态", "设备 ID、CNC 型号、系统版本、在线/离线、数据源状态、采集程序版本、最后更新时间。", "识别设备并判断数据是否可信。"),
("必须", "运行状态", "自动/手动/MDI、运行/暂停/停止/报警/急停、循环启动状态、单段、选择停止、门和关键联锁状态。", "判断设备是否正在执行及为何停机。"),
("必须", "程序执行", "当前程序号/文件名、子程序、当前行号或序列号、程序开始结束时间、循环时间、加工计数。", "把加工任务与实际执行记录关联。"),
("必须", "轴与坐标", "机床坐标、工件坐标、剩余移动量、进给速度、进给倍率、各轴负载、旋转轴角度;单位和坐标系标识。", "监控运动并分析异常。"),
("必须", "主轴数据", "实际/指令转速、倍率、负载、扭矩或功率、运行方向、主轴状态、温度(若有)。", "分析切削负载和加工状态。"),
("必须", "刀具数据", "当前刀号、刀位、刀长/刀径补偿、寿命/使用次数、刀具报警、备用刀及刀具表更新时间。", "检查程序选刀并积累刀具寿命数据。"),
("必须", "报警与诊断", "报警号、等级、文本、发生/解除时间、报警历史、控制器诊断状态;明确是否能读取机床厂 PLC 报警。", "故障追踪和自动告警。"),
("建议", "加工与质量结果", "完工状态、实际周期、零件计数、测头结果、尺寸检测、报废/返工原因、操作员确认。", "形成加工结果闭环。"),
("建议", "能耗与维护", "主轴运行时长、开机时间、润滑/冷却状态、过滤器、维护计数及能耗数据(若设备已有)。", "支持后续维护和效率分析。"),
]
add_requirement_table(doc, datapoint_rows)
doc.add_heading("11. 通信接口的工程参数", level=1)
comm_rows = [
("必须", "方向与权限", "明确每个接口是只读、文件上传下载、数据读写还是远程控制;列出允许和禁止的操作。", "划定安全边界。"),
("必须", "性能指标", "刷新周期、最小采样间隔、单次/批量读取数量、并发连接数、最大文件大小、传输速率和超时时间。", "评估能否满足监控和任务下发。"),
("必须", "可靠性机制", "断线检测、自动重连、续传、重复提交处理、任务唯一 ID、校验和、确认回执和错误码。", "避免程序重复上传、丢失或状态误判。"),
("必须", "时间与单位", "CNC 时间设置、时区、NTP/PTP 支持、时间戳精度;坐标、转速、负载等字段的单位与缩放系数。", "保证多系统数据可对齐。"),
("必须", "版本管理", "SDK/运行库/协议版本与 CNC 版本兼容矩阵;升级策略;弃用接口;补丁和技术支持期限。", "避免现场升级后接口失效。"),
("建议", "日志与审计", "连接日志、文件传输记录、调用方、操作时间、操作结果、配置修改和远程访问记录。", "故障定位和责任追踪。"),
]
add_requirement_table(doc, comm_rows)
doc.add_heading("12. 网络与信息安全要求", level=1)
security_rows = [
("必须", "网络拓扑", "机床所在网段、工业交换机、防火墙/隔离区、是否允许新增工控机、跨网访问方式和负责网络变更的人员。", "确定系统部署位置和连接路径。"),
("必须", "端口白名单", "逐项提供协议、源/目的 IP、TCP/UDP 端口、连接方向;禁止使用不受控的全网开放规则。", "完成最小权限网络配置。"),
("必须", "账号与证书", "账号类型、角色权限、密码策略、证书签发/更新、密钥保存、账号停用流程;禁止共享管理员账号。", "安全且可审计地访问设备。"),
("必须", "远程支持方案", "是否允许 VPN、堡垒机或厂商远程服务;审批流程、开放时间、录屏/审计和紧急断开方法。", "让远程调试可控。"),
("必须", "备份和变更控制", "CNC 参数、PLC、刀补、宏变量、接口配置的基线备份;变更申请、回退方案、恢复演练和负责人。", "降低调试对生产的风险。"),
("建议", "数据合规", "允许采集的数据范围、数据保存期限、技术图纸和 NC 程序的保密等级、外发和云端限制。", "明确数据能否用于分析和优化。"),
]
add_requirement_table(doc, security_rows)
doc.add_heading("13. 分阶段联调与验收标准", level=1)
acceptance_rows = [
("阶段 0", "资料审查", "型号、手册、代码表、样例、接口和许可证齐全;双方确认未知项和责任人。", "输出《设备接口基线表》。"),
("阶段 1", "离线后处理", "使用已验证样例生成 NC;与现场程序对比;通过 CAM/控制器仿真,无语法错误和明显碰撞。", "后处理器可进入现场试验。"),
("阶段 2", "程序传输", "上传、下载、覆盖保护、目录、文件名、校验、断线重试和回执测试通过;不启动机床。", "打通安全文件通道。"),
("阶段 3", "空运行验证", "机床锁定/抬刀/单段/低倍率条件下执行;核对坐标、刀具、换刀、行程和安全位置。", "证明程序与机床配置一致。"),
("阶段 4", "试切验收", "指定毛坯、刀具和装夹;加工样件;记录周期、报警、刀具和检测结果;尺寸及表面质量达到双方确认标准。", "证明可实际制造。"),
("阶段 5", "数据回传", "运行状态、程序、坐标、刀具、主轴和报警等约定数据点连续采集;断线恢复和时间戳正确。", "形成加工状态闭环。"),
("阶段 6", "试运行", "限定设备、班次和零件类型运行;统计成功率、人工干预、报警和返工;完成问题清单后转正式。", "控制上线风险。"),
]
add_requirement_table(doc, acceptance_rows)
doc.add_heading("14. 项目责任、商务和交付边界", level=1)
boundary_rows = [
("必须", "责任分工", "明确机床厂、三菱/代理商、甲方工艺/设备/网络人员和软件对接方各自负责的资料、配置、调试和验收内容。", "避免接口问题互相推诿。"),
("必须", "授权和费用", "SDK、运行库、OPC UA/MTConnect、仿真软件、后处理器、现场服务、培训和年度维护分别是否收费。", "形成真实预算。"),
("必须", "交付介质", "安装包、许可证文件、离线授权方式、手册、样例代码、源代码范围、版本号、校验值和下载有效期。", "保证后续可复现部署。"),
("必须", "支持机制", "工作时间、响应时限、问题升级路径、远程/现场支持、版本升级和保修期。", "确保问题有闭环负责人。"),
("建议", "培训与知识转移", "操作、编程、通信 SDK、数据接口、备份恢复和安全联调培训;提供录屏或培训材料。", "减少长期依赖单个厂商工程师。"),
]
add_requirement_table(doc, boundary_rows)
doc.add_heading("15. 最终要求对方交付的核心成果", level=1)
core_rows = [
("P0", "设备接口基线表", "每台机床一份:完整型号、CNC 版本、轴/主轴/刀库、选件、程序传输方式、可用接口、网络和联系人。", "没有这份表,不进入开发。"),
("P0", "机床编程资料包", "CNC 手册、机床厂手册、G/M 代码、专用 M 代码、程序模板、坐标/刀补/换刀规则。", "用于生成安全 NC 程序。"),
("P0", "验证样例包", "至少 3~10 套 STEP/图纸、毛坯、刀具、装夹、CAM、NC 和检测结果一一对应的完整样例。", "用于后处理和工艺验证。"),
("P1", "通信接口包", "SDK/运行库或协议文档、许可证、样例代码、数据字典、地址/节点表、错误码和兼容矩阵。", "用于程序传输和数据采集。"),
("P1", "测试与验收环境", "离线仿真或测试机、测试账号/目录、网络窗口、备份、现场人员和验收样件。", "用于安全联调。"),
("P2", "数字机床资料包", "机床、刀具、刀柄、夹具和毛坯模型;运动学;软限位;碰撞体;CAM 仿真工程。", "用于规模化自动编程和虚拟验证。"),
]
add_requirement_table(doc, core_rows)
doc.add_heading("附 A:不同机床类型还要追加确认什么", level=1)
machine_rows = [
("车床", "卡盘/夹头、主轴/副主轴、尾座、刀塔、动力刀具、Y/C/B 轴、棒料机、接料器和螺纹循环。"),
("三轴加工中心", "工作台尺寸、主轴锥度、刀库、换刀位置、探针、第四轴接口、固定循环和高速加工选件。"),
("四/五轴加工中心", "旋转轴结构、回转中心、轴限位、TCP/RTCP、刀尖点控制、奇异点策略、机床运动学和精确碰撞模型。"),
("车铣复合", "多通道/多系统、主副主轴同步、刀塔同步、程序等待码、工件交接、通道间变量和完整同步样例。"),
("磨床/专机", "砂轮修整、补偿、测量循环、专用 PLC 动作、机床厂自定义程序格式和专用工艺数据库。"),
]
table = doc.add_table(rows=1, cols=2)
table.style = "Table Grid"
set_table_fixed_width(table, [1.35, 5.15])
for i, text in enumerate(["机床类型", "追加资料"]):
set_cell_shading(table.rows[0].cells[i], BLUE)
set_cell_margins(table.rows[0].cells[i])
p = table.rows[0].cells[i].paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
add_text(p, text, size=9.5, bold=True, color=WHITE)
set_repeat_table_header(table.rows[0])
for machine_type, extra in machine_rows:
row = table.add_row()
keep_row_together(row)
for cell in row.cells:
set_cell_margins(cell)
cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
add_text(row.cells[0].paragraphs[0], machine_type, size=9.3, bold=True)
add_text(row.cells[1].paragraphs[0], extra, size=9.3)
doc.add_heading("附 B:三菱侧可供确认的典型产品名称", level=1)
p = doc.add_paragraph()
add_text(
p,
"以下只是对接时用于询问的候选名称,并不表示每台机床都具备:NC Explorer(程序文件传输)、"
"FCSB1224W000/W100CNC 通信 SDK/运行库)、MTConnect Data Collector、"
"NC Machine Tool ConnectorOPC UA)、NC Monitor2、NC Virtual Simulator、NC Trainer2 plus。",
size=9.5,
color=GRAY,
)
p = doc.add_paragraph()
p.paragraph_format.space_before = Pt(3)
add_text(
p,
"确认原则:以机床铭牌、CNC 型号、系统版本、已购选件及机床厂书面答复为准。",
size=9.5,
bold=True,
color=BLUE,
)
doc.add_heading("附 C:三菱官方参考入口", level=1)
official_sources = [
("NC 软件工具总览", "确认 NC Explorer、NC Monitor2、NC Virtual Simulator、NC Trainer2 plus 等工具。", "https://www.mitsubishielectric.com/fa/products/software/cnc/index.html"),
("NC Explorer", "官方说明其通过以太网在 Windows 资源管理器中操作 CNC 加工程序文件。", "https://us.mitsubishielectric.com/fa/en/products/cnt/computerized-numerical-controllers/software-tools/nc-explorer/"),
("FCSB1224W000 通信软件手册", "确认 SDK、运行库、支持控制器、开发语言和 API 能力。", "https://dl.mitsubishielectric.com/dl/fa/document/manual/cnc/ib1501209/ib1501209engh.pdf"),
("MTConnect Data Collector", "确认支持的 CNC、适配器、采集器和系统要求。", "https://www.mitsubishielectric.com/fa/products/cnt/cnc/pmerit/iot/mtconnect_data_collector/"),
("NC Machine Tool Connector", "确认 OPC UA/MTConnect 数据采集、连接对象和许可要求。", "https://dl.mitsubishielectric.com/dl/fa/document/manual/cnc/ib1501634/ib1501634engd.pdf"),
("三菱 CNC 手册下载", "按实际 CNC 型号和版本下载规格、编程、操作、连接和设置手册。", "https://www.mitsubishielectric.com/fa/download/search.page?kisyu=%2Fcnc&mode=manual"),
]
source_table = doc.add_table(rows=1, cols=3)
source_table.style = "Table Grid"
set_table_fixed_width(source_table, [1.55, 2.55, 2.40])
for i, text in enumerate(["官方入口", "用于确认", "网址"]):
set_cell_shading(source_table.rows[0].cells[i], BLUE)
set_cell_margins(source_table.rows[0].cells[i])
p = source_table.rows[0].cells[i].paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
add_text(p, text, size=9.3, bold=True, color=WHITE)
set_repeat_table_header(source_table.rows[0])
for name, use, url in official_sources:
row = source_table.add_row()
keep_row_together(row)
for cell in row.cells:
set_cell_margins(cell)
cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
add_text(row.cells[0].paragraphs[0], name, size=8.7, bold=True)
add_text(row.cells[1].paragraphs[0], use, size=8.7)
add_text(row.cells[2].paragraphs[0], url, size=7.8, color=BLUE)
OUT.parent.mkdir(parents=True, exist_ok=True)
doc.save(OUT)
print(OUT)
if __name__ == "__main__":
build()