zhangqian
2023-09-16 560985f421189fde3963b8c5af7d7ee1312f125b
换另外一个modbus库
2个文件已添加
5个文件已修改
166 ■■■■ 已修改文件
conf/apsClient.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
go.mod 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
go.sum 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pkg/plc/modbusx/connection_manager.go 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pkg/plc/modbusx/modbus.go 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pkg/plc/plc4x.go 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/plc.go 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
conf/apsClient.json
@@ -29,8 +29,8 @@
    "nsqlookupdAddr":""
  },
  "plc": {
    "finishNumberTimeInterval": 100,
    "totalNumberTimeInterval": 1000
    "finishNumberTimeInterval": 0,
    "totalNumberTimeInterval": 0
  }
}
go.mod
@@ -54,6 +54,8 @@
    github.com/go-playground/universal-translator v0.18.1 // indirect
    github.com/go-playground/validator/v10 v10.14.0 // indirect
    github.com/go-sql-driver/mysql v1.7.0 // indirect
    github.com/goburrow/modbus v0.1.0 // indirect
    github.com/goburrow/serial v0.1.0 // indirect
    github.com/goccy/go-json v0.10.2 // indirect
    github.com/gogo/protobuf v1.3.2 // indirect
    github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
go.sum
@@ -170,6 +170,10 @@
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/goburrow/modbus v0.1.0 h1:DejRZY73nEM6+bt5JSP6IsFolJ9dVcqxsYbpLbeW/ro=
github.com/goburrow/modbus v0.1.0/go.mod h1:Kx552D5rLIS8E7TyUwQ/UdHEqvX5T8tyiGBTlzMcZBg=
github.com/goburrow/serial v0.1.0 h1:v2T1SQa/dlUqQiYIT8+Cu7YolfqAi3K96UmhwYyuSrA=
github.com/goburrow/serial v0.1.0/go.mod h1:sAiqG0nRVswsm1C97xsttiYCzSLBmUZ/VSlVLZJ8haA=
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=
github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
pkg/plc/modbusx/connection_manager.go
New file
@@ -0,0 +1,55 @@
package modbusx
import (
    "github.com/goburrow/modbus"
    "sync"
    "time"
)
type ConnectionManager struct {
    connections map[string]modbus.Client
    mu          sync.Mutex
}
func newPlcConnectionManager() *ConnectionManager {
    return &ConnectionManager{
        connections: make(map[string]modbus.Client),
    }
}
func (cm *ConnectionManager) GetConnection(address string) (modbus.Client, bool) {
    cm.mu.Lock()
    defer cm.mu.Unlock()
    conn, ok := cm.connections[address]
    if !ok {
        return nil, false
    }
    return conn, true
}
var connectionManager = newPlcConnectionManager()
func (cm *ConnectionManager) AddConnection(address string, connection modbus.Client) {
    cm.mu.Lock()
    defer cm.mu.Unlock()
    cm.connections[address] = connection
}
func (cm *ConnectionManager) CheckConnect(conn modbus.Client, timeout time.Duration) (bool, error) {
    return true, nil
}
func getModbusConnection(ipAddr string) modbus.Client {
    if conn, ok := connectionManager.GetConnection(ipAddr); ok {
        return conn
    }
    conn := newGetModbusConnection(ipAddr)
    connectionManager.AddConnection(ipAddr, conn)
    return conn
}
func newGetModbusConnection(ipAddr string) modbus.Client {
    return modbus.TCPClient(ipAddr)
}
pkg/plc/modbusx/modbus.go
New file
@@ -0,0 +1,35 @@
package modbusx
import (
    "encoding/json"
)
func Read(ipAddr string, address uint16, quantity uint16) (data []byte, err error) {
    cli := getModbusConnection(ipAddr)
    data, err = cli.ReadHoldingRegisters(address, quantity)
    return
}
func Write(ipAddr string, address uint16, value interface{}) (err error) {
    bytesVal, err := json.Marshal(value)
    if err != nil {
        return err
    }
    cli := getModbusConnection(ipAddr)
    _, err = cli.WriteMultipleRegisters(address, uint16(len(bytesVal)), bytesVal)
    if err != nil {
        return err
    }
    //time.Sleep(time.Second)
    //// 校验写入的数据
    //result, err := cli.ReadHoldingRegisters(address, uint16(len(bytesVal)))
    //if err != nil {
    //    return err
    //}
    //resultVal := int(binary.BigEndian.Uint16(result))
    //valueInt := cast.ToInt(value)
    //if resultVal != valueInt {
    //    return errors.New("write result not equal read result")
    //}
    return nil
}
pkg/plc/plc4x.go
@@ -33,15 +33,11 @@
    if !ok {
        return nil, false
    }
    connOK, err := cm.CheckConnect(conn, time.Second*1)
    if err != nil {
        logx.Errorf("check plc conn err: %v", err.Error())
        return nil, false
    }
    if connOK {
    //if ok, _ := cm.CheckConnect(conn, time.Second); !ok {
    //    conn.Close()
    //}
        return conn, true
    }
    return nil, false
}
var connectionManager = newPlcConnectionManager()
@@ -70,7 +66,6 @@
func GetModbusConnection(ipAddr string) (plc4go.PlcConnection, error) {
    if conn, ok := connectionManager.GetConnection(ipAddr); ok {
        time.Sleep(time.Second * 1)
        return conn, nil
    }
    // 创建一个上下文,并设置 3 秒超时
@@ -82,7 +77,6 @@
        return nil, err
    }
    connectionManager.AddConnection(ipAddr, conn)
    time.Sleep(time.Second * 1)
    return conn, nil
}
service/plc.go
@@ -6,6 +6,7 @@
    "apsClient/model"
    "apsClient/pkg/logx"
    "apsClient/pkg/plc"
    "apsClient/pkg/plc/modbusx"
    "apsClient/pkg/plccom"
    "encoding/binary"
    "errors"
