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:
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Beijing Hardman Automation Equipment Co., LTD. All rights reserved.
|
||||
*
|
||||
* Project: adapter
|
||||
* File: common.go
|
||||
* Last: 2025-05-15 10:57:25
|
||||
* Author: wangcheng@bj-hardman.com
|
||||
*/
|
||||
|
||||
package robot
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"log/slog"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"bj_power_mes/constants"
|
||||
"bj_power_mes/internal/plc"
|
||||
"bj_power_mes/internal/preload"
|
||||
)
|
||||
|
||||
type arg struct {
|
||||
name string
|
||||
value any
|
||||
}
|
||||
|
||||
func newArg(value any, name ...string) arg {
|
||||
if len(name) > 0 {
|
||||
return arg{
|
||||
name: name[0],
|
||||
value: value,
|
||||
}
|
||||
}
|
||||
return arg{
|
||||
value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Controller) executeAction(ctx context.Context, action string, args ...arg) error {
|
||||
addr := preload.GetMAddress(action)
|
||||
return c.execute(ctx, addr, args, true)
|
||||
}
|
||||
|
||||
func (c *Controller) execute(ctx context.Context, addr preload.MAddress, args []arg, autoClear bool) error {
|
||||
c.mtx.Lock()
|
||||
defer c.mtx.Unlock()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
if err := c.sendSignal(addr, args...); err != nil {
|
||||
return err
|
||||
}
|
||||
return c.waitReply(ctx, addr, autoClear)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Controller) sendSignal(addr preload.MAddress, args ...arg) error {
|
||||
buf := new(bytes.Buffer)
|
||||
//buf.WriteByte(1)
|
||||
for _, a := range args {
|
||||
_ = binary.Write(buf, binary.BigEndian, a.value)
|
||||
}
|
||||
|
||||
//先写参数
|
||||
err := c.plcClient.Write(addr.Addr.Add(1, 0).String(), buf.Bytes())
|
||||
if err != nil {
|
||||
slog.Error("写入PLC信号失败",
|
||||
slog.Any("address", addr),
|
||||
slog.Any("error", err),
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
time.Sleep(time.Millisecond * 200)
|
||||
//再写信号
|
||||
err = c.plcClient.WriteByte(addr.Address(), 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
attrCount := 0
|
||||
for _, a := range args {
|
||||
if a.name != "" {
|
||||
attrCount++
|
||||
}
|
||||
}
|
||||
attrs := make([]any, 0, attrCount)
|
||||
for _, a := range args {
|
||||
if a.name == "" {
|
||||
continue
|
||||
}
|
||||
attrs = append(attrs, slog.Any(a.name, a.value))
|
||||
}
|
||||
|
||||
slog.Info("已发送PLC信号",
|
||||
slog.Any("address", addr),
|
||||
slog.Group("params", attrs...), // 使用Group包装属性
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) SendSignalOnly(addr preload.MAddress) error {
|
||||
err := c.plcClient.WriteByte(addr.Address(), 1)
|
||||
if err != nil {
|
||||
slog.Error("写入PLC信号失败",
|
||||
slog.Any("address", addr),
|
||||
slog.Any("error", err),
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
slog.Info("已发送PLC信号",
|
||||
slog.Any("address", addr),
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) WaitSignal(ctx context.Context, addr preload.MAddress, value bool, offsetAddress bool) error {
|
||||
replayAddr := addr.Addr.Add(0, 0)
|
||||
if offsetAddress {
|
||||
replayAddr = addr.Addr.Add(9, 0)
|
||||
}
|
||||
t := time.NewTicker(c.checkSignalDuration)
|
||||
defer t.Stop()
|
||||
|
||||
once := sync.Once{}
|
||||
retryCount := 0
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-t.C:
|
||||
result, err := c.plcClient.ReadBool(replayAddr.String())
|
||||
if err != nil {
|
||||
slog.Error("读取PLC信号失败",
|
||||
slog.String("address", replayAddr.String()),
|
||||
slog.Int("retry", retryCount),
|
||||
slog.Any("error", err),
|
||||
)
|
||||
retryCount++
|
||||
if retryCount >= c.maxRetries {
|
||||
slog.Error("读取PLC完成信号失败",
|
||||
slog.Any("address", replayAddr),
|
||||
slog.Any("error", err),
|
||||
)
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
if result == value {
|
||||
slog.Info("收到PLC完成信号",
|
||||
slog.Any("address", replayAddr),
|
||||
)
|
||||
return nil
|
||||
} else {
|
||||
if alarmSvc := c.alarmSvc; alarmSvc != nil {
|
||||
err = c.GetErrorCode()
|
||||
if err != nil {
|
||||
once.Do(func() {
|
||||
slog.Error("PLC Error", slog.Any("error", err))
|
||||
alarmSvc.Raise(ctx,
|
||||
"ROBOT_ERROR",
|
||||
err.Error(),
|
||||
constants.AlarmLevel_ERROR,
|
||||
0, 0,
|
||||
"robot",
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Controller) WaitSignal_TwoSignals(ctx context.Context, addr preload.MAddress, value bool, offsetAddress bool, addrResult preload.MAddress, valueResult bool) (bool, error) {
|
||||
replayAddr := addr.Addr.Add(0, 0)
|
||||
if offsetAddress {
|
||||
replayAddr = addr.Addr.Add(9, 0)
|
||||
}
|
||||
t := time.NewTicker(c.checkSignalDuration)
|
||||
defer t.Stop()
|
||||
|
||||
//once := sync.Once{}
|
||||
retryCount := 0
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return false, ctx.Err()
|
||||
case <-t.C:
|
||||
//1.Result
|
||||
result, err := c.plcClient.ReadBool(addrResult.Addr.Add(9, 0).String())
|
||||
if err != nil {
|
||||
slog.Error("读取PLC信号失败",
|
||||
slog.String("address", addrResult.String()),
|
||||
slog.Int("retry", retryCount),
|
||||
slog.Any("error", err),
|
||||
)
|
||||
retryCount++
|
||||
if retryCount >= c.maxRetries {
|
||||
slog.Error("读取PLC完成信号失败",
|
||||
slog.Any("address", addrResult),
|
||||
slog.Any("error", err),
|
||||
)
|
||||
return true, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
if result == valueResult {
|
||||
slog.Info("收到PLC完成信号",
|
||||
slog.Any("address", addrResult),
|
||||
)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
//2.wait
|
||||
result, err = c.plcClient.ReadBool(replayAddr.String())
|
||||
if err != nil {
|
||||
slog.Error("读取PLC信号失败",
|
||||
slog.String("address", replayAddr.String()),
|
||||
slog.Int("retry", retryCount),
|
||||
slog.Any("error", err),
|
||||
)
|
||||
retryCount++
|
||||
if retryCount >= c.maxRetries {
|
||||
slog.Error("读取PLC完成信号失败",
|
||||
slog.Any("address", replayAddr),
|
||||
slog.Any("error", err),
|
||||
)
|
||||
return false, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
if result == value {
|
||||
slog.Info("收到PLC完成信号",
|
||||
slog.Any("address", replayAddr),
|
||||
)
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Controller) waitReply(ctx context.Context, addr preload.MAddress, autoClear bool) error {
|
||||
if err := c.WaitSignal(ctx, addr, true, true); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if autoClear {
|
||||
_ = c.plcClient.Write(addr.Address(), make([]byte, 9))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) GetErrorCode() error {
|
||||
addr := preload.GetMAddress("ErrorCode")
|
||||
bs, err := c.plcClient.Read(addr.Address(), 8)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v := binary.LittleEndian.Uint64(bs)
|
||||
if v == 0 {
|
||||
return nil
|
||||
}
|
||||
e := plc.RobotError(v)
|
||||
return &e
|
||||
}
|
||||
Reference in New Issue
Block a user