feat: strengthen CAD experience distillation and routing
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,319 @@
|
||||
from pathlib import Path
|
||||
|
||||
from docx import Document
|
||||
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
|
||||
|
||||
from build_cnc_first_integration_checklist import (
|
||||
AMBER,
|
||||
BLACK,
|
||||
BLUE,
|
||||
GRAY,
|
||||
GREEN,
|
||||
LIGHT_BLUE,
|
||||
PALE_BLUE,
|
||||
WHITE,
|
||||
add_callout,
|
||||
add_text,
|
||||
keep_row_together,
|
||||
set_cell_margins,
|
||||
set_cell_shading,
|
||||
set_repeat_table_header,
|
||||
set_table_fixed_width,
|
||||
)
|
||||
|
||||
|
||||
OUT = Path("/Users/jerry/linkhand/CadSet/docs/CNC机床系统对接资料与技术支持需求函.docx")
|
||||
|
||||
|
||||
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.7)
|
||||
section.bottom_margin = Inches(0.7)
|
||||
section.left_margin = Inches(0.72)
|
||||
section.right_margin = Inches(0.72)
|
||||
section.header_distance = Inches(0.3)
|
||||
section.footer_distance = Inches(0.3)
|
||||
|
||||
normal = doc.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 = doc.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 name in ("List Bullet", "List Number"):
|
||||
style = doc.styles[name]
|
||||
style.font.name = "Arial"
|
||||
style._element.rPr.rFonts.set(qn("w:eastAsia"), "Arial")
|
||||
style.font.size = Pt(10.5)
|
||||
|
||||
hp = section.header.paragraphs[0]
|
||||
hp.alignment = WD_ALIGN_PARAGRAPH.RIGHT
|
||||
add_text(hp, "CNC 机床系统对接|资料与技术支持需求函", size=8.5, color=GRAY)
|
||||
fp = section.footer.paragraphs[0]
|
||||
fp.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||||
add_text(fp, "请按实际设备型号填写;不适用项目请标注“不适用”", size=8, color=GRAY)
|
||||
return doc
|
||||
|
||||
|
||||
def formal_matrix(doc, headers, widths, rows, first_col_fill=None, sizes=None):
|
||||
table = doc.add_table(rows=1, cols=len(headers))
|
||||
table.style = "Table Grid"
|
||||
set_table_fixed_width(table, widths)
|
||||
for idx, text in enumerate(headers):
|
||||
cell = table.rows[0].cells[idx]
|
||||
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.2, bold=True, color=WHITE)
|
||||
set_repeat_table_header(table.rows[0])
|
||||
for ridx, values in enumerate(rows):
|
||||
row = table.add_row()
|
||||
keep_row_together(row)
|
||||
for idx, value in enumerate(values):
|
||||
cell = row.cells[idx]
|
||||
set_cell_margins(cell, top=100, bottom=100)
|
||||
cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
|
||||
if idx == 0 and first_col_fill:
|
||||
set_cell_shading(cell, first_col_fill)
|
||||
p = cell.paragraphs[0]
|
||||
p.alignment = WD_ALIGN_PARAGRAPH.CENTER if idx == 0 else WD_ALIGN_PARAGRAPH.LEFT
|
||||
size = sizes[idx] if sizes else 9.2
|
||||
add_text(p, value, size=size, bold=(idx == 0))
|
||||
return table
|
||||
|
||||
|
||||
def add_form_lines(doc, pairs):
|
||||
table = doc.add_table(rows=0, cols=2)
|
||||
table.style = "Table Grid"
|
||||
set_table_fixed_width(table, [3.25, 3.25])
|
||||
for left, right in pairs:
|
||||
row = table.add_row()
|
||||
keep_row_together(row)
|
||||
for idx, value in enumerate((left, right)):
|
||||
cell = row.cells[idx]
|
||||
set_cell_margins(cell, top=120, bottom=120)
|
||||
add_text(cell.paragraphs[0], value, size=9.5)
|
||||
return table
|
||||
|
||||
|
||||
def build():
|
||||
doc = setup_document()
|
||||
|
||||
p = doc.add_paragraph()
|
||||
p.paragraph_format.space_before = Pt(12)
|
||||
p.paragraph_format.space_after = Pt(4)
|
||||
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=20, bold=True, color=BLUE)
|
||||
|
||||
doc.add_heading("一、需求目的", level=1)
|
||||
p = doc.add_paragraph()
|
||||
add_text(
|
||||
p,
|
||||
"为开展数字零件模型至 CNC 加工程序生成、程序传输、试切验证及加工状态采集等工作,"
|
||||
"现请贵方协助确认实际机床和 CNC 控制系统配置,并提供本函所列技术资料、接口信息、"
|
||||
"验证样例及联合调试支持。",
|
||||
)
|
||||
p = doc.add_paragraph()
|
||||
add_text(
|
||||
p,
|
||||
"本函中的通信产品和接口名称均为候选项,最终以实际机床型号、CNC 系统版本、已购选件、"
|
||||
"机床制造商配置及贵方书面确认为准。",
|
||||
color=GRAY,
|
||||
)
|
||||
|
||||
add_callout(
|
||||
doc,
|
||||
"回复方式",
|
||||
"请在对应表格中填写、勾选或标注“不支持/不适用/待确认”,并随回复附相关手册、"
|
||||
"安装包、许可证说明、样例文件和技术联系人信息。",
|
||||
PALE_BLUE,
|
||||
)
|
||||
|
||||
doc.add_heading("二、建议参与对接的技术人员", level=1)
|
||||
role_rows = [
|
||||
("机床制造商/集成商", "机械配置、轴与主轴、刀库/夹具、专用 M 代码、PLC/联锁、机床安全和现场调试。", "姓名:________ 电话:________"),
|
||||
("三菱 CNC/代理商", "CNC 型号与版本、已购选件、通信软件、SDK、许可证、标准接口和版本兼容。", "姓名:________ 电话:________"),
|
||||
("现场工艺/设备人员", "现用 CAM、后处理器、刀具、材料、装夹、坐标、切削参数和已验证程序。", "姓名:________ 电话:________"),
|
||||
("网络/信息化人员", "工业网络、IP/端口、账号、证书、远程访问、日志和数据合规。", "姓名:________ 电话:________"),
|
||||
]
|
||||
formal_matrix(doc, ["参与角色", "确认范围", "联系人"], [1.45, 3.70, 1.35], role_rows, first_col_fill=LIGHT_BLUE)
|
||||
|
||||
doc.add_heading("三、设备与 CNC 基础信息", level=1)
|
||||
equipment_rows = [
|
||||
("机床身份", "制造商、完整型号、序列号、出厂年份、设备编号", "____________________________", "铭牌及整机照片"),
|
||||
("CNC 控制系统", "三菱 CNC 系列、完整型号、系统软件版本", "____________________________", "系统信息页面照片"),
|
||||
("已安装选件", "高速加工、五轴、刀尖点控制、宏程序、通信等选件", "____________________________", "选件清单/参数页面"),
|
||||
("机床类型", "车床/铣床/加工中心/车铣复合/磨床/专机", "____________________________", "设备规格书"),
|
||||
("轴配置", "轴名称、正方向、行程、零点、软限位、旋转轴结构", "____________________________", "轴配置图"),
|
||||
("主轴配置", "数量、方向、最高转速、功率/扭矩、锥度", "____________________________", "主轴规格"),
|
||||
("刀库/刀塔", "类型、容量、刀位规则、刀具尺寸重量限制", "____________________________", "刀库规格"),
|
||||
("辅助装置", "探针、自动对刀、第四/第五轴、尾座、卡盘、托盘等", "____________________________", "配置说明"),
|
||||
]
|
||||
formal_matrix(
|
||||
doc,
|
||||
["项目", "请确认内容", "贵方填写", "建议附件"],
|
||||
[1.15, 2.65, 1.55, 1.15],
|
||||
equipment_rows,
|
||||
first_col_fill=LIGHT_BLUE,
|
||||
sizes=[9.0, 8.8, 8.8, 8.5],
|
||||
)
|
||||
|
||||
doc.add_heading("四、请提供的技术资料", level=1)
|
||||
material_rows = [
|
||||
("P0", "CNC 与机床手册", "CNC 规格/编程/操作/连接设置手册;机床厂操作、维护及专用功能手册。", "□已附 □后补 □不适用"),
|
||||
("P0", "代码和程序规则", "实际支持的 G/M/T/S/F 代码、自定义 M 代码、宏变量、固定循环、坐标系、刀补、换刀规则、程序格式限制。", "□已附 □后补 □不适用"),
|
||||
("P0", "程序模板", "机床厂认可的程序开头、换刀段、工序切换、异常退出和结束模板。", "□已附 □后补 □不适用"),
|
||||
("P0", "验证样例包", "至少 3~10 套已加工成功样例,每套对应 STEP/图纸、毛坯、材料、刀具、装夹、CAM、NC 和检测结果。", "数量:____套"),
|
||||
("P0", "现用 CAM/后处理", "CAM 名称和版本、后处理器、后处理配置、程序头尾模板和典型仿真项目。", "□已附 □后补 □无"),
|
||||
("P1", "刀具与刀柄", "真实刀具/刀柄清单、刀位号、刀补号、主要尺寸、寿命规则及 STEP/尺寸模型。", "□已附 □后补"),
|
||||
("P1", "夹具与工作区", "工作台、卡盘、虎钳、软爪、尾座、旋转轴、探针和防护区域的模型或关键尺寸。", "□已附 □后补"),
|
||||
("P1", "材料与工艺", "常用材料牌号、毛坯规格、余量、硬度/热处理、切削参数、冷却方式、公差和粗糙度。", "□已附 □后补"),
|
||||
("P2", "数字机床", "机床三维模型、运动学、回转中心、碰撞体、软限位、CAM 机床仿真工程。", "□已附 □后补 □无"),
|
||||
]
|
||||
formal_matrix(doc, ["优先级", "资料名称", "交付内容", "回复"], [0.70, 1.45, 3.30, 1.05], material_rows, first_col_fill=GREEN)
|
||||
|
||||
doc.add_heading("五、程序传输与通信能力确认", level=1)
|
||||
interface_rows = [
|
||||
("加工程序传输", "NC Explorer", "□已安装 □可新增 □不支持 □待确认", "版本/许可证/手册/网络配置"),
|
||||
("加工程序传输", "FTP、共享目录或机床厂文件服务", "□支持 □不支持 □待确认", "IP/端口/目录/账号/文件规则"),
|
||||
("加工程序传输", "DNC/MDC/MES 平台", "□已有 □无 □待确认", "产品名称、版本、第三方接口"),
|
||||
("加工程序传输", "RS-232C 或 USB", "□支持 □不支持", "传输设置与文件限制"),
|
||||
("CNC 通信 SDK", "FCSB1224W000 开发包", "□已授权 □可采购 □不支持 □待确认", "SDK、手册、样例、兼容矩阵"),
|
||||
("CNC 通信运行库", "FCSB1224W100", "□已授权 □可采购 □不支持 □待确认", "安装包、版本和部署许可"),
|
||||
("只读数据采集", "MTConnect", "□已配置 □可新增 □不支持 □待确认", "适配器/Agent、数据项和端点"),
|
||||
("只读数据采集", "OPC UA / NC Machine Tool Connector", "□已配置 □可新增 □不支持 □待确认", "服务器、节点表、证书、许可"),
|
||||
("运行监控", "NC Monitor2 或现有监控平台", "□已有 □无 □待确认", "产品版本与开放接口"),
|
||||
("PLC/设备访问", "SLMP 或机床厂专用接口", "□开放只读 □开放读写 □不开放 □待确认", "设备地址表、权限和联锁说明"),
|
||||
("机床厂专用 API", "机床厂二次开发接口", "□有 □无 □待确认", "API 文档、SDK、样例和授权"),
|
||||
]
|
||||
formal_matrix(
|
||||
doc,
|
||||
["用途", "候选通道", "贵方确认", "请附资料"],
|
||||
[1.15, 1.80, 1.95, 1.60],
|
||||
interface_rows,
|
||||
first_col_fill=LIGHT_BLUE,
|
||||
sizes=[8.6, 8.6, 8.3, 8.3],
|
||||
)
|
||||
|
||||
doc.add_heading("六、接口交付要求", level=1)
|
||||
interface_delivery_rows = [
|
||||
("兼容性", "适用 CNC 型号、系统版本、所需硬件/选件、安装状态、许可证数量和有效期。", "____________________________"),
|
||||
("开发资料", "API/协议手册、数据字典、错误码、示例程序、SDK/运行库安装包及版本说明。", "____________________________"),
|
||||
("连接参数", "协议、IP、端口、账号/证书、读写权限、超时、并发、频率和文件大小限制。", "____________________________"),
|
||||
("可靠性", "断线检测、重连、续传、重复提交处理、任务 ID、校验、回执和错误处理机制。", "____________________________"),
|
||||
("时间与单位", "时区、时间同步、时间戳精度、字段单位、缩放系数和枚举值说明。", "____________________________"),
|
||||
("版本支持", "SDK/协议与 CNC 兼容矩阵、升级策略、补丁和技术支持期限。", "____________________________"),
|
||||
("日志审计", "连接、文件传输、调用方、操作时间、结果、配置修改及远程访问日志。", "____________________________"),
|
||||
]
|
||||
formal_matrix(doc, ["项目", "交付要求", "贵方回复/附件"], [1.25, 3.85, 1.40], interface_delivery_rows, first_col_fill=LIGHT_BLUE)
|
||||
|
||||
doc.add_heading("七、状态数据项确认", level=1)
|
||||
p = doc.add_paragraph()
|
||||
add_text(
|
||||
p,
|
||||
"请针对可提供的数据项另附数据字典,并至少标明:接口来源、字段/节点地址、数据类型、单位、"
|
||||
"刷新周期、时间戳、枚举含义、无效值及报警条件。",
|
||||
color=GRAY,
|
||||
)
|
||||
data_rows = [
|
||||
("设备状态", "设备 ID、型号/版本、在线/离线、采集状态、最后更新时间", "□可提供 □部分 □不支持"),
|
||||
("运行状态", "自动/手动/MDI、运行/暂停/停止/报警/急停、循环启动、门和关键联锁", "□可提供 □部分 □不支持"),
|
||||
("程序执行", "当前程序、子程序、行号/序列号、开始结束时间、循环时间、加工计数", "□可提供 □部分 □不支持"),
|
||||
("轴与坐标", "机床/工件坐标、剩余移动、进给、倍率、轴负载、旋转轴角度", "□可提供 □部分 □不支持"),
|
||||
("主轴", "实际/指令转速、倍率、负载、扭矩/功率、方向、状态、温度", "□可提供 □部分 □不支持"),
|
||||
("刀具", "当前刀号、刀位、刀补、寿命、使用次数、刀具报警及刀具表更新", "□可提供 □部分 □不支持"),
|
||||
("报警诊断", "报警号、等级、文本、发生/解除时间、历史、CNC 与机床 PLC 报警", "□可提供 □部分 □不支持"),
|
||||
("加工质量", "完工状态、实际周期、测头/尺寸结果、报废返工原因", "□可提供 □部分 □不支持"),
|
||||
("维护能耗", "运行时长、润滑/冷却、维护计数、能耗等设备已有数据", "□可提供 □部分 □不支持"),
|
||||
]
|
||||
formal_matrix(doc, ["数据类别", "期望数据项", "贵方确认"], [1.20, 4.05, 1.25], data_rows, first_col_fill=LIGHT_BLUE)
|
||||
|
||||
doc.add_heading("八、网络与安全配合", level=1)
|
||||
security_rows = [
|
||||
("网络拓扑", "机床网段、工业交换机、防火墙/隔离区、可否新增工控机及跨网访问方式。", "□可提供 □待确认"),
|
||||
("端口白名单", "协议、源/目的 IP、TCP/UDP 端口、连接方向和网络变更流程。", "□可提供 □待确认"),
|
||||
("账号与证书", "角色权限、密码策略、证书签发/更新、密钥保存和账号停用流程。", "□可提供 □待确认"),
|
||||
("远程支持", "VPN/堡垒机/厂商远程服务、审批、开放时间、审计和紧急断开。", "□允许 □不允许 □待确认"),
|
||||
("备份恢复", "CNC 参数、PLC、刀补、宏变量和接口配置的备份、回退及恢复负责人。", "□可配合 □待确认"),
|
||||
("数据合规", "可采集范围、保存期限、图纸/NC 程序保密等级、外发和云端限制。", "□可提供 □待确认"),
|
||||
]
|
||||
formal_matrix(doc, ["项目", "请确认内容", "贵方回复"], [1.25, 4.00, 1.25], security_rows, first_col_fill=LIGHT_BLUE)
|
||||
|
||||
doc.add_heading("九、联合调试与验收支持", level=1)
|
||||
acceptance_rows = [
|
||||
("资料审查", "型号、手册、代码表、样例、接口和许可证资料齐全;共同确认未知项和责任人。", "□可配合"),
|
||||
("离线验证", "使用验证样例生成 NC,完成 CAM/CNC 仿真和现场程序对比。", "□可配合 仿真环境:________"),
|
||||
("程序传输", "验证上传、下载、覆盖保护、文件名、校验、断线重试和回执,不启动机床。", "□可配合"),
|
||||
("空运行", "在机床锁定/抬刀/单段/低倍率条件下核对坐标、刀具、换刀、行程和安全位置。", "□可配合"),
|
||||
("试切", "使用约定毛坯、刀具和装夹加工样件,记录周期、报警、刀具和检测结果。", "□可配合"),
|
||||
("状态采集", "验证约定数据项、时间戳、连续采集、断线恢复和报警记录。", "□可配合"),
|
||||
("试运行", "限定设备和零件范围运行,统计成功率、人工干预、报警和返工。", "□可配合"),
|
||||
]
|
||||
formal_matrix(doc, ["阶段", "配合与验收内容", "贵方确认"], [1.10, 4.20, 1.20], acceptance_rows, first_col_fill=LIGHT_BLUE)
|
||||
|
||||
doc.add_heading("十、首批交付成果", level=1)
|
||||
deliverable_rows = [
|
||||
("P0", "设备接口基线表", "每台机床的完整型号、CNC 版本、轴/主轴/刀库、选件、程序传输、可用接口、网络和联系人。", "□可提供"),
|
||||
("P0", "机床编程资料包", "CNC/机床手册、G/M 代码、专用 M 代码、程序模板、坐标/刀补/换刀规则。", "□可提供"),
|
||||
("P0", "验证样例包", "3~10 套 STEP/图纸、毛坯、刀具、装夹、CAM、NC 和检测结果对应的完整样例。", "□可提供"),
|
||||
("P1", "通信接口包", "SDK/运行库或协议、许可、样例、数据字典、节点/地址表、错误码和兼容矩阵。", "□可提供"),
|
||||
("P1", "测试验收环境", "离线仿真或测试机、账号/目录、网络窗口、备份、现场人员及验收样件。", "□可提供"),
|
||||
("P2", "数字机床资料包", "机床、刀具、刀柄、夹具和毛坯模型;运动学、软限位、碰撞体和 CAM 仿真工程。", "□可提供"),
|
||||
]
|
||||
formal_matrix(doc, ["优先级", "成果名称", "内容", "确认"], [0.70, 1.45, 3.30, 1.05], deliverable_rows, first_col_fill=GREEN)
|
||||
|
||||
doc.add_heading("十一、商务授权与支持信息", level=1)
|
||||
commercial_rows = [
|
||||
("软件与接口授权", "SDK、运行库、OPC UA/MTConnect、仿真软件、后处理器是否收费及授权方式", "____________________________"),
|
||||
("现场服务", "现场调试服务内容、人员、预计工期及费用", "____________________________"),
|
||||
("培训", "操作、编程、通信接口、备份恢复和安全联调培训", "____________________________"),
|
||||
("维护支持", "服务时间、响应时限、升级路径、远程/现场支持和年度维护", "____________________________"),
|
||||
("交付介质", "安装包、许可证、手册、样例代码、版本号、校验值和下载期限", "____________________________"),
|
||||
]
|
||||
formal_matrix(doc, ["项目", "请确认内容", "贵方回复"], [1.35, 3.65, 1.50], commercial_rows, first_col_fill=LIGHT_BLUE)
|
||||
|
||||
doc.add_heading("附:建议资料包目录", level=1)
|
||||
add_callout(
|
||||
doc,
|
||||
"建议压缩包结构",
|
||||
"01_设备铭牌与系统照片;02_机床与CNC手册;03_GM代码与机床专用说明;04_已验证样例;"
|
||||
"05_CAM与后处理;06_刀具夹具材料工艺;07_通信软件与接口文档;08_网络与测试环境;"
|
||||
"09_授权商务信息;10_联系人。",
|
||||
LIGHT_BLUE,
|
||||
)
|
||||
|
||||
OUT.parent.mkdir(parents=True, exist_ok=True)
|
||||
doc.save(OUT)
|
||||
print(OUT)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
build()
|
||||
@@ -0,0 +1,567 @@
|
||||
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/W100(CNC 通信 SDK/运行库)、MTConnect Data Collector、"
|
||||
"NC Machine Tool Connector(OPC 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()
|
||||
Reference in New Issue
Block a user