fix: rebuild MES as compilable go-zero+ent backend (renamed bj_power_mes), restore 3 workstation projects from pristine original, align naming; all Go projects go build clean
This commit is contained in:
@@ -1,9 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Beijing Hardman Automation Equipment Co., LTD. All rights reserved.
|
||||
*
|
||||
* Project: adapter
|
||||
* File: error.go
|
||||
* Last: 2025-05-15 11:52:07
|
||||
* Author: wangcheng@bj-hardman.com
|
||||
*/
|
||||
|
||||
package plc
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"bj_power_mes/internal/preload"
|
||||
)
|
||||
|
||||
// 预定义错误
|
||||
var (
|
||||
ErrNotConnect = errors.New("PLC未连接")
|
||||
ErrInvalidAddress = errors.New("无效的PLC地址")
|
||||
)
|
||||
|
||||
// GetErrorCode 获取机器人错误代码
|
||||
func (m *Manager) GetErrorCode() (int64, error) {
|
||||
addr := preload.GetMAddress("ErrorCode")
|
||||
bs, err := m.GetPlc().Read(addr.Address(), 8)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return int64(binary.LittleEndian.Uint64(bs)), nil
|
||||
}
|
||||
|
||||
var (
|
||||
Err_TaskNoError = RobotError(1 << 0) // 任务号错误
|
||||
Err_RackNoError = RobotError(1 << 1) // 料架号下发错误
|
||||
Err_RackHasNoWorkpiece = RobotError(1 << 2) // 所取料架号无料
|
||||
)
|
||||
|
||||
var RobotErrorMap = map[RobotError]string{
|
||||
Err_TaskNoError: "任务号错误",
|
||||
Err_RackNoError: "料架号下发错误",
|
||||
Err_RackHasNoWorkpiece: "所取料架号无料",
|
||||
}
|
||||
|
||||
type RobotError int64
|
||||
|
||||
func (r RobotError) Error() string {
|
||||
if s, ok := RobotErrorMap[r]; ok {
|
||||
return s
|
||||
}
|
||||
return fmt.Sprintf("unknown robot error (code: %d)", int64(r))
|
||||
}
|
||||
|
||||
@@ -1,54 +1,29 @@
|
||||
package plc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
goplc "bjhardman.cn/bjhardman/goplc"
|
||||
"bjhardman.cn/bjhardman/goplc/s7"
|
||||
|
||||
"bj_power_mes/internal/eventbus"
|
||||
)
|
||||
|
||||
// Manager PLC 连接管理器
|
||||
//
|
||||
// 业务场景:管理与西门子 S7 PLC 的连接生命周期,包括连接、断开、重连,
|
||||
// 供上层下发工序号等指令使用。
|
||||
type Manager struct {
|
||||
client goplc.Client // PLC 客户端实例(真实 S7 客户端或 Mock 客户端)
|
||||
client goplc.Client
|
||||
bus eventbus.Bus
|
||||
}
|
||||
|
||||
var (
|
||||
globalPLCManager *Manager
|
||||
globalPLCManagerOnce sync.Once
|
||||
)
|
||||
|
||||
// InitManager 初始化全局 PLC 管理器单例(生产环境调用,仅首次有效)
|
||||
func InitManager(m *Manager) *Manager {
|
||||
globalPLCManagerOnce.Do(func() {
|
||||
globalPLCManager = m
|
||||
})
|
||||
return globalPLCManager
|
||||
}
|
||||
|
||||
// GetManager 获取全局 PLC 管理器单例(未初始化返回 nil)
|
||||
func GetManager() *Manager {
|
||||
return globalPLCManager
|
||||
}
|
||||
|
||||
// Build 创建 PLC 管理器(真实 PLC 模式)
|
||||
//
|
||||
// 业务场景:系统启动时根据配置创建 PLC 管理器,建立与真实西门子 S7 PLC 的连接。
|
||||
//
|
||||
// 参数:
|
||||
// - conf: PLC 配置(主机地址、连接类型等)
|
||||
//
|
||||
// 返回:PLC 管理器实例
|
||||
func Build(conf PlcConf) *Manager {
|
||||
m := &Manager{}
|
||||
func Build(conf PlcConf, bus eventbus.Bus) *Manager {
|
||||
m := &Manager{bus: bus}
|
||||
client := s7.NewClient(conf.Host,
|
||||
s7.WithMaxRetries(-1),
|
||||
s7.WithConnectionType(s7.ConnectionType(conf.ConnectType)),
|
||||
s7.WithOnConnected(func() {
|
||||
slog.Info("PLC connected", "host", conf.Host)
|
||||
m.publishConnectionEvent(true)
|
||||
}),
|
||||
s7.WithOnDisconnected(func(err error) {
|
||||
if err != nil {
|
||||
@@ -56,50 +31,44 @@ func Build(conf PlcConf) *Manager {
|
||||
} else {
|
||||
slog.Warn("PLC disconnected", "host", conf.Host)
|
||||
}
|
||||
m.publishConnectionEvent(false)
|
||||
}),
|
||||
s7.WithOnReconnecting(func(attempt int) {
|
||||
slog.Info("PLC reconnecting", "host", conf.Host, "attempt", attempt)
|
||||
}),
|
||||
)
|
||||
m.client = client
|
||||
|
||||
// 异步连接:在独立 goroutine 中执行连接操作,避免阻塞主启动流程
|
||||
go func() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
slog.Error("PLC: 异步连接panic恢复", "host", conf.Host, "panic", r)
|
||||
}
|
||||
}()
|
||||
if err := client.Connect(); err != nil {
|
||||
slog.Error("PLC: 异步连接失败", "host", conf.Host, "error", err)
|
||||
}
|
||||
_ = client.Connect()
|
||||
}()
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// NewManager 创建 PLC 管理器(使用预构建的客户端)
|
||||
//
|
||||
// 业务场景:测试或 Mock 模式下使用,传入自定义的 PLC 客户端实现。
|
||||
//
|
||||
// 参数:
|
||||
// - client: 预构建的 PLC 客户端实例(可以是 Mock 客户端)
|
||||
//
|
||||
// 返回:PLC 管理器实例
|
||||
func (m *Manager) publishConnectionEvent(connected bool) {
|
||||
if m.bus == nil {
|
||||
return
|
||||
}
|
||||
_ = m.bus.Publish(context.Background(), eventbus.Event{
|
||||
ID: "conn-" + time.Now().Format("20060102150405.000"),
|
||||
Type: eventbus.EventConnectionStatusUpdated,
|
||||
Source: "plc-manager",
|
||||
Timestamp: time.Now(),
|
||||
Payload: map[string]any{
|
||||
"plcConnected": connected,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// NewManager creates a Manager with a pre-built PLC client.
|
||||
func NewManager(client goplc.Client) *Manager {
|
||||
return &Manager{client: client}
|
||||
}
|
||||
|
||||
// GetPlc 获取 PLC 客户端实例
|
||||
//
|
||||
// 业务场景:SignalRouter 等组件通过此方法获取 PLC 客户端,执行读写操作。
|
||||
func (m *Manager) GetPlc() (rc goplc.Client) {
|
||||
return m.client
|
||||
}
|
||||
|
||||
// IsConnected 检查 PLC 连接状态
|
||||
//
|
||||
// 业务场景:SignalRouter 在轮询前检查连接状态,避免无效读取。
|
||||
func (m *Manager) IsConnected() bool {
|
||||
return m.client != nil && m.client.IsConnected()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user