From d91a802e7aa2ad4075ed803b8ddc7536a91a0ef0 Mon Sep 17 00:00:00 2001
From: zhangqian <zhangqian@123.com>
Date: 星期五, 27 十月 2023 20:33:06 +0800
Subject: [PATCH] update

---
 constvar/const.go                     |   12 +++
 pkg/plc/modbusx/modbus.go             |   36 --------
 pkg/plc/apacheplc4x/modbus.go         |   28 ++++---
 pkg/plc/apacheplc4x/modbusrtu.go      |    1 
 pkg/plc/modbusx/modbusrtu.go          |   63 ++-------------
 pkg/plc/modbusx/connection_manager.go |   46 +++++++++++
 6 files changed, 83 insertions(+), 103 deletions(-)

diff --git a/constvar/const.go b/constvar/const.go
index 8976494..abe1c72 100644
--- a/constvar/const.go
+++ b/constvar/const.go
@@ -79,3 +79,15 @@
 	ParityOdd  Parity = 2 //鍋舵牎楠�
 	ParityNull Parity = 3 //鏃犳牎楠�
 )
+
+func (p Parity) String() string {
+	switch p {
+	case ParityEven:
+		return "E"
+	case ParityOdd:
+		return "O"
+	case ParityNull:
+		return "N"
+	}
+	return ""
+}
diff --git a/pkg/plc/apacheplc4x/modbus.go b/pkg/plc/apacheplc4x/modbus.go
index dd3621f..e828403 100644
--- a/pkg/plc/apacheplc4x/modbus.go
+++ b/pkg/plc/apacheplc4x/modbus.go
@@ -15,31 +15,35 @@
 	"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 := newModbusConnection(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 newModbusConnection(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:
diff --git a/pkg/plc/apacheplc4x/modbusrtu.go b/pkg/plc/apacheplc4x/modbusrtu.go
index 8c50ff5..6692a65 100644
--- a/pkg/plc/apacheplc4x/modbusrtu.go
+++ b/pkg/plc/apacheplc4x/modbusrtu.go
@@ -15,7 +15,6 @@
 func newModbusRTUConnection(c *common.RTUConfig) (plc4go.PlcConnection, error) {
 	ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
 	// 鍒涘缓涓�涓柊鐨� PLC 杩炴帴
-	driverManager := plc4go.NewPlcDriverManager()
 	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)
 	connectionRequestChanel := driverManager.GetConnection(connectionString)
 	// 绛夊緟杩炴帴鍝嶅簲锛屽悓鏃惰�冭檻涓婁笅鏂囩殑瓒呮椂
diff --git a/pkg/plc/modbusx/connection_manager.go b/pkg/plc/modbusx/connection_manager.go
index ae0b377..4389fe5 100644
--- a/pkg/plc/modbusx/connection_manager.go
+++ b/pkg/plc/modbusx/connection_manager.go
@@ -2,6 +2,8 @@
 
 import (
 	"apsClient/conf"
+	"apsClient/model/common"
+	"apsClient/pkg/logx"
 	"github.com/goburrow/modbus"
 	"sync"
 	"time"
@@ -49,7 +51,7 @@
 	if conn, ok := connectionManager.GetConnection(ipAddr); ok {
 		return conn
 	}
-	conn := newGetModbusConnection(ipAddr)
+	conn := newModbusConnection(ipAddr)
 	connectionManager.AddConnection(ipAddr, conn)
 	return conn
 }
@@ -65,9 +67,49 @@
 	}
 }
 
-func newGetModbusConnection(ipAddr string) modbus.Client {
+func newModbusConnection(ipAddr string) modbus.Client {
 	handler = modbus.NewTCPClientHandler(ipAddr)
 	handler.Timeout = 10 * time.Second
 	handler.SlaveId = byte(conf.Conf.PLC.SlaveId)
 	return modbus.NewClient(handler)
 }
+
+var rtuHandler *modbus.RTUClientHandler
+
+func getModbusRTUConnection(c *common.RTUConfig) modbus.Client {
+	if conn, ok := connectionManager.GetConnection(c.SerialName); ok {
+		return conn
+	}
+	conn := newModbusRTUConnection(c)
+	connectionManager.AddConnection(c.SerialName, conn)
+	return conn
+}
+
+func unsetModbusRTUConnection(serialName string) {
+	_, ok := connectionManager.GetConnection(serialName)
+	if !ok {
+		return
+	}
+	connectionManager.RemoveConnection(serialName)
+	if handler != nil {
+		handler.Close()
+	}
+}
+
+func newModbusRTUConnection(c *common.RTUConfig) modbus.Client {
+	// Modbus RTU/ASCII
+	rtuHandler = modbus.NewRTUClientHandler(c.SerialName)
+	rtuHandler.BaudRate = c.BaudRate
+	rtuHandler.DataBits = c.DataBit
+	rtuHandler.Parity = c.Parity.String()
+	rtuHandler.StopBits = c.StopBit
+	rtuHandler.SlaveId = 1
+	rtuHandler.Timeout = 5 * time.Second
+
+	err := rtuHandler.Connect()
+	if err != nil {
+		logx.Errorf("getModbusRTUConnection  Connect err:%v, config: %+v", err, c)
+		return nil
+	}
+	return modbus.NewClient(rtuHandler)
+}
diff --git a/pkg/plc/modbusx/modbus.go b/pkg/plc/modbusx/modbus.go
index 2d323ec..1a779c3 100644
--- a/pkg/plc/modbusx/modbus.go
+++ b/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) {
@@ -41,39 +40,6 @@
 
 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
 }
