【转】(C#)OPC客户端源码

 

前几天我就发布过这篇文章,可惜的是,发布后代码有的却看不到,后来我就删了,至今不明白什么原因- -!

关于C++、VB来开发OPC客户端的资料网上有很多,但C#的至今没发现有多少。

由于近期项目的需要,就开发了OPC客户端的一个模块。在我想来,程序员挺累的,原因我很累。所以我想大家也很累~~~嘿嘿。

特别是刚接手OPC客户端开发的前几天,天天盯住显示器,百度、GOOGLE不停的搜索。每天早上醒来,眼睛都瑟瑟的。

从事3年以上软件开发的朋友们,估计都会腰酸背痛吧!反正我是这样的。

不说那么多废话了,贴上源码,让需要的同行看看吧,代码的质量并不高,就当做抛砖引玉吧!

 


 

1、枚举本地服务器

2、获取服务器信息

3、列出了服务器上Tag

4、可以设置组的属性

5、读/写功能

6、可进行远程连接(DCOM需配置)

先看图:

引用类库:

OPC服务器:

开发工具:

当前环境:

 

源码:

 

///摘要
///程式使用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
    }
}
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
OPC客户C是一种与OPC服务器通信的软件。OPC(OLE for Process Control)是一种用于实时数据通信的开放标准,它允许不同供应商的软件和硬件设备在同一个网络上进行数据交换。 OPC客户C是一种OPC客户的具体实现。它通过与OPC服务器建立连接,可以读取和写入OPC服务器中的实时数据。OPC客户C可以是独立的软件应用程序,也可以是集成在其他系统中的模块。 使用OPC客户C可以实现以下功能: 1. 读取实时数据:OPC服务器中存储有各种实时数据,如温度、压力、流量等。OPC客户C可以向OPC服务器发送读取数据的请求,获取最新的实时数据。 2. 写入实时数据:除了读取,OPC客户C还可以向OPC服务器发送写入数据的请求,更新OPC服务器中的实时数据。 3. 监控报警信息:OPC服务器会监控各种参数,当某个参数超出设定的阈值时,会生成报警信息。OPC客户C可以接收并显示这些报警信息,供操作员及时处理。 4. 历史数据查询:OPC服务器会保存历史数据,OPC客户C可以向OPC服务器发送历史数据查询的请求,获取指定时间范围内的数据记录。 5. 数据分析与报表生成:OPC客户C可以将获取到的数据进行分析处理,并生成统计报表,以帮助用户更好地监控和管理实时数据。 总之,OPC客户C是一种用于与OPC服务器通信的软件,通过与OPC服务器建立连接,可以读取和写入实时数据,监控报警信息,查询历史数据并进行数据分析和报表生成。它在工业自动化系统和监控系统中发挥着重要的作用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值