Kepware与C#

@[Kepware与C#]

Kepware与C#

概述

本章描述的是,如何使用C#读写Kepware软件上的标记值。
这是我网上下载的示例代码☞提取码:jv4x
运行的程序如图所示:
在这里插入图片描述

个人测试代码

前提是安装了Kepware软件

①添加引用

下载DLL
在这里插入图片描述

②工具类代码

OpcUaClient工具类

using Common.Log;
using Opc.Ua;
using Opc.Ua.Client;
using Opc.Ua.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace namespace1
{
    /// <summary>
    /// 一个二次封装了的OPC UA库
    /// </summary>
    public class OpcUaClient
    {
        #region Private Fields 
        private static Logger logger = Logger.getLogger();
        private Dictionary<string, Subscription> dic_subscriptions;//系统所有的节点信息
        private ApplicationInstance application;
        private ApplicationConfiguration m_configuration;
        private Session m_session;
        private bool m_IsConnected;                       //是否已经连接过
        private SessionReconnectHandler m_reconnectHandler;
        private bool m_useSecurity;
        private EventHandler m_ConnectComplete;
        private EventHandler<OpcUaStatusEventArgs> m_OpcStatusChange;
        private int m_reconnectPeriod = 10;               // 重连状态
        private EventHandler m_ReconnectStarting;
        private EventHandler m_KeepAliveComplete;
        private EventHandler m_ReconnectComplete;
        #endregion

        #region Public Members 
        public string OpcUaName = "Opc Ua Helper";
        /// <summary>
        /// Whether to use security when connecting.
        /// </summary>
        public bool UseSecurity
        {
            get { return m_useSecurity; }
            set { m_useSecurity = value; }
        }

        /// <summary>
        /// The user identity to use when creating the session.
        /// </summary>
        public IUserIdentity UserIdentity { get; set; }



        /// <summary>
        /// The currently active session. 
        /// </summary>
        public Session Session
        {
            get { return m_session; }
        }

        /// <summary>
        /// Indicate the connect status
        /// </summary>
        public bool Connected
        {
            get { return m_IsConnected; }
        }

        /// <summary>
        /// The number of seconds between reconnect attempts (0 means reconnect is disabled).
        /// </summary>
        public int ReconnectPeriod
        {
            get { return m_reconnectPeriod; }
            set { m_reconnectPeriod = value; }
        }

        /// <summary>
        /// Raised when a good keep alive from the server arrives.
        /// </summary>
        public event EventHandler KeepAliveComplete
        {
            add { m_KeepAliveComplete += value; }
            remove { m_KeepAliveComplete -= value; }
        }
        
        /// <summary>
        /// Raised when a reconnect operation starts.
        /// </summary>
        public event EventHandler ReconnectStarting
        {
            add { m_ReconnectStarting += value; }
            remove { m_ReconnectStarting -= value; }
        }


        /// <summary>
        /// Raised when a reconnect operation completes.
        /// </summary>
        public event EventHandler ReconnectComplete
        {
            add { m_ReconnectComplete += value; }
            remove { m_ReconnectComplete -= value; }
        }

        /// <summary>
        /// Raised after successfully connecting to or disconnecing from a server.
        /// </summary>
        public event EventHandler ConnectComplete
        {
            add { m_ConnectComplete += value; }
            remove { m_ConnectComplete -= value; }
        }

        /// <summary>
        /// Raised after the client status change
        /// </summary>
        public event EventHandler<OpcUaStatusEventArgs> OpcStatusChange
        {
            add { m_OpcStatusChange += value; }
            remove { m_OpcStatusChange -= value; }
        }

        /// <summary>
        /// 配置信息
        /// </summary>
        public ApplicationConfiguration AppConfig
        {
            get
            {
                return m_configuration;
            }
        }
        #endregion

        #region OpcUaClient 默认的构造函数,实例化一个新的OPC UA类,初始化配置
        /// <summary>
        /// 默认的构造函数,实例化一个新的OPC UA类,初始化配置
        /// </summary>
        public OpcUaClient() 
        {
            dic_subscriptions = new Dictionary<string, Subscription>();//初始化变量 ‘系统所有的节点信息’

            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("Failed to validate certificate with error code {0}: {1}", eventArgs.Error.Code, eventArgs.Error.AdditionalInfo));
            };

            SecurityConfiguration securityConfigurationcv = new SecurityConfiguration
            {
                AutoAcceptUntrustedCertificates = true,
                RejectSHA1SignedCertificates = false,
                MinimumCertificateKeySize = 1024,
            };
            certificateValidator.Update(securityConfigurationcv);

            // Build the application configuration
            application = new ApplicationInstance
            {
                ApplicationType = ApplicationType.Client,
                ConfigSectionName = OpcUaName,
                ApplicationConfiguration = new ApplicationConfiguration
                {
                    ApplicationName = OpcUaName,
                    ApplicationType = ApplicationType.Client,
                    CertificateValidator = certificateValidator,
                    ServerConfiguration = new ServerConfiguration
                    {
                        MaxSubscriptionCount = 100000,
                        MaxMessageQueueSize = 1000000,
                        MaxNotificationQueueSize = 1000000,
                        MaxPublishRequestCount = 10000000,
                    },

                    SecurityConfiguration = new SecurityConfiguration
                    {
                        AutoAcceptUntrustedCertificates = true,
                        RejectSHA1SignedCertificates = false,
                        MinimumCertificateKeySize = 1024,
                    },

                    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
                }
            };
            m_configuration = application.ApplicationConfiguration;
        }
        #endregion

        #region Connect 连接 POC

        /// <summary>
        /// connect to server
        /// </summary>
        /// <param name="serverUrl">remote url</param>
        public async Task ConnectServer(string serverUrl)
        {
            m_session = await Connect(serverUrl);
        }
        /// <summary>
        /// Creates a new session.
        /// </summary>
        /// <returns>The new session object.</returns>
        private async Task<Session> Connect(string serverUrl)
        {
            logger.DebugStart("OpcUaClient.Connect -> serverUrl="+ serverUrl);
            // disconnect from existing session.
            //Disconnect();

            if (serverUrl==String.Empty|| serverUrl==null)
            {
                throw new ArgumentNullException("serverUrl");
            }
            if (m_configuration == null)
            {
                throw new ArgumentNullException("m_configuration");
            }

            // select the best endpoint.
            EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(serverUrl, UseSecurity,3000);//超时设置 为3s

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

            m_session = await Session.Create(
                m_configuration,
                endpoint,
                false,
                false,
                (string.IsNullOrEmpty(OpcUaName)) ? m_configuration.ApplicationName : OpcUaName,
                60000,
                UserIdentity,
                new string[] { });

            // set up keep alive callback.
            m_session.KeepAlive += new KeepAliveEventHandler(Session_KeepAlive);

            // update the client status
            m_IsConnected = true;

            // raise an event.
            DoConnectComplete(null);

            // return the new session.
            logger.DebugEnd("OpcUaClient.Connect");
            return m_session;
        }
        #endregion

        #region Disconnect 断开连接 POC
        /// <summary>
        /// Disconnects from the server.
        /// </summary>
        public void Disconnect()
        {
            //修改状态
            UpdateStatus(false, DateTime.UtcNow, "Disconnected");
            // stop any reconnect operation.
            if (m_reconnectHandler != null)
            {
                m_reconnectHandler.Dispose();
                m_reconnectHandler = null;
            }

            // disconnect any existing session.
            if (m_session != null)
            {
                m_session.Close(10000);
                m_session = null;
            }

            // update the client status
            m_IsConnected = false;

            // raise an event.
            DoConnectComplete(null);
        }
        #endregion

        #region 设置OPC客户端的日志输出
        /// <summary>
        /// 设置OPC客户端的日志输出
        /// </summary>
        /// <param name="filePath">完整的文件路径</param>
        /// <param name="deleteExisting">是否删除原文件</param>
        public void SetLogPathName(string filePath, bool deleteExisting)
        {
            Utils.SetTraceLog(filePath, deleteExisting);
            Utils.SetTraceMask(515);
        }
        #endregion

        #region Event Handlers 异常处理

        /// <summary>
        /// Handles a keep alive event from a session.
        /// </summary>
        private void Session_KeepAlive(Session session, KeepAliveEventArgs e)
        {

            try
            {
                // check for events from discarded sessions.
                if (!Object.ReferenceEquals( session, m_session ))
                {
                    return;
                }

                // start reconnect sequence on communication error.
                if (ServiceResult.IsBad( e.Status ))
                {
                    if (m_reconnectPeriod <= 0)
                    {
                        // 上报连接状态
                        UpdateStatus( true, e.CurrentTime, "Communication Error ({0})", e.Status );
                        return;
                    }
                    // 上报连接状态
                    UpdateStatus( true, e.CurrentTime, "Reconnecting in {0}s", m_reconnectPeriod );

                    if (m_reconnectHandler == null)
                    {
                        if(m_ReconnectStarting!=null){
                            m_ReconnectStarting.Invoke( this, e );
                        }

                        m_reconnectHandler = new SessionReconnectHandler( );
                        m_reconnectHandler.BeginReconnect( m_session, m_reconnectPeriod * 1000, Server_ReconnectComplete );
                    }

                    return;
                }

                // 上报连接状态
                UpdateStatus( false, e.CurrentTime, "Connected [{0}]", session.Endpoint.EndpointUrl );

                // raise any additional notifications.
                if (m_KeepAliveComplete != null)
                {
                    m_KeepAliveComplete.Invoke(this, e);
                }
            }
            catch (Exception exception)
            {
                Console.Write(exception);
                throw;
            }
        }

        /// <summary>
        /// Report the client status
        /// </summary>
        /// <param name="error">Whether the status represents an error.</param>
        /// <param name="time">The time associated with the status.</param>
        /// <param name="status">The status message.</param>
        /// <param name="args">Arguments used to format the status message.</param>
        private void UpdateStatus(bool error, DateTime time, string status, params object[] args)
        {
            m_OpcStatusChange?.Invoke(this, new OpcUaStatusEventArgs()
            {
                Error = error,
                Time = time.ToLocalTime(),
                Text = String.Format(status, args),
            });
        }

        /// <summary>
        /// Handles a reconnect event complete from the reconnect handler.
        /// </summary>
        private void Server_ReconnectComplete(object sender, EventArgs e)
        {

            try
            {
                // ignore callbacks from discarded objects.
                if (!Object.ReferenceEquals( sender, m_reconnectHandler ))
                {
                    return;
                }

                m_session = m_reconnectHandler.Session;
                m_reconnectHandler.Dispose( );
                m_reconnectHandler = null;

                // raise any additional notifications.
                if (m_ReconnectComplete != null)
                {
                    m_ReconnectComplete.Invoke(this, e);
                }
            }
            catch (Exception exception)
            {
                Console.Write(exception);
                throw;
            }
        }
        #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
            m_session.Read(
                null,
                0,
                TimestampsToReturn.Neither,
                nodesToRead,
                out DataValueCollection results,
                out DiagnosticInfoCollection diagnosticInfos);

            ClientBase.ValidateResponse(results, nodesToRead);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);

            return results[0];
        }

        /// <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
            };

            // 写入当前的值

            m_session.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]);
        }
        #endregion
        /// <summary>
        /// Raises the connect complete event on the main GUI thread.
        /// </summary>
        private void DoConnectComplete(object state)
        {
            //m_ConnectComplete?.Invoke( this, null );
            if(m_ConnectComplete!=null){
              m_ConnectComplete.Invoke(this, null);
            }
        }
    }
}

