【OPC UA】使用C#读取OPC UA电液控数据

时间:2025-02-13 16:13:56

C#读取OPC UA电液控数据

  • 前言
  • 一、读取数据前的确认事项
  • 二、具体步骤
    • 1.与服务器连接
    • 2.读取所有节点
    • 获取指定节点下的引用
    • 读取数据
  • 总结


前言

OPC UA与OPC DA协议常见于工业生产中使用,例如煤矿的综采支架电液控系统。OPC UA 是OPC 的后继标准,只是后面增加了UA ,意指”统一架构”(Unified Architecture).它的主要目的是摆脱windows! 实现与平台无关的OPC.从OPC 演进到OPC UA,它的目的并没有改变,依然是为了实现分布式控制系统中的分布式对象技术.但是它的方式变成了与平台无关.面向了开放系统.这也就意味着我们可以在一个Arm /linux平台上实现OPC 的server,或者在云端linux平台上实现Client 程序.

一、读取数据前的确认事项

目前,大部分OPC UA协议都会使用Kepserver EX6作为服务器端,当我们作为客户端去读取服务器端的数据时,必须确保服务器与客户端配置的匹配。
1: 服务器端与客户端必须保持网络通畅,这是最基本的要求。
2:确认服务器的IP地址与开放的端口号。
3:确认服务器端的安全策略,是否需要密码等。

二、具体步骤

1.与服务器连接

代码如下(C#为例):

try
            {
                // Create the configuration.     
                ApplicationConfiguration configuration = Helpers.CreateClientConfiguration();
                // Create the endpoint configuration (use the application configuration to provide default values).
                EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(configuration);
                // The default timeout for a requests sent using the channel.
                endpointConfiguration.OperationTimeout = 300000;
                // Use the pure binary encoding on the wire.
                endpointConfiguration.UseBinaryEncoding = true;
                // Create the endpoint.
                ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);
                // Create the binding factory.
                BindingFactory bindingFactory = BindingFactory.Create(configuration);
                X509Certificate2 clientCertificate = configuration.SecurityConfiguration.ApplicationCertificate.Find();
                // Set up a callback to handle certificate validation errors.
                configuration.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
                // Initialize the channel which will be created with the server.
                SessionChannel channel = SessionChannel.Create(
                    configuration,
                    endpointDescription,
                    endpointConfiguration,
                    bindingFactory,
                    clientCertificate,
                    null);
                // Wrap the channel with the session object.
                // This call will fail if the server does not trust the client certificate.
                m_Session = new Session(channel, configuration, endpoint);
                m_Session.ReturnDiagnostics = DiagnosticsMasks.All;
                // Register keep alive callback.
                m_Session.KeepAlive += new KeepAliveEventHandler(Session_KeepAlive);
                UserIdentity identity = new UserIdentity();
                // Create the session. This actually connects to the server.
                // Passing null for the user identity will create an anonymous session.
                m_Session.Open("OPC UA client", identity);
                return m_Session;
            }
            catch (Exception e)
            {
                throw e;
            }

2.读取所有节点

代码如下(示例):

public ReferenceDescriptionCollection BrowseNodes(NodeId sourceId)
        {
            m_Session = this.MySession;
            if (m_Session == null){return null;}
            // fetch references from the server.
            // find all of the components of the node.
            BrowseDescription nodeToBrowse1 = new BrowseDescription();

            nodeToBrowse1.NodeId = sourceId;
            nodeToBrowse1.BrowseDirection = BrowseDirection.Forward;
            // = ;
            nodeToBrowse1.ReferenceTypeId = ReferenceTypeIds.HasChild;
            nodeToBrowse1.IncludeSubtypes = false;
            // = (uint)( | );
            nodeToBrowse1.NodeClassMask = (uint)(NodeClass.Variable);
            nodeToBrowse1.ResultMask = (uint)BrowseResultMask.All;
            Browser bro = new Browser(m_Session);
            ReferenceDescriptionCollection references = bro.Browse(sourceId);
            return references;
        }

获取指定节点下的引用

private ReferenceDescriptionCollection getTargetItemList(ReferenceDescriptionCollection references, string targetStr)
        {
            ReferenceDescriptionCollection retrunRef = new ReferenceDescriptionCollection();
            foreach (ReferenceDescription rf in references)
            {
                if (!targetStr.Equals("item"))
                {
                    if (!rf.DisplayName.ToString().StartsWith(@"_") && targetStr.Equals(rf.DisplayName.ToString()) && rf.BrowseName.ToString() != "FolderType")
                    {
                        retrunRef = BrowseNodes((NodeId)rf.NodeId);
                        break;
                    }
                }
                else
                {
                    if (!rf.DisplayName.ToString().StartsWith(@"_") && rf.DisplayName.ToString() != "FolderType")
                    {
                        retrunRef.Add(rf);
                    }
                }
            }
            return retrunRef;
        }

读取数据

public ResponseHeader ReadValues(
            NodeIdCollection nodesToRead,
            out DataValueCollection results)
        {
            ResponseHeader response = null;
            results = null;
            DiagnosticInfoCollection diagnosticInfos;
            // build list of attributes to read.
            ReadValueIdCollection valueIdsToRead = new ReadValueIdCollection();
            try
            {
                for (int i = 0; i < nodesToRead.Count; i++)
                {
                    ReadValueId attributeToRead = new ReadValueId();
                    attributeToRead.NodeId = nodesToRead[i];
                    attributeToRead.AttributeId = Attributes.Value;
                    attributeToRead.Handle = attributeIdToString(Attributes.Value);
                    valueIdsToRead.Add(attributeToRead);
                }
                response = m_Session.Read(
                        null,
                        0,
                        TimestampsToReturn.Both,
                        valueIdsToRead,
                        out results,
                        out diagnosticInfos);
            }
            catch (Exception e)
            {
                throw e;
            }
            return response;
        }

总结

当我们作为客户端去读取服务器端的数据时,更多的还是要遵循服务器端的配置结构,比如,server、channel、group、item各个结构之间的组成关系。利用上面几个关键的方法,可以顺利的读取各中接口的OPC UA数据。