| | |
| | | package plc |
| | | |
| | | import ( |
| | | "context" |
| | | "errors" |
| | | "fmt" |
| | | apiModel "github.com/apache/plc4x/plc4go/pkg/api/model" |
| | | "github.com/apache/plc4x/plc4go/spi/options" |
| | | "sync" |
| | | "time" |
| | | |
| | |
| | | return conn, nil |
| | | } |
| | | } |
| | | // 创建一个上下文,并设置 5 秒超时 |
| | | ctx, cancel := context.WithTimeout(context.Background(), 5*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) { |
| | | // 创建驱动管理器 |
| | | option := options.WithReceiveTimeout(time.Second * 5) //五秒超时 |
| | | driverManager := plc4go.NewPlcDriverManager(option) |
| | | driverManager := plc4go.NewPlcDriverManager() |
| | | // 注册TCP传输 |
| | | transports.RegisterTcpTransport(driverManager) |
| | | |
| | | // 注册驱动 |
| | | //drivers.RegisterKnxDriver(driverManager) |
| | | drivers.RegisterModbusTcpDriver(driverManager) |
| | |
| | | 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() |
| | | } |
| | | |
| | | conn := connectionResult.GetConnection() |
| | | connectionManager.AddConnection(ipAddr, conn) |
| | | return conn, nil |
| | | } |
| | | |
| | | 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()) |
| | | return nil, err |
| | |
| | | } |
| | | |
| | | 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()) |
| | | return nil, err |
| | |
| | | } |
| | | |
| | | 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()) |
| | | return "", err |