OpcUaClient工具类

using System;
using Opc.Ua;
using Common.Log;
using Common.Response;

namespace namespace1
{
    public class OpcUaHelper
    {
        private static Logger logger = Logger.getLogger();
        
        private  OpcUaClient m_OpcUaClient = null;

        private string  curStatusStr=String.Empty;

        private bool curStatus = false;

        # region 单例模式
        /// <summary>
        /// 获取一个单例对象
        /// </summary>
        /// <returns></returns>
        private static OpcUaHelper instance;

        private static readonly object locks = new object();//确保线程同步

        private OpcUaHelper() {
            m_OpcUaClient = new OpcUaClient();
        }
       
       
        /// <summary>
        ///获取唯一可用的对象 
        /// </summary>
        /// <returns></returns>
        public static OpcUaHelper getInstance()
        {
            if (instance == null)
            {
                lock (locks)
                {
                    if (instance == null)
                    {
                        instance = new OpcUaHelper();
                    }
                }
            }
            return instance;
        }
        #endregion

        /// <summary>
        /// 连接OPC软件,返回m_OpcUaClient0
        /// </summary>
        /// <param name="url"></param>
        /// <param name="user"></param>
        /// <param name="password"></param>
        /// <param name="m_OpcUaClient0"></param>
        /// <returns></returns>
        public bool connectGet(string url, string user, string password,out OpcUaClient m_OpcUaClient0)
        {
            bool result = false;
            m_OpcUaClient0 = null; 
            try
            {
                //连接OPC软件
                connectServer(url, user, password);
                result = connectFlag;
                m_OpcUaClient0 = m_OpcUaClient;
            }
            catch (Exception ex)
            {
                logger.Error("Common.OpcUaHelper.connectGet -> url=" + url + ",user=" + user + ",password=" + password + "—>" + ex.ToString());
            }
            return result;
        }


