package modbusx
|
|
import (
|
"encoding/binary"
|
"sync/atomic"
|
)
|
|
func Read(ipAddr string, address uint16, quantity uint16) (data []byte, err error) {
|
address--
|
cli := getModbusConnection(ipAddr)
|
data, err = cli.ReadHoldingRegisters(address, quantity)
|
dealErr(err, ipAddr)
|
if err != nil {
|
cli = getModbusConnection(ipAddr)
|
data, err = cli.ReadHoldingRegisters(address, quantity)
|
dealErr(err, ipAddr)
|
}
|
return
|
}
|
|
func Write(ipAddr string, address uint16, value int) (err error) {
|
address--
|
var bytesVal []byte
|
bytesVal = intToBytes(value)
|
cli := getModbusConnection(ipAddr)
|
_, err = cli.WriteMultipleRegisters(address, uint16(len(bytesVal)), bytesVal)
|
dealErr(err, ipAddr)
|
return err
|
}
|
|
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() //重置失败剩余机会
|
}
|
}
|
|
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
|
}
|