C# OPC类库 升级版本 OPCAutomation.dll

using OPCAutomation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


class NewOPC
{
    OPCServer KepServer;
    public string ErrorMsg = "";
    bool opc_connected = false;
    //连接OPC
    public bool ConnectRemoteServer(string OpcIP, string OpcVersion)
    {
        try
        {
            KepServer = new OPCServer();
            KepServer.Connect(OpcVersion, OpcIP);

            if (KepServer.ServerState != (int)OPCServerState.OPCRunning)
            {
                ErrorMsg = "KepServer状态异常:" + KepServer.ServerState.ToString();
                return false;
            }
            opc_connected = true;
        }
        catch (Exception err)
        {
            ErrorMsg = "连接远程服务器出现错误:" + err.Message;
            return false;
        }
        return true;
    }
    public void Quite()
    {
        if (opc_connected)
        {
            KepServer.Disconnect();
        }
    }

    int itmHandleClient = 0;
    List<taginfo> taglist = new List<taginfo>();
    class taginfo
    {
        public string group = "";
        public string tag = "";
        public string Clientid = "";
        public int Serverid = 0;
        public string value = "";
        public taginfo(string _group, string _tag, string _cid, int _sid, string _val)
        {
            group = _group;
            tag = _tag;
            Clientid = _cid;
            Serverid = _sid;
            value = _val;
        }
    }
    OPCGroups KepGroups;
    OpcGroup_Class[] KepGroupCollect;
    //创建组
    public bool CreateGroup(OpcGroup_Class[] KepGroupCollect)
    {
        if (KepGroupCollect == null)
        {
            ErrorMsg = "异常:传入的opc组为空!";
            return false;
        }
        this.KepGroupCollect = KepGroupCollect;

        KepGroups = KepServer.OPCGroups;
        //宏观默认设定 具体执行要看具体的group
        KepGroups.DefaultGroupIsActive = true;//激活组
        KepGroups.DefaultGroupDeadband = 0;//死区值,设为0时,服务器端该组内任何数据变化都通知组。
        KepGroups.DefaultGroupUpdateRate = 100;//默认刷新频率
        foreach (OpcGroup_Class group in KepGroupCollect)
        {
            OPCGroup KepGroup = KepGroups.Add(group.groupName);
            KepGroup.UpdateRate = group.updateRate;
            KepGroup.IsActive = group.IsActive;
            KepGroup.IsSubscribed = group.IsSubscribed;
            KepGroup.DeadBand = group.Deadband;
            group.G = KepGroup;

            OPCItems KepItems = KepGroup.OPCItems;
            for (int i = 0; i < group.tags.Count(); i++)
            {
                itmHandleClient++;
                KepItems.AddItem(group.tags[i], itmHandleClient);
                int itemid = KepItems.Item(group.tags[i]).ServerHandle;

                taginfo tf = new taginfo(group.groupName, group.tags[i], itmHandleClient.ToString(), itemid, "");
                taglist.Add(tf);
            }
            if (group.isDataChange)
            {
                group.G.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);
            }
            if (group.isAsyncRead)
            {
                group.G.AsyncReadComplete += new DIOPCGroupEvent_AsyncReadCompleteEventHandler(KepGroup_AsyncReadComplete);
            }
            if (group.isAsyncWrite)
            {
                group.G.AsyncWriteComplete += new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(KepGroup_AsyncWriteComplete);
            }
        }
        return true;
    }
    public event EventHandler<EventData> DataChange;

    void KepGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
    {
        if (DataChange != null)
        {
            EventData ed = new EventData();
            for (int i = 1; i <= NumItems; i++)
            {
                DataChangeObject dco = new DataChangeObject();
                dco.TagHandler = ClientHandles.GetValue(i).ToString();
                taginfo tf = taglist.FirstOrDefault(p => p.Clientid == dco.TagHandler);
                if (tf != null)
                {
                    dco.TagFullName = tf.tag;
                    dco.TagValue = ItemValues.GetValue(i).ToString();
                    dco.Qualitie = Qualities.GetValue(i).ToString();
                    dco.TimeStamp = TimeStamps.GetValue(i).ToString();
                    ed.ChangeValues.Add(dco);
                }
            }
            DataChange(ClientHandles, ed);
        }
    }

    public event EventHandler<EventData> AsyncReadComplete;
    private void KepGroup_AsyncReadComplete(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps, ref Array Errors)
    {
        if (AsyncReadComplete != null)
        {
            EventData ed = new EventData();
            for (int i = 1; i <= NumItems; i++)
            {
                DataChangeObject dco = new DataChangeObject();
                dco.FlagNum = TransactionID;
                dco.TagHandler = ClientHandles.GetValue(i).ToString();
                taginfo tf = taglist.FirstOrDefault(p => p.Clientid == dco.TagHandler);
                if (tf != null)
                {
                    dco.TagFullName = tf.tag;
                    dco.TagValue = ItemValues.GetValue(i).ToString();
                    dco.Qualitie = Qualities.GetValue(i).ToString();
                    dco.TimeStamp = TimeStamps.GetValue(i).ToString();
                    dco.Errors = Errors.GetValue(i).ToString();
                    ed.ChangeValues.Add(dco);
                }
            }
            AsyncReadComplete(ClientHandles, ed);
        }
    }
    public event EventHandler<EventData> AsyncWriteComplete;
    void KepGroup_AsyncWriteComplete(int TransactionID, int NumItems, ref Array ClientHandles, ref Array Errors)
    {
        if (AsyncWriteComplete != null)
        {
            EventData ed = new EventData();
            for (int i = 1; i <= NumItems; i++)
            {
                DataChangeObject dco = new DataChangeObject();
                dco.TagHandler = ClientHandles.GetValue(i).ToString();
                taginfo tf = taglist.FirstOrDefault(p => p.Clientid == dco.TagHandler);
                if (tf != null)
                {
                    dco.TagFullName = tf.tag;
                    dco.TagValue = tf.value;
                    dco.Errors = Errors.GetValue(i).ToString();
                    ed.ChangeValues.Add(dco);
                }
            }
            AsyncWriteComplete(ClientHandles, ed);
        }
    }
    /// <summary>
    /// 注意 Group 是同一组的时候才能使用!!
    /// </summary>
    public bool AsyncWrite(ToWrite[] toWriteitems)
    {
        if (opc_connected)
        {
            //删除空Tag
            toWriteitems = toWriteitems.Where(s => !string.IsNullOrEmpty(s.Tag)).ToArray();

            int TagCount = toWriteitems.Count() + 1;
            if (TagCount == 1)
            {
                return true;
            }
            int[] temp = new int[TagCount];
            temp[0] = 0;
            object[] valueTemp = new object[TagCount];
            valueTemp[0] = "";
            int i = 1;
            string group = "";
            foreach (ToWrite item in toWriteitems)
            {
                taginfo tf = taglist.FirstOrDefault(p => p.tag == item.Tag);
                if (tf != null)
                {
                    temp[i] = tf.Serverid;
                    group = tf.group;
                    valueTemp[i] = item.Val;
                    tf.value = item.Val;
                    i++;
                }
                else
                {
                    ErrorMsg = "异常:未找到tag标签:" + item.Tag;
                    return false;
                }
            }
            Array serverHandles = (Array)temp;
            Array values = (Array)valueTemp;
            Array Errors;
            int cancelID;
            OPCGroup KepGroup = KepGroups.GetOPCGroup(group);
            if (KepGroup == null)
            {
                ErrorMsg = "异常:未找到OPCGroup组:" + group;
                return false;
            }
            Random r = new Random();
            int idnum = r.Next(0, 999999);
            KepGroup.AsyncWrite(TagCount - 1, ref serverHandles, ref values, out Errors, idnum, out cancelID);
            //KepItem.Write(txtWriteTagValue.Text);//这句也可以写入,但并不触发写入事件
            GC.Collect();
            return true;
        }
        else
        {
            ErrorMsg = "异常:OPC未连接!";
            return false;
        }
    }
    public bool AsyncWrite(string tag, string val)
    {
        if (opc_connected)
        {
            if (tag == "")
            {
                return true;
            }
            int[] temp = new int[2];
            taginfo tf = taglist.FirstOrDefault(p => p.tag == tag);
            if (tf != null)
            {
                temp[0] = 0;
                temp[1] = tf.Serverid;
                tf.value = val;
            }
            else
            {
                ErrorMsg = "异常:未找到tag标签:" + tag;
                return false;
            }
            Array serverHandles = (Array)temp;
            object[] valueTemp = new object[2] { "", val };
            Array values = (Array)valueTemp;
            Array Errors;
            int cancelID;
            OPCGroup KepGroup = KepGroups.GetOPCGroup(tf.group);
            if (KepGroup == null)
            {
                ErrorMsg = "异常:未找到OPCGroup组:" + tf.group;
                return false;
            }

            Random r = new Random();
            int idnum = r.Next(0, 999999);

            KepGroup.AsyncWrite(1, ref serverHandles, ref values, out Errors, idnum, out cancelID);
            //KepItem.Write(txtWriteTagValue.Text);//这句也可以写入,但并不触发写入事件
            GC.Collect();
            return true;
        }
        else
        {
            ErrorMsg = "异常:OPC未连接!";
            return false;
        }
    }
    public bool AsyncRead(string[] tags, int TransactionID)
    {
        if (opc_connected)
        {
            //删除空Tag
            tags = tags.Where(p => !string.IsNullOrEmpty(p)).ToArray();

            int TagCount = tags.Count() + 1;
            int[] temp = new int[TagCount];
            temp[0] = 0;
            int i = 1;
            string group = "";
            foreach (string tag in tags)
            {
                taginfo tf = taglist.FirstOrDefault(p => p.tag == tag);
                if (tf != null)
                {
                    temp[i] = tf.Serverid;
                    group = tf.group;
                    i++;
                }
                else
                {
                    ErrorMsg = "异常:未找到tag标签:" + tag;
                    return false;
                }
            }
            Array serverHandles = (Array)temp;
            Array Errors;
            int cancelID;
            OPCGroup KepGroup = KepGroups.GetOPCGroup(group);
            if (KepGroup == null)
            {
                ErrorMsg = "异常:未找到OPCGroup组:" + group;
                return false;
            }
            KepGroup.AsyncRead(TagCount - 1, ref serverHandles, out Errors, TransactionID, out cancelID);
            GC.Collect();
            return true;
        }
        else
        {
            return false;
        }
    }
    public bool AsyncRead(string tag, int TransactionID)
    {
        if (opc_connected)
        {
            int[] temp = new int[2];
            taginfo tf = taglist.FirstOrDefault(p => p.tag == tag);
            if (tf != null)
            {
                temp[0] = 0;
                temp[1] = tf.Serverid;
            }
            else
            {
                ErrorMsg = "异常:未找到tag标签:" + tag;
                return false;
            }
            Array serverHandles = (Array)temp;
            Array Errors;
            int cancelID;
            OPCGroup KepGroup = KepGroups.GetOPCGroup(tf.group);
            if (KepGroup == null)
            {
                ErrorMsg = "异常:未找到OPCGroup组:" + tf.group;
                return false;
            }
            KepGroup.AsyncRead(1, ref serverHandles, out Errors, TransactionID, out cancelID);
            GC.Collect();
            return true;
        }
        else
        {
            return false;
        }
    }
}
public class EventData : EventArgs
{
    public EventData()
    {
    }
    private List<DataChangeObject> _ChangeValues = new List<DataChangeObject>();

