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