        /// <summary>
        /// 连接OPC软件
        /// </summary>
        /// <param name="url"></param>
        /// <param name="user"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public bool connect(string url, string user, string password)
        {
            bool result = false;
            try
            {
                //连接OPC软件
                connectServer(url,user,password);
                result = connectFlag;
            }
            catch (Exception ex)
            {
                logger.Error("OpcUaHelper.connect -> url=" + url + ",user=" + user + ",password=" + password + "—>" + ex.ToString());
            }
            return result;
        }

        /// <summary>
        /// OPC 客户端的状态变化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void M_OpcUaClient_OpcStatusChange(object sender, OpcUaStatusEventArgs e)
        {
            //logger.Debug("Current session:" + m_OpcUaClient.Session.Connected);
            if (curStatusStr != e.Text|| e.Error||!m_OpcUaClient.Session.Connected)
            {
                curStatusStr = e.Text;
                logger.Debug("OpcStatus:" + e.ToString());
            }
            //修改当前会话状态
            if (e.Error || !m_OpcUaClient.Session.Connected)
            {
                curStatus = false;
            }
            else
            {
                curStatus = true;
            }

        }
        /// <summary>
        /// 获取当前会话的状态
        /// </summary>
        /// <returns></returns>
        public Boolean getCurrentStatue()
        {
            return curStatus;
        }
        /// <summary>
        /// 连接服务器结束后事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void M_OpcUaClient_ConnectComplete(object sender, EventArgs e)
        {
            try
            {
                //logger.Info("Connect Success.");
            }
            catch (Exception exception)
            {
                logger.Error("OpcUaHelper.M_OpcUaClient_ConnectComplete ->" + exception.ToString());
            }
        }
        private bool connectFlag = false;
        /// <summary>
        /// 连接OPC软件
        /// </summary>
        /// <param name="url"></param>
        /// <param name="user"></param>
        /// <param name="password"></param>
        private async void connectServer(string url, string user, string password)
        {
            connectFlag = false;
            try
            {
                m_OpcUaClient.SetLogPathName((new BasePathHelper().GetRootPath()) + "\\Log\\opc.ua.client.txt", true);//输出日志
                m_OpcUaClient.OpcStatusChange += M_OpcUaClient_OpcStatusChange;//监控状态
                m_OpcUaClient.ConnectComplete += M_OpcUaClient_ConnectComplete;//完成事件
                m_OpcUaClient.UserIdentity = new UserIdentity(user, password);
                await m_OpcUaClient.ConnectServer(url);
                connectFlag = true;
            }
            catch (Exception ex)
            {
                logger.Error("OpcUaHelper.connectServer url=" + url+ ",user="+ user+ ",password="+ password+"——"+ ex.ToString());
            }
         }
        /// <summary>
        /// 断开连接
        /// </summary>
        public void  Disconnect()
        {
            try
            {
                m_OpcUaClient.Disconnect();
            }
            catch (Exception ex)
            {
                logger.Error("Common.OpcUaHelper.connect Disconnect unsuccessfully. ——"+ex.ToString());
                throw;
            }
           
        }
            /// <summary>
            /// 读取指定地址的值
            /// </summary>
            /// <param name="tag"></param>
            /// <returns></returns>
        public ReturnVO<String> readNode(string tag)
        {
            ReturnVO<String> result = null;
            if (tag != string.Empty)
            {
                try
                {
                    NodeId nodeId = new NodeId(tag);
                    DataValue value = m_OpcUaClient.ReadNode(nodeId);
                    if (value != null)
                    {
                        if (!(value.ToString()).Contains("null"))
                        {
                            result = new ReturnVO<String>(true, null, value.ToString());
                        }
                        else
                        {

                            //读取指定地址失败,请查看OPC软件与PLC通讯是否正常或OPC软件中该地址是否存在
                            ErrorCode.Opc error = ErrorCode.Opc.ox100002;
                            result = new ReturnVO<String>(false, error.GetDescription(), null);
                            logger.Error("Common.OpcUaHelper.readNode  " + error + "->" + error.GetDescription() + "-> Param:tag=" + tag);
                        }

                    }
                    else
                    {
                        //读取指定地址失败,编码错误
                        ErrorCode.Common error = ErrorCode.Common.cx100001;
                        result = new ReturnVO<String>(false, error.GetDescription(), null);
                        logger.Error("Common.OpcUaHelper.readNode  " + error + "->" + error.GetDescription() + "-> Param:tag=" + tag);
                    }
                }
                catch (Exception ex)
                {
                    //读取指定地址失败,编码错误
                    ErrorCode.Common error = ErrorCode.Common.cx100001;
                    result = new ReturnVO<String>(false, error.GetDescription(), null);
                    Global.IsConnected = false;
                    logger.Error("Common.OpcUaHelper.readNode  " + error + "->" + error.GetDescription() + "-> Param:tag=" + tag);
                    logger.Error("Common.OpcUaHelper.readNode  " + ex.ToString());
                    throw;
                }
            }
            else
            {
                //参数传递错误
                ErrorCode.Common error = ErrorCode.Common.cx100002;
                result = new ReturnVO<String>(false, error.GetDescription(), null);
                logger.Error("Common.OpcUaHelper.readNode  " + error + "->" + error.GetDescription() + "-> Param:tag=" + tag);
            }
            return result;
        }

