From b555874608be2e4bb40cceba60b497c04caef842 Mon Sep 17 00:00:00 2001
From: zhangqian <zhangqian@123.com>
Date: 星期二, 12 九月 2023 14:17:51 +0800
Subject: [PATCH] 三菱协议更改

---
 pkg/plc/plc4x.go |  119 ++++++++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 85 insertions(+), 34 deletions(-)

diff --git a/pkg/plc/plc4x.go b/pkg/plc/plc4x.go
index 3e6c4a6..529c516 100644
--- a/pkg/plc/plc4x.go
+++ b/pkg/plc/plc4x.go
@@ -1,22 +1,68 @@
 package plc
 
 import (
+	"apsClient/pkg/logx"
+	"context"
 	"errors"
 	"fmt"
 	apiModel "github.com/apache/plc4x/plc4go/pkg/api/model"
+	"sync"
+	"time"
 
 	plc4go "github.com/apache/plc4x/plc4go/pkg/api"
 	"github.com/apache/plc4x/plc4go/pkg/api/drivers"
 	"github.com/apache/plc4x/plc4go/pkg/api/transports"
 )
 
-func NewModbusConnection(ipAddr string) (plc4go.PlcConnection, error) {
+type ConnectionManager struct {
+	connections map[string]plc4go.PlcConnection
+	mu          sync.Mutex
+}
+
+func newPlcConnectionManager() *ConnectionManager {
+	return &ConnectionManager{
+		connections: make(map[string]plc4go.PlcConnection),
+	}
+}
+
+func (cm *ConnectionManager) GetConnection(address string) (plc4go.PlcConnection, bool) {
+	cm.mu.Lock()
+	defer cm.mu.Unlock()
+
+	conn, ok := cm.connections[address]
+	return conn, ok
+}
+
+var connectionManager = newPlcConnectionManager()
+
+func (cm *ConnectionManager) AddConnection(address string, connection plc4go.PlcConnection) {
+	cm.mu.Lock()
+	defer cm.mu.Unlock()
+
+	cm.connections[address] = connection
+}
+func GetModbusConnection(ipAddr string) (plc4go.PlcConnection, error) {
+	if conn, ok := connectionManager.GetConnection(ipAddr); ok {
+		if conn.IsConnected() {
+			return conn, nil
+		}
+	}
+	// 鍒涘缓涓�涓笂涓嬫枃锛屽苟璁剧疆 3 绉掕秴鏃�
+	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
+	defer cancel()
+	conn, err := newGetModbusConnection(ctx, ipAddr)
+	if err != nil {
+		return nil, err
+	}
+	connectionManager.AddConnection(ipAddr, conn)
+	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)
@@ -25,69 +71,73 @@
 	connectionString := fmt.Sprintf("modbus-tcp://%s", ipAddr)
 	connectionRequestChanel := driverManager.GetConnection(connectionString)
 
-	// 绛夊緟杩炴帴鍝嶅簲
-	connectionResult := <-connectionRequestChanel
-
-	// 鍒ゆ柇鏄惁杩炴帴鎴愬姛
-	if err := connectionResult.GetErr(); err != nil {
-		return nil, err
+	// 绛夊緟杩炴帴鍝嶅簲锛屽悓鏃惰�冭檻涓婁笅鏂囩殑瓒呮椂
+	select {
+	case connectionResult := <-connectionRequestChanel:
+		if err := connectionResult.GetErr(); err != nil {
+			return nil, err
+		}
+		return connectionResult.GetConnection(), nil
+	case <-ctx.Done():
+		return nil, ctx.Err()
 	}
-
-	return connectionResult.GetConnection(), nil
 }
-func ReadHoldingRegisterSingle(connection plc4go.PlcConnection, address int) ([]byte, error) {
+
+func readHoldingRegisterSingle(connection plc4go.PlcConnection, address int) ([]byte, error) {
+	tag := fmt.Sprintf("tag:%v", address)
 	tagAddress := fmt.Sprintf("holding-register:%d:UINT", address)
 
 	// 璇绘ā寮�
-	readRequest, err := connection.ReadRequestBuilder().AddTagAddress("tag", tagAddress).Build()
+	readRequest, err := connection.ReadRequestBuilder().AddTagAddress(tag, tagAddress).Build()
 	if err != nil {
-		fmt.Printf("preparing read-request:%s\n", err.Error())
+		logx.Errorf("preparing read-request:%s\n", err.Error())
 		return nil, err
 	}
 
 	// 鎵ц
 	readResult := <-readRequest.Execute()
 	if err := readResult.GetErr(); err != nil {
-		fmt.Printf("execting read-request:%s\n", err.Error())
+		logx.Errorf("execting read-request:%s\n", err.Error())
 		return nil, err
 	}
 
 	// 鍒ゆ柇鍝嶅簲鐮佹槸鍚︽纭�
-	if readResult.GetResponse().GetResponseCode("tag") != apiModel.PlcResponseCode_OK {
-		fmt.Printf("error an non-ok return code: %s", readResult.GetResponse().GetResponseCode("tag").GetName())
+	if readResult.GetResponse().GetResponseCode(tag) != apiModel.PlcResponseCode_OK {
+		logx.Errorf("error an non-ok return code: %s", readResult.GetResponse().GetResponseCode(tag).GetName())
 		return nil, nil
 	}
 
-	value := readResult.GetResponse().GetValue("tag")
+	value := readResult.GetResponse().GetValue(tag)
 
 	return value.GetRaw(), err
 
 }
 
-func ReadHoldingRegisterList(connection plc4go.PlcConnection, address, length int) ([]byte, error) {
+func readHoldingRegisterList(connection plc4go.PlcConnection, address, length int) ([]byte, error) {
+	tag := fmt.Sprintf("tag:%v:%v", address, length)
 	tagAddress := fmt.Sprintf("holding-register:%d:UINT[%d]", address, length)
 
 	// 璇绘ā寮�
-	readRequest, err := connection.ReadRequestBuilder().AddTagAddress("tag", tagAddress).Build()
+	readRequest, err := connection.ReadRequestBuilder().AddTagAddress(tag, tagAddress).Build()
 	if err != nil {
-		fmt.Printf("preparing read-request:%s\n", err.Error())
+		logx.Errorf("preparing read-request:%s\n", err.Error())
 		return nil, err
 	}
 
 	// 鎵ц
 	readResult := <-readRequest.Execute()
 	if err := readResult.GetErr(); err != nil {
-		fmt.Printf("execting read-request:%s\n", err.Error())
+		logx.Errorf("execting read-request:%s\n", err.Error())
 		return nil, err
 	}
 
 	// 鍒ゆ柇鍝嶅簲鐮佹槸鍚︽纭�
-	if readResult.GetResponse().GetResponseCode("tag") != apiModel.PlcResponseCode_OK {
-		fmt.Printf("error an non-ok return code: %s", readResult.GetResponse().GetResponseCode("tag").GetName())
-		return nil, errors.New("error  code: " + readResult.GetResponse().GetResponseCode("tag").GetName())
+	if readResult.GetResponse().GetResponseCode(tag) != apiModel.PlcResponseCode_OK {
+		logx.Errorf("error an non-ok return code: %s", readResult.GetResponse().GetResponseCode(tag).GetName())
+		return nil, errors.New("error  code: " + readResult.GetResponse().GetResponseCode(tag).GetName())
 	}
 
-	value := readResult.GetResponse().GetValue("tag")
+	value := readResult.GetResponse().GetValue(tag)
 
 	var result []byte
 
@@ -100,33 +150,34 @@
 
 func ReadHoldingRegister(connection plc4go.PlcConnection, address, length int) ([]byte, error) {
 	if length > 1 {
-		return ReadHoldingRegisterList(connection, address, length)
+		return readHoldingRegisterList(connection, address, length)
 	}
 
-	return ReadHoldingRegisterSingle(connection, address)
+	return readHoldingRegisterSingle(connection, address)
 }
 
 func WriteHoldingRegister(connection plc4go.PlcConnection, address int, value any) (string, error) {
+	tag := fmt.Sprintf("tag:%v:w", address)
 	tagAddress := fmt.Sprintf("holding-register:%d:UINT", address)
 
 	// 鍐欐ā寮�
-	writeRequest, err := connection.WriteRequestBuilder().AddTagAddress("tag", tagAddress, value).Build()
+	writeRequest, err := connection.WriteRequestBuilder().AddTagAddress(tag, tagAddress, value).Build()
 	if err != nil {
-		fmt.Printf("preparing read-request:%s\n", err.Error())
+		logx.Errorf("preparing read-request:%s\n", err.Error())
 		return "", err
 	}
 
 	// 鎵ц
 	writeResult := <-writeRequest.Execute()
 	if err := writeResult.GetErr(); err != nil {
-		fmt.Printf("execting read-request:%s\n", err.Error())
+		logx.Errorf("execting read-request:%s\n", err.Error())
 		return "", err
 	}
 
 	// 鍒ゆ柇鍝嶅簲鐮佹槸鍚︽纭�
-	if writeResult.GetResponse().GetResponseCode("tag") != apiModel.PlcResponseCode_OK {
-		fmt.Printf("error an non-ok return code: %s", writeResult.GetResponse().GetResponseCode("tag").GetName())
-		return "", errors.New("error  code: " + writeResult.GetResponse().GetResponseCode("tag").GetName())
+	if writeResult.GetResponse().GetResponseCode(tag) != apiModel.PlcResponseCode_OK {
+		logx.Errorf("error an non-ok return code: %s", writeResult.GetResponse().GetResponseCode(tag).GetName())
+		return "", errors.New("error  code: " + writeResult.GetResponse().GetResponseCode(tag).GetName())
 	}
 
 	result := writeResult.GetResponse().String()

--
Gitblit v1.8.0