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<string, Item> itemReadDict;
|
public Dictionary<string, Item> itemWriteDict;
|
public Dictionary<string, Item> itemRobotDict;
|
|
public OPC(OPCConfig opcConfig)
|
{
|
serverIP = opcConfig.serverIP;
|
serverName = opcConfig.serverName;
|
itmHandleClient = opcConfig.itmHandleClient;
|
groupProperty = opcConfig.groupProperty;
|
}
|
|
public enum AlarmState
|
{
|
Ready,
|
NReady,
|
Alarm,
|
Warning
|
}
|
|
/// <summary>
|
/// 连接OPC服务器
|
/// </summary>
|
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;
|
}
|
}
|
|
/// <summary>
|
/// 列出OPC服务器中所有Tag 并加入到opcBrowser中
|
/// </summary>
|
/// <param name="opcBrowser"></param>
|
private void RecurBrowse(OPCBrowser opcBrowser)
|
{
|
//展开分支
|
opcBrowser.ShowBranches();
|
//展开叶子
|
opcBrowser.ShowLeafs(true);
|
// 初始化item列表
|
itemReadDict = new Dictionary<string, Item>();
|
itemWriteDict = new Dictionary<string, Item>();
|
itemRobotDict = new Dictionary<string, Item>();
|
|
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);
|
}
|
}
|
}
|
|
/// <summary>
|
/// 数据改变时运行
|
/// </summary>
|
/// <param name="TransactionID"></param>
|
/// <param name="NumItems"></param>
|
/// <param name="ClientHandles"></param>
|
/// <param name="ItemValues"></param>
|
/// <param name="Qualities"></param>
|
/// <param name="TimeStamps"></param>
|
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;
|
}
|
|
}
|
}
|
}
|
|
}
|
|
/// <summary>
|
/// 创建Group
|
/// </summary>
|
/// <returns></returns>
|
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;
|
}
|
|
|
/// <summary>
|
/// 设置属性
|
/// </summary>
|
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;
|
}
|
|
/// <summary>
|
/// 设置ClientHandles和ServerHandles
|
/// </summary>
|
/// <param name="opcGroup"></param>
|
/// <returns></returns>
|
public bool SetHandles(OPCGroup opcGroup, Dictionary<string, Item> 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;
|
}
|
|
/// <summary>
|
/// 异步写
|
/// </summary>
|
/// <param name="name"></param>
|
/// <param name="value"></param>
|
/// <returns></returns>
|
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();
|
}
|
|
}
|
}
|