    public List<DataChangeObject> ChangeValues
    {
        get
        {
            return _ChangeValues;
        }
        set
        {
            _ChangeValues = value;
        }
    }


}
public class DataChangeObject
{
    private string _TagFullName = string.Empty;

    /// <summary>
    /// 变量名
    /// </summary>
    public string TagFullName
    {
        get
        {
            return _TagFullName;
        }
        set
        {
            _TagFullName = value;
        }
    }
    private string _TagHandler = string.Empty;

    /// <summary>
    /// 变量索引
    /// </summary>
    public string TagHandler
    {
        get
        {
            return _TagHandler;
        }
        set
        {
            _TagHandler = value;
        }
    }
    private string _TagValue = string.Empty;

    /// <summary>
    /// 变量值
    /// </summary>
    public string TagValue
    {
        get
        {
            return _TagValue.ToLower();
        }
        set
        {
            _TagValue = value;
        }
    }
    private string _Qualitie = string.Empty;

    public string Qualitie
    {
        get
        {
            return _Qualitie;
        }
        set
        {
            _Qualitie = value;
        }
    }
    private string _TimeStamp = string.Empty;

    public string TimeStamp
    {
        get
        {
            return _TimeStamp;
        }
        set
        {
            _TimeStamp = value;
        }
    }
    private int _FlagNum = 0;
    public int FlagNum
    {
        get
        {
            return _FlagNum;
        }

        set
        {
            _FlagNum = value;
        }
    }
    private string _errors = "";
    public string Errors
    {
        get
        {
            return _errors;
        }

        set
        {
            _errors = value;
        }
    }
}
class OpcGroup_Class
{
    /// <summary>
    /// OPC组
    /// </summary>
    public OPCGroup G = null;
    /// <summary>
    /// 组名称
    /// </summary>
    public string groupName = "";
    /// <summary>
    /// 是否异步读取
    /// </summary>
    public bool isAsyncRead = true;
    /// <summary>
    /// 是否异步写入
    /// </summary>
    public bool isAsyncWrite = true;
    /// <summary>
    /// 变动触发
    /// </summary>
    public bool isDataChange = true;
    /// <summary>
    /// 更新频率
    /// </summary>
    public int updateRate = 100;
    /// <summary>
    /// 是否激活
    /// </summary>
    public bool IsActive = true;
    /// <summary>
    /// 是否订阅(异步则订阅)
    /// </summary>
    public bool IsSubscribed = true;
    /// <summary>
    /// 死区值 变化量超过死区后将会触发DataChange事件,合理的设置该值可以提高程序性能
    /// </summary>
    public float Deadband = 0;
    /// <summary>
    /// 标签集合
    /// </summary>
    public string[] tags = null;
}

