本文为使用golang实现OPC-UA协议通讯示例。
Opcua包使用:https://github.com/gopcua/opcua
Golang版本:1.20
测试环境:MacOS Ventura13.3.1、Windows10 22H2、CentOS9 Stream、Ubuntu Server 22.10、OpenEuler 22.09
组态软件使用博途V17、PLC为西门子1200
- OPC-UA概念
OPC UA(Open Platform Communications Unified Architecture,简称 OPC UA)是一种开放的、跨平台的通信协议和通讯框架,用于在工业自动化和物联网(IoT)领域中实现设备间的互联互通。
- 通讯示例
读取
func GetOpcUA() { // opc服务器地址 endPoint := "opc.tcp://192.168.3.71:4840" eps, err := opcua.GetEndpoints(context.Background(), endPoint) if err != nil { log.Println(err.Error()) return } log.Println(eps) client := opcua.NewClient(endPoint, opcua.SecurityMode(ua.MessageSecurityModeNone)) err = client.Connect(context.Background()) if err != nil { log.Println(err.Error()) return } defer func() { err = client.Close() if err != nil { log.Println(err.Error()) } }() // 取出第一命名空间为4, nodeID0 := "ns=4;i=120" nodeID1 := "ns=4;i=58" id1, err := ua.ParseNodeID(nodeID0) if err != nil { log.Println(err.Error()) return } id2, err := ua.ParseNodeID(nodeID1) if err != nil { log.Println(err.Error()) return } nodeIds := make([]*ua.ReadValueID, 0) nodeIds = append(nodeIds, &ua.ReadValueID{NodeID: id1}) nodeIds = append(nodeIds, &ua.ReadValueID{NodeID: id2}) req := &ua.ReadRequest{ MaxAge: 2000, NodesToRead: nodeIds, TimestampsToReturn: ua.TimestampsToReturnBoth, } reply, err := client.ReadWithContext(context.Background(), req) if err != nil { log.Println(err.Error()) } if reply.Results[0].Status != ua.StatusOK { log.Fatalf("Status not OK: %v", reply.Results[0].Status) } for _, result := range reply.Results { log.Println(result.Value.Value()) } }
写入
func WriteOpcUa() { endPoint := "opc.tcp://192.168.3.71:4840" _, err := opcua.GetEndpoints(context.Background(), endPoint) if err != nil { log.Println(err.Error()) return } client := opcua.NewClient(endPoint, opcua.SecurityMode(ua.MessageSecurityModeNone)) err = client.Connect(context.Background()) if err != nil { log.Println(err.Error()) return } defer func() { err = client.Close() if err != nil { log.Println(err.Error()) } }() nodeID0 := "ns=4;i=57" id1, err := ua.ParseNodeID(nodeID0) if err != nil { log.Println(err.Error()) return } var a float32 = 3.0 value, err := ua.NewVariant(a) if err != nil { log.Println(err.Error()) return } var req = &ua.WriteRequest{ NodesToWrite: []*ua.WriteValue{ { NodeID: id1, AttributeID: ua.AttributeIDValue, Value: &ua.DataValue{ EncodingMask: ua.DataValueValue, Value: value, }, }, }, } res, err := client.WriteWithContext(context.Background(), req) fmt.Println(res) }