using System; using System.Collections.Generic; using System.Windows.Forms; using System.Linq; using System.Text; using OPCAutomation; using EventTool; namespace M423project { public class OPC { public const int TransIDMainform = 2012; private OPCServer opcServer; private OPCGroups opcGroups; private OPCGroup opcReadGroup; private OPCGroup opcWriteGroup; private int itmHandleClient; private string serverName; private string serverIP; private GroupProperty groupProperty; public ListenEventCreater listenEventCreater; public class Item { public string name; public int clientHandle; public int serverHandle; public object value; public Control control; public string onText; public string offText; } public Dictionary itemReadDict; public Dictionary itemWriteDict; public OPC(opcConfig opcConfig) { serverIP = opcConfig.serverIP; serverName = opcConfig.serverName; itmHandleClient = opcConfig.itmHandleClient; groupProperty = opcConfig.groupProperty; } /// /// 连接OPC服务器 /// /// public bool Connect() { CommonUtil.WriteLog(LogType.Inf, "开始连接OPC Server..."); try { opcServer = new OPCServer(); opcServer.Connect(serverName, serverIP); if (opcServer.ServerState==(int)OPCServerState.OPCRunning) { CommonUtil.WriteLog(LogType.Inf, string.Format("已连接到OPC Server(ServerName:{0}, IP:{1})", serverName, serverIP)); return true; } else { CommonUtil.WriteLog(LogType.Err, string.Format("连接OPC Server(ServerName:{0}, IP:{1})失败,状态:{2}", serverName, serverIP, opcServer.ServerState)); } } catch (Exception ee) { CommonUtil.WriteLog(LogType.Exc, string.Format("连接 OPC-Server 出现错误, ServerName:{0}, IP:{1}, 错误信息:{2}", serverName, serverIP, ee.Message)); } return false; } /// /// 创建组 /// . /// public bool CreateGroup() { CommonUtil.WriteLog(LogType.Inf, "开始连接创建OPC Server组列表..."); try { OPCBrowser browser = opcServer.CreateBrowser(); RecurBrowser(browser); opcGroups = opcServer.OPCGroups; opcReadGroup = opcGroups.Add("ReadGroup"); opcWriteGroup = opcGroups.Add("WriteGroup"); SetGroupProperty(opcReadGroup); SetGroupProperty(opcWriteGroup); listenEventCreater = new ListenEventCreater(); opcReadGroup.DataChange+=new DIOPCGroupEvent_DataChangeEventHandler(opcReadGroup_DataChange); SetHandles(opcReadGroup, itemReadDict); SetHandles(opcWriteGroup, itemWriteDict); CommonUtil.WriteLog(LogType.Inf, "OPC Server 组列表创建完成"); return true; } catch (Exception ee) { CommonUtil.WriteLog(LogType.Exc, string.Format("创建OPCServer组列表出现异常:{0}", ee.Message)); } return false; } /// /// 列出OPC服务器中所有Tag 并加入到opcBrowser中 /// /// private void RecurBrowser(OPCBrowser opcBrowser) { //将所有子项全部展开,所有的Item opcBrowser.ShowBranches(); opcBrowser.ShowLeafs(true); // 初始化item列表 itemReadDict = new Dictionary(); itemWriteDict = new Dictionary(); foreach (object turn in opcBrowser) { Item item = new Item(); item.name = turn.ToString(); if (turn.ToString().Contains("Input")) { itemReadDict.Add(item.name, item); } else if (turn.ToString().Contains("Output")) { itemWriteDict.Add(item.name, item); } } } /// /// 设置组属性 /// /// private void SetGroupProperty(OPCGroup opcGroup) { opcServer.OPCGroups.DefaultGroupIsActive = groupProperty.defaultGroupIsActive; opcServer.OPCGroups.DefaultGroupDeadband = groupProperty.defaultGroupDeadband; opcGroup.UpdateRate = groupProperty.updateRate; opcGroup.IsActive = groupProperty.isActive; opcGroup.IsSubscribed = groupProperty.isSubscribed; } /// /// ReadGroup组数据发生变化时发生的事件 /// /// /// /// /// /// /// private void opcReadGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps) { for (int i = 1; i <= NumItems; i++) { foreach (Item item in itemReadDict.Values) { if (item.clientHandle == Convert.ToInt32(ClientHandles.GetValue(i))) { itemReadDict[item.name].value = Convert.ToInt32(ItemValues.GetValue(i)); string state = item.name; // 改变的item的名称 item.value = ItemValues.GetValue(i); listenEventCreater.ChangeValue(new EventData(item)); } } } } /// /// 为组内每一个Item设置serverHandle与clientHandle /// /// /// /// private bool SetHandles(OPCGroup opcGroup, Dictionary itemDict) { OPCItems opcItems; OPCItem opcItem; opcItems = opcGroup.OPCItems; foreach (var item in itemDict.Values) { item.clientHandle = itmHandleClient; itmHandleClient++; opcItem = opcItems.AddItem(item.name, item.clientHandle); item.serverHandle = opcItem.ServerHandle; } return true; } /// /// 异步写 /// /// /// /// public bool Write(string name, object value) { Array serverHandles = new int[2] { 0, itemWriteDict[name].serverHandle }; Array values; // = new object[2] { "", value.ToString()}; Array Errors; int cancelID; values = new object[2] { "", value.ToString() }; opcWriteGroup.AsyncWrite(1, ref serverHandles, ref values, out Errors, TransIDMainform, out cancelID); GC.Collect(); return true; } public bool Write(string name, object value, ref string warning) { Array serverHandles = new int[2] { 0, itemWriteDict[name].serverHandle }; Array values = new object[2] { "", value.ToString() }; Array Errors; int cancelID; try { opcWriteGroup.AsyncWrite(1, ref serverHandles, ref values, out Errors, TransIDMainform, out cancelID); } catch (Exception e) { warning = e.Message; GC.Collect(); return false; } GC.Collect(); return true; } public bool Write(OPCGroup group, int handle, object value, ref string warning) { Array serverHandles = new int[2] { 0, handle }; Array values = new object[2] { "", value.ToString() }; Array Errors; int cancelID; try { group.AsyncWrite(1, ref serverHandles, ref values, out Errors, TransIDMainform, out cancelID); } catch (Exception e) { warning = e.Message; GC.Collect(); return false; } GC.Collect(); return true; } public bool ReadOneItem_Wrapper(string name, ref object result) { Item item; if (itemReadDict.ContainsKey(name)) { item = itemReadDict[name]; ReadOneItem(ref item, opcReadGroup); result = item.value; itemReadDict[name].value = result; } else if (itemWriteDict.ContainsKey(name)) { item = itemWriteDict[name]; ReadOneItem(ref item, opcWriteGroup); result = item.value; itemWriteDict[name].value = result; } else { return false; } return true; } public bool ReadOneItem(ref Item item, OPCGroup opcGroup) { Array serverHandles; Array values; Array errors; object qualities; object timeStamps; serverHandles = new int[2] { 0, item.serverHandle }; opcGroup.SyncRead(1, 1, ref serverHandles, out values, out errors, out qualities, out timeStamps); item.value = values.GetValue(1); GC.Collect(); return true; } internal void Close() { opcServer.Disconnect(); } } }