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

75 lines
2.4 KiB
Go
Raw Normal View History

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() {}