Files
bj_power/bj_power_mes/待确定方案.md
T

9.3 KiB
Raw Blame History

高压清洗机 FANUC 宏变量控制方案(待确定)

一、业务背景

高压清洗机(设备ID=5)的加工程序按零件号分成 9 组,通过 FANUC(发那科)CNC 宏变量 #666(左工位)和 #888(右工位)的值来调用对应的子程序(O1001~O1018)。

当前软件只发送 workpieceType(毛坯号,即 product_type 主键ID)给 PLC没有发送零件号和 FANUC 宏变量的功能,需要新增。

二、业务规则

1. 零件号 → 组号映射(9组,共19个零件号)

组号 #666(左) #888(右) 种类 毛坯号 零件号
1 1 1 A6VM107 B99414 B02858、B20044、B20223、B20480
2 2 2 A6VM107 B99414 B20177、B20248、B20538
3 3 3 A6VM107 B99487 B20227、B20257
4 4 4 A6VM160 B99464 B20141
5 5 5 A6VM160 B99464 B20061、B20235
6 6 6 A6VM160 B99464 B02943
7 7 7 A6VM160 B99464 B20149
8 8 8 A6VM160 B99488 B20240
9 9 9 A6VM200 B99259 B02533、B02681、B20102、B20144

注:第9组零件号以你核对过的 临时.txt 为准(B02533);手写稿中记为 B20533,旧Excel图片中亦为 B02533。

2. 高压清洗机运行流程(新)

放料前:
  1. 从工单取出零件号(新建工单时用户选择,存入子表)
  2. 根据零件号查映射表,得到组号(1~9)
  3. 通过 FANUCgofocas 库)写入宏变量:
       左工位 → #666 = 组号
       右工位 → #888 = 组号
  4. 通过 PLC 发送放料命令(M1040,现有逻辑不变)
  5. 通过 PLC 发送启动命令(M1144.2,现有逻辑不变)

清洗完成后:
  6. 两个槽位都必须完成,才能取料
  7. 禁止换料(exchange),先全部取下,再单独放入

三、改动清单(按模块)

1. 数据库(新增2张表 + 1个字段)

新表 part_no(零件号表):存零件号、所属毛坯号、清洗机组号

字段 说明
id 主键,自增
code 零件号(如 B02858),全局唯一,工单选择零件号时显示的选项值
productTypeId 所属毛坯号(关联 product_type.id),与现有工件分类体系保持一致,此主键ID是所有其他设备(CNC、去毛刺等)识别工件类型的依据,不可改变
washerGroupNo 高压清洗机组号(1~9),即写入 FANUC 宏变量 #666/#888 的值;仅高压清洗机使用,其他设备忽略
remark 备注(可选)
createdAt 创建时间

新表 work_order_part(工单零件号表):存工单选了哪个零件号

字段 说明
id 主键
workOrderId 工单ID(关联 work_order.id
partNoId 零件号ID(关联 part_no.id

equipment 表:高压清洗机记录(ID=5)的 ipAddress 字段值 = FANUC 连接地址,格式 IP:端口(如 192.168.x.x:8193),不写死端口,生产提供后整串填入;端口默认 8193,但以数据库实际配置为准。

2. 前端(新建工单弹窗)

现有选择是两级:种类 → 毛坯号work-order-editor/index.tsx 的 Select 分组)。

改为三级:种类 → 毛坯号 → 零件号,样式不变,多一层显示,用户选择零件号后随工单一起提交。

3. 后端

新增 FANUC 通讯模块(替换现有 internal/cnc/ 的 stub):

  • 使用公用库 bjhardman.cn/bjhardman/gofocas(与 goplc 同仓库,已有权限)
  • 连接地址从 equipment 表 ipAddress 字段读取(格式 IP:端口,如 192.168.x.x:8193
  • 提供写宏变量方法:SetMacroVar(addr, macroNo, value),即写 #666/#888

清洗机调度流程修改washer_orchestrator.go):

  • 放料动作前插入"查零件号 → FANUC 写 #666/#888"
  • 卸载逻辑取消换料(exchange),改为两个槽位都完成后再逐个取出

新建工单逻辑修改create_work_order_logic.go):

  • 接收并保存零件号到 work_order_part