public class ToWrite
{
    public string Tag { get; set; }
    public string Val { get; set; }
    public ToWrite(string _Tag, string _Val)
    {
        Tag = _Tag;
        Val = _Val;
    }
}

调用

   #region OPC初始化
 NewOPC opc=new NewOPC();
        private bool InitOpc(string server, string ip)
        {
            if (!opc.ConnectRemoteServer(ip, server))
            {
                showMessage(opc.ErrorMsg, true);
                opc.ErrorMsg = "";
                return false;
            }
            showMessage("OPC:连接成功!", false);
            OpcGroup_Class[] ocg = new OpcGroup_Class[3];
            #region 采集
            //触发采集 0-1,  1-0
            OpcGroup_Class change1 = new OpcGroup_Class();
            change1.groupName = "Change";
            change1.updateRate = 10;
            change1.IsActive = true;
            change1.Deadband = 0;
            change1.IsSubscribed = true;
            change1.isAsyncRead = false; //是否异步读取
            change1.isAsyncWrite = true; //是否异步写入
            change1.isDataChange = true; //是否变化
            ocg[0] = change1;
            //数据只读区
            OpcGroup_Class read1 = new OpcGroup_Class();
            read1.groupName = "Read";
            read1.updateRate = 500;
            read1.IsActive = false;
            read1.Deadband = 100;
            read1.IsSubscribed = true;
            read1.isAsyncRead = true;
            read1.isAsyncWrite = false;
            read1.isDataChange = false;
            ocg[1] = read1;
            //数据写入区域
            OpcGroup_Class write1 = new OpcGroup_Class();
            write1.groupName = "Write";
            write1.updateRate = 500;
            write1.IsActive = false;
            write1.Deadband = 100;
            write1.IsSubscribed = true;
            write1.isAsyncRead = false;
            write1.isAsyncWrite = true;
            write1.isDataChange = false;
            ocg[2] = write1;
            #endregion
            //节点赋值 根据实际需求
            foreach (SpectInfo item in xxx)
            {
                if (item.ShiYangTag != "")
                {
                    readNode.Add(item.ShiYangTag);
                }
                if (item.PinFanTag != "")
                {
                    readNode.Add(item.PinFanTag);
                }
                if (item.ReadTag != "")
                {
                    changeNode.Add(item.ReadTag);
                }
                if (item.SaveFinishTag != "")
                {
                    writeNode.Add(item.SaveFinishTag);
                }
            }

            //去重并赋值到Tag组
            read1.tags = readNode.Where((x, i) => readNode.FindIndex(p => p.ToString() == x.ToString()) == i).ToArray();
            write1.tags = writeNode.Where((x, i) => writeNode.FindIndex(p => p.ToString() == x.ToString()) == i).ToArray();
            change1.tags = changeNode.Where((x, i) => changeNode.FindIndex(p => p.ToString() == x.ToString()) == i).ToArray();

            if (!opc.CreateGroup(ocg))
            {
                showMessage(opc.ErrorMsg, true);
                opc.ErrorMsg = "";
                return false;
            }
            //事件
            opc.DataChange += Opc_DataChange;
            opc.AsyncReadComplete += Opc_AsyncReadComplete;
            opc.AsyncWriteComplete += Opc_AsyncWriteComplete;
            List<ToWrite> tw = new List<ToWrite>();
            //复位
            foreach (string item in change1.tags)
            {
                ToWrite _t = new ToWrite(item, "0");
                tw.Add(_t);
            }
            if (!opc.AsyncWrite(tw.ToArray()))
            {
                showMessage("初始化写入0失败,原因:" + opc.ErrorMsg, false);
                opc.ErrorMsg = "";
            }
            showMessage("********信号初始化完毕********", false);
            return true;
        }

        #endregion

        #region OPC 事件
        private void Opc_DataChange(object sender, EventData e)
        {
            Object obj = e.ChangeValues as Object;
            List<DataChangeObject> DataChangeList = obj as List<DataChangeObject>;
            foreach (DataChangeObject dco in DataChangeList)
            {
                string tag = dco.TagFullName;
                string val = dco.TagValue;
                if (val == "true" || val == "1")
                {
                    //数据并行处理
                    Task.Run(() => TagCollect(tag));
                }
            }
        }
        private void TagCollect(string tag)
        {
            //工位数据采集----1
            SpectInfo spc = list_Spect.FirstOrDefault(p => p.ReadTag == tag);
            if (spc != null)
            {
                string specid = spc.Specficationid;
                List<CollectInfo> ac = list_Collect.Where(p => p.Specficationid == specid).ToList();
                string[] tags = new string[ac.Count + 2];
                tags[0] = spc.ShiYangTag;
                tags[1] = spc.PinFanTag;
                for (int i = 2; i < ac.Count + 2; i++)
                {
                    tags[i] = ac[i - 2].DataTag;
                }
                //spc.Num 写入什么  opc读取完毕后 Opc_AsyncReadComplete 回传什么
                //此处务必注意
                opc.AsyncRead(tags, spc.Num);
            }
            else
            {
                //十万之后
                CheckInfo ck = list_Check.FirstOrDefault(p => p.ReadTag == tag);
                if (ck != null)
                {
                    string[] tags = new string[2];
                    tags[0] = ck.ShiYangTag;
                    tags[1] = ck.PinFanTag;
                    opc.AsyncRead(tags, ck.Num);
                }
            }
        }
        private void Opc_AsyncReadComplete(object sender, EventData e)
        {
            List<DataChangeObject> DataChangeList = e.ChangeValues as List<DataChangeObject>;
            if (DataChangeList[0].FlagNum < 100000)
            {
                Task.Run(() => SaveDate(DataChangeList));
            }
            else if (DataChangeList[0].FlagNum > 100000)
            {
                Task.Run(() => CheckDate(DataChangeList));
            }
        }
        private void Opc_AsyncWriteComplete(object sender, EventData e)
        {
            Object obj = e.ChangeValues as Object;
            List<DataChangeObject> DataChangeList = obj as List<DataChangeObject>;
            foreach (DataChangeObject dco in DataChangeList)
            {
                showMessage("写----入----完----毕 :" + dco.TagFullName, false);
            }
        }
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult R = MessageBox.Show("您确定要关闭本系统吗?点击确定退出!", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button2);
            if (R == DialogResult.OK)
            {
                timer1.Enabled = false;
                opc.DataChange -= Opc_DataChange;
                opc.AsyncReadComplete -= Opc_AsyncReadComplete;
                opc.AsyncWriteComplete -= Opc_AsyncWriteComplete;
                opc.Quite();
                //退出系统(其他线体的窗体可能在开启中,必须使用这个退出)
                System.Environment.Exit(0);
            }
            else
            {
                e.Cancel = true;
            }
        }

欢迎使用测试!

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

fanwenhu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值