紫外工控论坛

 找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

搜索
查看: 2755|回复: 0

[其他] 【转】(C#)OPC客户端源码

[复制链接]
冰糖 发表于 2011-7-11 14:05:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
前几天我就发布过这篇文章,可惜的是,发布后代码有的却看不到,后来我就删了,至今不明白什么原因- -!
关于C++、VB来开发OPC客户端的资料网上有很多,但C#的至今没发现有多少。
由于近期项目的需要,就开发了OPC客户端的一个模块。在我想来,程序员挺累的,原因我很累。所以我想大家也很累~~~嘿嘿。
特别是刚接手OPC客户端开发的前几天,天天盯住显示器,百度、GOOGLE不停的搜索。每天早上醒来,眼睛都瑟瑟的。
从事3年以上软件开发的朋友们,估计都会腰酸背痛吧!反正我是这样的。
不说那么多废话了,贴上源码,让需要的同行看看吧,代码的质量并不高,就当做抛砖引玉吧!



1、枚举本地服务器
2、获取服务器信息
3、列出了服务器上Tag
4、可以设置组的属性
5、读/写功能
6、可进行远程连接(DCOM需配置)
先看图:

引用类库:

OPC服务器:

开发工具:

当前环境:

源码:

Code
///摘要
///程式使用C#.NET 2005 编写
///引用类库OPCDAAuto.dll
///OPCServer采用KEPWare
///在windows xp sp2、sp3、windows 2003上测试通过
///完成于:2008年12月31日
///测试于:2009年01月05日
///
///作者:潇洒草
///Email:zhkai868@163.com
///QQ:44649029
///
///如分发,请保留此摘要。
///鄙视那些拿代码当宝贝的人,鄙视那些你不拿源码换就不稀罕你的人,鄙视那些自私的人。
///别人看到你的代码,你能死啊?对你有多大威胁啊?强烈鄙视~~~
///如果你是这样的人,赶紧关了。。偶不欢迎。。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Collections;
using OPCAutomation;

namespace OPC测试通过
{
public
partial
class MainFrom : Form
{
public MainFrom()
{
InitializeComponent();
}

#region 私有变量
///
<summary>
/// OPCServer Object
///
</summary>
OPCServer KepServer;
///
<summary>
/// OPCGroups Object
///
</summary>
OPCGroups KepGroups;
///
<summary>
/// OPCGroup Object
///
</summary>
OPCGroup KepGroup;
///
<summary>
/// OPCItems Object
///
</summary>
OPCItems KepItems;
///
<summary>
/// OPCItem Object
///
</summary>
OPCItem KepItem;
///
<summary>
/// 主机IP
///
</summary>

string strHostIP =
"";
///
<summary>
/// 主机名称
///
</summary>

string strHostName =
"";
///
<summary>
/// 连接状态
///
</summary>

bool opc_connected =
false;
///
<summary>
/// 客户端句柄
///
</summary>

int itmHandleClient =
0;
///
<summary>
/// 服务端句柄
///
</summary>

int itmHandleServer =
0;
#endregion
#region 方法
///
<summary>
/// 枚举本地OPC服务器
///
</summary>

private
void GetLocalServer()
{
//获取本地计算机IP,计算机名称
IPHostEntry IPHost = Dns.Resolve(Environment.MachineName);
if (IPHost.AddressList.Length >
0)
{
strHostIP
= IPHost.AddressList[0].ToString();
}
else
{
return;
}
//通过IP来获取计算机名称,可用在局域网内
IPHostEntry ipHostEntry = Dns.GetHostByAddress(strHostIP);
strHostName
=ipHostEntry.HostName.ToString();

//获取本地计算机上的OPCServerName

try
{
KepServer
=
new OPCServer();
object serverList = KepServer.GetOPCServers(strHostName);

foreach (string turn in (Array)serverList)
{
cmbServerName.Items.Add(turn);
}

cmbServerName.SelectedIndex
=
0;
btnConnServer.Enabled
=
true;
}
catch(Exception err)
{
MessageBox.Show(
"枚举本地OPC服务器出错:"+err.Message,"提示信息",MessageBoxButtons.OK,MessageBoxIcon.Warning);
}

}
///
<summary>
/// 创建组
///
</summary>

private
bool CreateGroup()
{
try
{
KepGroups
= KepServer.OPCGroups;
KepGroup
= KepGroups.Add("OPCDOTNETGROUP");
SetGroupProperty();
KepGroup.DataChange
+=
new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);
KepGroup.AsyncWriteComplete
+=
new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(KepGroup_AsyncWriteComplete);
KepItems
= KepGroup.OPCItems;
}
catch (Exception err)
{
MessageBox.Show(
"创建组出现错误:"+err.Message,"提示信息",MessageBoxButtons.OK,MessageBoxIcon.Warning);
return
false;
}
return
true;
}
///
<summary>
/// 设置组属性
///
</summary>

private
void SetGroupProperty()
{
KepServer.OPCGroups.DefaultGroupIsActive
=Convert.ToBoolean(txtGroupIsActive.Text);
KepServer.OPCGroups.DefaultGroupDeadband
= Convert.ToInt32(txtGroupDeadband.Text);
KepGroup.UpdateRate
= Convert.ToInt32(txtUpdateRate.Text);
KepGroup.IsActive
= Convert.ToBoolean(txtIsActive.Text);
KepGroup.IsSubscribed
=Convert.ToBoolean(txtIsSubscribed.Text);
}
///
<summary>
/// 列出OPC服务器中所有节点
///
</summary>
///
<param name="oPCBrowser"></param>

private
void RecurBrowse(OPCBrowser oPCBrowser)
{
//展开分支
oPCBrowser.ShowBranches();
//展开叶子
oPCBrowser.ShowLeafs(true);
foreach (object turn in oPCBrowser)
{
listBox1.Items.Add(turn.ToString());
}
}
///
<summary>
/// 获取服务器信息,并显示在窗体状态栏上
///
</summary>

private
void GetServerInfo()
{
tsslServerStartTime.Text
="开始时间:"+ KepServer.StartTime.ToString()+"
";
tsslversion.Text
="版本:"+ KepServer.MajorVersion.ToString() +
"."
+ KepServer.MinorVersion.ToString()+"."+KepServer.BuildNumber.ToString();
}
///
<summary>
/// 连接OPC服务器
///
</summary>
///
<param name="remoteServerIP">OPCServerIP</param>
///
<param name="remoteServerName">OPCServer名称</param>

private
bool ConnectRemoteServer(string remoteServerIP, string remoteServerName)
{
try
{
KepServer.Connect(remoteServerName, remoteServerIP);

if (KepServer.ServerState == (int)OPCServerState.OPCRunning)
{
tsslServerState.Text
=
"已连接到-"
+ KepServer.ServerName +
"
";
}
else
{
//这里你可以根据返回的状态来自定义显示信息,请查看自动化接口API文档
tsslServerState.Text =
"状态:"
+ KepServer.ServerState.ToString() +
"
";
}
}
catch (Exception err)
{
MessageBox.Show(
"连接远程服务器出现错误:"
+ err.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return
false;
}
return
true;
}
#endregion
#region 事件
///
<summary>
/// 写入TAG值时执行的事件
///
</summary>
///
<param name="TransactionID"></param>
///
<param name="NumItems"></param>
///
<param name="ClientHandles"></param>
///
<param name="Errors"></param>

void KepGroup_AsyncWriteComplete(int TransactionID, int NumItems, ref Array ClientHandles, ref Array Errors)
{
lblState.Text
=
"";
for (int i =
1; i <= NumItems; i++)
{
lblState.Text
+=
"Tran:"
+ TransactionID.ToString() +
" CH:"
+ ClientHandles.GetValue(i).ToString() +
" Error:"
+ Errors.GetValue(i).ToString();
}
}
///
<summary>
/// 每当项数据有变化时执行的事件
///
</summary>
///
<param name="TransactionID">处理ID</param>
///
<param name="NumItems">项个数</param>
///
<param name="ClientHandles">项客户端句柄</param>
///
<param name="ItemValues">TAG值</param>
///
<param name="Qualities">品质</param>
///
<param name="TimeStamps">时间戳</param>

void KepGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
{
//为了测试,所以加了控制台的输出,来查看事物ID号
//Console.WriteLine("********"+TransactionID.ToString()+"*********");

for (int i =
1; i <= NumItems; i++)
{
this.txtTagValue.Text = ItemValues.GetValue(i).ToString();
this.txtQualities.Text = Qualities.GetValue(i).ToString();
this.txtTimeStamps.Text = TimeStamps.GetValue(i).ToString();
}
}
///
<summary>
/// 选择列表项时处理的事情
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>

private
void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
if (itmHandleClient !=
0)
{
this.txtTagValue.Text =
"";
this.txtQualities.Text ="";
this.txtTimeStamps.Text =
"";

Array Errors;
OPCItem bItem
= KepItems.GetOPCItem(itmHandleServer);
//注:OPC中以1为数组的基数

int[] temp =
new
int[2] { 0, bItem.ServerHandle };
Array serverHandle
= (Array)temp;
//移除上一次选择的项
KepItems.Remove(KepItems.Count, ref serverHandle, out Errors);
}
itmHandleClient
=
1234;
KepItem
= KepItems.AddItem(listBox1.SelectedItem.ToString(), itmHandleClient);
itmHandleServer
= KepItem.ServerHandle;
}
catch(Exception err)
{
//没有任何权限的项,都是OPC服务器保留的系统项,此处可不做处理。
itmHandleClient =
0;
txtTagValue.Text
=
"Error ox";
txtQualities.Text
=
"Error ox";
txtTimeStamps.Text
=
"Error ox";
MessageBox.Show(
"此项为系统保留项:"+err.Message,"提示信息");
}
}
///
<summary>
/// 载入窗体时处理的事情
///
</summary>

private
void MainFrom_Load(object sender, EventArgs e)
{
GetLocalServer();
}
///
<summary>
/// 关闭窗体时处理的事情
///
</summary>

private
void MainFrom_FormClosing(object sender, FormClosingEventArgs e)
{
if (!opc_connected)
{
return;
}

if (KepGroup !=
null)
{
KepGroup.DataChange
-=
new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);
}

if (KepServer !=
null)
{
KepServer.Disconnect();
KepServer
=
null;
}

opc_connected
=
false;
}
///
<summary>
/// 【按钮】设置
///
</summary>

