| | |
| | | package main |
| | | |
| | | import ( |
| | | "encoding/binary" |
| | | "flag" |
| | | "fmt" |
| | | |
| | | plc4go "github.com/apache/plc4x/plc4go/pkg/api" |
| | | "github.com/apache/plc4x/plc4go/pkg/api/drivers" |
| | | apiModel "github.com/apache/plc4x/plc4go/pkg/api/model" |
| | | "github.com/apache/plc4x/plc4go/pkg/api/transports" |
| | | //"github.com/apache/plc4x/plc4go/spi/options" |
| | | "github.com/rs/zerolog" |
| | | ) |
| | | |
| | | var ( |
| | | ipAddr string |
| | | address int |
| | | length int |
| | | format string |
| | | ) |
| | | |
| | | func init() { |
| | | flag.StringVar(&ipAddr, "ip", "", "设备ip") |
| | | flag.StringVar(&format, "format", "hex", "格式化: hex, 十六进制, dec 十进制, str, 字符串") |
| | | flag.IntVar(&address, "addr", 100, "起始地址") |
| | | flag.IntVar(&length, "len", 1, "长度") |
| | | } |
| | | |
| | | func main() { |
| | | flag.Parse() |
| | | |
| | | if ipAddr == "" { |
| | | flag.PrintDefaults() |
| | | return |
| | | } |
| | | |
| | | // 强制读一个地址 |
| | | if length == 0 { |
| | | length = 1 |
| | | } |
| | | |
| | | // 控制日志打印级别 |
| | | zerolog.SetGlobalLevel(zerolog.FatalLevel) |
| | | |
| | | // 创建驱动管理器 |
| | | driverManager := plc4go.NewPlcDriverManager() |
| | | |
| | |
| | | drivers.RegisterModbusTcpDriver(driverManager) |
| | | |
| | | // 通过TCP连接PLC设备 |
| | | connectionRequestChanel := driverManager.GetConnection("modbus-tcp://192.168.1.88") |
| | | connectionString := fmt.Sprintf("modbus-tcp://%s", ipAddr) |
| | | connectionRequestChanel := driverManager.GetConnection(connectionString) |
| | | |
| | | // 等待连接响应 |
| | | connectionResult := <-connectionRequestChanel |
| | |
| | | defer connection.Close() |
| | | |
| | | // 测试是否可以正常通信 |
| | | pingResult := <-connection.Ping() |
| | | if err := pingResult.GetErr(); err != nil { |
| | | fmt.Printf("Couldn't ping device: %s\n", err.Error()) |
| | | //pingResult := <-connection.Ping() |
| | | //if err := pingResult.GetErr(); err != nil { |
| | | // fmt.Printf("Couldn't ping device: %s\n", err.Error()) |
| | | //} |
| | | // |
| | | //// 验证是否可读 |
| | | //if !connection.GetMetadata().CanRead() { |
| | | // fmt.Printf("This connection doesn't support read operations\n") |
| | | // return |
| | | //} |
| | | |
| | | // 将长度按60切割, 太长了modbus不返回 |
| | | for i, len := 0, 60; i < length; i = i + 60 { |
| | | if i+len > length { |
| | | len = length - i |
| | | } |
| | | |
| | | tagAddress := fmt.Sprintf("holding-register:%d:DINT[%d]", address+i, len) |
| | | |
| | | // 读模式 |
| | | readRequest, err := connection.ReadRequestBuilder().AddTagAddress("tag0", tagAddress).Build() |
| | | if err != nil { |
| | | fmt.Printf("Error preparing read-request:%s\n", err.Error()) |
| | | return |
| | | } |
| | | |
| | | // 执行 |
| | | readResult := <-readRequest.Execute() |
| | | if err := readResult.GetErr(); err != nil { |
| | | fmt.Printf("Error execting read-request:%s\n", err.Error()) |
| | | return |
| | | } |
| | | |
| | | // 判断响应码是否正确 |
| | | if readResult.GetResponse().GetResponseCode("tag0") != apiModel.PlcResponseCode_OK { |
| | | fmt.Printf("error an non-ok return code: %s", readResult.GetResponse().GetResponseCode("tag0").GetName()) |
| | | return |
| | | } |
| | | |
| | | // 测试获取变量名称 |
| | | //names := readResult.GetResponse().GetTagNames() |
| | | //fmt.Printf("Got tag names %+v", names) |
| | | |
| | | value := readResult.GetResponse().GetValue("tag0") |
| | | |
| | | //// 按字符串打印变量 |
| | | //fmt.Printf("val data: %s\n", value.GetRaw()) |
| | | for idx, val := range value.GetList() { |
| | | raw := val.GetRaw() |
| | | if format == "hex" { |
| | | fmt.Printf("%d:%X\t", address+i+idx, raw) |
| | | } |
| | | if format == "dec" { |
| | | fmt.Printf("%d:%d\t", address+i+idx, binary.BigEndian.Uint16(raw)) |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 验证是否可读 |
| | | if !connection.GetMetadata().CanRead() { |
| | | fmt.Printf("This connection doesn't support read operations\n") |
| | | return |
| | | } |
| | | |
| | | // 读模式 |
| | | readRequest, err := connection.ReadRequestBuilder().AddTagAddress("count", "holding-register:1230:DINT[20]").Build() |
| | | if err != nil { |
| | | fmt.Printf("Error preparing read-request:%s\n", err.Error()) |
| | | return |
| | | } |
| | | |
| | | // 执行 |
| | | readResult := <-readRequest.Execute() |
| | | if err := readResult.GetErr(); err != nil { |
| | | fmt.Printf("Error execting read-request:%s\n", err.Error()) |
| | | return |
| | | } |
| | | |
| | | // 判断响应码是否正确 |
| | | if readResult.GetResponse().GetResponseCode("count") != apiModel.PlcResponseCode_OK { |
| | | fmt.Printf("error an non-ok return code: %s", readResult.GetResponse().GetResponseCode("count").GetName()) |
| | | return |
| | | } |
| | | |
| | | // 测试获取变量名称 |
| | | //names := readResult.GetResponse().GetTagNames() |
| | | //fmt.Printf("Got tag names %+v", names) |
| | | |
| | | value := readResult.GetResponse().GetValue("count") |
| | | fmt.Printf("Got result length %d\n", value.GetLength()) |
| | | |
| | | // 按字符串打印变量 |
| | | fmt.Printf("val data: %s\n", value.GetRaw()) |
| | | for _, val := range value.GetList() { |
| | | fmt.Printf("%d ", val.GetUint16()) |
| | | } |
| | | fmt.Printf("\n") |
| | | |
| | | } |