OPC DA通信,自动读写数据

主打的就是简单,使用非常简单!

            opcDaTags.Add(new OpcDaTag("numeric.random.int32"));
            opcDaTags.Add(new OpcDaTag("time.current"));
            opcDaTags.Add(new OpcDaTag("textual.weekday"));
            opcDaTags.Add(new OpcDaTag("storage.bool.reg14"));
            opcDaTags.Add(new OpcDaTag("storage.bool.reg15"));
            opcDaTags.Add(new OpcDaTag("storage.bool.reg16"));
            opcDaTags.Add(new OpcDaTag("storage.bool.reg17"));
            OpcHelper = new OpcDA_Helper("Graybox.Simulator.1","ABB", opcDaTags.ToList());

然后需要读取数据的地方,只要订阅OpcDaTag的OnValueChange

需要写入数据的地方,只要调用OpcDaTag的 Write方法

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using TitaniumAS.Opc.Client.Common;
using TitaniumAS.Opc.Client.Da;
using TitaniumAS.Opc.Client.Da.Browsing;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace TitaniumASDemo
{
    public class OpcDA_Helper
    {
        public static List<string> GetOpcServers()
        {
            var list = new List<string>();
            var enumerator = new OpcServerEnumeratorAuto();
            var serverDescriptions = enumerator.Enumerate(enumerator.Localhost, OpcServerCategory.OpcDaServer10);
            foreach (var item in serverDescriptions)
            {
                list.Add(item.ProgId);
            }
            return list;
        }
        /// <summary>
        /// 使用TitaniumAS通信的帮助,次类构造后,会自动连接服务器,读写数据,并且按照列表的数据订阅服务器的数据
        /// 需要读取数据的地方,只需要订阅列表里的tag的数据变化委托
        /// 需要写入数据的地方,只有调用列表里的tag的Write方法,数据会自动写入到opc服务器
        /// </summary>
        /// <param name="serverName">opc da服务器的名称</param>
        /// <param name="groupName">当前通信群组的名字</param>
        /// <param name="tagList">opc da 要通信的数据</param>
        public OpcDA_Helper(string serverName, string groupName, List<OpcDaTag> tagList)
        {
            ServerName = serverName;
            GroupName = groupName;
            TagList = tagList ?? new List<OpcDaTag>();
            server = new OpcDaServer(ServerName);
            server.ConnectionStateChanged += OnConnected;
            //browser = new OpcDaBrowserAuto(server);
            AutoConnectThread = new Thread(AutoConnect) { IsBackground = true };
            AutoConnectThread.Start();
            foreach(var tag in tagList)
            {
                tag.WriteHandle += WriteValue;
            }
        }

        private void OnConnected(object sender, OpcDaServerConnectionStateChangedEventArgs e)
        {
            Connected = e.IsConnected;
        }

        Thread AutoConnectThread;
        /// <summary>
        /// opc da服务器名字
        /// </summary>
        public string ServerName { get; private set; } = "ServerName";
        /// <summary>
        /// 群组名字
        /// </summary>
        public string GroupName { get; private set; } = "GroupName";
        /// <summary>
        /// 通信tag列表
        /// </summary>
        List<OpcDaTag> TagList;
        /// <summary>
        /// opc da服务器
        /// </summary>
        public OpcDaServer server;
        OpcDaGroup group;
        /// <summary>
        /// 自动连接服务器
        /// </summary>
        private void AutoConnect()
        {
            while (true)
            {
                if (!Connected)
                {
                    ConnectToServer();
                }
                Connected = server.IsConnected;
                //每分钟尝试连接服务器
                Thread.Sleep(60000);
            }
        }
        /// <summary>
        /// 写入数据到服务器
        /// </summary>
        /// <param name="tag"></param>
        private void WriteValue(OpcDaTag tag)
        {
            Write(tag);
        }
        public Action<OpcDA_Helper> ConnectionStatesChange;
        bool connected = false;
        /// <summary>
        /// 连接服务器。
        /// </summary>
        public bool Connected
        {
            private set
            {
                if (connected != value)
                {
                    connected = value;
                    ConnectionStatesChange?.Invoke(this);
                }
            }
            get => connected;
        }
        /// <summary>
        /// 连接服务器,如果连接成功,则读取一次数据,并且订阅数据,以后的数据变化自动更新
        /// </summary>
        /// <returns></returns>
        private bool ConnectToServer()
        {
            try
            {
                Uri url = UrlBuilder.Build(ServerName);
                server = new OpcDaServer(url);
                server.Connect();
                if (server.IsConnected)
                {                    
                    if(group != null)
                    {
                        server.RemoveGroup(group);
                    }
                    AddGroup(GroupName, TagList.Select(a => a.TagID).ToArray());
                    group.SyncItems();
                    //Read(TagList);
                }                
                return server.IsConnected;
            }
            catch (Exception)
            {

            }
            return false;
        }
        public void Read()
        {
            Read(TagList);
        }
        /// <summary>
        /// 手动读取数据
        /// </summary>
        /// <param name="opcDaTags"></param>
        public void Read(List<OpcDaTag> opcDaTags)
        {
            OpcDaVQTE[] ret = new OpcDaVQTE[opcDaTags.Count];
            Dictionary<string, OpcDaVQTE> result = new Dictionary<string, OpcDaVQTE>(opcDaTags.Count);
            List<string> items = opcDaTags.Select(a => a.TagID).ToList();
            List<object> values = new List<object>(opcDaTags.Count);
            if (!server.IsConnected)
            {
                ConnectToServer();
            }
            if (server.IsConnected)
            {
                //从opc服务器读取数据,返回数据的数组
                ret = server.Read(items, new TimeSpan[opcDaTags.Count]);
                for (int i = 0; i < items.Count; i++)
                {
                    opcDaTags[i].Value = ret[i].Value;
                    opcDaTags[i].Quality = ret[0].Quality;
                    opcDaTags[i].TimeStamp = DateTime.Now;
                }
            }
        }
        /// <summary>
        /// 手动写入数据
        /// </summary>
        /// <param name="id"></param>
        /// <param name="value"></param>
        private void Write(string id, object value)
        {
            if (!server.IsConnected)
            {
                ConnectToServer();
            }
            if (server.IsConnected)
            {
                var ret = server.WriteVQT(new[] { id }, new[] { new OpcDaVQT { Value = value } });
            }
        }
        /// <summary>
        /// 手动写入数据
        /// </summary>
        /// <param name="tag"></param>
        public void Write(OpcDaTag tag)
        {
            if (tag == null) return;
            Write(tag.TagID, tag.ValueToWrite);
        }
        public Action<OpcDaItemValuesChangedEventArgs> GroupValuesChangedHandle;
        OpcDaTag tag;
        private void OnGroupValuesChanged(object sender, OpcDaItemValuesChangedEventArgs args)
        {

            try
            {
                //GroupValuesChangedHandle?.Invoke(args);
                foreach (var item in args.Values)
                {
                    tag = TagList.Where(a => a.TagID == item.Item.ItemId).First();
                    if (tag != null)
                    {
                        tag.TimeStamp = DateTime.Now;
                        tag.Value = item.Value;
                    }
                }
            }
            catch (Exception ex)
            {
                //throw ex;
            }            
        }
        public OpcDaItemResult[] AddGroup(string groupName, string[] items)
        {
            group = server.AddGroup(groupName);
            group.ValuesChanged -= OnGroupValuesChanged;
            group.ValuesChanged += OnGroupValuesChanged;
            group.UpdateRate = TimeSpan.FromMilliseconds(100);
            group.IsActive = true;
            OpcDaItemDefinition[] definitions = new OpcDaItemDefinition[items.Length];
            for (int i = 0; i < items.Length; i++)
            {
                definitions[i] = new OpcDaItemDefinition
                {
                    ItemId = items[i],
                    IsActive = true
                };
            }
            OpcDaItemResult[] results = group.AddItems(definitions);
            return results;
        }
    }
    /// <summary>
    /// OpcDa的核心,用于存储opcda的数据
    /// </summary>
    public class OpcDaTag : INotifyPropertyChanged
    {
        public OpcDaTag(string tagId)
        {
            TagID = tagId;
        }
        public string TagID { get; set; }
        object value = new object();
        public object Value
        {
            get => value;
            set
            {
                if (!Equals(this.value, value))
                {
                    this.value = value;
                    PropertyChange();
                }
            }
        }
        DateTime timeStamp = new DateTime();
        public DateTime TimeStamp
        {
            get => timeStamp;
            set
            {
                if (value != timeStamp)
                {
                    timeStamp = value;
                    PropertyChange();
                }
            }
        }
        OpcDaQuality quality;
        public OpcDaQuality Quality
        {
            get => quality;
            set
            {
                if(!Equals(this.quality, value))
                {
                    quality = value;
                    PropertyChange();
                }
            }
        }
        public void Write(object value)
        {
            ValueToWrite = value;
            WriteHandle?.Invoke(this);
        }
        object valueToWrite = new object();
        public object ValueToWrite
        {
            get => valueToWrite;
            set
            {
                if (!Equals(this.valueToWrite, value))
                {
                    this.valueToWrite = value;
                    PropertyChange();
                }
            }
        }
        private void PropertyChange([CallerMemberName] string property = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
            OnValueChange?.Invoke(this);
        }
        public Action<OpcDaTag> OnValueChange;
        public Action<OpcDaTag> WriteHandle;
        public event PropertyChangedEventHandler PropertyChanged;
    }
}

 

posted @ 2024-04-17 15:42  冬日厦语  阅读(76)  评论(0编辑  收藏  举报