        /// <summary>
        /// 写入指定地址指定数据类型的值
        /// </summary>
        /// <param name="tag"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public ReturnVO<String> writeNode(string tag, string value)
        {
            ReturnVO<String> result = null;
            if (tag != string.Empty && value != string.Empty)
            {
                try
                {
                    //获取节点的数据类型
                    NodeId nodeId = new NodeId(tag);
                    DataValue node = m_OpcUaClient.ReadNode(nodeId);
                    if (node != null)
                    {
                        if (!(node.ToString()).Contains("null"))
                        {
                            BuiltInType builtInType = node.WrappedValue.TypeInfo.BuiltInType;
                            //写入数据
                            dynamic inputValue = GetValueFromString(value, builtInType);
                            bool b = m_OpcUaClient.WriteNode(tag, inputValue);
                            result = new ReturnVO<String>(b,b?"": ErrorCode.Opc.ox100004.GetDescription(), null);//可能出现写入失败 ox100004
                        }
                        else
                        {
                            //读取指定地址失败,请查看OPC软件与PLC通讯是否正常或OPC软件中该地址是否存在
                            ErrorCode.Opc error = ErrorCode.Opc.ox100002;
                            result = new ReturnVO<String>(false, error.GetDescription(), null);
                            logger.Error("Common.OpcUaHelper.writeNode  " + error + "->" + error.GetDescription() + "-> Param:tag=" + tag + ",value=" + value);
                        }

                    }
                    else
                    {
                        //编码错误
                        ErrorCode.Common error = ErrorCode.Common.cx100001;
                        result = new ReturnVO<String>(false, error.GetDescription(), null);
                        logger.Error("Common.OpcUaHelper.writeNode  " + error + "->" + error.GetDescription() + "-> Param:tag=" + tag + ",value=" + value);
                    }
                }
                catch (Exception ex)
                {
                    //编码错误
                    ErrorCode.Common error = ErrorCode.Common.cx100001;
                    result = new ReturnVO<String>(false, error.GetDescription(), null);
                    Global.IsConnected = false;
                    logger.Error("Common.OpcUaHelper.writeNode  " + error + "->" + error.GetDescription() + "-> Param:tag=" + tag + ",value=" + value);
                    logger.Error("Common.OpcUaHelper.writeNode  " + ex.ToString());
                    throw;
                }
            }
            else
            {
                //参数传递错误
                ErrorCode.Common error = ErrorCode.Common.cx100002;
                result = new ReturnVO<String>(false, error.GetDescription(), null);
                logger.Error("Common.OpcUaHelper.writeNode  " + error + "->" + error.GetDescription() + "-> Param:tag=" + tag + ",value=" + value);
            }
            return result;
        }
        /// <summary>
        /// 将字符串转换为指定数据类型
        /// </summary>
        /// <param name="value"></param>
        /// <param name="builtInType"></param>
        /// <returns></returns>
        private dynamic GetValueFromString(string value, BuiltInType builtInType)
        {
            switch (builtInType)
            {
                case BuiltInType.Boolean:
                    {
                        return bool.Parse(value);
                    }
                case BuiltInType.Byte:
                    {
                        return byte.Parse(value);
                    }
                case BuiltInType.DateTime:
                    {
                        return DateTime.Parse(value);
                    }
                case BuiltInType.Double:
                    {
                        return double.Parse(value);
                    }
                case BuiltInType.Float:
                    {
                        return float.Parse(value);
                    }
                case BuiltInType.Guid:
                    {
                        return Guid.Parse(value);
                    }
                case BuiltInType.Int16:
                    {
                        return short.Parse(value);
                    }
                case BuiltInType.Int32:
                    {
                        return int.Parse(value);
                    }
                case BuiltInType.Int64:
                    {
                        return long.Parse(value);
                    }
                case BuiltInType.Integer:
                    {
                        return int.Parse(value);
                    }
                case BuiltInType.LocalizedText:
                    {
                        return value;
                    }
                case BuiltInType.SByte:
                    {
                        return sbyte.Parse(value);
                    }
                case BuiltInType.String:
                    {
                        return value;
                    }
                case BuiltInType.UInt16:
                    {
                        return ushort.Parse(value);
                    }
                case BuiltInType.UInt32:
                    {
                        return uint.Parse(value);
                    }
                case BuiltInType.UInt64:
                    {
                        return ulong.Parse(value);
                    }
                case BuiltInType.UInteger:
                    {
                        return uint.Parse(value);
                    }
                default: throw new Exception("Not supported data type");
            }
        }
    }
}