diff --git a/pkg/plc/modbusx/modbusrtu.go b/pkg/plc/modbusx/modbusrtu.go
index 0d40e43..253bc88 100644
--- a/pkg/plc/modbusx/modbusrtu.go
+++ b/pkg/plc/modbusx/modbusrtu.go
@@ -1,80 +1,37 @@
 package modbusx
 
 import (
-	"apsClient/constvar"
 	"apsClient/model/common"
-	"apsClient/pkg/logx"
-	"github.com/goburrow/modbus"
-	"time"
 )
 
 func ReadByRTU(c *common.RTUConfig, address uint16, quantity uint16) (data []byte, err error) {
-	address--
-	cli, err := getModbusRTUConnection(c)
-	if err != nil {
-		return nil, err
-	}
+	cli := getModbusRTUConnection(c)
 	data, err = cli.ReadHoldingRegisters(address, quantity)
+	dealRTUErr(err, c.SerialName)
 	if err != nil {
-		cli, err = getModbusRTUConnection(c)
-		if err != nil {
-			return nil, err
-		}
+		cli = getModbusRTUConnection(c)
 		data, err = cli.ReadHoldingRegisters(address, quantity)
-	}
-	if err != nil {
-		logx.Errorf("ReadByRTU ReadHoldingRegisters err:%v", err)
+		dealRTUErr(err, c.SerialName)
 	}
 	return
 }
 
 func WriteByRTU(c *common.RTUConfig, address uint16, value int) (err error) {
-	address--
 	var bytesVal []byte
 	bytesVal = intToBytes(value)
-
-	cli, err := getModbusRTUConnection(c)
-	if err != nil {
-		return err
-	}
+	cli := getModbusRTUConnection(c)
 	_, err = cli.WriteMultipleRegisters(address, uint16(len(bytesVal)), bytesVal)
+	dealRTUErr(err, c.SerialName)
 	if err != nil {
-		cli, err = getModbusRTUConnection(c)
-		if err != nil {
-			return err
-		}
+		cli = getModbusRTUConnection(c)
 		_, err = cli.WriteMultipleRegisters(address, uint16(len(bytesVal)), bytesVal)
-	}
-	if err != nil {
-		logx.Errorf("WriteByRTU WriteMultipleRegisters err:%v", err)
+		dealRTUErr(err, c.SerialName)
 	}
 	return err
 }
 
-func getModbusRTUConnection(c *common.RTUConfig) (cli modbus.Client, err error) {
-	// Modbus RTU/ASCII
-	h := modbus.NewRTUClientHandler(c.SerialName)
-	h.BaudRate = c.BaudRate
-	h.DataBits = c.DataBit
-	switch c.Parity {
-	case constvar.ParityEven:
-		h.Parity = "E"
-	case constvar.ParityOdd:
-		h.Parity = "O"
-	case constvar.ParityNull:
-		h.Parity = "N"
-	}
-
-	h.StopBits = c.StopBit
-	h.SlaveId = 1
-	h.Timeout = 5 * time.Second
-
-	err = h.Connect()
+func dealRTUErr(err error, serialName string) {
 	if err != nil {
-		logx.Errorf("getModbusRTUConnection  Connect err:%v, config: %+v", err, c)
-		return nil, err
+		unsetModbusRTUConnection(serialName) //澶辫触鍒欏垹闄ょ紦瀛樼殑杩炴帴
 	}
-	defer h.Close()
-	cli = modbus.NewClient(h)
-	return
 }

--
Gitblit v1.8.0