Files
bj_power/bj_power_mes/internal/cnc/manager.go
T

75 lines
2.4 KiB
Go
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.
package cnc
import (
"context"
"fmt"
"log/slog"
"net"
"strconv"
"strings"
"time"
"bjhardman.cn/bjhardman/gofocas"
)
// Manager FANUC CNC 通讯管理器(FOCAS 协议)。
// 设备地址从 equipment.ipAddress 读取,格式 "IP:端口"(如 192.168.x.x:8193)
// 端口不写死,由数据库配置;若省略端口,默认使用 8193。
type Manager struct {
addrs map[int]string // machineID → "IP:端口"
timeout time.Duration
}
// NewManager 用 equipment 地址映射创建 Manager。
// addrMap: machineID → "IP:端口"。
func NewManager(addrMap map[int]string) *Manager {
return &Manager{addrs: addrMap, timeout: 3 * time.Second}
}
// MustNewManager 同 NewManager,为兼容旧调用保留。
func MustNewManager(addrMap map[int]string) *Manager {
return NewManager(addrMap)
}
// WriteMacro 向指定设备的 FANUC 写入宏变量(如 #666/#888)。
// 设备地址未配置(ipAddress 为空)时跳过写入并记录警告,不阻塞流程;
// 地址已配置但连接/写入失败时返回错误(防止清洗机用错程序)。
func (m *Manager) WriteMacro(ctx context.Context, machineID, macroNo int, value float64) error {
addr := m.addrs[machineID]
if addr == "" {
slog.Warn("cnc: FANUC address not configured, skip macro write",
"machineId", machineID, "macroNo", macroNo, "value", value)
return nil
}
// 兼容仅配置 IP 未配置端口的场景,FANUC FOCAS 默认端口为 8193
if !strings.Contains(addr, ":") {
addr = net.JoinHostPort(addr, "8193")
}
host, portStr, err := net.SplitHostPort(addr)
if err != nil {
return fmt.Errorf("cnc: invalid FANUC address %q for machine %d (expected \"IP:端口\"): %w",
addr, machineID, err)
}
port, err := strconv.Atoi(portStr)
if err != nil {
return fmt.Errorf("cnc: invalid FANUC port %q for machine %d: %w", portStr, machineID, err)
}
client := focas.NewClient(host, port, focas.WithTimeout(m.timeout))
if err := client.Connect(); err != nil {
return fmt.Errorf("cnc: connect %s failed: %w", addr, err)
}
defer client.Disconnect()
if err := client.WriteMacro(macroNo, value); err != nil {
return fmt.Errorf("cnc: write macro #%d=%v to %s failed: %w", macroNo, value, addr, err)
}
slog.Info("cnc: macro written", "machineId", machineID, "macroNo", macroNo, "value", value, "addr", addr)
return nil
}
// Release 释放资源(当前为短连接模式,无长连接需要释放)。
func (m *Manager) Release() {}