OpcUaClient工具类

using Opc.Ua;
using System;

namespace namespace1 
{
    /// <summary>
    /// OPC UA的状态更新消息
    /// </summary>
    public class OpcUaStatusEventArgs
    {


        /// <summary>
        /// 是否异常
        /// </summary>
        public bool Error { get; set; }
        /// <summary>
        /// 时间
        /// </summary>
        public DateTime Time { get; set; }
        /// <summary>
        /// 文本
        /// </summary>
        public string Text { get; set; }

        /// <summary>
        /// 转化为字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return Error ? "[异常]" : "[正常]" + Time.ToString("  yyyy-MM-dd HH:mm:ss  ") + Text;
        }


    }

    /// <summary>
    /// 读取属性过程中用于描述的
    /// </summary>
    public class OpcNodeAttribute
    {
        /// <summary>
        /// 属性的名称
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 属性的类型描述
        /// </summary>
        public string Type { get; set; }
        /// <summary>
        /// 操作结果状态描述
        /// </summary>
        public StatusCode StatusCode { get; set; }
        /// <summary>
        /// 属性的值,如果读取错误,返回文本描述
        /// </summary>
        public object Value { get; set; }

    }
}

Server工具类

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace namespace1 
{
    [DataContract]
    public class Server
    {
        [DataMember]
        public String IP { set; get; }
        [DataMember]
        public String User { set; get; }
        [DataMember]
        public String PassWord { set; get; }
        [DataMember]
        public String Code { set; get; }
        [DataMember]
        public String Name { set; get; }
        [DataMember]
        public String Description { set; get; }
        [DataMember]
        public List<Sign> Signs{ set; get; }

        public String toString()
        {
            return "Server[Code="+Code+ ",Name="+Name+",Description="+Description+",IP="+IP +",User="+User+",PassWord="+PassWord+ ",Signs.Length="+(Signs==null?"0":(Signs.Count+""))+"]";
        }
    }
    [DataContract]
    public class Sign
    {
        [DataMember]
        public String Code { set; get; }
        [DataMember]
        public String Name { set; get; }
        [DataMember]
        public String Description { set; get; }
        [DataMember]
        public String DataType { set; get; }
        [DataMember]
        public String ReadPeriod { set; get; }
        [DataMember]
        public String NodeID { set; get; }
        [DataMember]
        public String Value { set; get; }
    }
}

