C#调用OPC UA 解决方案

1、Opc 基金会git地址:OPC Foundation · GitHub

其中:UA-.NETStandard  、UA-.NETStandard-Samples比价有参考价值

2、参数传递方式:ns=2;s=参数名(ns表示命名空间索引,一般为2)

特殊情况可以查看所有命名空间:ns=0;i=2255,也可以用(OpcUaHelper.Tool)工具查看

下载地址:C#opc学习资源代码-其它文档类资源-CSDN下载

3、根据opc基金会提供方法整理出调用代码:OPCUAC#控制类库-制造文档类资源-CSDN下载

using Opc.Ua;
using Opc.Ua.Client;
using Opc.Ua.Configuration;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace OPCUALink
{
    /// <summary>
    /// OPC UA Client with examples of basic functionality.
    /// </summary>
    public class UAClient
    {
        #region Constructors
        public UAClient(bool isdebug = false)
        {
            if (isdebug)
            {
                return;
            }
            ApplicationInstance application = new ApplicationInstance();
            application.ApplicationName = SessionName;
            application.ApplicationType = ApplicationType.Client;
            //加载配置文件
            application.LoadApplicationConfiguration(ConfigPath, silent: false).Wait();
            // check the application certificate.
            //application.CheckApplicationInstanceCertificate(silent: false, minimumKeySize: 0).Wait();
            m_validateResponse = ClientBase.ValidateResponse;
            m_configuration = application.ApplicationConfiguration;
            m_configuration.CertificateValidator.CertificateValidation += CertificateValidation;
            ReceiveMsg += Msg;
        }
        #endregion

        #region Public Properties
        /// <summary>
        /// session.
        /// </summary>
        public Session Session => m_session;
        public static string conStr = "ns=3;s=";
        /// <summary>
        /// session名称
        /// </summary>
        public string SessionName { get; set; } = "DefaultSession";
        /// <summary>
        /// opcua服务地址
        /// </summary>
        public string ServerUrl { get; set; } = "opc.tcp://192.168.0.1/";
        /// <summary>
        /// 配置文件
        /// </summary>
        public string ConfigPath { get; set; } = "ConsoleReferenceClient.Config.xml";
        /// <summary>
        /// 日志委托
        /// </summary>
        public Action<string> LogAction { get; set; } = t => { Console.Write(t); };
        /// <summary>
        /// 订阅委托
        /// </summary>
        /// <param name="DisplayName"></param>
        /// <param name="Value"></param>
        public delegate void ShowMonitoredItemNotification(string DisplayName, string Value);
        public ShowMonitoredItemNotification ReceiveMsg;
        #endregion

        #region Public Methods
        /// <summary>
        /// 连接服务器
        /// </summary>
        public async Task<bool> ConnectAsync()
        {

            try
            {
                //if (m_session != null && m_session.Connected && m_session.SessionId.ToString() == null)
                //{
                //    LogAction?.Invoke("Session already connected!");
                //}
                //else
                //{
                //    LogAction?.Invoke("Connecting...");
                //    EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(ServerUrl, false);
                //    EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
                //    Session session = await Session.Create(endpoint: new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration), configuration: m_configuration, updateBeforeConnect: false, checkDomain: false, sessionName: m_configuration.ApplicationName, sessionTimeout: 1800000u, identity: new UserIdentity(), preferredLocales: null);
                //    if (session?.Connected ?? false)
                //    {
                //        m_session = session;
                //    }

                //    LogAction?.Invoke("New Session Created with SessionName = " + m_session.SessionName);
                //    WriteLogWorkDate_n("OpcUa", "连接成功:" + ServerUrl);
                //}

                if (m_session != null && m_session.Connected == true && m_session.SessionId.ToString() == null)
                {
                    LogAction?.Invoke("Session already connected!");
                }
                else
                {
                    //Conect();
                    LogAction?.Invoke("Connecting...");

                    // Get the endpoint by connecting to server's discovery endpoint.
                    // Try to find the first endopint without security.
                    EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(ServerUrl, false);

                    EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
                    ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);

                    // Create the session
                    Session session = await Session.Create(
                        m_configuration,
                        endpoint,
                        false,
                        false,
                        m_configuration.ApplicationName,
                        30 * 60 * 1000,//30 * 60 * 10,//
                        new UserIdentity(),
                        null
                    );

                    // Assign the created session
                    if (session != null && session.Connected)
                    {
                        m_session = session;
                    }

                    // Session created successfully.
                    LogAction?.Invoke($"New Session Created with SessionName = {m_session.SessionName}");
                    WriteLogWorkDate_n("OpcUa", "连接成功:" + ServerUrl);

                }
                return true;
            }
            catch (Exception ex)
            {
                // Log Error
                LogAction?.Invoke($"Create Session Error : {ex.Message}");
                WriteLogWorkDate_n("OpcUa", "连接失败:" + ServerUrl + ":" + ex.Message);
                ConnectAsync().Wait();
                return false;
            }
        }

        private async void Conect()
        {
            LogAction?.Invoke("Connecting...");

            // Get the endpoint by connecting to server's discovery endpoint.
            // Try to find the first endopint without security.
            EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(ServerUrl, false);

            EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
            ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);

            // Create the session
            Session session = await Session.Create(
                m_configuration,
                endpoint,
                false,
                false,
                m_configuration.ApplicationName,
                30 * 60 * 10,//30 * 60 * 1000,
                new UserIdentity(),
                null
            );

            // Assign the created session
            if (session != null && session.Connected)
            {
                m_session = session;
            }

            // Session created successfully.
            LogAction?.Invoke($"New Session Created with SessionName = {m_session.SessionName}");

        }

        /// <summary>
        /// 断开链接
        /// </summary>
        public void Disconnect()
        {
            try
            {
                WriteLogWorkDate_n("OpcUa", "断开连接:" + ServerUrl);

                if (m_session != null)
                {
                    LogAction?.Invoke("Disconnecting...");

                    m_session.Close();
                    m_session.Dispose();
                    m_session = null;

                    // Log Session Disconnected event
                    LogAction?.Invoke("Session Disconnected.");
                }
                else
                {
                    LogAction?.Invoke("Session not created!");
                }
            }
            catch (Exception ex)
            {
                // Log Error
                LogAction?.Invoke($"Disconnect Error : {ex.Message}");
            }
        }
        string oldword = "";
        /// <summary>
        /// 读单个节点
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="location">ns=4;s=A_AGV到周转桶</param>
        /// <returns>ns=0;i=2255 查看所有命名空间</returns>
        public T ReadNode<T>(string location)
        {
            #region 
            //DataValue dataValue = null;
            //if (m_session == null || !m_session.Connected)
            //{
            //     ConnectAsync();
            //}

            //try
            //{
            //    dataValue = m_session.ReadValue(conStr + location);
            //}
            //catch
            //{
            //    ConnectAsync();
            //    dataValue = m_session.ReadValue(conStr + location);
            //}

            //return (T)dataValue.Value; 
            #endregion
            if (m_session == null || m_session.Connected == false)
            {
                ConnectAsync().Wait();
            }
            DataValue value = null;
            try
            {
                value = m_session.ReadValue(conStr + location);
            }
            catch (Exception)
            {
                ConnectAsync().Wait();
                value = m_session.ReadValue(conStr + location);
            }
            string newword = "读单个节点:" + location + ":" + value.Value;
            if (newword != oldword)
            {
                WriteLogWorkDate_n("OpcUa", newword);
                oldword = newword;
            }

            return (T)value.Value;
        }
        /// <summary>
        /// 读多个节点
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="locations"></param>
        /// <returns></returns>
        public List<T> ReadNodes<T>(List<string> locations)
        {
            for (int i = 0; i < locations.Count; i++)
            {
                locations[i] = conStr + locations[i];
            }
            if (m_session == null || m_session.Connected == false)
            {
                ConnectAsync().Wait();
            }
            var typeList = new List<Type>();
            foreach (var location in locations)
            {
                typeList.Add(typeof(T));
            }
            var nodeIds = locations.Select(t => new NodeId(t)).ToList();
            List<object> values = new List<object>();
            try
            {
                m_session.ReadValues(nodeIds, typeList, out values, out List<ServiceResult> errors);
            }
            catch (Exception)
            {
                ConnectAsync().Wait();
                m_session.ReadValues(nodeIds, typeList, out values, out List<ServiceResult> errors);
            }
            return values.Select(t => (T)t).ToList();

        }
        /// <summary>
        /// 写单个节点
        /// </summary>
        /// <param name="location"></param>
        /// <param name="value"></param>
        public void WriteNode(string location, object value)
        {
            location = conStr + location;
            if (m_session == null || m_session.Connected == false)
            {
                ConnectAsync().Wait();
            }
            WriteLogWorkDate_n("OpcUa", "写单个节点:" + location + ":" + value);

            WriteValueCollection nodesToWrite = new WriteValueCollection();
            WriteValue intWriteVal = new WriteValue();
            intWriteVal.NodeId = new NodeId(location);
            intWriteVal.AttributeId = Attributes.Value;
            intWriteVal.Value = new DataValue();
            intWriteVal.Value.Value = value;
            nodesToWrite.Add(intWriteVal);
            try
            {
                m_session.Write(null,
                                   nodesToWrite,
                                   out StatusCodeCollection results,
                                   out DiagnosticInfoCollection diagnosticInfos);
            }
            catch (Exception)
            {
                ConnectAsync().Wait();
                m_session.Write(null,
                                  nodesToWrite,
                                  out StatusCodeCollection results,
                                  out DiagnosticInfoCollection diagnosticInfos);
            }
        }
        /// <summary>
        /// 写多个节点
        /// </summary>
        /// <param name="locations"></param>
        /// <param name="values"></param>
        public void WriteNodes(List<string> locations, List<object> values)
        {
            if (m_session == null || m_session.Connected == false)
            {
                ConnectAsync().Wait();
            }
            WriteValueCollection nodesToWrite = new WriteValueCollection();
            for (int i = 0; i < locations.Count; i++)
            {
                WriteLogWorkDate_n("OpcUa", "写多个节点:" + locations[i] + ":" + values[i]);

                WriteValue intWriteVal = new WriteValue();
                intWriteVal.NodeId = new NodeId(conStr + locations[i]);
                intWriteVal.AttributeId = Attributes.Value;
                intWriteVal.Value = new DataValue();
                intWriteVal.Value.Value = values[i];
                nodesToWrite.Add(intWriteVal);
            }
            m_session.Write(null,
                            nodesToWrite,
                            out StatusCodeCollection results,
                            out DiagnosticInfoCollection diagnosticInfos);
        }
        /// <summary>
        ///订阅多个节点
        /// </summary>
        public void SubscribeToDataChanges(List<string> locations)
        {
            if (m_session == null || m_session.Connected == false)
            {
                ConnectAsync().Wait();
                return;
            }
            try
            {
                // 创建订阅以接收数据更改通知
                // 定义订阅参数
                Subscription subscription = new Subscription(m_session.DefaultSubscription);

                subscription.DisplayName = "Console ReferenceClient Subscription";
                subscription.PublishingEnabled = true;
                subscription.PublishingInterval = 1000;

                m_session.AddSubscription(subscription);

                //在服务器端创建订阅
                subscription.Create();

                foreach (string loa in locations)
                {
                    MonitoredItem intMonitoredItem = new MonitoredItem(subscription.DefaultItem);
                    // Int32 Node - Objects\CTT\Scalar\Simulation\Int32
                    intMonitoredItem.StartNodeId = new NodeId(conStr + loa);
                    intMonitoredItem.AttributeId = Attributes.Value;
                    intMonitoredItem.DisplayName = conStr + loa;
                    intMonitoredItem.SamplingInterval = 1000;
                    intMonitoredItem.Notification += OnMonitoredItemNotification;
                    subscription.AddItem(intMonitoredItem);
                }
                // 在服务器端创建监控项
                subscription.ApplyChanges();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 从服务器读取值节点,不分类型
        /// </summary>
        /// <param name="nodeId">node id</param>
        /// <returns>DataValue</returns>
        public string ReadAllNode()//DataValue ReadAllNode()
        {
            NodeId nodeId = new NodeId(conStr + $"\"上位机读取交互数据\".\"培养箱抓取完成\"");
            string res = "";
            ReadValueIdCollection nodesToRead = new ReadValueIdCollection
            {
                new ReadValueId( )
                {
                    NodeId = nodeId,
                    AttributeId = Attributes.Value
                }
            };

            // read the current value
            try
            {
                m_session.Read(
                       null,
                       0,
                       TimestampsToReturn.Neither,
                       nodesToRead,
                       out DataValueCollection results,
                       out DiagnosticInfoCollection diagnosticInfos);

                ClientBase.ValidateResponse(results, nodesToRead);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);
                DataValue dv = results[0];
            }
            catch
            {
                ConnectAsync().Wait();
                m_session.Read(
                       null,
                       0,
                       TimestampsToReturn.Neither,
                       nodesToRead,
                       out DataValueCollection results,
                       out DiagnosticInfoCollection diagnosticInfos);

                ClientBase.ValidateResponse(results, nodesToRead);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);
                DataValue dv = results[0];
                res = dv.Value.ToString();
            }
            return res;
        }

        #endregion

        #region Private Methods

        private void Msg(string DisplayName, string Value)
        {

        }
        private void OnMonitoredItemNotification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            try
            {
                // Log MonitoredItem Notification event
                MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
                WriteLogWorkDate_n("OpcUa", "订阅反馈:" + monitoredItem.DisplayName + ":" + notification.Value.ToString());
                ReceiveMsg(monitoredItem.DisplayName, notification.Value.ToString());
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
                WriteLogWorkDate_n("OpcUa", "订阅反馈:" + monitoredItem.DisplayName + ":" + ex.Message);
            }
        }

        /// <summary>
        /// Handles the certificate validation event.
        /// This event is triggered every time an untrusted certificate is received from the server.
        /// </summary>
        private void CertificateValidation(CertificateValidator sender, CertificateValidationEventArgs e)
        {
            bool certificateAccepted = true;

            // ****
            // Implement a custom logic to decide if the certificate should be
            // accepted or not and set certificateAccepted flag accordingly.
            // The certificate can be retrieved from the e.Certificate field
            // ***

            ServiceResult error = e.Error;
            while (error != null)
            {
                LogAction?.Invoke(error.ToString());
                error = error.InnerResult;
            }

            if (certificateAccepted)
            {
                LogAction?.Invoke($"Untrusted Certificate accepted. SubjectName = {e.Certificate.SubjectName}");
            }

            e.AcceptAll = certificateAccepted;
        }
        #endregion

        #region Private Fields

        private ApplicationConfiguration m_configuration;

        private Session m_session;

        private readonly Action<IList, IList> m_validateResponse;

        #endregion

        public static void WriteLogWorkDate_n(string fstyle, string messagestr)
        {
            #region  日志文件写入每天生成一个文件 txt
            try
            {
                //创建一个文件流,用以写入或者创建一个StreamWriter
                string filenamenew = fstyle + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
                string date = DateTime.Now.ToString("yyyy-MM-dd");

                //信息中下上时间直接写入 wqy 20180319
                string msg = "";
                if (messagestr == "")
                {
                    msg = messagestr;
                }
                else
                {
                    msg = DateTime.Now.ToString("HH:mm:ss:fff") + " " + messagestr;
                }

                //包装箱文件夹不存在创建
                string xhpath = AppDomain.CurrentDomain.BaseDirectory + "log\\" + date + "\\";
                //文件夹不存在创建
                if (!Directory.Exists(xhpath))
                {
                    Directory.CreateDirectory(xhpath);
                }

                filenamenew = xhpath + filenamenew;

                FileStream fs = new FileStream(filenamenew, FileMode.OpenOrCreate, FileAccess.ReadWrite);
                StreamWriter m_streamWriter = new StreamWriter(fs);
                m_streamWriter.Flush();
                // 使用StreamWriter来往文件中写入内容
                m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
                // 把richTextBox1中的内容写入文件
                m_streamWriter.Write(msg + "\r\n");
                //关闭此文件
                m_streamWriter.Flush();
                m_streamWriter.Close();
                fs.Close();
            }
            catch (Exception ex)
            {
            }
            #endregion
        }

    }
}

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值