75 lines
2.4 KiB
Go
75 lines
2.4 KiB
Go
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() {}
|