From a699ff979c84d024ca33fb1139224258f278319f Mon Sep 17 00:00:00 2001
From: zhangqian <zhangqian@123.com>
Date: 星期五, 20 十月 2023 11:32:23 +0800
Subject: [PATCH] debug
---
pkg/plc/plc4x.go | 145 +++++++++++++++++++++++++++++++++++++----------
1 files changed, 113 insertions(+), 32 deletions(-)
diff --git a/pkg/plc/plc4x.go b/pkg/plc/plc4x.go
index 8afb487..68562a6 100644
--- a/pkg/plc/plc4x.go
+++ b/pkg/plc/plc4x.go
@@ -1,22 +1,90 @@
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]
+ if !ok {
+ return nil, false
+ }
+ //if ok, _ := cm.CheckConnect(conn, time.Second); !ok {
+ // conn.Close()
+ //}
+
+ return conn, true
+}
+
+var connectionManager = newPlcConnectionManager()
+
+func (cm *ConnectionManager) AddConnection(address string, connection plc4go.PlcConnection) {
+ cm.mu.Lock()
+ defer cm.mu.Unlock()
+
+ cm.connections[address] = connection
+}
+
+func (cm *ConnectionManager) CheckConnect(conn plc4go.PlcConnection, timeout time.Duration) (bool, error) {
+ pingCh := conn.Ping()
+ timer := time.NewTimer(timeout)
+
+ select {
+ case err := <-pingCh:
+ if err == nil {
+ return true, nil
+ }
+ return false, err.GetErr()
+ case <-timer.C:
+ return false, fmt.Errorf("connection timed out after %s", timeout)
+ }
+}
+
+func GetModbusConnection(ipAddr string) (plc4go.PlcConnection, error) {
+ if conn, ok := connectionManager.GetConnection(ipAddr); ok {
+ return conn, nil
+ }
+ // 鍒涘缓涓�涓笂涓嬫枃锛屽苟璁剧疆 3 绉掕秴鏃�
+ ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
+ defer cancel()
+ conn, err := newGetModbusConnection(ctx, ipAddr)
+ if err != nil {
+ logx.Errorf("new modbus connection err: %v", err.Error())
+ 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 +93,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
@@ -98,27 +170,36 @@
return result, nil
}
+func ReadHoldingRegister(connection plc4go.PlcConnection, address, length int) ([]byte, error) {
+ if length > 1 {
+ return readHoldingRegisterList(connection, address, length)
+ }
+
+ 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