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;//连接OPCpublic 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;//宏观默认设定 具体执行要看具体的groupKepGroups.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){//删除空TagtoWriteitems = 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){//删除空Tagtags = 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初始化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-0OpcGroup_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){//工位数据采集----1SpectInfo 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 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;}}

欢迎使用测试!

C# OPC类库 升级版本 OPCAutomation.dll相关推荐

  1. Interop.OPCAutomation.dll注册失败处理

    Interop.OPCAutomation.dll注册失败 Interop.OPCAutomation.dll注册失败处理 开发OPC客户端程序时,使用了Interop.OPCAutomation.d ...

  2. 如何将C# 7类库升级到C# 8?使用可空引用类型

    这篇文章将介绍将C# 7类库升级到C# 8(支持可空引用类型)的一个案例.本案例中使用的项目Tortuga Anchor由一组MVVM风格的基类.反射代码和各种实用程序函数组成.之所以选择这个项目,是 ...

  3. 填补商用安全产品空白 山石云安全升级版本亮相OpenStack Days

    7月24-25日,2017 OpenStack Days China如约降临国家会议中心,来自云计算.存储.网络.安全等各个专业领域的"高精尖"专家及厂商云集于这场开源盛会,长袖善 ...

  4. CentOS7升级版本

    一.挂载本地yum源 1.将光盘中的内容scp到本地目录下,这里我的目录是/home/sda5/cdrom 2.修改配置文件,将本地源指向拷贝的目录 cd /etc/yum.repos.d/ mkdi ...

  5. [原]Asp.net替换不同版本的Dll文件碰到的问题以及解决办法.

    情景还原: 今天一个朋友说网站不能上传图片,我检查后发现一直卡住在上传页面,一直滚动,是个Fckeditor控件2.6.3的. 经过google以后得到的结论是图片上传成功,但是没有返回结果,在服务器 ...

  6. OneNote重装或升级版本后如何同步之前的在线笔记?

    OneNote重装或升级版本后如何同步之前的在线笔记? ⚙️1.软件环境⚙️

  7. linux 升级golang版本,go语言如何升级版本

    go语言升级版本的方法:1.在官网下载最新的源码包:2.将源码包放在相应目录下:3.运行[sh install.sh go1.xx.linux-amd64.tar.gz]命令即可. 本文操作环境:wi ...

  8. 苹果三代耳机_苹果AirPodsPro三代耳机 升级版本 苹果AirPods二代耳机

    下单赠送 卡通保护套!苹果AirPodsPro三代耳机 升级版本!原厂黑网罩+开孔降噪网 重量同步正品56g!络达高配芯片 真实降噪通透模式 随意切换!设置随意改名跟定位 带IPX4防水功能!按压切歌 ...

  9. GC9110T 12V 直流电机驱动芯片 GC9110(低压6V驱动)的12V升级版本

    GC9110T是一款12V直流电机驱动芯片,为摄像机.消费类产品.玩具和其他低压或者电池供电的运动控制类应用提供了集成的电机驱动解决方案.芯片一般用了驱动一个直流电机或者使用两颗来驱动一个步进电机.G ...

最新文章

  1. android studio dump java heap_Android Studio 3.0 Memory Profiler使用
  2. 手动创建swap分区
  3. 【组合数学】递推方程 ( 常系数线性非齐次递推方程求解 | 递推方程标准型及通解 | 递推方程通解证明 )
  4. 计算机网络硬件的作用是什么,网络技术在计算机软硬件的作用
  5. 你不得不了解的10款服务器监控工具
  6. caffeine 缓存_使用Caffeine和Spring Boot的多个缓存配置
  7. [转载]eXeScope 6.50本地溢出分析
  8. android xml defaulthandler解析,sax解析xml文件的DefaultHandler处理类
  9. java开发属于itsm吗_【行业】IT服务管理(ITSM):IT行业变革的思考(1)
  10. 将C/C++代码中的注释删除
  11. java 中文路径 读取_Java读取文件时中文路径处理
  12. vb mysql 插入记录_vb实现数据库的连接,修改,删除,插入(ADO.Net)
  13. 什么是java OOM Out Of Memory 内存溢出?如何分析及解决oom问题?
  14. C++ 继承语法及修饰符
  15. PDH性能测试之五--待续
  16. 高级前端必会手写面试题及答案
  17. oracle--游标
  18. numpy 中ravel()和flatten()区别
  19. python股票数据分析_用Python进行股票数据分析
  20. 2月第二周安全要闻回顾:微软发通缉令 IBM关注犯罪

热门文章

  1. lammps胶体输出的日志文件
  2. 坐等膜拜|什么是真正的架构设计?十年Java经验让我总结出了这些,不愧是我
  3. 阿里云大数据平台的实操:ODPS的SQL语句
  4. C语言教程(七):函数
  5. HDUOJ1865 1string
  6. 安卓分屏神器_手机端必备神器,一经推出轻松拥有过千万用户下载量!
  7. Python计算温度植被干旱指数(TVDI)
  8. 微信企业号突飞猛进,移步到微为何坐稳移动审批头把交椅
  9. 极路由b70路由器虚拟服务器,极路由B70刷固件详细步骤说明(整合其它坛友经验)-少走弯路,造福坛友...
  10. Android 10.0 修改Recovery字体图片的大小(正在清理)文字大小