精华内容
下载资源
问答
  • C#OPC同步读写

    2019-04-24 16:13:53
    C#OPC同步读写源码,西门子PLC,工程师的福音
  • C# OPC Client

    2018-11-21 22:00:31
    C#开发OPC Client,可实现根据IP地址选取局域网内的OPC Server,然后选择该server上的items,进行数据实时采集。
  • C#OPC通讯(KepServer)Demo

    2020-10-30 19:18:55
    C#OPC通讯(KepServer)Demo
  • c# OPC UA .NET Client代码实例,亲测可用。 可与西门子 PLC 连接读写数据,通用型OPC UA 读写
  • OPC开发资料非常详细 C#连接OPC KEPServer文档 OPC 连接多台 AB OPC 硬件组态资料
  • C# OPC UA 客户端,亲测可以使用。这个是西门子的客户端,对其他也可以使用,对OPC UA 敢兴趣的可以参考下。
  • C#编写的 OPC UA ,DA两种方式与PLC通讯源码,已在项目中稳定使用。
  • 这是一个真正完整的C#OPC DA客户端程序,可做修改后用理开发上位组态!
  • C#OPC读取数据

    千次下载 热门讨论 2013-05-17 17:23:03
    C#访问OPC读取数据 一般用于自动化编程
  • c# OPC Client

    热门讨论 2013-11-02 09:08:34
    c#开发的opc client 值得学习OPC协议和如何通过OPC来通信
  • C# OPC通讯

    2019-04-11 13:54:04
    本程序支持监控KEPServer通讯测试,能够检测目标服务器上的KEPServer ,通过选择TagName,能够查看到当前地址位的数据,并能够修改该数据值。
  • C#OPC读取数据-C#代码类资源
  • c# OPCClient获取OpcServer数据

    热门讨论 2013-07-11 16:50:23
    自动获取OpcServer的名称,查看OpcServer相应tag数据
  • C#Opc读取数据客户端

    2019-08-07 14:25:45
    包含OPC2.0的用户手册和OPCAutomation的dll文件。
  • C# opc dll

    2018-07-30 10:45:38
    C#通过opc链接plc所需要的dll,可以方便了解C#程序员能够快速开发基于opc协议程序与plc通讯
  • c# OPC通讯实例

    2011-10-05 10:20:08
    c#通过OPC服务器与PLC通讯的实例 /// /// opc服务器连接、数据跟新 /// /// /// 连接OPC服务器 /// </summary>
  • C# OPC 数据采集 .rar

    2018-06-14 13:22:41
    OPC数据共享,可用于通讯,C#源代码实现,加快通讯模块的开发
  • C# OPC软件 操作 安装
  • C# OPC 类库

    2017-09-14 21:18:49
    theSrv = new OpcServer(); //init opc server theSrv.Connect(txtSvrName.Text); Thread.Sleep(100); theSrv.SetClientName("ZDTOPC" + thisprocess.Id); SERVERSTATUS sts; theSrv.GetStatus(out sts); ...
  • C# OPC客户端测试

    2017-06-22 11:52:28
    主要通过OpcNetApiChs访问OPC服务器,开发环境VS2010
  • C#opc通讯客户端

    2018-01-29 14:54:51
    可以实现OPC通讯,自动搜索OPC服务器,连接目标服务器,从OPC服务器中读取Item的状态,并且可以给Item赋值,实现OPC变量读写操作
  • C# OPC UA 客户端开发

    千次阅读 2021-08-05 15:11:40
    OPC UA(OPC Unified Architecture)是为了在工业自动化等行业安全可靠地进行数据交换而制定的开放式国际标准规格。由OPC Foundation于2008年发布,之后制定了国际标准IEC62541.跨越设备的种类、操作系统(OS)、...

    OPC UA(OPC Unified Architecture)是为了在工业自动化等行业安全可靠地进行数据交换而制定的开放式国际标准规格。由OPC Foundation于2008年发布,之后制定了国际标准IEC62541.跨越设备的种类、操作系统(OS)、制造商的壁垒,可以安全地进行高可靠性的数据交换,作为标准通信协议得到了工业 4.0的推荐。https://opcfoundation.org/

    OPC UA开发首先需要一个服务器端:这里使用KEPServer来模拟。首先下载并安装KepServer,基本一路下一步。配置OPC UA:

    在桌面右下角右键点击“OPC UA配置”

    选择网卡和端口号,修改成自己想要的地址。

    服务端测试:下载softing OPC Client 工具并安装。如下图所示连接KepServer 

     数据节点读写测试:

    有了以上准备后,利用C# 开发自己的OPC UA helper:

    我使用的VS2019,新建.net framework类库项目:修改.net framework版本4.6.2以上,nuget 包管理器里搜索opc.ua.client.选择opc 基金会的开发组件:如下图所示:

    新建类OPCUAClient.cs

    using Opc.Ua;
    using Opc.Ua.Client;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace hg.opc.client
    {
        public class OPCUAClient
        {
            #region Private Fields
            private ApplicationConfiguration appConfig;
            private Session clientSession;
            private bool isConnected = false;                       //是否已经连接过
            private int reconnectPeriod = 10;               // 重连状态
            private SessionReconnectHandler sessionReconnectHandler;
            private EventHandler onConnectedEventHandler;
            private Dictionary<string, Subscription> subscriptionNodes=new Dictionary<string, Subscription>();        // 系统所有的节点信息
            #endregion Private Fields
    
            #region Public Members
    
            public IUserIdentity UserIdentity { get; set; }= new UserIdentity(new AnonymousIdentityToken());
            public bool IsConnected { get => isConnected; private set => isConnected = value; }
            public Dictionary<string, Subscription> SubscriptionNodes { get => subscriptionNodes; set => subscriptionNodes = value; }
    
            public event EventHandler OnConnectedEvent
            {
                add { onConnectedEventHandler += value; }
                remove { onConnectedEventHandler -= value; }
            }
            #endregion
    
            #region 构造函数
            public OPCUAClient()
            {
                var certificateValidator = new CertificateValidator();
                certificateValidator.CertificateValidation += (sender, eventArgs) =>
                {
                    if (ServiceResult.IsGood(eventArgs.Error))
                        eventArgs.Accept = true;
                    else if (eventArgs.Error.StatusCode.Code == StatusCodes.BadCertificateUntrusted)
                        eventArgs.Accept = true;
                    else
                        throw new Exception(string.Format("证书验证错误: {0}: {1}", eventArgs.Error.Code, eventArgs.Error.AdditionalInfo));
                };
    
                certificateValidator.Update(new SecurityConfiguration
                {
                    AutoAcceptUntrustedCertificates = true,
                    RejectSHA1SignedCertificates = false,
                    MinimumCertificateKeySize = 1024,
                });
    
                var configuration = new ApplicationConfiguration
                {
                    ApplicationName = "MyOpc_Client",
                    ApplicationType = ApplicationType.Client,
                    CertificateValidator = certificateValidator,
                    ApplicationUri = string.Empty, 
                    ServerConfiguration = new ServerConfiguration
                    {
                        MaxSubscriptionCount = 100000,
                        MaxMessageQueueSize = 100000,
                        MaxNotificationQueueSize = 100000,
                        MaxPublishRequestCount = 100000,
                    },
                    SecurityConfiguration = new SecurityConfiguration
                    {
                        AutoAcceptUntrustedCertificates = true,
                        RejectSHA1SignedCertificates = false,
                        MinimumCertificateKeySize = 1024,
                        SuppressNonceValidationErrors = true,
    
                        ApplicationCertificate = new CertificateIdentifier
                        {
                            StoreType = CertificateStoreType.X509Store,
                            StorePath = "CurrentUser\\My",
                        },
                        TrustedIssuerCertificates = new CertificateTrustList
                        {
                            StoreType = CertificateStoreType.X509Store,
                            StorePath = "CurrentUser\\Root",
                        },
                        TrustedPeerCertificates = new CertificateTrustList
                        {
                            StoreType = CertificateStoreType.X509Store,
                            StorePath = "CurrentUser\\Root",
                        }
                    },
                    TransportQuotas = new TransportQuotas
                    {
                        OperationTimeout = 6000000,
                        MaxStringLength = int.MaxValue,
                        MaxByteStringLength = int.MaxValue,
                        MaxArrayLength = 65535,
                        MaxMessageSize = 419430400,
                        MaxBufferSize = 65535,
                        ChannelLifetime = -1,
                        SecurityTokenLifetime = -1
                    },
                    ClientConfiguration = new ClientConfiguration
                    {
                        DefaultSessionTimeout = -1,
                        MinSubscriptionLifetime = -1,
                    },
                    DisableHiResClock = true
                };
    
                configuration.Validate(ApplicationType.Client);
                appConfig = configuration;
            }
            #endregion
            #region 连接
            public async Task ConnectServer(string serverUrl)
            {
                Disconnect();
                var endpointDescription = CoreClientUtils.SelectEndpoint(serverUrl, false);
                var endpointConfiguration = EndpointConfiguration.Create(appConfig);
                var endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);
                clientSession = await Task.Run(async ()=> {
                    
                    return await Session.Create(
                        appConfig,
                        endpoint,
                        false,
                        false,
                        appConfig.ApplicationName,
                        60000,
                        UserIdentity,
                        new string[] { });
                });
                clientSession.KeepAlive += Session_KeepAlive;
                IsConnected = true;
                onConnectedEventHandler?.Invoke(this, EventArgs.Empty);
            }
    
            private void Session_KeepAlive(Session session, KeepAliveEventArgs e)
            {
                try
                {
                    if (!object.ReferenceEquals(session, this.clientSession))
                    {
                        return;
                    }
                    if (ServiceResult.IsBad(e.Status))
                    {
                        if (reconnectPeriod <= 0)
                        {
                            return;
                        }
                        if (sessionReconnectHandler == null)
                        {
                            sessionReconnectHandler = new SessionReconnectHandler();
                            sessionReconnectHandler.BeginReconnect(session, reconnectPeriod * 1000, Server_ReconnectComplete);
                        }
                        return;
                    }
                }
                catch (Exception exception)
                {
                    throw exception;
                }
            }
    
            private void Server_ReconnectComplete(object sender, EventArgs e)
            {
                try
                {
                    if (!ReferenceEquals(sender, sessionReconnectHandler))
                    {
                        return;
                    }
                    clientSession = sessionReconnectHandler.Session;
                    sessionReconnectHandler.Dispose();
                    sessionReconnectHandler = null;
                }
                catch (Exception exception)
                {
                    throw exception;
                }
            }
    
            public void Disconnect()
            {
                if (sessionReconnectHandler != null)
                {
                    sessionReconnectHandler.Dispose();
                    sessionReconnectHandler = null;
                }
    
                if (clientSession != null)
                {
                    clientSession.Close(10000);
                    clientSession = null;
                }
                IsConnected = false;
            }
            #endregion
    
            #region 浏览节点
    
            public ReferenceDescriptionCollection BrowserNode2(NodeId nodeId)
            {
                var browser = new Browser(clientSession);
                return browser.Browse(nodeId);
            }
    
            public ReferenceDescriptionCollection BrowserNode(NodeId nodeId)
            { 
                var browseDescriptions = new BrowseDescriptionCollection();
                var browserDesc = new BrowseDescription();
                browserDesc.NodeId = nodeId;
                browserDesc.BrowseDirection = BrowseDirection.Forward;
                browserDesc.ReferenceTypeId = ReferenceTypeIds.Aggregates;
                browserDesc.IncludeSubtypes = true;
                browserDesc.NodeClassMask = (uint)(NodeClass.Object | NodeClass.Variable | NodeClass.Method | NodeClass.ReferenceType | NodeClass.ObjectType | NodeClass.View | NodeClass.VariableType | NodeClass.DataType);
                browserDesc.ResultMask = (uint)BrowseResultMask.All;
    
                var browseDesc2 = new BrowseDescription();
                browseDesc2.NodeId = nodeId;
                browseDesc2.BrowseDirection = BrowseDirection.Forward;
                browseDesc2.ReferenceTypeId = ReferenceTypeIds.Organizes;
                browseDesc2.IncludeSubtypes = true;
                browseDesc2.NodeClassMask = (uint)(NodeClass.Object | NodeClass.Variable | NodeClass.Method | NodeClass.View | NodeClass.ReferenceType | NodeClass.ObjectType | NodeClass.VariableType | NodeClass.DataType);
                browseDesc2.ResultMask = (uint)BrowseResultMask.All;
               
    
                browseDescriptions.Add(browserDesc);
                browseDescriptions.Add(browseDesc2);
    
                ReferenceDescriptionCollection references = GetReferenceDescriptionCollection(browseDescriptions);
                return references;
            }
    
            public ReferenceDescriptionCollection GetReferenceDescriptionCollection(BrowseDescriptionCollection browseDescriptions)
            {
                try
                {
                    var referenceDescriptions = new ReferenceDescriptionCollection();
                    var unprocessedOperations = new BrowseDescriptionCollection();
    
                    while (browseDescriptions.Count > 0)
                    {
                        BrowseResultCollection results = null;
                        DiagnosticInfoCollection diagnosticInfos = null;
                        clientSession.Browse(null, null,  0, browseDescriptions,out results,out diagnosticInfos);
    
                        ClientBase.ValidateResponse(results, browseDescriptions);
                        ClientBase.ValidateDiagnosticInfos(diagnosticInfos, browseDescriptions);
    
                        ByteStringCollection continuationPoints = new ByteStringCollection();
                        for (int i = 0; i < browseDescriptions.Count; i++)
                        {
                            if (StatusCode.IsBad(results[i].StatusCode))
                            {
                                if (results[i].StatusCode == StatusCodes.BadNoContinuationPoints)
                                {
                                    unprocessedOperations.Add(browseDescriptions[i]);
                                }
                                continue;
                            }
    
                            // check if all references have been fetched.
                            if (results[i].References.Count == 0)
                            {
                                continue;
                            }
                            referenceDescriptions.AddRange(results[i].References);
                            if (results[i].ContinuationPoint != null)
                            {
                                continuationPoints.Add(results[i].ContinuationPoint);
                            }
                        }
                        ByteStringCollection revisedContiuationPoints = new ByteStringCollection();
                        while (continuationPoints.Count > 0)
                        {
                            // continue browse operation.
                            clientSession.BrowseNext(
                                null,
                                true,
                                continuationPoints,
                                out results,
                                out diagnosticInfos);
    
                            ClientBase.ValidateResponse(results, continuationPoints);
                            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, continuationPoints);
    
                            for (int j = 0; j < continuationPoints.Count; j++)
                            {
                                if (StatusCode.IsBad(results[j].StatusCode))
                                {
                                    continue;
                                }
                                if (results[j].References.Count == 0)
                                {
                                    continue;
                                }
    
                                referenceDescriptions.AddRange(results[j].References);
    
                                if (results[j].ContinuationPoint != null)
                                {
                                    revisedContiuationPoints.Add(results[j].ContinuationPoint);
                                }
                            }
                            revisedContiuationPoints = continuationPoints;
                        }
                        browseDescriptions = unprocessedOperations;
                    }
                    return referenceDescriptions;
                }
                catch (Exception exception)
                {
                    return null;
                }
            }
    
    
            #endregion
    
            #region Node Write/Read Support
    
            /// <summary>
            /// Read a value node from server
            /// </summary>
            /// <param name="nodeId">node id</param>
            /// <returns>DataValue</returns>
            public DataValue ReadNode(NodeId nodeId)
            {
                ReadValueIdCollection nodesToRead = new ReadValueIdCollection
                {
                    new ReadValueId( )
                    {
                        NodeId = nodeId,
                        AttributeId = Attributes.Value
                    }
                };
    
                // read the current value
                clientSession.Read(
                    null,
                    0,
                    TimestampsToReturn.Neither,
                    nodesToRead,
                    out DataValueCollection results,
                    out DiagnosticInfoCollection diagnosticInfos);
    
                ClientBase.ValidateResponse(results, nodesToRead);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);
    
                return results[0];
            }
    
            /// <summary>
            /// 是否可读写节点
            /// </summary>
            /// <param name="nodeId"></param>
            /// <returns></returns>
            public bool IsWriteableNode(NodeId nodeId)
            {
                ReadValueIdCollection nodesToRead = new ReadValueIdCollection
                {
                    new ReadValueId( )
                    {
                        NodeId = nodeId,
                        AttributeId = Attributes.AccessLevel
                    }
                };
    
                // read the current value
                clientSession.Read(
                    null,
                    0,
                    TimestampsToReturn.Neither,
                    nodesToRead,
                    out DataValueCollection results,
                    out DiagnosticInfoCollection diagnosticInfos);
    
                ClientBase.ValidateResponse(results, nodesToRead);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);
    
                DataValue value= results[0];
                if (value.WrappedValue == Variant.Null)
                {
                    return true;
                }
                return !((byte)value.WrappedValue.Value == 1);
    
            }
    
            /// <summary>
            /// Read a value node from server
            /// </summary>
            /// <typeparam name="T">type of value</typeparam>
            /// <param name="tag">node id</param>
            /// <returns>实际值</returns>
            public T ReadNode<T>(string tag)
            {
                DataValue dataValue = ReadNode(new NodeId(tag));
                return (T)dataValue.Value;
            }
    
            /// <summary>
            /// Read a tag asynchronously
            /// </summary>
            /// <typeparam name="T">The type of tag to read</typeparam>
            /// <param name="tag">tag值</param>
            /// <returns>The value retrieved from the OPC</returns>
            public Task<T> ReadNodeAsync<T>(string tag)
            {
                ReadValueIdCollection nodesToRead = new ReadValueIdCollection
                {
                    new ReadValueId()
                    {
                        NodeId = new NodeId(tag),
                        AttributeId = Attributes.Value
                    }
                };
    
                // Wrap the ReadAsync logic in a TaskCompletionSource, so we can use C# async/await syntax to call it:
                var taskCompletionSource = new TaskCompletionSource<T>();
                clientSession.BeginRead(
                    requestHeader: null,
                    maxAge: 0,
                    timestampsToReturn: TimestampsToReturn.Neither,
                    nodesToRead: nodesToRead,
                    callback: ar =>
                    {
                        DataValueCollection results;
                        DiagnosticInfoCollection diag;
                        var response = clientSession.EndRead(
                          result: ar,
                          results: out results,
                          diagnosticInfos: out diag);
    
                        try
                        {
                            if (!StatusCode.IsGood(response.ServiceResult))
                                throw new Exception(string.Format("Invalid response from the server. (Response Status: {0})", response.ServiceResult));
    
                            if (!StatusCode.IsGood(results[0].StatusCode))
                                throw new Exception(string.Format("Invalid response from the server. (Response Status: {0})", results[0].StatusCode));
                            var val = results[0];
                            taskCompletionSource.TrySetResult((T)val.Value);
                        }
                        catch (Exception ex)
                        {
                            taskCompletionSource.TrySetException(ex);
                        }
                    },
                    asyncState: null);
    
                return taskCompletionSource.Task;
            }
    
            /// <summary>
            /// read several value nodes from server
            /// </summary>
            /// <param name="nodeIds">all NodeIds</param>
            /// <returns>all values</returns>
            public List<DataValue> ReadNodes(NodeId[] nodeIds)
            {
                ReadValueIdCollection nodesToRead = new ReadValueIdCollection();
                for (int i = 0; i < nodeIds.Length; i++)
                {
                    nodesToRead.Add(new ReadValueId()
                    {
                        NodeId = nodeIds[i],
                        AttributeId = Attributes.Value
                    });
                }
    
                // 读取当前的值
                clientSession.Read(
                    null,
                    0,
                    TimestampsToReturn.Neither,
                    nodesToRead,
                    out DataValueCollection results,
                    out DiagnosticInfoCollection diagnosticInfos);
    
                ClientBase.ValidateResponse(results, nodesToRead);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);
    
                return results.ToList();
            }
    
            /// <summary>
            /// read several value nodes from server
            /// </summary>
            /// <param name="nodeIds">all NodeIds</param>
            /// <returns>all values</returns>
            public Task<List<DataValue>> ReadNodesAsync(NodeId[] nodeIds)
            {
                ReadValueIdCollection nodesToRead = new ReadValueIdCollection();
                for (int i = 0; i < nodeIds.Length; i++)
                {
                    nodesToRead.Add(new ReadValueId()
                    {
                        NodeId = nodeIds[i],
                        AttributeId = Attributes.Value
                    });
                }
    
                var taskCompletionSource = new TaskCompletionSource<List<DataValue>>();
                // 读取当前的值
                clientSession.BeginRead(
                    null,
                    0,
                    TimestampsToReturn.Neither,
                    nodesToRead,
                    callback: ar =>
                    {
                        DataValueCollection results;
                        DiagnosticInfoCollection diag;
                        var response = clientSession.EndRead(
                          result: ar,
                          results: out results,
                          diagnosticInfos: out diag);
    
                        try
                        {
                            CheckReturnValue(response.ServiceResult);
                            taskCompletionSource.TrySetResult(results.ToList());
                        }
                        catch (Exception ex)
                        {
                            taskCompletionSource.TrySetException(ex);
                        }
                    },
                    asyncState: null);
    
                return taskCompletionSource.Task;
            }
    
            /// <summary>
            /// read several value nodes from server
            /// </summary>
            /// <param name="tags">所以的节点数组信息</param>
            /// <returns>all values</returns>
            public List<T> ReadNodes<T>(string[] tags)
            {
                List<T> result = new List<T>();
                ReadValueIdCollection nodesToRead = new ReadValueIdCollection();
                for (int i = 0; i < tags.Length; i++)
                {
                    nodesToRead.Add(new ReadValueId()
                    {
                        NodeId = new NodeId(tags[i]),
                        AttributeId = Attributes.Value
                    });
                }
    
                // 读取当前的值
                clientSession.Read(
                    null,
                    0,
                    TimestampsToReturn.Neither,
                    nodesToRead,
                    out DataValueCollection results,
                    out DiagnosticInfoCollection diagnosticInfos);
    
                ClientBase.ValidateResponse(results, nodesToRead);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);
    
                foreach (var item in results)
                {
                    result.Add((T)item.Value);
                }
                return result;
            }
    
            /// <summary>
            /// read several value nodes from server
            /// </summary>
            /// <param name="tags">all NodeIds</param>
            /// <returns>all values</returns>
            public Task<List<T>> ReadNodesAsync<T>(string[] tags)
            {
                ReadValueIdCollection nodesToRead = new ReadValueIdCollection();
                for (int i = 0; i < tags.Length; i++)
                {
                    nodesToRead.Add(new ReadValueId()
                    {
                        NodeId = new NodeId(tags[i]),
                        AttributeId = Attributes.Value
                    });
                }
    
                var taskCompletionSource = new TaskCompletionSource<List<T>>();
                // 读取当前的值
                clientSession.BeginRead(
                    null,
                    0,
                    TimestampsToReturn.Neither,
                    nodesToRead,
                    callback: ar =>
                    {
                        DataValueCollection results;
                        DiagnosticInfoCollection diag;
                        var response = clientSession.EndRead(
                          result: ar,
                          results: out results,
                          diagnosticInfos: out diag);
    
                        try
                        {
                            CheckReturnValue(response.ServiceResult);
                            List<T> result = new List<T>();
                            foreach (var item in results)
                            {
                                result.Add((T)item.Value);
                            }
                            taskCompletionSource.TrySetResult(result);
                        }
                        catch (Exception ex)
                        {
                            taskCompletionSource.TrySetException(ex);
                        }
                    },
                    asyncState: null);
    
                return taskCompletionSource.Task;
            }
    
    
    
            /// <summary>
            /// 0:NodeClass  1:Value  2:AccessLevel  3:DisplayName  4:Description
            /// </summary>
            /// <param name="nodeIds"></param>
            /// <returns></returns>
            public DataValue[] ReadNodeAttributes(List<NodeId> nodeIds)
            {
                ReadValueIdCollection nodesToRead = new ReadValueIdCollection();
                foreach (var nodeId in nodeIds)
                {
                    NodeId sourceId = nodeId;
                    nodesToRead.Add(new ReadValueId()
                    {
                        NodeId = sourceId,
                        AttributeId = Attributes.NodeClass
                    });
                    nodesToRead.Add(new ReadValueId()
                    {
                        NodeId = sourceId,
                        AttributeId = Attributes.Value
                    });
                    nodesToRead.Add(new ReadValueId()
                    {
                        NodeId = sourceId,
                        AttributeId = Attributes.AccessLevel
                    });
                    nodesToRead.Add(new ReadValueId()
                    {
                        NodeId = sourceId,
                        AttributeId = Attributes.DisplayName
                    });
                    nodesToRead.Add(new ReadValueId()
                    {
                        NodeId = sourceId,
                        AttributeId = Attributes.Description
                    });
                }
    
                // read all values.
                clientSession.Read(
                    null,
                    0,
                    TimestampsToReturn.Neither,
                    nodesToRead,
                    out DataValueCollection results,
                    out DiagnosticInfoCollection diagnosticInfos);
    
                ClientBase.ValidateResponse(results, nodesToRead);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);
    
                return results.ToArray();
            }
    
    
            /// <summary>
            /// write a note to server(you should use try catch)
            /// </summary>
            /// <typeparam name="T">The type of tag to write on</typeparam>
            /// <param name="tag">节点名称</param>
            /// <param name="value">值</param>
            /// <returns>if success True,otherwise False</returns>
            public bool WriteNode<T>(string tag, T value)
            {
                WriteValue valueToWrite = new WriteValue()
                {
                    NodeId = new NodeId(tag),
                    AttributeId = Attributes.Value
                };
                valueToWrite.Value.Value = value;
                valueToWrite.Value.StatusCode = StatusCodes.Good;
                valueToWrite.Value.ServerTimestamp = DateTime.MinValue;
                valueToWrite.Value.SourceTimestamp = DateTime.MinValue;
    
                WriteValueCollection valuesToWrite = new WriteValueCollection
                {
                    valueToWrite
                };
    
                // 写入当前的值
    
                clientSession.Write(
                    null,
                    valuesToWrite,
                    out StatusCodeCollection results,
                    out DiagnosticInfoCollection diagnosticInfos);
    
                ClientBase.ValidateResponse(results, valuesToWrite);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToWrite);
    
                if (StatusCode.IsBad(results[0]))
                {
                    throw new ServiceResultException(results[0]);
                }
    
                return !StatusCode.IsBad(results[0]);
            }
    
            /// <summary>
            /// Write a value on the specified opc tag asynchronously
            /// </summary>
            /// <typeparam name="T">The type of tag to write on</typeparam>
            /// <param name="tag">The fully-qualified identifier of the tag. You can specify a subfolder by using a comma delimited name. E.g: the tag `foo.bar` writes on the tag `bar` on the folder `foo`</param>
            /// <param name="value">The value for the item to write</param>
            public Task<bool> WriteNodeAsync<T>(string tag, T value)
            {
                WriteValue valueToWrite = new WriteValue()
                {
                    NodeId = new NodeId(tag),
                    AttributeId = Attributes.Value,
                };
                valueToWrite.Value.Value = value;
                valueToWrite.Value.StatusCode = StatusCodes.Good;
                valueToWrite.Value.ServerTimestamp = DateTime.MinValue;
                valueToWrite.Value.SourceTimestamp = DateTime.MinValue;
                WriteValueCollection valuesToWrite = new WriteValueCollection
                {
                    valueToWrite
                };
    
                // Wrap the WriteAsync logic in a TaskCompletionSource, so we can use C# async/await syntax to call it:
                var taskCompletionSource = new TaskCompletionSource<bool>();
                clientSession.BeginWrite(
                    requestHeader: null,
                    nodesToWrite: valuesToWrite,
                    callback: ar =>
                    {
                   
                        var response = clientSession.EndWrite(
                          result: ar,
                          results: out StatusCodeCollection results,
                          diagnosticInfos: out DiagnosticInfoCollection diag);
    
                        try
                        {
                            ClientBase.ValidateResponse(results, valuesToWrite);
                            ClientBase.ValidateDiagnosticInfos(diag, valuesToWrite);
                            taskCompletionSource.SetResult(StatusCode.IsGood(results[0]));
                        }
                        catch (Exception ex)
                        {
                            taskCompletionSource.TrySetException(ex);
                        }
                    },
                    asyncState: null);
                return taskCompletionSource.Task;
            }
    
            /// <summary>
            /// 所有的节点都写入成功,返回<c>True</c>,否则返回<c>False</c>
            /// </summary>
            /// <param name="tags">节点名称数组</param>
            /// <param name="values">节点的值数据</param>
            /// <returns>所有的是否都写入成功</returns>
            public bool WriteNodes(string[] tags, object[] values)
            {
                WriteValueCollection valuesToWrite = new WriteValueCollection();
    
                for (int i = 0; i < tags.Length; i++)
                {
                    if (i < values.Length)
                    {
                        WriteValue valueToWrite = new WriteValue()
                        {
                            NodeId = new NodeId(tags[i]),
                            AttributeId = Attributes.Value
                        };
                        valueToWrite.Value.Value = values[i];
                        valueToWrite.Value.StatusCode = StatusCodes.Good;
                        valueToWrite.Value.ServerTimestamp = DateTime.MinValue;
                        valueToWrite.Value.SourceTimestamp = DateTime.MinValue;
                        valuesToWrite.Add(valueToWrite);
                    }
                }
    
                // 写入当前的值
    
                clientSession.Write(
                    null,
                    valuesToWrite,
                    out StatusCodeCollection results,
                    out DiagnosticInfoCollection diagnosticInfos);
    
                ClientBase.ValidateResponse(results, valuesToWrite);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToWrite);
    
                bool result = true;
                foreach (var r in results)
                {
                    if (StatusCode.IsBad(r))
                    {
                        result = false;
                        break;
                    }
                }
    
                return result;
            }
    
            private void CheckReturnValue(StatusCode status)
            {
                if (!StatusCode.IsGood(status))
                    throw new Exception(string.Format("Invalid response from the server. (Response Status: {0})", status));
            }
            #endregion Node Write/Read Support
    
            #region 订阅
    
            /// <summary>
            /// 新增一批订阅,需要指定订阅的关键字,订阅的tag名数组,以及回调方法
            /// </summary>
            /// <param name="key">关键字</param>
            /// <param name="tags">节点名称数组</param>
            /// <param name="callback">回调方法</param>
            public void AddSubscription(string key, string[] tags, Action<string, MonitoredItem, MonitoredItemNotificationEventArgs> callback)
            {
                Subscription m_subscription = new Subscription(clientSession.DefaultSubscription);
    
                m_subscription.PublishingEnabled = true;
                m_subscription.PublishingInterval = 0;
                m_subscription.KeepAliveCount = uint.MaxValue;
                m_subscription.LifetimeCount = uint.MaxValue;
                m_subscription.MaxNotificationsPerPublish = uint.MaxValue;
                m_subscription.Priority = 100;
                m_subscription.DisplayName = key;
    
                for (int i = 0; i < tags.Length; i++)
                {
                    var item = new MonitoredItem
                    {
                        StartNodeId = new NodeId(tags[i]),
                        AttributeId = Attributes.Value,
                        DisplayName = tags[i],
                        SamplingInterval = 100,
                    };
                    item.Notification += (MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs args) =>
                    {
                        callback?.Invoke(key, monitoredItem, args);
                    };
                    m_subscription.AddItem(item);
                }
    
                clientSession.AddSubscription(m_subscription);
                m_subscription.Create();
    
                lock (SubscriptionNodes)
                {
                    if (SubscriptionNodes.ContainsKey(key))
                    {
                        // remove
                        SubscriptionNodes[key].Delete(true);
                        clientSession.RemoveSubscription(SubscriptionNodes[key]);
                        SubscriptionNodes[key].Dispose();
                        SubscriptionNodes[key] = m_subscription;
                    }
                    else
                    {
                        SubscriptionNodes.Add(key, m_subscription);
                    }
                }
            }
    
            /// <summary>
            /// 新增订阅,需要指定订阅的关键字,订阅的tag名数组,以及回调方法
            /// </summary>
            /// <param name="key">关键字</param>
            /// <param name="tags">节点名称数组</param>
            /// <param name="callback">回调方法</param>
            public void AddSubscription(string key, string tag, Action<string, MonitoredItem, MonitoredItemNotificationEventArgs> callback)
            {
                AddSubscription(key, new string[] { tag }, callback);
            }
    
            /// <summary>
            /// 移除订阅消息,如果该订阅消息是批量的,也直接移除
            /// </summary>
            /// <param name="key">订阅关键值</param>
            public void RemoveSubscription(string key)
            {
                lock (SubscriptionNodes)
                {
                    if (SubscriptionNodes.ContainsKey(key))
                    {
                        // remove
                        SubscriptionNodes[key].Delete(true);
                        clientSession.RemoveSubscription(SubscriptionNodes[key]);
                        SubscriptionNodes[key].Dispose();
                        SubscriptionNodes.Remove(key);
                    }
                }
            }
    
            /// <summary>
            /// 移除所有的订阅消息
            /// </summary>
            public void RemoveAllSubscription()
            {
                lock (SubscriptionNodes)
                {
                    foreach (var item in SubscriptionNodes)
                    {
                        item.Value.Delete(true);
                        clientSession.RemoveSubscription(item.Value);
                        item.Value.Dispose();
                    }
                    SubscriptionNodes.Clear();
                }
            }
            #endregion
        }
    }
    

     利用上面的OPCUAClient开发的winform程序:

     源码下载:https://download.csdn.net/download/elie_yang/20814696

    展开全文
  • C#OPC 通讯

    2018-08-31 14:40:03
    C# 读取OPC 数据。
  • C#opc实例_opc_C#OPC

    2018-12-17 15:16:27
    opc C#实例 源代码
  • C# OPC客户端测试程序

    2014-12-31 16:41:01
    C# OPC客户端测试程序,可以在上面进行修改。
  • vs 2012 c# 编译成功。 源码是基于 KEPServerEX提供的西门子SiemensTCP/IP驱动能够为用户提供一个OPC服务器接口,将西门子TCP/IP以太网设备连接到OPC客户端应用程序中。 下面以西门子S7-300系列PLC为例,说明如何...
  • OpcUA C#实现

    2019-03-18 14:04:22
    本资源来自网络,这是用C#实现的OpcUA Client, 希望帮助新人学习。
  • C# OPC使用

    2019-08-13 14:28:08
    C# OPC使用 OPC客户端操作主要有4个步骤: 1.连接OPC服务器 2.创建组和项 3.读写数据 4.断开服务器连接 全部代码: 复制代码 using System; using System.Collections.Generic; using System.Net; using System....

    C# OPC使用

    OPC客户端操作主要有4个步骤:

    1.连接OPC服务器

    2.创建组和项

    3.读写数据

    4.断开服务器连接

    全部代码:

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Net;
    using System.Threading;
    using OPCAutomation;

    namespace ConsoleOPC
    {
    public class OPCClient
    {
    private OPCServer KepServer;
    private OPCGroups KepGroups;
    public OPCGroup KepGroup;
    private OPCItems KepItems;
    private OPCItem KepItem;
    int itmHandleClient = 0;
    int itmHandleServer = 0;

        public object readValue;
    
        public List<string> serverNames = new List<string>();
        public List<string> Tags = new List<string>();
    
        /// <summary>
        /// 枚举本地OPC SERVER
        /// </summary>
        public void GetOPCServers()
        {
            IPHostEntry IPHost = Dns.GetHostEntry(Environment.MachineName);
    
            Console.WriteLine("MAC Address:");
            foreach (IPAddress ip in IPHost.AddressList)
            {
                Console.WriteLine(ip.ToString());
            }
            Console.WriteLine("Please Enter IPHOST");
    
            string strHostIP = "localhost";//Console.ReadLine();
    
            IPHostEntry ipHostEntry = Dns.GetHostEntry(strHostIP);
            try
            {
                KepServer = new OPCServer();
                object serverList = KepServer.GetOPCServers(ipHostEntry.HostName.ToString());
                int i = 0;
                foreach (string serverName in (Array)serverList)
                {
                    Console.WriteLine(i.ToString() + "." + serverName);
                    serverNames.Add(serverName);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Connect Error:" + ex.Message);
            }
        }
    
        /// <summary>
        /// 连接OPC SERVER
        /// </summary>
        /// <param name="serverName">OPC SERVER名字</param>
        public void ConnectServer(string serverName)
        {
            try
            {
                KepServer.Connect(serverName, "");
                CreateGroup("");
                CreateItems();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Connect Error:" + ex.Message);
            }
        }
    
        /// <summary>
        /// 创建组,组名无所谓
        /// </summary>
        private void CreateGroup(string groupName)
        {
            try
            {
                KepGroups = KepServer.OPCGroups;
                KepGroup = KepGroups.Add(groupName);
                KepServer.OPCGroups.DefaultGroupIsActive = true;
                KepServer.OPCGroups.DefaultGroupDeadband = 0;
                KepGroup.UpdateRate = 250;
                KepGroup.IsActive = true;
                KepGroup.IsSubscribed = true;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Create group error:" + ex.Message);
            }
        }
    
        private void CreateItems()
        {
            KepItems = KepGroup.OPCItems;
            KepGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);
        }
    
        private void KepGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
        {
            for (int i = 1; i <= NumItems; i++)
            {
                readValue = ItemValues.GetValue(i).ToString();
            }
        }
    
        private void GetTagValue(string tagName)
        {
            try
            {
                readValue = "";
                if (itmHandleClient != 0)
                {
                    Array Errors;
                    OPCItem bItem = KepItems.GetOPCItem(itmHandleServer);
                    //注:OPC中以1为数组的基数
                    int[] temp = new int[2] { 0, bItem.ServerHandle };
                    Array serverHandle = (Array)temp;
                    //移除上一次选择的项
                    KepItems.Remove(KepItems.Count, ref serverHandle, out Errors);
                }
                itmHandleClient = 12345;
                KepItem = KepItems.AddItem(tagName, itmHandleClient);
                itmHandleServer = KepItem.ServerHandle;
            }
            catch (Exception err)
            {
                //没有任何权限的项,都是OPC服务器保留的系统项,此处可不做处理。
                itmHandleClient = 0;
                Console.WriteLine("Read value error:" + err.Message);
            }
        }
    
        public void WriteValue(string tagName, object _value)
        {
            GetTagValue(tagName);
            OPCItem bItem = KepItems.GetOPCItem(itmHandleServer);
            int[] temp = new int[2] { 0, bItem.ServerHandle };
            Array serverHandles = (Array)temp;
            object[] valueTemp = new object[2] { "", _value };
            Array values = (Array)valueTemp;
            Array Errors;
            int cancelID;
            KepGroup.AsyncWrite(1, ref serverHandles, ref values, out Errors, 2009, out cancelID);
            //KepItem.Write(txtWriteTagValue.Text);//这句也可以写入,但并不触发写入事件
            GC.Collect();
        }
    
        public object ReadValue(string tagName)
        {
            GetTagValue(tagName);
            Thread.Sleep(500);
            try
            {
                return KepItem.Value;
            }
            catch
            {
                return null;
            }
        }
    
        public void ReadValue(string tagName,bool wtf)
        {
            GetTagValue(tagName);
            OPCItem bItem = KepItems.GetOPCItem(itmHandleServer);
            int[] temp = new int[2] { 0, bItem.ServerHandle };
            Array serverHandles = (Array)temp;
            Array Errors;
            int cancel;
            KepGroup.AsyncRead(1, ref serverHandles, out Errors, 2009, out cancel);
            GC.Collect();
        }
    
    
    }
    

    }

    步骤:

    1.使用GetOPCServers方法,将本地所有OPC Server上所有OPC服务器服务枚举并写入serverNames变量中

    2.使用ConnectServer方法,连接服务器。此方法自动创建OPC Group,创建方法中的groupname任意写

    3.使用ReadValue及WriteValue方法读写数据。

    PS:

    1.OPCItems是一个列表,每次将旧数据移除,插入新数据,即列表中永远只有一个元素;

    2.读的时候有可能旧数据移除,新数据未写入,报对象为null的错误,sleep一下即可

    第二条不一定对,使用模拟器的时候也有此问题,连PLC时无此问题

    转载于:https://www.cnblogs.com/punkrocker/archive/2012/09/01/2666307.html

    展开全文
  • C#连接OPC获取数据

    2018-01-11 13:45:57
    C#连接OPC获取数据,代码中连接的是KEPServer4.5中自带的Demo地址
  • 相信我,这应该是最全最全的 C#通过opc ua 协议连接plc的项目和文档资料了!如果又不明白的可浏览我的博客,有相关的介绍和使用,欢迎交流讨论。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,033
精华内容 813
关键字:

c#opc

c# 订阅