ReturnVO 工具类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace namespace1
{
    [DataContract]
    public class ReturnVO<T>
    {
        [DataMember]
        private Boolean ret = true;
        [DataMember]
        private String msg = "";
        [DataMember]
        private T model;

        public ReturnVO(Boolean ret, String msg, T model)
        {
            this.ret = ret;
            this.msg = msg;
            this.model = model;
        }
        public Boolean isRet()
        {
            return ret;
        }

        public void setRet(Boolean ret)
        {
            this.ret = ret;
        }

        public String getMsg()
        {
            return msg;
        }

        public void setMsg(String msg)
        {
            this.msg = msg;
        }

        public T getModel()
        {
            return model;
        }

        public void setModel(T model)
        {
            this.model = model;
        }

        public String toString()
        {
            String str = "";
            if (model != null)
            {
                str = model.ToString();
            }
            return "ReturnVO [ret=" + ret + ", msg=" + msg + ", model=" + str + "]";
        }
    }
}

调用代码:

连接Kepware

   OpcUaHelper opcUaHelper = OpcUaHelper.getInstance();
   string url="";//Kepware上设置的URL
   string user="";//Kepware上设置的账号
   string password="";//Kepware上设置的密码
   bool b = opcUaHelper.connect(url, user, password);
   if (b) {
    //连接成功
   }else{
    //连接失败
    }

