zhangqian
2024-04-25 2d6875c93b25d0b7336c7fa11e066d213259fe2e
pkg/plc/apacheplc4x/modbus.go
@@ -1,7 +1,6 @@
package apacheplc4x
import (
   "apsClient/conf"
   "apsClient/pkg/logx"
   "context"
   "errors"
@@ -10,36 +9,39 @@
   "github.com/apache/plc4x/plc4go/pkg/api/drivers"
   apiModel "github.com/apache/plc4x/plc4go/pkg/api/model"
   "github.com/apache/plc4x/plc4go/pkg/api/transports"
   "github.com/spf13/cast"
   "sync/atomic"
   "time"
)
var driverManager plc4go.PlcDriverManager
func init() {
   // 创建驱动管理器
   driverManager = plc4go.NewPlcDriverManager()
   // 注册TCP传输
   transports.RegisterTcpTransport(driverManager)
   // 注册串口传输
   transports.RegisterSerialTransport(driverManager)
   // 注册驱动
   drivers.RegisterModbusTcpDriver(driverManager)
   drivers.RegisterModbusRtuDriver(driverManager)
}
func GetModbusConnection(ipAddr string) (plc4go.PlcConnection, error) {
   // 创建一个上下文,并设置 3 秒超时
   ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
   defer cancel()
   conn, err := newGetModbusConnection(ctx, ipAddr)
   conn, err := newModbusTCPConnection(ctx, ipAddr)
   if err != nil {
      logx.Errorf("new modbus connection err: %v", err.Error())
      return nil, err
   }
   return conn, nil
}
func newGetModbusConnection(ctx context.Context, ipAddr string) (plc4go.PlcConnection, error) {
   // 创建驱动管理器
   driverManager := plc4go.NewPlcDriverManager()
   // 注册TCP传输
   transports.RegisterTcpTransport(driverManager)
   // 注册驱动
   //drivers.RegisterKnxDriver(driverManager)
   drivers.RegisterModbusTcpDriver(driverManager)
func newModbusTCPConnection(ctx context.Context, ipAddr string) (plc4go.PlcConnection, error) {
   // 通过TCP连接PLC设备
   connectionString := fmt.Sprintf("modbus-tcp://%s", ipAddr)
   connectionRequestChanel := driverManager.GetConnection(connectionString)
   // 等待连接响应,同时考虑上下文的超时
   select {
   case connectionResult := <-connectionRequestChanel:
@@ -52,9 +54,9 @@
   }
}
func readHoldingRegisterSingle(connection plc4go.PlcConnection, address int) ([]byte, error) {
func readHoldingRegisterSingle(connection plc4go.PlcConnection, address int, intType string) ([]byte, error) {
   tag := fmt.Sprintf("tag:%v", address)
   tagAddress := getTagAddress(address, 1)
   tagAddress := getTagAddress(address, 1, intType)
   // 读模式
   readRequest, err := connection.ReadRequestBuilder().AddTagAddress(tag, tagAddress).Build()
@@ -82,9 +84,9 @@
}
func readHoldingRegisterList(connection plc4go.PlcConnection, address, length int) ([]byte, error) {
func readHoldingRegisterList(connection plc4go.PlcConnection, address, length int, intType string) ([]byte, error) {
   tag := fmt.Sprintf("tag:%v:%v", address, length)
   tagAddress := getTagAddress(address, length)
   tagAddress := getTagAddress(address, length, intType)
   // 读模式
   readRequest, err := connection.ReadRequestBuilder().AddTagAddress(tag, tagAddress).Build()
@@ -117,7 +119,7 @@
   return result, nil
}
func ReadHoldingRegister(ipAddr string, address, length int) ([]byte, error) {
func ReadHoldingRegister(ipAddr string, address, length int, intType string) ([]byte, error) {
   connection, err := GetModbusConnection(ipAddr)
   dealErr(err, ipAddr)
   if err != nil {
@@ -125,14 +127,13 @@
   }
   defer connection.Close()
   if length > 1 {
      return readHoldingRegisterList(connection, address, length)
      return readHoldingRegisterList(connection, address, length, intType)
   }
   return readHoldingRegisterSingle(connection, address)
   return readHoldingRegisterSingle(connection, address, intType)
}
func getTagAddress(address int, length int) string {
   intType := conf.Conf.PLC.ModbusIntType
func getTagAddress(address int, length int, intType string) string {
   if intType == "" {
      intType = "DINT"
   }
@@ -143,7 +144,7 @@
   }
}
func WriteHoldingRegister(ipAddr string, address int, value any) (string, error) {
func WriteHoldingRegister(ipAddr string, address int, value any, intType string) (string, error) {
   connection, err := GetModbusConnection(ipAddr)
   dealErr(err, ipAddr)
   if err != nil {
@@ -152,11 +153,7 @@
   defer connection.Close()
   tag := fmt.Sprintf("tag:%v:w", address)
   var tagAddress string
   if cast.ToInt32(value) > 2<<16 {
      tagAddress = getTagAddress(address, 2)
   } else {
      tagAddress = getTagAddress(address, 1)
   }
   tagAddress = getTagAddress(address, 1, intType)
   // 写模式
   writeRequest, err := connection.WriteRequestBuilder().AddTagAddress(tag, tagAddress, value).Build()