private
void btnSetGroupPro_Click(object sender, EventArgs e)
{
SetGroupProperty();
}
///
<summary>
/// 【按钮】连接OPC服务器
///
</summary>

private
void btnConnLocalServer_Click(object sender, EventArgs e)
{
try
{
if (!ConnectRemoteServer(txtRemoteServerIP.Text,cmbServerName.Text))
{
return;
}

btnSetGroupPro.Enabled
=
true;

opc_connected
=
true;

GetServerInfo();

RecurBrowse(KepServer.CreateBrowser());

if (!CreateGroup())
{
return;
}
}
catch (Exception err)
{
MessageBox.Show(
"初始化出错:"
+ err.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
///
<summary>
/// 【按钮】写入
///
</summary>

private
void btnWrite_Click(object sender, EventArgs e)
{
OPCItem bItem
= KepItems.GetOPCItem(itmHandleServer);
int[] temp =
new
int[2] { 0, bItem.ServerHandle };
Array serverHandles
=(Array)temp;
object[] valueTemp =
new
object[2] {"",txtWriteTagValue.Text };
Array values
=(Array)valueTemp;
Array Errors;
int cancelID;
KepGroup.AsyncWrite(
1,ref serverHandles,ref values,out Errors, 2009,out cancelID);
//KepItem.Write(txtWriteTagValue.Text);//这句也可以写入,但并不触发写入事件
GC.Collect();
}
#endregion
}
}

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


--------------------------------------------------------------------------------------------------------------------
本站是工控技术交流站点,论坛内容均为网络收集或会员所发表,并不代表本站立场,会员拥有该内容的所有权力及责任!
本站内容如有侵犯您的版权,请按下面方式联系本站管理员,我们将及时删除处理
管理员:冰糖 QQ:5483695(请直击主题), Mail:admin#ziwai.net(#改成@) 其它非本人.
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论!

QQ|Archiver|手机版|小黑屋|紫外工控论坛. ( 苏ICP备11032118号-1 )

GMT+8, 2024-5-7 11:36 , Processed in 0.328127 second(s), 17 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表