4. 种子数据(追加到 doc/data.sql

19 条 part_no 记录(映射关系见第二节表格,数据已核对)。

四、实施顺序(确认后按此执行)

  1. 拉取 gofocas 库,确认其 API(写宏变量的方法签名)
  2. 数据库:新增 part_no、work_order_part 表 + 种子数据
  3. 后端:FANUC 通讯模块封装
  4. 前端:工单选择增加零件号层级
  5. 后端:清洗机流程接入 FANUC 写入 + 取消换料
  6. mockrun 验证(gofocas 用 mock 模拟)

五、待确认事项

  1. gofocas 库:与 goplc 同仓库,有权限可拉取,实施时直接 go get
  2. FANUC 连接地址:生产提供高压清洗机 CNC 的 IP:端口(端口默认 8193),填入 equipment.ip_address,先留空
  3. 一个工单只选一个零件号:已确认,工单内所有工件同一零件号
  4. 说明:本方案只追加新表/新数据,不修改 signals.sql 及现有信号(StartMeasure 等在 signals.sql 中保持不变)

六、代码示例(放文档底部,仅供确认,不直接改代码)

1. 种子数据 SQL(追加到 doc/data.sql

-- 零件号表(含清洗机组号)
CREATE TABLE IF NOT EXISTS part_no (
    id               SERIAL PRIMARY KEY,
    code             VARCHAR(20) NOT NULL UNIQUE,
    product_type_id  INT NOT NULL REFERENCES product_type(id),
    washer_group_no  INT NOT NULL,
    remark           VARCHAR(255) DEFAULT '',
    created_at       TIMESTAMPTZ DEFAULT now()
);

COMMENT ON TABLE part_no IS '零件号表(高压清洗机按零件号分9组程序)';
COMMENT ON COLUMN part_no.id IS '主键,自增';
COMMENT ON COLUMN part_no.code IS '零件号(如 B02858),全局唯一,工单选择零件号时的选项值';
COMMENT ON COLUMN part_no.product_type_id IS '所属毛坯号(关联 product_type.id),与现有工件分类体系一致,此主键ID是所有设备(CNC、去毛刺等)识别工件类型的依据,不可改变';
COMMENT ON COLUMN part_no.washer_group_no IS '高压清洗机组号(1~9),即写入 FANUC 宏变量 #666/#888 的值;仅高压清洗机使用,其他设备忽略';
COMMENT ON COLUMN part_no.remark IS '备注(可选)';
COMMENT ON COLUMN part_no.created_at IS '创建时间';

-- 工单零件号关联表
CREATE TABLE IF NOT EXISTS work_order_part (
    id            SERIAL PRIMARY KEY,
    work_order_id INT NOT NULL REFERENCES work_order(id),
    part_no_id    INT NOT NULL REFERENCES part_no(id),
    created_at    TIMESTAMPTZ DEFAULT now()
);

COMMENT ON TABLE work_order_part IS '工单零件号关联表(一个工单只选一个零件号)';
COMMENT ON COLUMN work_order_part.id IS '主键,自增';
COMMENT ON COLUMN work_order_part.work_order_id IS '工单ID(关联 work_order.id),一个工单只对应一个零件号';
COMMENT ON COLUMN work_order_part.part_no_id IS '零件号ID(关联 part_no.id';
COMMENT ON COLUMN work_order_part.created_at IS '创建时间';

-- 种子数据(19个零件号,对应9组)
INSERT INTO part_no (code, product_type_id, washer_group_no) VALUES
('B02858', 1, 1), ('B20044', 1, 1), ('B20223', 1, 1), ('B20480', 1, 1),
('B20177', 1, 2), ('B20248', 1, 2), ('B20538', 1, 2),
('B20227', 2, 3), ('B20257', 2, 3),
('B20141', 3, 4),
('B20061', 3, 5), ('B20235', 3, 5),
('B02943', 3, 6),
('B20149', 3, 7),
('B20240', 4, 8),
('B02533', 5, 9), ('B02681', 5, 9), ('B20102', 5, 9), ('B20144', 5, 9);

-- 高压清洗机 FANUC 连接地址(格式 IP:端口,如 192.168.x.x:8193;待生产提供,先留空)
UPDATE equipment SET ip_address = '' WHERE id = 5;

2. FANUC 通讯模块(internal/cnc/ 替换 stub

package cnc

// 写 FANUC 宏变量(如 #666、#888
// gofocas 库 API 以实际拉取到的版本为准,这里先画结构
// 连接地址从 equipment.ip_address 读取,格式 "IP:端口"(如 192.168.x.x:8193),端口不写死

type Client struct {
    addr string // equipment.ipAddress,格式 "IP:端口"
}

func NewClient(addr string) *Client {
    return &Client{addr: addr}
}

// WriteMacro 写宏变量,如 WriteMacro(666, 1)
func (c *Client) WriteMacro(ctx context.Context, macroNo int, value int) error {
    // 解析 addr 为 host:port,调用 gofocas 库:连接 → 写宏变量 → 断开
    return nil
}

3. 清洗机放料流程(washer_orchestrator.go 改动点)

// 放料动作前:写 FANUC 宏变量
// 伪代码,具体以现有 buildWasherLoadActions 结构为准
for _, act := range actions {
    if act.Kind == "load_to_machine" && act.MachineID == WASHER_HP {
        // 1. 查零件号
        partNo := queryWorkOrderPart(act.JobID)
        // 2. 查组号
        groupNo := partNo.washerGroupNo
        // 3. FANUC 写宏变量(slotNo=1 写 #666slotNo=2 写 #888
        fanuc.WriteMacro(ctx, 666, groupNo) // 左
        fanuc.WriteMacro(ctx, 888, groupNo) // 右
        // 4. 再走现有 PLC 放料
    }
}

4. 前端三级选择(work-order-editor/index.tsx 改动点)

// 现有:种类 → 毛坯号(两级)
// 新增:毛坯号 children 下再加零件号一层
// 数据来源:listProductTypes 接口扩展返回 partNos 数组
// 提交时:productTypeId + partNoId 一起传给 createWorkOrder