使用Rockwell的 RsiOPCAuto.dll
或者Siemens的 Interop.OPCSiemensDAAutomation.dll时,
若直接拷贝的Dll使用,需要注册后才可添加引用到VS2008.
注册:D:\>regsvr32 rsiopcauto.dll
已下为OPC读取标签的核心内容:
使用了Hash表存储标签位置对应标签多代表的含义:
代码如下:
public partial class PZYS_StorQualityMonitor2 : Form
{
public PZYS_StorQualityMonitor2()
{
InitializeComponent();
}
//错误列表
private static IList<Struct_ErrMessage> ErrList = new List<Struct_ErrMessage>();
/***************OPC采集全局静态变量**************
*使用局部变量不能持续刷新标签
*全局静态变量可以持续刷新标签数据
*/
//OPC服务器
private static OPCServer OpcSvr = new OPCServerClass();
//OPC组集
private static OPCGroups OpcGps;
//储柜标签组,仅使用一个
private static OPCGroup OpcGpStorage;
/********************哈希缓存表***************************/
//哈希表,缓存储柜号与标签组中ID的匹配关系
private static Hashtable HashCache_storage = Hashtable.Synchronized(new Hashtable());
/// <summary>
/// 页面加载
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PZYS_StorQualityMonitor2_Load(object sender, EventArgs e)
{
//初始化OPC
InitializeOPCObject();
}
//********************OPC配置***************************
/// <summary>
/// OPC初始化
/// </summary>
/// <returns></returns>
private void InitializeOPCObject()
{
try
{
//读取OPC配置信息
string OPCServerName = System.Configuration.ConfigurationSettings.AppSettings["OPCServerName"].Trim();
string NodeName = System.Configuration.ConfigurationSettings.AppSettings["NodeName"].Trim();
//与OPC服务器建立连接
OpcSvr.Connect(OPCServerName, NodeName);
//建立OPC服务器标签组集合
OpcGps = OpcSvr.OPCGroups;
OpcGps.DefaultGroupUpdateRate = 1000;
OpcGps.DefaultGroupIsActive = true;
//初始化储柜标签组
InitializeOpcGpStorageTag();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "初始化错误,发生时刻:"+System.DateTime.Now.ToString());
}
}
/// <summary>
/// 初始化储柜标签组
/// </summary>
private void InitializeOpcGpStorageTag()
{
//储柜标签组
OpcGpStorage = OpcGps.Add("Storage");
//OpcGpStorage.OPCItems.DefaultAccessPath = "PLC2006";
OpcGpStorage.UpdateRate = 1000;
OpcGpStorage.IsActive = true;
OpcGpStorage.IsSubscribed = true;
//*************此DataChage事件必须定义在标签初始化之前才可以获取到标签的初始值********************//
//标签组数值变化处理函数
OpcGpStorage.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(OpcGpStorage_DataChange);
//获取储柜标签列表
IList<Model.PZYS_Storage.StorageTag> StorTagList = BusinessLogicLayer.PZYS_Storage.StorageTag.GetAllStorageTagList();
//位置号
int Position = 1;
foreach (Model.PZYS_Storage.StorageTag tag in StorTagList)
{
//储柜任务号
if (tag.Tag_StorTaskID.Trim() != "")
{
try
{
Struct_StorageFeild StorField = new Struct_StorageFeild();
StorField.StorID = tag.StorID;
StorField.FeildName = ENUM_StorageFeild.StorTaskID;
HashCache_storage.Add(Position, StorField);
OpcGpStorage.OPCItems.AddItem(tag.Tag_StorTaskID, Position);
}
catch(Exception ex)
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "储柜[" + tag.StorName + "]“储柜任务号标签”错误。信息:"+ex.ToString();
ErrList.Add(emsg);
}
Position++;
}
else
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "储柜["+tag.StorName+"]没有配置“储柜任务号标签”";
ErrList.Add(emsg);
}
//储柜批次
if (tag.Tag_Batch.Trim() != "")
{
try
{
Struct_StorageFeild StorField = new Struct_StorageFeild();
StorField.StorID = tag.StorID;
StorField.FeildName = ENUM_StorageFeild.Batch;
HashCache_storage.Add(Position, StorField);
OpcGpStorage.OPCItems.AddItem(tag.Tag_Batch, Position);
}
catch (Exception ex)
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "储柜[" + tag.StorName + "]“储柜批次标签”错误。信息:" + ex.ToString();
ErrList.Add(emsg);
}
Position++;
}
else
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "储柜[" + tag.StorName + "]没有配置“储柜批次标签”";
ErrList.Add(emsg);
}
//储柜牌号ID
if (tag.Tag_BrandID.Trim() != "")
{
try
{
Struct_StorageFeild StorField = new Struct_StorageFeild();
StorField.StorID = tag.StorID;
StorField.FeildName = ENUM_StorageFeild.BrandID;
HashCache_storage.Add(Position, StorField);
OpcGpStorage.OPCItems.AddItem(tag.Tag_BrandID, Position);
}
catch (Exception ex)
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "储柜[" + tag.StorName + "]“储柜牌号ID标签”错误。信息:" + ex.ToString();
ErrList.Add(emsg);
}
Position++;
}
else
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "储柜[" + tag.StorName + "]没有配置“储柜牌号ID标签”";
ErrList.Add(emsg);
}
//储柜运行状态
if (tag.Tag_RunState.Trim() != "")
{
try
{
Struct_StorageFeild StorField = new Struct_StorageFeild();
StorField.StorID = tag.StorID;
StorField.FeildName = ENUM_StorageFeild.RunState;
HashCache_storage.Add(Position, StorField);
OpcGpStorage.OPCItems.AddItem(tag.Tag_RunState, Position);
}
catch (Exception ex)
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "储柜[" + tag.StorName + "]“储柜运行状态标签”错误。信息:" + ex.ToString();
ErrList.Add(emsg);
}
Position++;
}
else
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "储柜[" + tag.StorName + "]没有配置“储柜运行状态标签”";
ErrList.Add(emsg);
}
//储柜重量
if (tag.Tag_Weight.Trim() != "")
{
try
{
Struct_StorageFeild StorField = new Struct_StorageFeild();
StorField.StorID = tag.StorID;
StorField.FeildName = ENUM_StorageFeild.Weight;
HashCache_storage.Add(Position, StorField);
OpcGpStorage.OPCItems.AddItem(tag.Tag_Weight, Position);
}
catch (Exception ex)
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "储柜[" + tag.StorName + "]“储柜重量标签”错误。信息:" + ex.ToString();
ErrList.Add(emsg);
}
Position++;
}
else
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "储柜[" + tag.StorName + "]没有配置“储柜重量标签”";
ErrList.Add(emsg);
}
//储柜底带剩余
if (tag.Tag_RemailPercent.Trim() != "")
{
try
{
Struct_StorageFeild StorField = new Struct_StorageFeild();
StorField.StorID = tag.StorID;
StorField.FeildName = ENUM_StorageFeild.RemainPercent;
HashCache_storage.Add(Position, StorField);
OpcGpStorage.OPCItems.AddItem(tag.Tag_RemailPercent, Position);
}
catch (Exception ex)
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "储柜[" + tag.StorName + "]“储柜底带剩余标签”错误。信息:" + ex.ToString();
ErrList.Add(emsg);
}
Position++;
}
else
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "储柜[" + tag.StorName + "]没有配置“储柜底带剩余标签”";
ErrList.Add(emsg);
}
//储柜统计标记
if (tag.Tag_StatMarkStr.Trim() != "")
{
try
{
Struct_StorageFeild StorField = new Struct_StorageFeild();
StorField.StorID = tag.StorID;
StorField.FeildName = ENUM_StorageFeild.StatMarkStr;
HashCache_storage.Add(Position, StorField);
OpcGpStorage.OPCItems.AddItem(tag.Tag_StatMarkStr, Position);
}
catch (Exception ex)
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "储柜[" + tag.StorName + "]“储柜统计标记标签”错误。信息:" + ex.ToString();
ErrList.Add(emsg);
}
Position++;
}
else
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "储柜[" + tag.StorName + "]没有配置“储柜底带剩余标签”";
ErrList.Add(emsg);
}
}
//foreach循环结束
}
/// <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>
void OpcGpStorage_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
{
try
{
//变化标签的位置
int Position = 0;
//变化的数值
string ChangeValue = "";
//储柜编号
string StorID = "";
//数据质量
string Quality = "";
//此项对应的数据库字段位置
ENUM_StorageFeild Field = ENUM_StorageFeild.StatMarkStr;
for (int i = 1; i <= ClientHandles.Length; i++)
{
//变化标签的位置号
Position = (int)ClientHandles.GetValue(i);
//变化值
ChangeValue = ItemValues.GetValue(i).ToString();
Struct_StorageFeild StorField = (Struct_StorageFeild)HashCache_storage[Position];
//变化位置好对应的储柜ID
StorID = StorField.StorID;
//对应的字段位置
Field = StorField.FeildName;
//质量
Quality = Qualities.GetValue(i).ToString();
if (Quality != "192")
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "字段【"+Field.ToString()+"】获取到Bad数据,柜号:" + StorID + ";bad值:" + ChangeValue + ";";
ErrList.Add(emsg);
continue;
}
//数据库更新影响行数
int rlt = 0;
if (Field == ENUM_StorageFeild.Batch)//更新 批次
{
rlt= BusinessLogicLayer.PZYS_Storage.StorageData.UpdateStorageBatch(StorID,ChangeValue);
if (rlt != 1)
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "【批次】值数据更新错误,柜号:" + StorID + ";更新值:" + ChangeValue + ";数据库返回影响行数:"+rlt.ToString()+";";
ErrList.Add(emsg);
}
}
else if (Field == ENUM_StorageFeild.BrandID)//更新 牌号ID
{
rlt = BusinessLogicLayer.PZYS_Storage.StorageData.UpdateStorageBrandID(StorID, ChangeValue);
if (rlt != 1)
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "【牌号ID】值数据更新错误,柜号:" + StorID + ";更新值:" + ChangeValue + ";数据库返回影响行数:" + rlt.ToString() + ";";
ErrList.Add(emsg);
}
}
else if (Field == ENUM_StorageFeild.RemainPercent)//更新 底带剩余
{
rlt = BusinessLogicLayer.PZYS_Storage.StorageData.UpdateStorageRemainPercent(StorID, ChangeValue);
if (rlt != 1)
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "【底带剩余】值数据更新错误,柜号:" + StorID + ";更新值:" + ChangeValue + ";数据库返回影响行数:" + rlt.ToString() + ";";
ErrList.Add(emsg);
}
}
else if (Field == ENUM_StorageFeild.RunState)//更新 运行状态
{
rlt = BusinessLogicLayer.PZYS_Storage.StorageData.UpdateStorageRunState(StorID, ChangeValue);
if (rlt != 1)
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "【运行状态】值数据更新错误,柜号:" + StorID + ";更新值:" + ChangeValue + ";数据库返回影响行数:" + rlt.ToString() + ";";
ErrList.Add(emsg);
}
}
else if (Field == ENUM_StorageFeild.StatMarkStr)//更新 统计标记
{
rlt = BusinessLogicLayer.PZYS_Storage.StorageData.UpdateStorageStatMarkStr(StorID, ChangeValue);
if (rlt != 1)
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "【统计标识】值数据更新错误,柜号:" + StorID + ";更新值:" + ChangeValue + ";数据库返回影响行数:" + rlt.ToString() + ";";
ErrList.Add(emsg);
}
}
else if (Field == ENUM_StorageFeild.StorTaskID)//更新 进柜任务ID
{
rlt = BusinessLogicLayer.PZYS_Storage.StorageData.UpdateStorageTaskID(StorID, ChangeValue);
if (rlt != 1)
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "【进柜任务ID】值数据更新错误,柜号:" + StorID + ";更新值:" + ChangeValue + ";数据库返回影响行数:" + rlt.ToString() + ";";
ErrList.Add(emsg);
}
}
else if (Field == ENUM_StorageFeild.Weight)//更新 存量
{
rlt = BusinessLogicLayer.PZYS_Storage.StorageData.UpdateStorageWeight(StorID, ChangeValue);
if (rlt != 1)
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "【存储量】值数据更新错误,柜号:" + StorID + ";更新值:" + ChangeValue + ";数据库返回影响行数:" + rlt.ToString() + ";";
ErrList.Add(emsg);
}
}
}
}
catch (Exception ex)
{
Struct_ErrMessage emsg = new Struct_ErrMessage();
emsg.TimeStamp = System.DateTime.Now;
emsg.ErrText = "标签变化值更新错误!" + ex.ToString();
ErrList.Add(emsg);
}
//最后刷新时间
label3.Text = "OPC最后反馈时间:" + System.DateTime.Now.ToString();
}
//******************基础结构*********************
/// <summary>
/// 异常错误信息结构
/// </summary>
private struct Struct_ErrMessage
{
/// <summary>
/// 发生时刻
/// </summary>
public DateTime TimeStamp;
/// <summary>
/// 错误信息
/// </summary>
public string ErrText;
}
/// <summary>
/// 储柜字段结构
/// </summary>
private struct Struct_StorageFeild
{
/// <summary>
/// 发生时刻
/// </summary>
public string StorID;
/// <summary>
/// 错误信息
/// </summary>
public ENUM_StorageFeild FeildName;
}
/// <summary>
/// 储柜表字段使用标签更新列的枚举
/// </summary>
private enum ENUM_StorageFeild
{
/// <summary>
/// 储柜任务号
/// </summary>
StorTaskID = 0,
/// <summary>
/// 批次
/// </summary>
Batch = 1,
/// <summary>
/// 牌号ID
/// </summary>
BrandID = 2,
/// <summary>
/// 储柜重量
/// </summary>
Weight = 3,
/// <summary>
/// 底带剩余量
/// </summary>
RemainPercent = 4,
/// <summary>
/// 储柜运行状态
/// </summary>
RunState = 5,
/// <summary>
/// 统计标识字符串,任务号+X或Y,Y表示统计
/// </summary>
StatMarkStr = 6
}
//****************************************************
}