读标记

  ReturnVO<string> obj=opcUaHelper.readNode(NodeID);
  if (obj.isRet())
  {
        string v = obj.getModel();//正确的时候放入读取的信息
   }else{
        string v = obj.getMsg();//错误的时候放入错误信息
   }

写标记

  ReturnVO<string> obj=opcUaHelper.writeNode(NodeID,Value);
  if (obj.isRet())
  {
        string v = obj.getModel();//正确的时候放入读取的信息
   }else{
        string v = obj.getMsg();//错误的时候放入错误信息
   }

NodeID和Value都是string类型,
NodeID是标记的地址ID,例如‘ns=2;s=Ethernet.Equip1.B0221’
Value 是 数字

断开连接

  opcUaHelper.Disconnect();

关于如何设置Kepware的URL、账号与密码

点开右下角的托盘,找到Kepware的小图标,选中右击
在这里插入图片描述

①设置URL

点击[OPC UA 配置],显示如下
在这里插入图片描述
注意:需要使用的URL必须处于[已启用]状态
可以新删改URL,并可编辑URL的安全策略
在这里插入图片描述

②设置账号、密码

打开[设置]→[用户管理器]
在这里插入图片描述
可以新删改账户与密码。

注意:最后改完后,一定要点击[重新初始化®]

阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
KEPServerEX是一款由PTC公司推出的通信服务器软件,是KEPWare系列产品中的最新版本。KEPWare6 C是其中的一种版本,它主要用于工业自动化领域。该软件提供了强大的连接和通信功能,能够实现不同设备和系统之间的数据交互和集成。 KEPWare6 C支持多种通信协议,包括OPC(OLE for Process Control)、OPC-UAOPC Unified Architecture)、DDE(Dynamic Data Exchange)等。这些协议可以很好地与不同厂家的设备进行通信,实现数据采集、监控和控制。用户可以通过简单的配置来建立与设备之间的连接,无需编写复杂的代码。 KEPWare6 C还提供了丰富的数据处理功能,可以进行数据解析、转换和过滤等操作。用户可以根据需要对数据进行处理,使其变得更加符合自己的需求。同时,该软件还支持数据存储和历史记录功能,可以将数据存储到数据库中,并可以随时查询历史数据和生成报表。 除此之外,KEPWare6 C还具有安全可靠的特性。它支持数据加密和访问控制,确保数据在传输和存储过程中的安全性。此外,软件本身也具有高可靠性和稳定性,可以长时间运行而不会出现故障。 总之,KEPWare6 C是一款功能强大的通信服务器软件,可广泛应用于工业自动化和物联网领域。它能够方便地连接不同设备和系统,并实现数据交互和集成,提供了丰富的数据处理和存储功能,同时还具有高安全性和可靠性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

探索者0711

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值