using System; using System.Collections.Generic; using System.Windows.Forms; using OPCAutomation; using EventTool; namespace LLMF { public class OPC { public const int TransIDMainform = 2012; public const int TransIDSetttings = 2013; public const int ReadTagNum = 3; private OPCServer opcServer; private OPCGroups opcGroups; public OPCGroup opcReadGroup; public OPCGroup opcWriteGroup; public OPCGroup opcRobotGroup; private int itmHandleClient; private string serverIP; private string serverName; 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 AlarmState alarmState; } public Dictionary itemReadDict; public Dictionary itemWriteDict; public Dictionary itemRobotDict; public OPC(OPCConfig opcConfig) { serverIP = opcConfig.serverIP; serverName = opcConfig.serverName; itmHandleClient = opcConfig.itmHandleClient; groupProperty = opcConfig.groupProperty; } public enum AlarmState { Ready, NReady, Alarm, Warning } /// /// 连接OPC服务器 /// public bool Connect() { try { opcServer = new OPCServer(); opcServer.Connect(serverName, serverIP); if (opcServer.ServerState == (int) OPCServerState.OPCRunning) { return true; } else { return false; } } catch (Exception err) { MessageBox.Show("连接 OPC-Server 出现错误:" + err.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning); return false; } } /// /// 列出OPC服务器中所有Tag 并加入到opcBrowser中 /// /// private void RecurBrowse(OPCBrowser opcBrowser) { //展开分支 opcBrowser.ShowBranches(); //展开叶子 opcBrowser.ShowLeafs(true); // 初始化item列表 itemReadDict = new Dictionary(); itemWriteDict = new Dictionary(); itemRobotDict = 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 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)); switch (state) { //I/O界面输入显示 case InputTag.X_JinDian: case InputTag.Z_JinDian: case InputTag.X_CW: case InputTag.X_CCW: case InputTag.Z_CW: case InputTag.Z_CCW: case InputTag.DingWei_CW: case InputTag.DingWei_CCW: case InputTag.DingWei_JinDian: case InputTag.Reset: case InputTag.OpenJieJin: case InputTag.CeBianQian: case InputTag.CeBianHou: case InputTag.WuGanQian: case InputTag.WuGanHou: SignalSensorAndElse(item,true); break; //传感器、轴和其他信号 case InputTag.Start1: case InputTag.Start2: SignalSensorAndElse(item, false); break; //传感器、轴和其他信号 case InputTag.X_Alarm: case InputTag.Z_Alarm: case InputTag.E_Stop: case InputTag.SafeCurtain: case InputTag.DingWei_Alarm: SignalAlarm(item); break; //报警信号 } } } } } public void SignalSensorAndElse(Item item, bool IsPlus) { if (item.control != null) { if (IsPlus) { if (Convert.ToBoolean(item.value)) { item.control.BackColor = System.Drawing.Color.Green; } else { item.control.BackColor = System.Drawing.Color.Gray; } } else { if (Convert.ToBoolean(item.value)) { item.control.BackColor = System.Drawing.Color.Gray; } else { item.control.BackColor = System.Drawing.Color.Green; } } } } public void SignalAlarm(Item item) { if (item.control != null) { if (Convert.ToBoolean(item.value)) { item.control.BackColor = System.Drawing.Color.Gray; } else { item.control.BackColor = System.Drawing.Color.Red; } } } private void opcRobotGroup_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 itemRobotDict.Values) { if (item.clientHandle == Convert.ToInt32(ClientHandles.GetValue(i))) { itemRobotDict[item.name].value = Convert.ToInt32(ItemValues.GetValue(i)); string state = item.name; // 改变的item的名称 item.value = ItemValues.GetValue(i); listenEventCreater.ChangeValue(new EventData(item)); } } } } private void opcWriteGroup_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 itemWriteDict.Values) { if (item.clientHandle == Convert.ToInt32(ClientHandles.GetValue(i))) { itemWriteDict[item.name].value = Convert.ToInt32(ItemValues.GetValue(i)); item.value = ItemValues.GetValue(i); listenEventCreater.ChangeValue(new EventData(item)); string state = item.name; // 改变的item的名称 switch (state) { //I/O界面输出显示 case OutputTag.Red: case OutputTag.Yellow: case OutputTag.Green: case OutputTag.Buzzer: case OutputTag.CeBianCylider: case OutputTag.ZhengBianCylider: case OutputTag.WuGanCylider: case OutputTag.HuaTaiCylider : case OutputTag.SiFuPowerOn: case OutputTag.X_SRV_ON: case OutputTag.Z_SRV_ON: case OutputTag.DingWei_SRV_ON : case OutputTag.Z_ShaChe: case OutputTag.ForApple : case OutputTag.CameraLighto: case OutputTag.WuGanCylider2: SignalSensorAndElse(item, true); break; } } } } } /// /// 创建Group /// /// public bool CreateGroup() { try { OPCBrowser browser = opcServer.CreateBrowser(); RecurBrowse(browser); // 建立读字典和写字典 opcGroups = opcServer.OPCGroups; opcReadGroup = opcGroups.Add("ReadGroup"); opcWriteGroup = opcGroups.Add("WriteGroup"); opcRobotGroup = opcGroups.Add("RobotGroup"); /* 设置监听相关属性 */ SetGroupProperty(opcReadGroup); SetGroupProperty(opcWriteGroup); SetGroupProperty(opcRobotGroup); listenEventCreater = new ListenEventCreater(); // 初始化监听 opcReadGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(opcReadGroup_DataChange); // 读区域数据变化 opcWriteGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(opcWriteGroup_DataChange); // 写区域数据变化 /* 设置handles */ SetHandles(opcReadGroup, itemReadDict); SetHandles(opcWriteGroup, itemWriteDict); } catch (Exception err) { MessageBox.Show("创建组出现错误:" + err.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning); return false; } return true; } /// /// 设置属性 /// 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; } /// /// 设置ClientHandles和ServerHandles /// /// /// public 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); //KepItem.Write(txtWriteTagValue.Text);//这句也可以写入,但并不触发写入事件 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); //KepItem.Write(txtWriteTagValue.Text);//这句也可以写入,但并不触发写入事件 } 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); //KepItem.Write(txtWriteTagValue.Text);//这句也可以写入,但并不触发写入事件 } 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(); } } }