@@ -85,20 +86,21 @@
    if plcConfig.Method == constvar.PlcMethodModbusTCP {
        ipAddr = fmt.Sprintf("%s:%v", plcConfig.Address, plcConfig.Port)
        conn, err := plc.GetModbusConnection(ipAddr)
        if err != nil {
            logx.Errorf("plc write failed, 连接plc失败: %v", err.Error())
            plcConfig.CurrentErr = err
            return PlcWrite(plcConfig, fieldType, position, value)
        }
        result, err := plc.WriteHoldingRegister(conn, startAddress, value)
        //conn, err := plc.GetModbusConnection(ipAddr)
        //if err != nil {
        //    logx.Errorf("plc write failed, 连接plc失败: %v", err.Error())
        //    plcConfig.CurrentErr = err
        //    return PlcWrite(plcConfig, fieldType, position, value)
        //}
        //
        //result, err := plc.WriteHoldingRegister(conn, startAddress, value)
        err = modbusx.Write(ipAddr, uint16(startAddress), value)
        if err != nil {
            logx.Errorf("plc write failed, address: %v, value: %v, err: %v", startAddress, value, err.Error())
            plcConfig.CurrentErr = err
            return PlcWrite(plcConfig, fieldType, position, value)
        }
        logx.Infof("plc write ok, address: %v, value: %v, result: %v", startAddress, value, result)
        logx.Infof("plc write ok, address: %v, value: %v", startAddress, value)
    } else if plcConfig.Method == constvar.PlcMethodSerial {
        ipAddr = conf.Conf.Services.Serial
        if ipAddr == "" {
@@ -116,24 +118,27 @@
    )
    if plcConfig.CurrentTryTimes > plcConfig.MaxTryTimes {
        logx.Errorf("plc write try time beyond max try times, err: %v", plcConfig.CurrentErr)
        return plcConfig.CurrentErr
    }
    plcConfig.CurrentTryTimes++
    if plcConfig.Method == constvar.PlcMethodModbusTCP {
        ipAddr = fmt.Sprintf("%s:%v", plcConfig.Address, plcConfig.Port)
        conn, err := plc.GetModbusConnection(ipAddr)
        if err != nil {
            logx.Errorf("plc write failed, 连接plc失败: %v", err.Error())
            plcConfig.CurrentErr = err
            return PlcWriteDirect(plcConfig, address, value)
        }
        result, err := plc.WriteHoldingRegister(conn, address, value)
        //conn, err := plc.GetModbusConnection(ipAddr)
        //if err != nil {
        //    logx.Errorf("plc write failed, 连接plc失败: %v", err.Error())
        //    plcConfig.CurrentErr = err
        //    return PlcWriteDirect(plcConfig, address, value)
        //}
        //result, err := plc.WriteHoldingRegister(conn, address, value)
        err = modbusx.Write(ipAddr, uint16(address), value)
        if err != nil {
            logx.Errorf("plc write failed, address: %v, value: %v, err: %v", address, value, err.Error())
            plcConfig.CurrentErr = err
            return PlcWriteDirect(plcConfig, address, value)
        }
        logx.Infof("plc write ok, address: %v, value: %v, result: %v", address, value, result)
        logx.Infof("plc write ok, address: %v, value: %v", address, value)
    } else if plcConfig.Method == constvar.PlcMethodSerial {
        ipAddr = conf.Conf.Services.Serial
        if ipAddr == "" {
@@ -157,12 +162,13 @@
    plcConfig.CurrentTryTimes++
    if plcConfig.Method == constvar.PlcMethodModbusTCP {
        ipAddr = fmt.Sprintf("%s:%v", plcConfig.Address, plcConfig.Port)
        conn, err := plc.GetModbusConnection(ipAddr)
        if err != nil {
            plcConfig.CurrentErr = err
            return PlcReadDirect(plcConfig, address, dataLength, valueType)
        }
        value, err := plc.ReadHoldingRegister(conn, address, dataLength)
        //conn, err := plc.GetModbusConnection(ipAddr)
        //if err != nil {
        //    plcConfig.CurrentErr = err
        //    return PlcReadDirect(plcConfig, address, dataLength, valueType)
        //}
        //value, err := plc.ReadHoldingRegister(conn, address, dataLength)
        value, err := modbusx.Read(ipAddr, uint16(address), uint16(dataLength))
        if err != nil {
            plcConfig.CurrentErr = err
            return PlcReadDirect(plcConfig, address, dataLength, valueType)