zhangqian
2023-12-19 be40c6bbad18cee0444c50069d98967cd26b6c3b
pkg/plc/apacheplc4x/modbusrtu.go
@@ -1,84 +1,85 @@
package apacheplc4x
import (
   "apsClient/model/common"
   "apsClient/pkg/logx"
   "context"
   "errors"
   "fmt"
   plc4go "github.com/apache/plc4x/plc4go/pkg/api"
   apiModel "github.com/apache/plc4x/plc4go/pkg/api/model"
   "github.com/spf13/cast"
   "time"
)
func newModbusRTUConnection(c *common.RTUConfig) (plc4go.PlcConnection, error) {
   ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
   // 创建一个新的 PLC 连接
   connectionString := fmt.Sprintf("modbus-rtu:serial://%s?baudrate=%d&databits=%d&stopbits=%d&parity=%s", c.SerialName, c.BaudRate, c.DataBit, c.StopBit, c.Parity.ToString())
   connectionRequestChanel := driverManager.GetConnection(connectionString)
   // 等待连接响应,同时考虑上下文的超时
   select {
   case connectionResult := <-connectionRequestChanel:
      cancel()
      if err := connectionResult.GetErr(); err != nil {
         return nil, err
      }
      return connectionResult.GetConnection(), nil
   case <-ctx.Done():
      cancel()
      return nil, errors.New("connect plc by modbusRTU timeout")
   }
}
func ReadHoldingRegisterByRTU(c *common.RTUConfig, address, length int) ([]byte, error) {
   connection, err := newModbusRTUConnection(c)
   if err != nil {
      return nil, err
   }
   defer connection.Close()
   if length > 1 {
      return readHoldingRegisterList(connection, address, length)
   }
   return readHoldingRegisterSingle(connection, address)
}
func WriteHoldingRegisterByRTU(c *common.RTUConfig, address int, value any) (string, error) {
   connection, err := newModbusRTUConnection(c)
   if err != nil {
      return "", err
   }
   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)
   }
   // 写模式
   writeRequest, err := connection.WriteRequestBuilder().AddTagAddress(tag, tagAddress, value).Build()
   if err != nil {
      logx.Errorf("plc4x preparing read-request:%s\n", err.Error())
      return "", err
   }
   // 执行
   writeResult := <-writeRequest.Execute()
   if err := writeResult.GetErr(); err != nil {
      logx.Errorf("plc4x execute write-request:%s\n", err.Error())
      return "", err
   }
   // 判断响应码是否正确
   if writeResult.GetResponse().GetResponseCode(tag) != apiModel.PlcResponseCode_OK {
      logx.Errorf("plc4x  response error code: %s", writeResult.GetResponse().GetResponseCode(tag).GetName())
      return "", errors.New("error  code: " + writeResult.GetResponse().GetResponseCode(tag).GetName())
   }
   result := writeResult.GetResponse().String()
   return result, nil
}
//
//import (
//   "apsClient/model/common"
//   "apsClient/pkg/logx"
//   "context"
//   "errors"
//   "fmt"
//   plc4go "github.com/apache/plc4x/plc4go/pkg/api"
//   apiModel "github.com/apache/plc4x/plc4go/pkg/api/model"
//   "github.com/spf13/cast"
//   "time"
//)
//
//func newModbusRTUConnection(c *common.RTUConfig) (plc4go.PlcConnection, error) {
//   ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
//   // 创建一个新的 PLC 连接
//   connectionString := fmt.Sprintf("modbus-rtu:serial://%s?baudrate=%d&databits=%d&stopbits=%d&parity=%s", c.SerialName, c.BaudRate, c.DataBit, c.StopBit, c.Parity.ToString())
//   connectionRequestChanel := driverManager.GetConnection(connectionString)
//   // 等待连接响应,同时考虑上下文的超时
//   select {
//   case connectionResult := <-connectionRequestChanel:
//      cancel()
//      if err := connectionResult.GetErr(); err != nil {
//         return nil, err
//      }
//      return connectionResult.GetConnection(), nil
//   case <-ctx.Done():
//      cancel()
//      return nil, errors.New("connect plc by modbusRTU timeout")
//   }
//}
//
//func ReadHoldingRegisterByRTU(c *common.RTUConfig, address, length int) ([]byte, error) {
//   connection, err := newModbusRTUConnection(c)
//   if err != nil {
//      return nil, err
//   }
//   defer connection.Close()
//   if length > 1 {
//      return readHoldingRegisterList(connection, address, length)
//   }
//
//   return readHoldingRegisterSingle(connection, address)
//}
//
//func WriteHoldingRegisterByRTU(c *common.RTUConfig, address int, value any) (string, error) {
//   connection, err := newModbusRTUConnection(c)
//   if err != nil {
//      return "", err
//   }
//   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)
//   }
//
//   // 写模式
//   writeRequest, err := connection.WriteRequestBuilder().AddTagAddress(tag, tagAddress, value).Build()
//   if err != nil {
//      logx.Errorf("plc4x preparing read-request:%s\n", err.Error())
//      return "", err
//   }
//
//   // 执行
//   writeResult := <-writeRequest.Execute()
//   if err := writeResult.GetErr(); err != nil {
//      logx.Errorf("plc4x execute write-request:%s\n", err.Error())
//      return "", err
//   }
//
//   // 判断响应码是否正确
//   if writeResult.GetResponse().GetResponseCode(tag) != apiModel.PlcResponseCode_OK {
//      logx.Errorf("plc4x  response error code: %s", writeResult.GetResponse().GetResponseCode(tag).GetName())
//      return "", errors.New("error  code: " + writeResult.GetResponse().GetResponseCode(tag).GetName())
//   }
//
//   result := writeResult.GetResponse().String()
//
//   return result, nil
//}