fix
zhangqian
2023-12-01 8324f872ef3a4d0c978a9b1d062800c6a1701c12
pkg/plc/modbusx/modbus.go
@@ -2,7 +2,6 @@
import (
   "encoding/binary"
   "sync/atomic"
)
func Read(ipAddr string, address uint16, quantity uint16) (data []byte, err error) {
@@ -19,74 +18,28 @@
}
func Write(ipAddr string, address uint16, value int) (err error) {
   address--
   var bytesVal []byte
   if value <= 1<<16 {
      uint16ToBytes(uint16(value))
   } else {
      bytesVal = intToBytes(value)
   }
   bytesVal = intToBytes(value)
   cli := getModbusConnection(ipAddr)
   _, err = cli.WriteMultipleRegisters(address, uint16(len(bytesVal)), bytesVal)
   dealErr(err, ipAddr)
   return err
}
func uint16ToBytes(value uint16) []byte {
   // 创建一个长度为2的字节切片
   bytes := make([]byte, 2)
   // 将 uint16 的值写入字节切片,可以选择使用大端或小端字节序
   bytes[0] = byte(value >> 8) // 获取高8位
   bytes[1] = byte(value)      // 获取低8位
   return bytes
}
func intToBytes(value int) []byte {
   // 创建一个长度为4的字节切片,用于存储 int 值
   bytes := make([]byte, 4)
   // 使用 binary 包将 int 值转换为字节切片
   binary.BigEndian.PutUint32(bytes, uint32(value))
   return bytes
func intToBytes(value int) (data []byte) {
   if value <= 1<<16 {
      data = make([]byte, 2)
      binary.BigEndian.PutUint16(data, uint16(value))
   } else {
      data = make([]byte, 4)
      binary.BigEndian.PutUint32(data, uint32(value))
   }
   return
}
func dealErr(err error, ipAddr string) {
   if err != nil {
      unsetModbusConnection(ipAddr)       //失败则删除缓存的连接
      FailureRemainingOpportunitiesDecr() //减少失败剩余机会
   } else {
      FailureRemainingOpportunitiesReset() //重置失败剩余机会
      unsetModbusConnection(ipAddr) //失败则删除缓存的连接
   }
}
var connectionStatus atomic.Bool
var failureRemainingOpportunities atomic.Int64
const (
   defaultFailureRemainingOpportunities = 20
)
func IsConnect() bool {
   return connectionStatus.Load()
}
func FailureRemainingOpportunitiesDecr() {
   newValue := failureRemainingOpportunities.Add(-1)
   if newValue <= 0 {
      connectionStatus.Store(false)
   }
   return
}
func FailureRemainingOpportunitiesReset() {
   if failureRemainingOpportunities.Load() < defaultFailureRemainingOpportunities {
      failureRemainingOpportunities.Store(defaultFailureRemainingOpportunities)
   }
   if connectionStatus.Load() == false {
      connectionStatus.Store(true)
   }
   return
}